[TYPO3-mvc] Fluid: Fallback paths for templates

Helmut Hummel helmut.hummel at typo3.org
Sun Jul 28 18:50:18 CEST 2013


Hi Claus,

I wanted to be precise and clear with my arguments, which resulted in a 
very long post, sorry about that.

Nevertheless I think (at least hope) I can clarify a few things so we 
can proceed to implement a great feature into Fluid.

On 19.07.13 02:14, Claus Due wrote:

> I'll sum this up as best I can.

Thanks, that helps.

> Your solution:
>
> ```
> plugin.tx_ext.view.templateRootPaths.foo = ...

> # which will be removed when setting...
> plugin.tx_ext.view.templateRootPaths { ... }

Not true!

plugin.tx_ext.view.templateRootPaths.baz = /path/to/baz/
plugin.tx_ext.view.templateRootPaths {
	foo = /path/to/foo/
	bar = /path/to/bar/
}

results in:

array (
   'view.' =>
   array (
     'templateRootPaths.' =>
     array (
       'baz' => '/path/to/baz/',
       'foo' => '/path/to/foo/',
       'bar' => '/path/to/bar/',
     ),
   ),
)

No unexpected overriding here!
This is how TypoScript worked ever since (and also is what you rely on 
in your configuration variant).

To explicitly overwrite the already present configuration, you have to 
unset it:

plugin.tx_ext.view.templateRootPaths >

If you do so, you have to know what you're doing ;)

> # which will now be ignored when someone sets...
> plugin.tx_ext.view.templateRootPath =

To be defined. Bastian "only" made a suggestion of how the Fluid API 
should behave when the old setters are used.

But it is still undefined, which configuration option should be 
evaluated first, templateRootPath or templateRootPaths, which will then 
define which option takes precedence. This can indeed be tricky, see 
below...

> Your solution forces you to use one way or the other and disables one way
> when the other is used.

> Which is fine if what you need to do is to at some
> point remove the old convention. But you don't need to. So you should not.

---------------------------------------------------------------------
I think we should differentiate the change of the PHP API of Fluid and 
the way the configuration is consumed by the PHP API.
---------------------------------------------------------------------

Let's at first put aside the way how to configure the fallback paths for 
templates, partials and layouts (I will only mention templates these 
three as "templates" later on) and have a look at the PHP side/ 
implementation of that feature.

I think we should at first celebrate that we *all* agree on the fact 
that fallback paths is a great feature that should be part of Fluid.

Now there are two suggested ways to implement this feature.

First of all Claus' suggestion[1], which directly couples the 
TemplateView object with the configuration manager to be able to read 
the configuration for the fallback paths.

 From a OO standpoint, this is code smell as it introduces a direct 
coupling to a very specific (configuration) component, which makes the 
code harder to re-use in different contexts (standalone view, other 
applications, Flow/ Neos).

Secondly there is the suggestion which is the outcome from a discussion 
with several people from the Flow, TYPO3 and Extbase Teams,

which is to extend the public API of Fluid Template View to not only 
accept one root path for templates, but an array of templates, which can 
be set through a new setter (setTemplateRootPaths), while making the old 
setter call the new setter (read Bastians first post for more details). 
By doing so Fluid's Template View can then iterate over these arrays and 
do the fallback handling. (BTW. This happens for partials and layouts 
already, where these are looked up in several places below one specific 
root path).

The BC impact for this change of Fluid's PHP API would be
... wait for it ... wait for it ...
0!

We add new API which can be used to benefit from a new feature and if 
there is code that uses the existent API, Fluid works like it worked before.

Another benefit for this approach is that we solve the problem in a 
central place. All applications (Flow, Neos, Extbase, ...) can benefit 
from this great new feature and the code for that stay portable and thus 
the Fluid core stays the same for TYPO3 as it is for Flow.

---------------------------------------------------------------------
No backporting hell, no organisational problems, clean, easy, straight 
forward, beautiful, no BC break.
---------------------------------------------------------------------

Can we also agree on this? Or am I missing something?

---------------------------------------------------------------------
Now since we have this point clear, we can look into how this feature 
can be configured and where the configuration should be read and be 
applied to make use of the new Fluid PHP API.

Let's start with "where the configuration should be applied" as it is 
quite easy to agree upon.

In Extbase we already have a view configuration possibility by 
TypoScript which is read and applied in the abstract ActionController in 
the method ::setViewConfiguration() which is called from ::resolveView()

In Flow it also will be done in the ActionController in ::resolveView() 
once the views.yml change[2] is applied.

Nice, so we have a similarity here, although the implementation would be 
a bit different, since Flow will use EEL and Views.yml and Extbase will 
still rely on TypoScript for that.

I think we can also agree on that part, right? Pretty strightforward, no 
downside, or am I missing something here?

---------------------------------------------------------------------
If I did not miss anything until here and there are no further 
objections, I would say Bastian you could start implementing that in 
Fluid as we need that anyway in TYPO3 and Flow.
---------------------------------------------------------------------

Last but not least, we can now focus on how the configuration of that 
feature should look like. I already mentioned it and it was mentioned in 
this thread several times, the configuration will be very different in 
Flow and TYPO3/ Extbase as there are different concepts present for 
configuration in these projects, while unifying them is way beyond the 
scope of this change!

So while I would find it nice, if the way to configure this feature 
would be similar in Extbase and Flow, I would be fine it would differ to 
make more sense in both projects.

Nevertheless, the most obvious thing would be, to make the configuration 
similar to the PHP API, just like it is now.
Currently there is a setter ::setTemplateRootPath() and a corresponding 
configuration option view.templateRootPath. So it looks very obvious to 
choose a new configuration option view.templateRootPaths {} to be the 
array for the ::setTemplateRootPaths() API.

Looks easy, straight forward.

This is what has been agreed upon during the Conf Call.
---------------------------------------------------------------------


> My solution:

---------------------------------------------------------------------
First of all I'd like to mention that everything you suggest below can 
be implemented with *very few lines of code* in 
ActionController::setViewConfiguration() if we extend the Fluid PHP API 
like I mentioned above!
---------------------------------------------------------------------

What I like with your solution is that the way to configure template 
path overlay is done by some kind of "configuration overlay".

Especially having this kind of option:

 > plugin.tx_ext.view.overlays {
 >      foo < plugin.tx_foo.view
 >      bar < plugin.tx_bar.view
 > }

looks like a nice and powerful thing to have.

On the other hand at the same time I do not like it for several reasons.

First of all this kind of "configuration overlay" would be unique in the 
TYPO3 world and only available for this very feature in Fluid. In no 
other place one could use this approach to configure something in 
TypoScript.

Secondly (and I very well might have missed something) I do not see how 
the additional complexity in configuring something, adds more 
flexibility for developers or integrators, in contrast to the 
straightforward configuration mentioned above (and by Bastian).

As far as I can see both ways offer the same felxibility and 
extensibility and it is equally possible to atomically configure the 
templates for one plugin.

Let's look at concrete examples:

====================================================================
plugin.tx_news.view.templateRootPath.tx_news = /orig/path/
plugin.tx_news.view.templateRootPath.tx_extA = /path/to/a/
plugin.tx_news.view.templateRootPath.tx_extB = /path/to/b/

plugin.tx_news.view.templateRootPath {
	tx_extC = /path/to/c/
}
====================================================================

Results in the exact same as:

====================================================================
plugin.tx_news.view.templateRootPath = /orig/path/

plugin.tx_news.view.overlays.tx_extA.templateRootPath = /path/to/a/
plugin.tx_news.view.overlays.tx_extB.templateRootPath = /path/to/b/

plugin.tx_news.view.overlays {
	tx_extC.templateRootPath = /path/to/c/
}
====================================================================

I read your mails carfully, but I do not see anything that is not 
possible with the first configuration style that is possible with the 
latter. But as I said, I also may be missing something here.

> ```
> plugin.tx_ext.view.templateRootPath = ...
> # would still be considered as the LAST path if adding...

