MotivationIn projects of the more ambitious kind, the need for rather complex Fusion objects arises. Think of a faceted search with parameters for query, filters, pagination, hits per page, reference coordinates for distance calculation etc. All those data, both input and result, have to be relayed to nested Fusion objects and finally the view, without sending the same request multiple times.
Status quoTo make all those parameters available where they are needed, you can either use * @context to add variables to nested objects * Eel helpers to add variables where needed, supported by a singleton service that performs the search request
Why I consider this un-NeosyAdding data with the given complexity via @context is not viable. The complex search query alone gives the term "Eel expression" a completely new (and fitting) meaning. Also you cannot access @context variables within other @context variables which prevents you from effectively dividing the declaration in multiple parts.
Eel helpers are a much better approach as you can hand over most of the logic from Fusion to PHP.
But I am not completely happy with this approach because as I see them, Eel helpers should be general purpose, contextless helpers to be used in any place that supports eel expressions. Also you have to configure them explicitly to be be usable in Fusion. In this case, the helper would both need a context (e.g. which node to search in) and is single purpose to a single Fusion prototype and that prototype alone.
Proposition: Supporting write access to the current rendering context for Fusion implementation classesIn my opinion, a more clean approach would be to use a custom implementation class with the goal to server as a kind of presentation model. It derives its data from the same service the Eel helper would use, but is tightly bound to the Fusion prototype it is configured in (by MyPackage:Search.@class=MyPackage\\Presentation\\Model\\Search). It also has direct access to the context and can e.g. fetch the current site directly from there.
What’s currently also possible (though explictly disencouraged) is to add additional context variables by using something like
$context = $this->tsRuntime->popContext(); /** @var NodeInterface $site */ $site = $context['site']; $context = array_merge($context, $this->contextVariableService->getFinderVariables($site)); $this->tsRuntime->pushContextArray($context);
in your fusion implementation class. That’s basically the same what @context does in the first place.
My suggestion is (given that there are no serious drawbacks I overlooked) to add an addToContextArray() method to the Fusion runtime that can be used by @context and fusion implementation classes alike and serves as an official entry point.