apmsooner → created an issue.
This now works good with ctools blocks, layout builder, etc... so merging and calling it Fixed!
Okay, i'm also unable to produce this issue on another site now and I think what we're seeing here is from another patch at https://www.drupal.org/project/graphql_compose/issues/3507357 🐛 Cannot return null for non-nullable field for Link Field in Paragraph Active so I'll modify that patch and I'm sure that will fix this issue and will close accordingly.
Let me see. It would need to happen in the RoutesTest.php I would guess since thats where we're seeing it.
apmsooner → created an issue.
apmsooner → created an issue.
@mrconnerton, I created a documentation page. Can you review this and improve if needed?
https://www.drupal.org/docs/extending-drupal/contributed-modules/contrib... →
Oh wow, thats awesome news! Yes, if you would create a new page there, that would be perfect and appreciated!
apmsooner → created an issue.
You could essentially have a valid name & url but null width/height which would cause issues with the schema expected. I stand by the PR as is.
@klausi,
I added the fallback because the values could technically be null if the image is invalid. Thinking with migrations and such, there could be bad images and the graphql_compose module expects a nonNull value in its schema. I mean theres nothing preventing anyone from setting the value for width/height to null so I felt it was better to have a safe fallback.
https://git.drupalcode.org/project/graphql_compose/-/blob/2.4.x/modules/...
Ahh, yeah theres no main property on custom fields. Relationships are supported in views if you can go that route. The dot notation stuff on referenced entities I guess is specific for entity references at the field level. So you would otherwise probably have to go with the database api select query.
I don't know for sure but try this:
field_custom.reference__entity.field_number
the custom field name with __entity appended (double underscore) is a computed property.
Thanks for the encouragement and happy the module is found useful! Good interim idea for your own custom widget. The documentation is here for doing that: https://www.drupal.org/docs/extending-drupal/contributed-modules/contrib... →
I honestly havn't used layout_paragraphs and therefore didn't have a chance to test this scenario. I will try to find time to test it and reproduce the issue but it also looks like theres a good number of issues with their module with at least a few related to media so really hard to say where the issue lives. I do know that in normal paragraphs, the media library widget has been working as expected. Layout paragraphs must be doing something a little differently perhaps.
I've never used twig_tweak but from the cheat sheet listed on the module page, it looks to be pretty specifically coded for the common fields in core and doesn't look to support custom fields with properties unknown to its own api. You might ask in their channel but I don't really know how I could help you for this module. Generally speaking, theres a ton of formatters that come with this module with some advanced display settings like being able to modify field wrappers and add classes so not really sure how much value twig_tweak would provide beyond that.
I can't merge this with renderRoot solution. The cache doesn't get invalidated. Clone your custom field to a node type and you'll see that a referenced entity when changed does not change the rendered result on the custom field. I'm gonna push a new release but will have to leave this on hold for now as I just can't reproduce the issue and I don't feel comfortable with the caching issue resulting from swapping out renderRoot for render.
I also just tested placing the block in a block layout (theme region) and not using layout builder. I have no issues with rendering as is with the patch. Not getting those errors and not having to convert to renderRoot. What version of Drupal core are you on? I'm on 10.4.3 locally. I can only assume you must have something considerably different going on than me with your configuration and I don't know of anyone else having this issue. I was previously getting similar errors when in layout builder but just moving the render up to the base formatter of the field resolved that. I assume also this is just a custom field directly on the block right? No paragraphs or other weirdness in the mix?
Thanks @benstallings,
If anyone finds any further issues with this, please open a new ticket but I think we are good to go so merging :)
@ultrabob, Something to note here is that with renderRoot and I assume also renderInIsolation, the cache tags don't get invalidated so if you had changed the referenced entity's title for instance, you likely didn't see that change reflected on the parent entity. Now, with the changes, you should see proper behavior. I was able to reproduce a similar error you were receiving prior to the change which was happening on updating the block in layout builder. I don't ever use layout builder so didn't catch this problem. I do think the updated patch should resolve your issues though and encompasses all the formatters that were using the renderer method.
renderRoot isn't working cause cache isn't getting invalidated so I moved the render call up the field BaseFormatter and it seems to be working fine with this revision both in layout builder and in normal entity context. Please test the revised patch and see if that works for you.
Filters, arguments and sort all available in the patch. Please test and add a review.
Thanks for the encouragement! I've tried to promote the module in slack and various other places to increase usage but I guess alot of devs like to do things their own way or just don't understand the value proposition.
I ran this through Grok to get suggestions and explain the impact of the suggested change. It suggested instead using renderRoot(). I need verification that the following would work and test out in both cases for working in layout builder while preserving cache invalidation in other contexts.
Your concern is valid: the difference between render() and renderInIsolation() (or similar methods) in Drupal’s rendering system can indeed affect how caching behaves, especially when moving from a node context to a Layout Builder block context. Let’s analyze the issue, explain why the error occurs, assess the caching implications, and propose a solution that balances functionality and performance.
The Problem
Normal Node Context: Your formatValue() method works fine because nodes are typically rendered as part of a full page render pipeline, where the renderer (RendererInterface) can process the render array ($build) and integrate it into the page’s cacheable metadata (e.g., cache tags, contexts, etc.).
Layout Builder Block Context: When this field is rendered inside a block used in Layout Builder, the rendering process happens in a more isolated or nested context. Layout Builder often renders components individually, and the renderer may expect the output to be "isolated" (e.g., not relying on the full page’s render pipeline). The error suggesting renderInIsolation() likely stems from this isolation requirement—Drupal’s renderer might detect that $this->renderer->render($build) is being called in a way that doesn’t properly handle nested rendering or placeholder replacement.
render() vs. renderInIsolation()
render():
Processes the render array, applies #pre_render callbacks, resolves placeholders, and integrates cache metadata into the current render context.
Relies on being part of a broader render pipeline (e.g., a page or a parent element) to finalize output and caching.
If called in an isolated context (like Layout Builder’s block rendering), it might throw an error or fail to handle nested dependencies correctly.
renderInIsolation():
Renders the element in a standalone way, bypassing some of the broader render context dependencies (e.g., placeholders or late-stage processing).
Often used for AJAX responses, previews, or isolated components where the full page context isn’t available.
Can skip certain optimizations (like placeholder replacement), potentially impacting caching.
Caching Concerns
In Node Context: Using render() ensures that the cache metadata (e.g., #cache['tags'] from the entity) is bubbled up to the page level. This means the node’s rendered output is cached efficiently, and cache invalidation works as expected (e.g., when the referenced entity changes, its cache tags invalidate the node’s cache).
With renderInIsolation(): If you switch to renderInIsolation(), the rendered output might not fully participate in the page’s cache bubbling. This could:
Prevent cache tags from being merged into the parent context (e.g., the block or page), reducing cache invalidation granularity.
Force the element to be re-rendered more often (e.g., if it’s treated as uncacheable or cached separately).
Potentially bypass Drupal’s BigPipe or lazy loading optimizations.
Your concern about caching being “negatively impacted in the first scenario” (node context) if you switch to renderInIsolation() is spot-on—moving away from render() could disrupt the seamless cache integration that works well in the node case.
Suggested Solution
To fix the Layout Builder error while preserving caching behavior in both contexts (node and block), you should:
Use renderRoot() instead of renderInIsolation(): This method is designed for rendering standalone elements while still respecting cache metadata and bubbling it up to the parent context.
Ensure cache metadata is properly attached: Explicitly add cache contexts or max-age if needed, though your current #cache['tags'] should suffice for entity-based invalidation.
Test for isolation needs: If renderRoot() doesn’t resolve the error, consider conditionally isolating the render based on the context (though this should be a last resort).
Thanks for the patch and reviews!
apmsooner → made their first commit to this issue’s fork.
apmsooner → created an issue.
@andreasderijcke, can you weigh in with a review on that patch in https://www.drupal.org/project/custom_field/issues/3510744 🐛 Entity translation does not necessarily exist Active please?
Thanks for the patch on this. I verified it was indeed introduced in 10.2. In 10.3 there is a trait introduced that we can use to further simplify but will cross that bridge later ;)
Okay let me test this. If you can please push the change to the issue fork, i can test easier also.
Thank you @keshav! Using the issue forks are definitely preferred :)
PHP stan says they were introduced in 10.3? https://git.drupalcode.org/project/custom_field/-/jobs/4499168
Sorry, I can't make this happen for the same reason you mentioned that custom fields are NOT entities therefore can't be edited contextually on their own. At one time there was the ability to do this for fields but no longer part of CORE. I think its maybe moved to this contrib module that you can maybe try but no idea if it works well: https://www.drupal.org/project/quickedit → .
We will probably need to create a 4.x new branch with core dependency ^10.3 || 11 to handle this as I believe these changes to file logic were introduced in 10.3 and therefore not compatible with 10.2. I'd say let me do that first and then can reassign this issue to that branch.
Hmm... maybe its failing here: https://git.drupalcode.org/project/custom_field/-/blob/3.1.x/src/Plugin/.... If you can open a new ticket with some steps to reproduce, it should be an easy fix.
@swentel, are you using the latest version 3.1.x? The variable here already falls back to empty array so the error shouldn't occur: https://git.drupalcode.org/project/custom_field/-/blob/3.1.x/src/Plugin/...
apmsooner → created an issue.
Merging this fix to resolve the fatal error. Creating a new ticket to track the missing field replacements: https://www.drupal.org/project/custom_field/issues/3509249 🐛 Deep nested field tokens in entity_reference not replaced Active
apmsooner → created an issue.
Merged!
Try the updated patch please. I forgot to add it to the default settings.
Yes, the views support is still a bit spotty in some areas. This would need a custom work and hopefully i can find some time. If anyone else wants to take a stab at it, The relevant files to look at for guidance are:
- core/modules/datetime/datetime.views.inc
- core/modules/datetime/src/Plugin/views
Thanks for the detailed explanation! Yes, i went ahead and already merged it: https://www.drupal.org/project/custom_field/issues/3508870#comment-16004809 🐛 InvalidArgumentException: Invalid translation language (en) specified Active
I'm gonna be putting out a new release soon so if you want this feature in, please review sooner than later. If there's any form field mods you want like label, description, etc... just let me know as they are easy alterations. Thanks
Wasn't able to reproduce but looking at the patch now and seeing the default type, it totally makes sense for your fix so I'm merging. Thanks for the patch!
Can you give some more steps on how to reproduce this? I have an entity already created in english which is my default language. I've added a new language (spanish). Should i change default language here: /admin/config/regional/language to spanish? I tried that and edited the node but didn't see any issues. There must be some other configuration steps i'm missing.
Awesome. Thanks so much and glad you're getting use out of the module. Just an FYI, enable the custom_field_viewfield sub-module and you might get some interesting ideas for sitebuilding ;)
Testing instructions:
- Add a custom field to any entity type
- Make sure you have at least 1 view with a graphql display type
- Add a subfield of type 'viewfield' and any other subfields you like
- Configure the widget viewfield subfield options to enable any views with graphql display types.
- Optionally - configure the custom field to allow 1 or unlimited values.
- Create the entity with attached custom field
- Test the advanced options in the viewfield subfield: arguments (tokens are supported) & items to display
- Test output in graphql explorer
Oh, i guess this is just core stuff. I realize migrate_plus just extends core functionality. So yeah... looks good to me. I'll publish it. Thanks for the contribution and glad it works for you!
Looks pretty good to me. I think you might just want to reference the dependency modules. You're using migrate_plus correct?
Okay great! I think that example works but like i said its been a bit. That example would be pertinent if you were migrating from e.g. xml with structure like:
<links>
<link>
<url>https://www.example.com</url>
<title>Example Website</title>
</link>
<link>
<url>https://www.wikipedia.org</url>
<title>Wikipedia</title>
</link>
<link>
<url>https://www.github.com</url>
<title>GitHub</title>
</link>
</links>
Migrating from csv is a little more challenging for multi-valued fields so I try to avoid it. Feeds module is also supported in custom_field but its a little tricky with multi-valued, you'd basically need to have a source thats providing json that you can import into a temporary target and have a feeds event subscriber in custom module that would convert the data on presave. Here's an example of that:
/**
* Subscribe to events from the `feeds` module.
*/
class FeedsEventSubscriber implements EventSubscriberInterface {
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents(): array {
$events = [];
$events[FeedsEvents::PROCESS_ENTITY_PRESAVE][] = 'presave';
return $events;
}
/**
* Acts on presaving an entity.
*
* @param \Drupal\feeds\Event\EntityEvent $event
* The feed event.
*/
public function presave(EntityEvent $event) {
$json = $event->getItem()->get('portions_json');
$values = json_decode($json, TRUE);
$event->getEntity()->get('field_weights')->setValue($values);
}
}
Same idea as if you had a multi-valued address field using the address module. Custom fields are structured just like address fields or link fields. The properties are just dynamic. Migrations should be handled exactly the same way as if you were importing into one of these field types.
Are you asking for an example for instance with migration yml via migrate_plus module? Its been a bit since I've done migrations and it certainly depends on what the source data looks like but I believe would be handled through a sub_process plugin just like if you were importing into a multi-value drupal core link field. Something like this example? This makes some broad assumptions about the data of course... other migrate plugins may be needed depending on the source.
field_links:
plugin: sub_process
source: links
process:
url:
plugin: get
source: link/url
title:
plugin: get
source: link/title
Try the patch. There will be a new field in the field settings form.
It really should be a CORE thing... but I can do it pretty easily as I assume it could probably take a long time to get reviewed. I'll put together a patch you can test out.
Weird that I can't even reproduce the error in config inspector but the patch isn't gonna break anything either way so merging it in and call it fixed. Thanks
Thanks for the patch. Since we're on at least php 8, how about we simplify to:
$value = $entity?->id();
This patch should resolve the fatal error and would output term properties on the custom field entity reference but any fields on them is still a work in progress. Just wanted to post something here as a placeholder that you may be able to get by with until something more complete is figured out.
Noting also that the Wunder patch referenced above is against the graphql module so do we address these issues there or within graphql_compose? It certainly feels at least graphql_compose is more actively maintained but leveraging functions from graphql which seem to be the source of the underlying issues we're seeing.
@almunnings, i'm assuming yes an abstraction may be favorable but also a behavioral setting to how a site wants to handle. I found in the Wunder starter kit that they also have their own patch (https://patch-diff.githubusercontent.com/raw/drupal-graphql/graphql/pull...) that is addressing similar errors but they are just returning NULL which wouldn't be the expected behavior for everyone. I think there perhaps needs to be an underlying global setting that determines if default language fallbacks should be returned everywhere applicable.
Hmm... yeah that is weird. Thanks for the patch, i'll just double check later today that i can reproduce the same warning and verify it fixes and I'll happily merge in. Appreciate the help :)
Working just fine for me!