Problem/Motivation
Scenario:
-Content type with field_image added.
-Default image set for field on content type.
-Core layout builder is used to define display layout.
-Body field and image field are added in side by side columns.
-Page will render images explicitly added to field on node but not the default field image.
It's worth noting that the issue happens on both default images added to the node bundle scope AND to the field itself.
When this happens, there is NO html output for the image field at all, only the wrapping column.
When layout builder was disabled and I returned to the default display editor, the default image rendered.
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Release notes snippet
Comment | File | Size | Author |
---|
Issue fork drupal-3119786
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
tim.plunkettComment #5
emerham CreditAttribution: emerham as a volunteer commentedShould also add that _any_ fields default values are not rendered on said nodes. Tested Body with summary, Link, email etc
Comment #6
JordiK CreditAttribution: JordiK commentedHad the same problem while using Layout Builder with the user entity and a user picture.
Narrowed down the problem to /core/modules/layout_builder/src/Plugin/Block/FieldBlock.php.
The function blockAccess denies access if the field is empty (using $field->isEmpty()) without a check for a default value.
The issue is that $field->isEmpty() returns TRUE and $fieldDefinition->getDefaultValue() returns an empty array.
Skipping the $field->isEmpty() check for image fields only allows the default image to be rendered.
The rest of the checks, namely whether the user has access to the entity and to the field itself remain untouched.
The patch provided solved the issue for me.
Comment #7
JordiK CreditAttribution: JordiK commentedComment #8
JordiK CreditAttribution: JordiK commentedThe field default value (e.g. for text fields) did not work for me on entities, which were created before this default value was set.
To check this, set a default value for a field of an entity - it will not render for existing entities neither in the entity edit form (empty field), nor in the display. New entities created after that will have the default value for the field populated on the create entity form - if saved, the value gets rendered also in Layout builder.
This is not a problem with Layout builder, but rather how the field system component behaves. Check also these issues:
#1430454: Differentiate NULL and empty for default values
#3003735: Add a way to use field's default value for existing content as well
Comment #9
tim.plunkettIt makes much more sense to be broken for all fields than for just images.
But #6 worries me.
If that's true, where does the default value come from?
Comment #10
JordiK CreditAttribution: JordiK commentedIt is broken only for image fields, as far as I can tell from the cases I tested.
For text fields:
$field->getFieldDefinition->getDefaultValue($entity) returns an array in the form [0][value] = 'some default value'
$field->getSettings() returns an array with settings, such as max-length, case-sensitive etc.
For image fields:
$field->getFieldDefinition->getDefaultValue($entity) returns an empty array.
$field->getSettings() returns an array with image settings, including the default image (if one is set).
Since the role of the blockAccess function is, well, to block access, the simple check for $field->isEmpty() is insufficient for images.
Whether excluding image fields from the check (like in the patch) or creating a more sophisticated IF-statement (e.g. checking that the getSettings() returns an array with a key 'handler' set to 'default:file') will not change the logic much.
Comment #11
tim.plunkettBut why is
$field->getFieldDefinition->getDefaultValue($entity)
empty for images?Comment #12
JordiK CreditAttribution: JordiK commentedI guess because defaults for images (and also files) are stored differently (see the getSettings() return array) - the default_value variable is not used.
And this also is a question which goes beyond the scope and the logic of the layout builder module.
As far as this bug is concerned, for me it is clear that the blockAccess() function needs to be modified (one way or another).
Comment #13
tim.plunkettHere's a fix that correctly uses the Field API (as I understand it), and a kernel test.
This still needs a functional test for a couple field types, including images.
Due to #10, it sounds like this won't fix images.
But this is the API that exists. Layout Builder should not have logic that addresses individual bugs in other parts of core. Either images will be fixable in this patch, or we'll need a follow-up/blocking issue.
Comment #15
JordiK CreditAttribution: JordiK commentedYou are right, it won't.
Let me try to formulate a different question: why do we need a check for the field being empty?
Comment #16
tim.plunkettSee #2918500-61: Create a block which can render entity fields (Comment in 61 leads to new patch in 62, see the interdiff).
Comment #17
Berdiryeah, images always had some pretty weird special handling for default value, could be related to file usage tracking, storing the default explicitly would result in lots and lots of usages being reported on that default image. And you can change the default, but only image fields are capable of doing that.
that said, without reading through that referenced comment closely, default values should otherwise just work. I default value should be explicitly stored in the field and shouldn't need to be checked at runtime. Adding/changing default value later on was never supported.
Comment #18
tim.plunkettGlad you chimed in @Berdir, I was debating about pinging you just now!
That's... unexpected. I'm guessing this has been the case for a long time, but I'm surprised no other code has hit this special case before.
\Drupal\image\Plugin\Field\FieldFormatter\ImageFormatterBase::getEntitiesToView()
seems to be the part that handles default images. And it also consultsisEmpty()
, which is not a good sign.This also doesn't seem to be relevant for files, which might also be a setback. Since the $field object we have access to is
Drupal\file\Plugin\Field\FieldType\FileFieldItemList
, not anything image-specific.Comment #19
JordiK CreditAttribution: JordiK commentedThank you for the clarification in #16, @tim.plunkett!
Adding the condition !$field->getFieldDefinition()->getDefaultValue($entity) does not solve the issue with images (yes, they are weird).
Other field types (e.g. text fields) with default_value set do not render their default_value in Layout builder, only in the entity edit form.
And when the entity is saved after edit, the field value is not empty anymore.
The default_value is not shown on entity view displays either.
Comment #20
JordiK CreditAttribution: JordiK commentedComment #21
andrewsuth CreditAttribution: andrewsuth at World Food Programme commentedI can confirm what JordiK said regarding patch #13 not fixing the visualisation for default images.
As he flagged in another ticket, patch #3067982: Formatters for empty fields do not render with layout builder enabled works for this issue.
Comment #23
Mav_fly CreditAttribution: Mav_fly commentedI used the patch https://www.drupal.org/files/issues/2020-01-24/3067982-8.patch mentioned in https://www.drupal.org/project/drupal/issues/3067982
And the problem was solved for my image fields. But I have also fields of "Font Awesome Icon" and these are still not shown their default values.
This was tested on drupal 8.9.7
Comment #24
JoseCarlosss CreditAttribution: JoseCarlosss commented+1 Mav_fly. Fixed using patch https://www.drupal.org/files/issues/2020-01-24/3067982-8.patch mentioned from this issue https://www.drupal.org/project/drupal/issues/3067982
Comment #25
JoseCarlosss CreditAttribution: JoseCarlosss commented+1 Mav_fly. Fixed using patch https://www.drupal.org/files/issues/2020-01-24/3067982-8.patch mentioned from this issue https://www.drupal.org/project/drupal/issues/3067982
Comment #27
liquidcms CreditAttribution: liquidcms commentedI was not getting the Picture field (core field on User entity) to show the default image when placing this field with Layout Builder.
The patch in #13 against 9.2.8 seems to have fixed this. :)My mistake; as reported above that this does not work for images - this does not work for Picutre default image.
Before this patch, I was using Views to create a block with that field - which does work.
Comment #29
danflanagan8Here's a functional test that exposes the bug, as requested in #13. This patch has the new functional test on top of the fail test from 13.
Comment #30
danflanagan8Oops, git mishap in #29. Here's the correct patch (I hope!)
Comment #32
danflanagan8The new functional test failed as I had hoped, so I'm removing the Needs tests tag.
Now here's the partial fix from #13 applied on top of the patch in #28. We'll see that the functional test still fails. So there's still some work to do here.
Comment #34
danflanagan8Here's yet another patch that I'm expecting to pass. It adds some special logic for image fields since they store the default value differently from other fields.
I'm also adding a number of assertions to the functional test, rearranging, and commenting. Most notably, I add a second image field that does not have a default value, kind of as a control. These are all additions, so I don't feel the need to run yet it as a test only patch again.
Comment #36
danflanagan8Oof, too confident! Here's a slight update to the failing test such that it can handle the new call to
getType()
inFieldBlock
. This should pass...Comment #37
danflanagan8Me again! I realized I messed up setting the default value in my test. Here is a much improved Functional test that I think covers all the bases. Without the fix part of the patch, the improved Functional test still fails only with an image field's default value. LB handles other default values just like normal field-based display does.
Comment #38
WebbehI'm only using #37 for a use-case of an empty image field, but so far it works as expected.
Comment #39
lobodakyrylo CreditAttribution: lobodakyrylo as a volunteer commentedPatch #37 works like a charm.
Comment #40
tim.plunkettI pushed back against this 2 years ago, and I still don't think this is correct now.
See #9 through #18.
And if we must, at least document how broken this is, making it clear that no one field type should be given this special treatment, and file a follow-up to fix it (with an in-code @todo pointing to it)
Comment #41
danflanagan8I looked into this pretty deeply and came to the conclusion that image fields are currently unique and require unique treatment given the current state of APIs.
I did some searching juts now and found a core issue that looks like its goal is to attack the root of the problem: #3005528: Fields' "default value" functionality only works in formatters and widgets, not at the data level and hence not in HTTP APIs
Here's a copy of the patch from #37 with an additional @todo that references that issue. I'm telling it not to run tests because there's no point.
I don't have any strong personal feelings about whether a patch like this should be committed. On one hand, it fixes a bug. On the other hand, the bug should ideally be fixed somewhere else.
Comment #42
tim.plunkettThanks @danflanagan8! Good to see there's a dedicated issue.
I'm going to make one tweak to the code, which is to separate the temporary portion to it's own code block to make it easier to remove someday.
Comment #43
JordiK CreditAttribution: JordiK commentedThank you for digging deeper into it @danflanagan8 - the special treatment of image fields was exactly my point almost two years ago. Would be happy, if this will be (temporarily) solved here, until the big fix for the image fields comes one day.
Comment #44
tonytheferg CreditAttribution: tonytheferg commentedPatch works.
Comment #46
jon.lund CreditAttribution: jon.lund commentedPatch #42 seems to be working for me. I am using Drupal 9.4.2 Note: make sure to Clear Cache... THANK YOU
Comment #48
tim.plunkettSwitched to an MR
Comment #49
smustgrave CreditAttribution: smustgrave at Mobomo commentedTested the MR out following the steps in the summary (thank you for that)
Added an image field to the content type
Set a default image for the field.
Enabled layout builder for the content type
Created a node
Verified image was NOT there
Applied patch
Verified image is now there
Comment #50
crutch CreditAttribution: crutch commentedTrying to move to Layout Builder from Panels, #42 isn't applying for 9.4.5
Comment #51
tim.plunkettComment #52
alexpottNice fix and nice test coverage. It's great to see the follow-up to fix this in a more generic way.
Committed and pushed da8a916ea3 to 10.1.x and 65a6c2fb91 to 10.0.x and 348d20be24 to 9.5.x. Thanks!
As there are no API concerns here and the behaviour fix makes sense backporting the bug fix to 9.5.x.
Comment #56
alexpottDiscussed with @longwave we agreed to backport to 9.4.x too.
Comment #59
kruser CreditAttribution: kruser commented- deleted-