Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem: currently there is only a textfield giving you no idea what you can fill in for a context of a condition/action. We should have the autocomplete same as in D7 again.
Comments
Comment #2
klausiComment #3
dasjoComment #4
KiranJoshi CreditAttribution: KiranJoshi as a volunteer and commentedComment #5
KiranJoshi CreditAttribution: KiranJoshi as a volunteer and commentedThere was too much for me to learn about Drupal 8 and how Rules worked for me to complete much.
My original idea was to (a) learn autocomplete, (b) pass in / retrieve context, (c) use context (with conditions) to generate / filter possible autocomplete matches.
I got stuck in (b) because I could pass in some information but not retrieve the entire context for the rules and conditions. Even ignoring that, I was not able to proceed due to some issues with rules validation.
I've added a link to do a small diff to show what I've learned for anyone else that may wish to continue.
https://github.com/fago/rules/compare/8.x-3.x...KingJoshi:2648326-data-s...
* We need to add a route in rules.routing.yml for rules.autocomplete
* Form element needs two new options "#autocomplete_route_name" and "#autocomplete_route_parameters" to trigger autocomplete
** "#autocomplete_route_name" is the route created in rules.routing.yml
** "#autocomplete_route_parameters" is an array of parameters for the url
* I made it point to a new autocomplete function in src/Controller/RulesController.php
* Function returns
return new JsonResponse($matches);
where $matches is an array of arrays of the format:**
[ ['value'=>'value1','label'=>'label1'], ['value'=>'value2','label'=>'label2'] ]
* I was not able to retrieve the current form using form_build_id in Drupal8
* there were validation issues with Rules at this time
* The data selector concept seems simple for doing autocomplete, but the actual UI seems confusing for new users. I would have assumed autocomplete for the direct values. For example, if I'm trying to match a user to a role, then autocomplete should be of the roles
* I do pass in the mode (selector/input) in to the autocomplete function. It's not clear to me what information needs to be passed and what can be regenerated (very unfamiliar with Drupal 8 Forms)
Comment #6
klausiStarted with the backend work of this at: https://github.com/fago/rules/pull/379
For autocompletion we need the metadata state to be set up. That only happens during integrityCheck(), so I'm currently calling that to populate the variables in the metadata state. Example: if an action adds a variable "foo" then foo needs to be available for autocompletion in the next action but it must not be available in the action before.
That's why we pass an expression UUID to the checkIntegrity() method. The check will then only be performed up to that UUID.
I'm not sure if we should really do the metadata sate setup with the checkIntegrity() method. We could also invent a new method on expression plugins: proccessMetadataState() or similar to do that separately. Then adding variables to the state is duplicated in checkIntegrity() and processMetadataState(), which is not ideal but also not a big deal?
Comment #7
fagoI think duplicating that logic would be very bad, as it will become even more complex in future with metadata assertions etc. So checkIntegrity() should re-use the generally available Metadatastate, which has been processed etc.
In Drupal 7, there was something like $expression->getAvailabileVariables() which did all the calculation and returned you the info about available variables based on the metadata execution / processing UNTIL the expression. So it asked the parent expression about state + added in all variables / metadata assertions of sibling expressions being executed earlier.
proccessMetadataState() sounds exactly like that in d8, so I assume the only difference is that it would pass around the metadata state instead of keeping it internally. But we cannot easily reverse-the-flow with asking parents as we did in d7, as we do not have the (cyclic) parent relationship. But I do not really see another way to implement that, so it looks like we have to add that $parentExpression variable and cyclic object references. People are more used to them anyway now as entities have them also :D Or do you have another idea?
Comment #8
klausiSplitting off the metadata state setup stuff into #2501939: Prepare execution metadata state for an expression in the tree.
Comment #9
klausiDrafting a first working prototype in https://github.com/fago/rules/pull/379
Comment #10
klausiMerged a first version of the autocomplete.
TODO:
* add an autocomplete service to the typed data service. Currently only the first level is autocompleted, for example "node" works but "node.uid.entity" does not yet.
* restrict the autocomplete results to matching types that are allowed for the context.
* Implement human readable labels/descriptions for the autocomplete results.
* make the autocomplete correctly work when adding expressions - currently it just shows all available variables from the very end of the Rule. Example: if an action adds a "node" variable then the "node" variable should not be available on the autocomplete when adding a condition. This seems to be very hard to do, so I think we can ignore this for now.
Comment #11
klausiContinued in https://github.com/fago/rules/pull/435
Comment #14
klausiCommitted that PR to continue in steps here.
TODO:
* Add 2 autocomplete suggestions if a variable has nested properties. Example: "node" and "node..." to drill down should be provided.
* restrict the autocomplete results to matching types that are allowed for the context.
* Implement human readable labels/descriptions for the autocomplete results.
* make the autocomplete correctly work when adding expressions - currently it just shows all available variables from the very end of the Rule. Example: if an action adds a "node" variable then the "node" variable should not be available on the autocomplete when adding a condition. This seems to be very hard to do, so I think we can ignore this for now.
Comment #15
klausiContinuing at https://github.com/fago/rules/pull/437
Comment #17
klausiAnd merged.
TODO:
* Implement human readable labels/descriptions for the autocomplete results.
* restrict the autocomplete results to matching types that are allowed for the context.
Comment #18
klausiPR for adding better labels: https://github.com/fago/rules/pull/438
Comment #20
klausiMerged that PR.
TODO:
* restrict the autocomplete results to matching types that are allowed for the context.
Comment #21
fagothanks a lot for the great progress here :)
Looking at the code, it looks good overally and I'm happy to see decent test coverage.
Here are some comments:
This seems to repeat API which is on the metadata state anyway. I think, instead we just miss an API function gets the metadata prepared for a certain $until element. Then you can do whatever necessary with that metadata state, e.g. get autocompletion results or other data information as needed for the UI.
ad \Drupal\rules\TypedData\DataFetcher::autocompletePropertyPath:
The separation into first,middle and last part confused me bit. I realized then, that it takes care of find the first variable while other methods like fetchDataByPropertyPath() take the starting variable as first parameter. It should follow that pattern and if necessary separate the part of finding the right variable in another method.
ad
this should use fetchDefinitionBySubPaths() and save the imploding.
If it can be a property path, the variable name should be $property_path not $variable_name.
Comment #22
eigentor CreditAttribution: eigentor commentedAny progress here? Just checked Rules again today and no autocomplete suggestion. This appears to be the make or break feature to make Rules usable via the UI.
Maybe the progress is happening somewhere else? Happy to be pointed there.
----- Edit -----
Autocomplete Suggestions work, just somehow did not see it / get it to trigger.
Comment #23
TR CreditAttribution: TR commented@eigentor: I'm not sure what you are expecting to see, but the autocomplete suggestion code was committed more than two years ago, as per the above, and has working in Rules since then ... Note this is for the data selection mode only, not for direct input ...
This should probably be moved to Typed Data API Enhancements module now? The DataFetcher was moved, but the autocomplete test is still in Rules ... I think the JavaScript and the tests should probably be moved too - Rules is just a consumer of that API.
Comment #24
eigentor CreditAttribution: eigentor commentedSorry for not reporting back. I meanwhile discovered the autocomplete is working fine. Somehow did not get to trigger it before. So forget my comment.