Coming from #2214241-327: Field default markup - removing the divitis
'#theme' => 'field' / template_preprocess_field() / field.html.twig expect the render array's '#items' entry to contain the field values as a FieldItemListInterface object. That is how the preprocessor and template can access the field definition (like, what's the field type, cardinality, etc...) : $element['#items']->getFieldDefinition()
quickedit_test_entity_view_alter(), added in #2057973: Don't add Edit module's data- attributes on pseudo fields (as used e.g. by Display Suite), uses a bespoke "rendered field" to the render array, that is hand-made rather than the actual output of an actual formatter.
It uses '#theme' => 'field' and thus triggers template_preprocess_field() / field.html.twig, but its content is not strictly compatible with what a real formatter would output (see FormatterBase::view()) - notably its '#items' entry is an array of values instead of an object implementing FieldItemListInterface :
function quickedit_test_entity_view_alter(&$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
if ($entity->getEntityTypeId() == 'node' && $entity->bundle() == 'article') {
$build['pseudo'] = array(
'#theme' => 'field',
// ...
'#items' => array(
0 => array(
'value' => 'pseudo field',
),
),
0 => array(
'#markup' => 'pseudo field',
),
);
}
}
#2214241: Field default markup - removing the divitis is currently forced to introduce a safeguard check in template_preprocess_field() like :
$variables['multiple'] = is_object($element['#items']) ? $element['#items']->getFieldDefinition()->getFieldStorageDefinition()->isMultiple() : FALSE;
We should fix this, $element['#items'] should by contract be a FieldItemListInterface. template_preprocess_field() (or any other custom field preprocessors or templates trying to access the field definition) shouldn't have to safeguard for tests that take shortcuts :-)
Comment | File | Size | Author |
---|---|---|---|
#28 | 2550225-28.patch | 1.54 KB | swentel |
#12 | 2550225-12.patch | 3.97 KB | swentel |
#17 | interdiff.txt | 1.54 KB | swentel |
#17 | 2550225-17.patch | 4.93 KB | swentel |
Comments
Comment #2
yched CreditAttribution: yched commentedComment #3
Wim LeersI should ping somebody with significant d.o rights about removing the old component.
Comment #4
Wim LeersHrm:
So it is indeed 100% a test problem, i.e. the "simulation of a pseudofield generated by Display Suite" in
quickedit_test_entity_view_alter()
needs to be updated.I don't know what exactly that should look like, but I think you do, yched? :)
Comment #5
Wim LeersComment #6
yched CreditAttribution: yched commentedSo quickedit_entity_view_alter() is mimicking what DS "pseudo fields" do, to make sure that core's quickedit support them, correct ?
I'm not too familiar with DS pseudo fields, but I fear it might be tricky to make them go through '#theme' => 'field' *without* being backed by an "official field with an officially registered definition in that entity type + bundle".
Because :
- '#theme' => 'field' and its substack (preprocess + template) assume they have a FieldItemListInterface object to work with in #items
- Would need checking, but IIRC, it's not easy to build a bespoke, runtime FieldItemList object based on an arbitrary runtime field definition. The ContentEntity / Field system is (sadly, but late / hard to change) not designed on an injection pattern, field definitions are *pulled* from the official registry : TypedDataManager::getPropertyInstance() creates FieldItemLists using a "propertyDefinition" that is pulled from EntityManager::getFieldDefinitions(), which itself reads from field.field.* config records. So it's hard to do anything with a runtime field definition that's not in the registry :-/
Comment #7
swentel CreditAttribution: swentel commentedHmm yeah, I started fearing that. The reason why DS uses theme field is because DS also allows you to swap the field templates, for both 'core' fields, and letting the pseudo fields use theme_field is just convenient. But yes, this doesn't fly nicely anymore in D8.
I'll have to figure out whether I can register the fields that are created in DS UI or in code as something that TypedData will understand and then well run through a formatter I guess. However, we'd still need some kind of opt-out if possible.
Other - sad - option is to rework the code completely and register my own theme function. I'll have to think a bit about this - and also have a look at the code, it's been a while :)
Comment #8
yched CreditAttribution: yched commentedWell, if we could make TDM::getPropertyInstance() support "hey, please create a TD object using *this* definition I'm handing you", it could also be pretty handy for a lot of other cases ;-)
Comment #9
yched CreditAttribution: yched commentedEither way, not sure what's the exact use case quickedit_test_entity_view_alter() is supposed to test, but since what it is currently testing is wrong, shouldn't we just remove it ?
Comment #10
swentel CreditAttribution: swentel commentedWell the use case is that since DS is using field_theme - which pretty much is the only contrib afaik doing that - quickedit picks in and adds a pencil to edit the field. Now, DS fields aren't necessarily editable data (sometimes it is, sometimes it's just simple markup, or maybe a combination of some fields wrapped into one output with some funky manipulations), and there's no widget either so the pencil simply does nothing and the javascript breaks completely.
Comment #11
swentel CreditAttribution: swentel commentedBasically, I guess you could say that in some way, DS fields are computed, maybe that's a way out of it, haven't investigated that option yet.
Comment #12
swentel CreditAttribution: swentel commentedUploading patch that removes this check - will try to test later today with DS to see how I can get around it
Comment #13
swentel CreditAttribution: swentel commentedLooking at this today
Comment #14
Wim LeersTo be clear, I'd love to see this "pseudo field" support in Quick Edit removed :) It was added solely for Display Suite.
Comment #15
aspilicious CreditAttribution: aspilicious commentedWell it's added for anyone that wants to use the field theme function. It's strange to have a theme function that only can be used in a specific use case.
But I do see DS is the only contrib module doing this trickery at the moment.
So Yeah +1 to remove it if we don't loose field templates in DS.
Damn, I wish I could be in Barcelona...
Comment #16
yched CreditAttribution: yched commentedWell, a theme function can only be expected to work for the use cases that provide the arguments it expects, that sounds fair ?
("You want to output a field value, fine, give me the corresponding FieldItemList object")
I mean, if theme functions / processors had proper signatures instead of a convenient array of args, that would only be natural ?
Comment #17
swentel CreditAttribution: swentel commentedFound a workaround so DS can still use theme_field(), see patch for DS at #2563925: Figure out if we need to use a different theme function for our fields
Changes: introduce '#is_multiple' on FormatterBase.
Also removed another is_object() check in template_preprocess_field().
Comment #18
swentel CreditAttribution: swentel commentedComment #19
aspilicious CreditAttribution: aspilicious commentedYou're right yched :)
Comment #20
Wim LeersThis patch fully reverts #2057973: Don't add Edit module's data- attributes on pseudo fields (as used e.g. by Display Suite). Therefore, from a Quick Edit POV, this is definitely RTBC.
The first 2 hunks make tiny modifications to Field API. Do those need additional test coverage?
Comment #21
yched CreditAttribution: yched commentedThanks for reviving this @swentel
So the patch removes the current access to $field_item->getFieldDefinition() from template_preprocess_field(), and instead has the caller extract the info (is_multiple) and pass it explicitly from the outside. That way, DS can still make use of the theme hook passing a fake $field_item that doesn't have the definition.
I guess that works, until some other (custom / contrib) field preprocess or template wants to access $field_item->getFieldDefinition() (or otherwise uses $field_item as a FieldItemListInterface), then the DS calls will break as well ?
From #7
What would getting rid of that convenience mean eaxactly ?
Since, according to #10, DS using theme_field has the added drawback of kicking quick_edit in, which is not intended ?
Comment #22
swentel CreditAttribution: swentel commentedGood point, the only thing I can come up with is that we should document this in DS - maybe even on the project page - and add an additional property on our field so that custom/contrib knows that this will be a invalid field. I'm fairly sure that accessing the field definition won't happen every 5 minutes around the planet, so I can totally live with that.
We should probably open an issue allowing to create runtime field definitions so DS can create a 'fake' field then, that should be possible for 8.1 no ?
Quick edit doesn't kick in anymore in our patch for DS since we're telling our fields that their view mode is _custom - that check exist in quickedit itself already. So at least this part is fine.
Comment #23
aspilicious CreditAttribution: aspilicious commented1)
DS has a mechanism to inject any arbitrary output into the entity display.
By using the defualt core field template to wrap the output we can ensure the display looks OK for any non coder/themer.
2)
On top of that, we have a feature called "field templates", it allows people to customize the field wrappers on a field basis in the UI.
Technically it is using field theme suggestions. This feature is used a lot.
I'm pro looking at different ways to achieve this goal. But at the moment I have no clue how to do it properly AND at the moment my time is very limited as I only can work on DS one day each month. It would be sad to not have DS finished when 8.0.0 is out.
The only way to decouple this completly without losing to much time is "duplicating" the field theme templates.
But I don't think this ia future proof solution.
Yes that's true, in DS itself, we have some "not so nice" object checks.
Comment #24
yched CreditAttribution: yched commentedAgreed that the drawback I pointed in #21 is probably not going to be too common, so that's probably the best way forward.
The underlying issue being :
- we should indeed be able to create an arbitrary runtime FieldItemList object with an arbitrary definition.
- as @swentel points, not sure what's the conceptual difference between DS pseudo-fields (arbitrary, admin-specified output wrapped in a field tpl) and computed fields. Except for computed fields still being blurry, of course :-/
So I guess that's an RTBC here :-)
Comment #25
Wim LeersYay! :)
Comment #26
alexpottCommitted e686c9d and pushed to 8.0.x. Thanks!
Comment #28
swentel CreditAttribution: swentel commentedThe wrong patch was committed, the one from #12, not #17
Attaching the interdiff from 17 again as a patch.
Comment #29
yched CreditAttribution: yched commentedOops :-)
@alexpott : do you want a followup issue instead ?
Comment #30
alexpottOops indeed - thanks for noticing. Committed bfcba53 and pushed to 8.0.x. Thanks!
Comment #33
star-szrCould probably use some wisdom in #2604220: PHP notice for single value image field configured with a default image (no image present) and a hidden label please :)