Problem/Motivation
We had a project where customer requested to be able to select dynamically different layouts for different site elements like pages, headers, footers, separate blocks, paragraphs etc.
One of the requirements was to configure selected layout based on different entity fields including taxonomies, different entity types like nodes, taxonomy terms etc
Proposed resolution
We implemented a new multistep condition plugin which allows you to select a field from plugins entity context, click continue & select a value by using field's widget.
We deleted old plugin in the patch just to not create several plugins, also we decided to share this solution if it will be interesting for you & hopefully you can use it some way or integrate in existing module.
Also we implemented layout library module patch which have some implementation to support multistep ajax condition plugins & this plugin is basically used by that interfaces which are based on ctools ManageConditions ajax popup forms you can try it on your own: https://www.drupal.org/project/layout_library/issues/3089493
Remaining tasks
Field value in configuration is stored like : [{value: 'dasda'}] (default result from $entity->get('name')->getValue() & in summary it has this string, as we have many different field types & their formatters probably it's a good idea to render it a more human friendly format
Sometime entity fields results in evaluation have additional garbage fields like _loaded, _accessCachablity etc, we get rid of it during plugin evalute probably some fields will need additional checks, we tested with taxonomies, entity references & basic properties like status etc.
User interface changes
Multistep form with back submit on the second step, select entity (context one) field, then using widget select value, save
Issue fork entity_field_condition-3091898
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 #2
pavel ruban commentedComment #3
pavel ruban commentedComment #4
pavel ruban commentedComment #5
pavel ruban commentedComment #6
davidferlay commentedHi Pavel,
I tested the module :
error: context "entity" is missing.displaysScrrenshots of the issue :
Comment #7
davidferlay commentedComment #8
pavel ruban commentedHi davidferlay,
Thanks for feedback.
That plugin requires entity context to be able to get list of fields & generate the form to select the entity's field & then its value.
When you select this plugin in the block space then you have no entity context as it's generic regions for different pages.
Yes, when you access a page the entity context will be filled but it will be different entities so it's a bit messy.
The patch was done for our project to let user use this condition with layout library & it works fine.
However what I can think of the possible solution is to implement additional step to allow you select from list of Content Type if entity context isn't provided & then select field & the value. This way we can also implement a logic to show block if our entity context meets selected bundle & condition or hide & add other conditions like show block if entity context is missing or doesn't match the selected bundle etc.
As for current purpose (condition plugin for spaces where entity context is defined) I consider this as properly working solution.
For missing entity context instance spaces, yes it can be additionally handled & provided a better UX.
Comment #9
kiseleva.t commentedHello,
I'm using patch #5, but faced with error
RuntimeException: The subform and parent form must contain the #parents property, which must be an array. Try calling this method from a #process callback instead. in Drupal\Core\Form\SubformState->getParents() (line 76 of /docroot/core/lib/Drupal/Core/Form/SubformState.php).Probably something was changed since patch.
I've fixed this issue, but form doesn't work for me as multistep currently.
I have to open condition for edit and then I'm able to specify value of the field.
@pavel-ruban do you have any idea what I have to change?
Comment #10
kiseleva.t commentedUpdated patch for 8.x-1.1 release, previous one works on dev version only.
Comment #11
kiseleva.t commentedPrevious patch broken condition for layout library itself (not for the block inside), corrected this.
Comment #12
manuel.adan1. Not working with Page Manager, I got "error: context "entity" is missing." adding a field value page access condition:
2. An update hook should be implemented to update config with the new plugin ID in existing installations, or leave the current node based field condition and mark it as deprecated
Comment #13
kiseleva.t commented@manueladan, you're right, in some cases, we don't have the required context like we have on layout builder.
I returned back the Field node plugin but modified that a bit to have correctly work with the Extra field module (when subform attached not as `visibility` component) + I faced issues with negating condition and absence check on empty value (not NULL), made corrections for that.
Plugin Entity field will be advance for the cases when we have entity context (layout builder and etc).
Comment #14
kiseleva.t commentedModified NodeField plugin to don't set default value with entity_type_id, because it works only with node, but this setting forces Extra field module thinks that condition configured when in fact it wasn't.
Comment #15
kiseleva.t commentedAdded fix of the notice when $form['#parents'] absent.
Comment #16
kiseleva.t commentedCorrected return of result in case of the Negated condition, it should be outside condition plugin evaluate.
Comment #17
kiseleva.t commentedUpdated patch for the latest dev version.
Comment #18
kiseleva.t commentedFixed notice.
Comment #19
kiseleva.t commentedCorrected context_definitions for FieldValue to work correctly on D9.
Comment #20
dmitriy.trt commentedAttaching an alternative patch on top of #3225480: Separate condition plugin for entity reference fields. It also requires #3230847: AJAX is broken on the add condition form for Ctools-based UIs. It should be backward-compatible with #19, but with a different implementation of the config form without continue/back buttons. The evaluation logic is the same with #19.
It still needs some cleanup and it may be better to spending time on porting some improvements to 2.0.x, that's why I change status on the issue.
Comment #21
kiseleva.t commentedAdded check that selected entity has the defined field.
Comment #22
liquidcms commentedTrying to get block visibility in LB based off field value. The set of 3 patches in #20 is the only solution i have found so far. Thanks @Dmitriy.trt
EDIT:
i thought those 3 patches were working but doesn't seem to now. :(
also, any of these i think requires: "2916876 = block visibility control for LB": "https://www.drupal.org/files/issues/2021-11-03/2916876-144.patch" to get this to work with LB
I get:
- Control Visibility option with contextual links for blocks in LB (2916876)
- under vis options i have 2 field options: Field value and Node Field (without preview) - not sure which is from this module (but will track it down)
- Field Value when i click Add condition does nothing.
- Node Field adds condition but when i pick bundle, it says loading fields but loads nothing.
Is it possible these solutions only work when doing the layout of a specific node - as opposed to what i am doing which is defining the layout for all nodes of a specific bundle?
Comment #23
liquidcms commentedWondering if this work is still on going and if someone can comment on status.
My guess is this is trying to make a generic/universal field conditional plugin. Is this correct? A bit confused by a few things though:
- it sounds like it is focused on LB although i see mention of patches for Layout Library (which doesn't make a lot of sense as that isnt a LB requirement) and no mention of the core patch #2916876: Add visibility control conditions to blocks within Layout Builder which i think is needed just to get visibility setting in LB at all.
- i havent been able to get any of the combinations mentioned here to work in LB (without trying LL patch which doesnt apply)
My 2 uses cases at the moment are:
1. pathauto (with a patch) allows conditional patterns
2. layout builder (with a core patch and a ctools patch) allows controlling block visibility
For which i think would require 3 patches:
- the core one i mentioned (for LB only)
- this ctools one: #3230847: AJAX is broken on the add condition form to allow ajax loading field list once the bundle has been selected
- a patch for this module to allow it to work in these applications
Mostly just curious if the work here (not including whatever LL discussion is about) is heading down that road or if i misjudged what the title of this issue is about.
Comment #24
liquidcms commentedJust as a reference, this is what i get currently:
core 9.2.11
patches:
- https://www.drupal.org/files/issues/2021-11-03/2916876-144.patch (core)
- https://www.drupal.org/files/issues/2021-09-15/ctools-condition-form-aja... (ctools)
- https://www.drupal.org/files/issues/2021-07-28/entity_field_condition-ge... (efc)
The patch from here changes the Node field condition to now 2 conditions:
- Field value (does nothing)
- Node field (without preview)
Field Value
- in pathauto condition just states "error: context "entity" is missing. "
- in LB (for a content type, not a specific node): WORKS!!, odd, tried this multiple times and didnt seem to work but does now. required to re-edit after saving condition to set the field value - but working. Yay
Node field (without preview)
- in pathauto: when selecting bundle, node field selector disappears.
- in LB: when bundle selected, it shows loading fields, but returns an empty list.
Seems like a solution here for LB but not generically. I did seem comments above about this requiring node context which would explain the error when trying to use this with pathauto. Perhaps this is the difference between field value and node field. Node field adds its own context by allowing user to pick bundle (but isnt loading fields correctly) and field value relies on figuring out bundle.
Although nice not to pick bundle; this doesn't seem like it will be a very generic solution as many places to use a condition won't provide this context (and shouldnt need to).
Comment #25
webdrips commentedThe patch in #20/21 breaks dev/8.x-1.3
Drupal core 9.3.12
If you edit a block before the patch is applied, everything works. But after the patch is applied, clear the cache and you get:
Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException: You have requested a non-existent service "entity_field_condition.subform.helper_factory". in Drupal\Component\DependencyInjection\Container->get() (line 156 of /core/lib/Drupal/Component/DependencyInjection/Container.php).Will try to track the issue down if I get a chance and re-roll
Edit: ironically #19 seems to work for LB, but seems to break the block "Field Value" tab:
error: context "entity" is missing.Comment #26
delacosta456 commentedhi
thanks for this feature
However i would like know if we can also have possibility to test empty field
Comment #27
socialnicheguru commentedFrom #25 changed status
Comment #31
codebymikey commentedRerolled existing patch targeting the latest dev (and supporting Drupal 10).
Comment #32
webdrips commentedThe patch from #31 still has the same issue I reported in #25 unfortunately.
Here is the full stack trace:
Now using Drupal 9.5.9 and the EFC 8.1.4
I didn't need to do anything to get this error this time except view a page on the site.
We are using this in conjunction with the Layout Builder to show various views/fields based on field conditions (e.g. a taxonomy value).
Comment #33
punamshelkeComment #34
punamshelkeThis is for D9.5 and php 8.1
Comment #35
punamshelkeCompatible for 9.5 and php 8.1
Comment #36
webdrips commentedPatch #35 kicks out an error:
Drupal 9.5.11
PHP 8.1.23
Comment #37
codebymikey commentedJust an FYI, regarding #25, the reason Layout Builder context integration broke in D10 is referenced in #2916876-192: Add visibility control conditions to blocks within Layout Builder
Comment #38
liquidcms commentedAnyone know the status of this?
We had it working on D9.5 but it does not work for D10. I see the patch has code which references: \Drupal\entity_field_condition\Subform\SubformHelperFactoryInterface but this doesnt exist in the 1.x or 2.x branches.
Comment #39
liquidcms commentedNot sure what #35 patch is as it refers to code which doesn't exist. To get this working for D10 i took the version i was using in D9 (1.3) and the patch i was using from here (#19) and simply made it D10 compatible by removing the composer.json file and setting core_version_requirement.
Not quite the proper path forward i suspect but unclear the direction here.
Comment #43
joseph.olstadOk I scrapped my own merge request.
Try this patch instead
Comment #44
joseph.olstadpatch 43 now removes the garbage .orig file and I did a better job dealing with conflicts than patch #35
With that said, I am still reviewing the patch
***EDIT** This patch works.
Comment #45
joseph.olstadPatch 43 is a re-roll of patch #19. I resolved the conflicts manually.
Testing of patch #43 shows that it resolves the issues that we noticed with patch #35
Tested with Drupal 10.0.11 and the latest dev 8.x-1.x of entity_field_condition
Please review
Comment #46
joseph.olstadThanks to @liquidcms for reporting the success with patch #19 on Drupal 10 using a modified version of release 1.3.
I took this as proof that patch #19 works well with Drupal 10.
So I re-rolled patch #19 on top of 8.x-1.x head of dev to create #43. The conflicts were carefully resolved and I believe the re-roll is a path forward here.
I have only done very minimal testing with #43, so it does require additional review.
Comment #47
webdrips commentedEDIT #2: patch 43 above and #192 (Drupal core patch) from the link below work for me.
#43 (and #19) no longer seem to work for me on Drupal 10 sites (10.1.5 or 10.1.6). I can't edit an existing field condition for visibility controls nor add a new one.
In both cases, I get
"error: context "entity" is missing."with an "Update" button that does nothing and a "Back" link.Steps to reproduce on an existing block with an existing rule:
"error: context "entity" is missing."On a new block or one without a visibility condition:
"error: context "entity" is missing."The field in question is a list (text) field.
EDIT: I should have mentioned I'm using the patch here (#167): https://www.drupal.org/project/drupal/issues/2916876
Perhaps that is the issue causing problems, but I'd be curious to know what patch combination people are using on D10.
Comment #48
codebymikey commentedUpdated the default "Node Field (without preview)" condition so it's a bit more robust - such that the AJAX callbacks now works regardless of where it's used from e.g. Layout Builder and Blocks.
Also added a new
equalsandregexoperation, making thecontainsoperation now more of astr_contains()check instead of a regex.Comment #49
kevinquillen commented@codebymikey does the patch in #48 fix the issue here as well?
https://www.drupal.org/project/entity_field_condition/issues/3278442#com...
Comment #50
darkodev commentedI tested MR5 in the following forms and it works. Thanks very much for getting this far with this!
Layout Builder (my original need for this patch along with the block visibility patches in https://www.drupal.org/project/drupal/issues/2916876).
Works as expected, but throws an AJAX error after choosing the node type. In spite of the console error, it does load the fields and allows saving of the condition, which then works as expected.
Core Block Layout
Works as expected.
Menu Position
This module used to ship with a field value option in D7, which no longer exists in D10.
Works as expected.
It also works with Context module
Comment #52
pavel ruban commentedTested with core 10.4.3 & 8.x-1.4
* If you use layout builder visibility rules you need to apply this patch https://www.drupal.org/files/issues/2025-02-27/2916876-3091898-10.4.3-26...
* If you use ctools, e.g. for this #3089493 you need to apply this patch https://www.drupal.org/files/issues/2025-02-27/ctools-condition-form-aja...
* Plus this 3091898-3225480-8.x-1.4-52.patch main patch #52 or feel free to use https://git.drupalcode.org/project/entity_field_condition/-/merge_reques...
Patch notes:
* Issue #3091898: Enhance layout builder integration, allow ajax context mapping which now automatically rebuilds field selection widget, fix uuid issues on submit, complex widgets like address and media library previously didn’t populate default values due to missing widget dependent items values processing, fix fatals when not fieldable context entity was used by context mapping.
* Issue #2916876-3091898: Sometimes we can have a conditional plugin which uses ajax dynamical form elements, current layout builder visibility rules ecosystem doesn’t allow this. It’s not possible to use ajax subform of a conditional plugin. There was a similar issue in context of ctools framework, it was solved here #3230847, in our case we have this entity field value condition plugin #3091898 which allows you select an entity field and then form rebuilds with generated field widget to set visibility rule in a user friendly manner. The idea is to proxy all request context data to sub form via symphony http sub request to the plugin configure form route, imitate ajax request and then grab sub response on the host block visibility form and proxy back as ajax command response, allowing different conditional plugins have different form elements which will trigger automatically appropriate ajax callbacks by form API.
* Issue #3230847: On any complex widgets like media library which use sub dialog modal was the error which leaded to initial dialogue overwrite & complete data loss following by dialogue close, prevent this by render initial widget form in off canvas sidebar which allows to use secondary dialog modal.
Comment #53
darkodev commentedThe fix in https://www.drupal.org/project/entity_field_condition/issues/3506895 needs to be applied for this patch, I believe.
Undefined array key "value" in:
$value_to_compare = $value_item[$main_property_name];
Could be fixed with:
$value_to_compare = !empty($value_item[$main_property_name]) ?? NULL;
Comment #54
pavel ruban commentedThe warning message you refer to is happening in node field plugin which we don't use at all. I believe you can apply mentioned by you patch on top if needed to fix the warning as it's the separate issue not linked with the context of this thread - entity field condition plugin.
We mainly use field value plugin which allows to use node field as well but with field widgets.
If patch doesn't apply you may reroll it on top of these patches.
Comment #55
socialnicheguru commentedNo longer applies:
drupal/entity_field_condition (1.4.0 => 1.5.0)
Comment #57
codebymikey commentedAttached a copy of the MR 5 applied on top of #3225480: Separate condition plugin for entity reference fields
Comment #58
liquidcms commentedI want to add a Selection Criteria to my Page Manager page based on a field in the current user's profile. I am able to add a Context to my page config for "current user" and then this work gives me a Selection Criteria of "Field Value". But selecting it fails as there is no context called "entity". Looking through code it seems it needs any context to be defined as "entity", which of course would not work as soon as one doesnt declare itself as that or there are more than 2.
This patch lets me select which context (out of the ones added in Contexts) to use for the field value.