I recently stumbled over an inconsitent or at least unexpected behavior of the Views.yaml that occurs if multiple TemplateRootPathes are defined and overridden. (LayoutRootPathes and PartialRootPathes behave the same)
If multiple requestFilters match they are sorted by weight and afterwards the configurations of all matching filters are merged with the lowest weight first. The problem is that during that process keys that are added to ‚templateRootPaths‘ in the higher weighted requestFilters end up last in the merged configuration. That leads to the situation that the first templateRootPaths of the highest weighted configuration is used as last.
As you can see the Vendor.Site path is added as last key and thus never used. This behavior makes it impossible to add single pathes to the top of the list to make sure they are evaluated first. Also adding the original pathes to the overriding configuration does not alter this situation.
In general i see some possible approaches to solving this problem. I already tried the two promising aproaches and created pr’s for that.
Make ArrayMergeRecursiveOverrule ordering aware … i think this would lead to many unexpected effects and should be avoided
As 3 changes the configuration syntax it should be considered breaking as well I guess. Maybe a fallback can be done though. So I guess 2 or 3 it is. One particular problem I have with hte implementation is that IMHO the fluid view shouldn’t need to know about this. It receives an array of paths and uses them in order. The sorting should happen beforehand.
In that regard option 2 could be easier to implement. I think the basic use case is to be able to override view options from the outside, maybe even multiple times, which would be fulfilled with 2 and 3 IMHO as long as you manage to create a __higher_weighted_matcher__ to override the previous one. I am not sure about that, but that’s a story for another day.
We just can’t know what the correct behavior should be if the more specific configuration just sets one array item to an existing array.
In the case of TemplatePaths you probably want to add it to the beginning but there might be other options where you just want to append this.
I like that solution because it can be implemented completely backwards compatible.
On the other hand it makes the configuration pretty “bloated” making the “merging” not really worthwile… that’s why:
would be the most consistent and easy to comprehend…
It would also solve another issue that we currently have:
If you change the template implementation in your Views.yaml The View will complain about any base options that are not supported by that view…
I think we could live with that different behavior if we communicate it in the release notes and provide a core migration that adjusts any existing Views.yaml
I don’t think that core migrations are possible because the filters are evaluated at runtime. Nearly impossible to find all filters that could match the same requests as a given filter. At least with reasonable effort.
I would prefer option 4 because of it is clean and predictable. I could do a pr for that but if we want a core-migration for old filters i would abstain. I fear such a migration would take a real high effort to get it right with very little benefit.
The PR for Option 3 is already there so if that is preferred i can clean this up.
You’re right, it will probably be quite a hassle to get that working.
What we should do though is to display a generic warning for any existing Views.yaml – we did similar things previously and I can take care of the respective core migration.