Fluid
Fluid copied to clipboard
Unable to retrieve nested objects requiring arguments
The Fluid syntax only allows to resolve object properties without arguments:
{item.name} results in $item->getName()
Retrieving a specific value based on an argument like $item->getName('url') is impossible and requires for every parameterized method a separate view helper.
In the Twig and Blade template engines, this is no problem.
How would/should a call to $item->getName('url') look in fluid then?
{item.getName.url} ?
To be honest, i'm not sure, that this is such a good idea, because we'd kind of introduce a way to create side-effects inside variable calls, because what would hinder you from calling a method to execute a function instead of getting some value?
We have plenty of ways to expose the data you mentioned through "hardcoded" getters, magic __get, ArrayAccess, etc.
Could you post a specific usecase you have, that hinders you to go any of the methods mentioned above?
Our objects have some convenient methods like
$detailProductItem->getRefItems( 'attribute', null, 'config' )
- attribute: domain
- null: type
- config: list type
In this example, from a flat list of items it returns the items which are attributes, of arbitrary type and have "config" as list type (sorted according to their positions in addition). To do the same in Fluid, it would require a lot of "for" loops and "if/else" constructs, which is far from being elegant.
An no, we can't hand over the result of the method to Fluid because it highly depends on what the frontend developer wants to output in the template. We can only provide all relevant data. Which one is used and how is outside of our control.
yes, i know all to well, the for/if hell you're talking about ;) have you considered a general ViewHelper that behaves like this?:
{detailProductItem -> ai:getRefItems(domain: 'attribute', listType: 'config')}
how exactly does twig/blade handle this method/behavior for you?
Yes, that was our first thought but it would require a view helper for every method that contains a parameter ... too much to be a suitable solution ...
In Twig/Blade you can do this without problems:
detailProductItem.getRefItems('attribute',null,'config')
Might be some kind of RegEx stuff to retrieve the method parameters. The Fluid Viewhelpers are very close to what would be useful if there would be a generic parameterized method call view helper like this:
{detailProductItem -> call(method: 'getRefItems', domain: 'attribute', listType: 'config')}
but even better and more intuitive would be
{detailProductItem -> getRefItems(domain: 'attribute', listType: 'config')}
A view helper that catches all unknown method calls, provided it can be chained in some way:
{detailProductItem -> getRefItems(domain: 'attribute', listType: 'config') -> getValue(type: 'size')}
v:call currently exists in VHS and will become part of a universal VH library. That should do the trick.
Hey.
Fluid already deals pretty well with sub references {foo}.bar.{baz} an resolves get*(), has*() and is*() methods as well as properties, including sub references {{foo.bar}}. The variable provider getByPath() is heavily under load in real life and has been optimized for performance quite a bit with recent releases.
We're currently looking into options to make this heavily used construct even quicker.
I think adding a syntax for arguments to get*() methods would add quite some additional overhead and complexity that Fluid should rather try to avoid in this performance related area.
I also think that optional getters with additional arguments are rather edgy and I think they should usually be avoided on casual "model" objects that are assigned to Fluid.
All in all, I think we should reject this issue. Projects that really want to have something like that should add according magic on their own with dedicated view helpers or similar. Claus referenced a possible solution with an earlier comment already.