This is indeed something that needs to be carefully thought of how to 
handle in case we decide to use the the first config option, and is no 
problem if we go with the overlay style and may be a good argument to 
use the latter.

> My suggestion allows integrators as well as extension developers to add
> the extra templates they think should be present at any place they think it
> should apply; and it respects (uses as last lookup location) the existing
> conventional location. These are two ideal flexibility points for both integrator
> and extension developer.

I fail to understand, how the other way does not support that (as 
mentioned above).

> Your solution forces the integrator to choose between one or the other. It
> encourages complete overrides of template paths and at some point

Not true (see above).

> , it might
> mean that legacy support is broken because of a removed configuration loc.

Good point. This needs to be taken into consideration.

---------------------------------------------------------------------
Final words:
I have a strong opinion on how this feature should be implemented on the 
PHP level and have good arguments to support that (but I'm still looking 
forward to be challenged on that).

However, although I would prefer the simplest possibility to configure 
the path overlay feature, I would agree to implement a more complicated 
one even if it diverges from the way it is configured in Flow, but only 
if we (Extbase Team, TYPO3 Core Team and Active Contributors) agree that 
is a future proof, more flexible and thus better option for TYPO3 CMS
---------------------------------------------------------------------

Thanks for your patience and time reading through this long post :)
Really! Thank you!

Kind regards,
Helmut

[1] 
https://review.typo3.org/#/c/21580/9/typo3/sysext/fluid/Classes/View/TemplateView.php,unified

[2] 
https://review.typo3.org/#/c/16392/40/Classes/TYPO3/Flow/Mvc/Controller/ActionController.php,unified

-- 
Helmut Hummel
Release Manager TYPO3 6.0
TYPO3 Core Developer, TYPO3 Security Team Member

TYPO3 .... inspiring people to share!
Get involved: typo3.org


More information about the TYPO3-project-typo3v4mvc mailing list