Bug #81099
closed
Extension cannot override default (fallback) templateRootPaths/partialRootPaths/partialRootPaths
100%
Description
I upgraded from 7.6 to 8.7 today and discovered a regression in TemplatePaths.php.
Wanted behaviour (TYPO3 7.6):¶
I have two extensions:
1. Extension "base_templates" contains a lot of fluid Partials
2. Extension "specific_templates" uses the Partials from "base_templates" and overwrites some of them.
So fluid should use the following order:
1. Check if "specific_templates" has the searched partial
2. Check if "base_templates" has the search partial
So "base_templates" is a fallback for "specific_templates".
To achieve this behaviour I configured partialRootPaths of "specific_templates":
plugin.tx_specific_templates { view { partialRootPaths { 10 = EXT:base_templates/Resources/Private/Partials/ 20 = EXT:specific_templates/Resources/Private/Partials/ } } }
This setup worked in TYPO3 7.6 (Higher key overwrites lower key).
Actual behaviour (TYPO3 8.7):¶
8.7 changed the merging of default partialRootPaths and configured partialRootPaths.
The problem is "getContextSpecificViewConfiguration" in TemplatePaths.php:
https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_8-7-1/typo3/sysext/fluid/Classes/View/TemplatePaths.php#L77
Since the partialRootPaths.0
is always set to EXT:specific_templates/Resources/Private/Partials/
they always get overwritten by Partials in EXT:base_templates/Resources/Private/Partials/
.
The array_merge in https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_8-7-1/typo3/sysext/fluid/Classes/View/TemplatePaths.php#L124 makes it impossible to overwrite partialRootPaths.0, because numeric array keys are not overwritten but appended.
So the result is always the following:
array ( 0 => 'BASE_PATH/www/typo3conf/ext/specific_templates/Resources/Private/Partials/', 1 => 'BASE_PATH/www/typo3conf/ext/base_templates/Resources/Private/Partials/', )
Wanted result:
array ( 0 => 'BASE_PATH/www/typo3conf/ext/base_templates/Resources/Private/Partials/', 1 => 'BASE_PATH/www/typo3conf/ext/specific_templates/Resources/Private/Partials/', )
Possible solutions¶
Replace
$paths[$name] = array_merge($defaultPaths, (array)$configuredPaths[$name]);with (used in 8.5.1 https://github.com/TYPO3/TYPO3.CMS/blob/TYPO3_8-5-1/typo3/sysext/fluid/Classes/View/TemplatePaths.php#L120)
$paths[$name] = (array)$configuredPaths[$name] + $defaultPaths;
Sadly this seems to cause other problems: #79681,#79290
Maybe we should just check if partialRootPaths.0
is explicitly set with TypoScript and in this case do not set the default partialRootPaths?
Files
Updated by Anonymous almost 8 years ago
- Related to Bug #79681: Configured Fluid template not found added
Updated by Anonymous almost 8 years ago
- Related to Bug #79290: Fluid cannot override default resolved paths if default paths exist added
Updated by Riccardo De Contardi over 7 years ago
- File bhdummy.zip bhdummy.zip added
- File cattura.png cattura.png added
- Status changed from New to Needs Feedback
Hi @christoph - Bessei, I just did the following test with the latest TYPO3 8.7.4:
1) I defined a very stupid and dummy extension (attached bhdummy.zip) that has at least one partial
2) I already use a "frontend configuration" extension (bhsiteconf) that is loaded as last in TypoScript Setup (Include static from Extension) where I copied the partial from bhdummy (and I modified it)
3) I set the constant $plugin.tx_bhdummy.view.partialRootPath so the final result is shown in Cattura.png
Result: I am not able to reproduce the issue; the partial shown is the one from
plugin.tx_bhdummy.view.partialRootPaths.1
Do you think that a different test should be done? Did I miss something? Thank you!
Updated by Stephan Leithold over 7 years ago
I tested in Typo3 8.7.6. I can't override the template paths like Christoph. In Version 8.7.4 / 8.7.5 it works as expected.
Updated by Mario Lubenka over 7 years ago
I can also confirm the issue described by Christian from 8.7.6 to 8.7.8.
Updated by Frank Krüger about 7 years ago
This is still an issue in 8.7.9, afaik caused by
https://github.com/TYPO3/TYPO3.CMS/commit/cdd6dca4c9dbc0a5563f8beb68aed2dde2d061cf#diff-e29c9d272acd4119f0a7f907625256c7
Updated by Riccardo De Contardi about 7 years ago
- Status changed from Needs Feedback to New
Updated by Claus Due almost 7 years ago
- Has duplicate Bug #79926: InvalidTemplateResourceException never thrown added
Updated by Riccardo De Contardi over 6 years ago
- Status changed from New to Needs Feedback
I am not able to reproduce this issue on version 8.7.17 (see my comment 3 for the test); can you confirm it?
Moreover, the lines on the commit reported on comment 8 are changed:
foreach ($paths as $name => $defaultPaths) { if (!empty($configuredPaths[$name])) { $paths[$name] = array_merge($defaultPaths, ArrayUtility::sortArrayWithIntegerKeys((array)$configuredPaths[$name])); } }
Updated by Krzysztof Napora over 6 years ago
I have the same problem . I'm use typo3 version 8.7.18 .
Example . I have news extension and next for example I create new extension where I extend news for example so_my_news . And now we have setup for Layout, Template like here
10 => EXT: so_my_news/Resources/Private/Layouts
100 =>EXT:news/Resources/Private/Layouts/
and now you have
1 => string '/var/www/html/web/typo3conf/ext/news/Resources/Private/Layouts/'
2 => string '/var/www/html/web/typo3conf/ext/so_my_news/Resources/Private/Layouts/'
how you see the order is not the same . You can check this : typo3/cms/typo3/sysext/fluid/Classes/View/TemplatePaths function setLayoutRootPaths
Updated by Riccardo De Contardi over 6 years ago
- Status changed from Needs Feedback to New
Updated by Christian Heindl over 6 years ago
Affects also 9.3. Problem still existing there.
Updated by Marti McFlight over 5 years ago
We just experiences a similar problem in TYPO3 version 9.5.8:
Our extension was named like „our_extension“. So we did the typoscript setup inside the extension like
plugin.tx_our_extension { view { partialRootPaths { 0 = EXT: our_extension/Resources/Private/Partials/ 1 = {$plugin.tx_our_extension.view.partialRootPath} } } }
and tried to overwrite it in another extension like
plugin.tx_our_extension { view { partialRootPaths { 10 = EXT: another_extension/Resources/Private/Partials/ } } }
It didn’t work until we changed „plugin.tx_our_extension“ to „plugin.tx_ourextension“. Just without the underscore:
plugin.tx_ourextension { view { partialRootPaths { 10 = EXT: another_extension/Resources/Private/Partials/ } } }
Updated by Riccardo De Contardi almost 5 years ago
Is this somehow related? #87737
Updated by Jennifer Hauß almost 5 years ago
Hi,
I think I'm facing a similiar issue. I can't override template/partial/layout root paths if I have following setup:
I include typoscript of a extern extension - let's call it extern_extension - via static template. It has defined partialRootPaths like this:
plugin.tx_externextension {
view {
partialRootPaths {
0 = EXT: our_extension/Resources/Private/Partials/
1 = {$plugin.tx_externextension.view.partialRootPath}
}
}
}
I also include my own typoscript template from my sitepackage via static template. In the sitepackage I try to set the constant plugin.tx_externextension.view.partialRootPath in the constants in my sitepackage. But: I don't do it in Configuration/TypoScript/constants.typoscript directly, but in an extra file which is included in my constants.typoscript via @import / <INCLUDE_TYPOSCRIPT>.
With this setup, I can see my added partialRootPaths in the backend in the typoscript object browser, but in FE they are not taken into account. Same problem if I don't use the constant, but do it in setup (but also in an extra file which gets included from my setup.typoscript).
Solution for me was to either, put my overrides directly in setup.typoscript or constants.typoscript OR to not import the typoscript settings from the extern extension via static template, but use @import in the same file I do the overrides. Both solutions aren't really good in my opinion.
Updated by Christian Müller about 3 years ago
This sounds related too: https://forge.typo3.org/issues/93544
And this one: https://forge.typo3.org/issues/95588
Updated by Christian Müller about 3 years ago
I'm having trouble ordering the root paths too. Running TYPO3 10.4 with PHP 7.4 .
Inside of my controller action I'm debugging "$this->resolveView()" and looking for:
baseRenderingContext -> templatePaths -> partialRootPaths
I have configured three items but only two are shown there. It seems like douplicate parths are removed But lets look at the resulting array:
$partialRootPaths = [ 0 = '/var/www/.../typo3conf/ext/foo/Resources/Private/Partials/' 2 = '/var/www/.../typo3conf/ext/bar/Resources/Private/Extensions/Foo/Partials/' ]
If I look at the TypoScript object browser, it shows me the desired/configured paths and order (see below).
Also if I remove all elements except the one from EXT:bar, the path for EXT:foo is still present and I'm unable to get the array completely empty.
plugin.tx_foo { view { partialRootPaths { 0 = {$plugin.tx_foo.view.partialRootPath} 1 = EXT:bar/Resources/Private/Extensions/Foo/Partials/ 2 = EXT:foo/Resources/Private/Partials/ } } } fooPage = PAGE fooPage { typeNum = 1642686437 10 = USER_INT 10 { userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run extensionName = Foo pluginName = Foo vendorName = RANDOHG } }
Updated by Friedemann Altrock almost 2 years ago
This is still applicable to 10.4, 11.5, and presumably 12.5 as well.
The rabbit-hole goes deep.
- Back in 2015, somebody introduces a method
sanitizePath
to the classTemplatePaths
, see here https://github.com/TYPO3/Fluid/commit/fbf343bb25739e2151d8b100be27eb44a36841bc
The change is supposed to ensure that paths are absolute and can be concatenated with File-Paths easily (by having a trailing slash).
BUT, the commit also adds a call toarray_unique
, which means that each path can only be contained once in the resulting array. - During initialization of the Extbase MVC view, the following code is executed:
setViewConfiguration
, which correctly sets the array from the TypoScript view settings
https://github.com/TYPO3/typo3/blob/08c6c69db86497572e639df5bd0c7b7079c63c31/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php#L541
This calls the setXRootPaths methods, which sanitize (unique-ify) the arrays.- Directly after that,
TemplatePaths::fillDefaultsByPackageName
is called as well
https://github.com/TYPO3/typo3/blob/08c6c69db86497572e639df5bd0c7b7079c63c31/typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php#L527-L529 - This calls
TemplatePaths::getContextSpecificViewConfiguration
, and here is where the trouble starts
https://github.com/TYPO3/typo3/blob/08c6c69db86497572e639df5bd0c7b7079c63c31/typo3/sysext/fluid/Classes/View/TemplatePaths.php#L64-L108
That function sets the extension resource paths with index 0 as the "default" base paths.
If the paths were already configured, which they already were, the base paths and the configured paths are merged. So far, so good.
Except, this merged array is then passed to setXRootPaths again. Which removes any duplicate paths.
- Effectively, if you configured the extension path with your TypoScript at any other index but 0, it will get moved to index 0.
- Even if you left the extension paths out of the TS config, the paths will get added at index 0.
EDIT:
The workaround to have an extension which has another extension's resource paths as the fallback is to re-order the template paths in your controller action or initializeView
method "by hand".
That is obviously dumb and this should work out of the box with just TypoScript.
Updated by Simon Praetorius over 1 year ago
- Status changed from New to Needs Feedback
Probably we need to fix several layers here, but I made a first attempt to solve it in Fluid Standalone. Could you check if this changes anything in your case?
Updated by Friedemann Altrock over 1 year ago
I have made a reproduction for 10.4.37, 11.5.30, and 12.4.5, which are currently available via public composer (not ELTS):
https://github.com/fwg/typo3-bugs/tree/forge/81099
The bit that should work but doesn't is here: https://github.com/fwg/typo3-bugs/blob/forge/81099/src/bugs_ext/ext_localconf.php#L24-L29
@Simon Praetorius the patch for typo3fluid/fluid does fix the issue – I think it's better though if the core is fixed.
(The patch does not cleanly apply via composer-patches but it still works.)
This is a patch for typo3/cms-fluid
that also fixes the issue:
https://github.com/fwg/typo3/commit/3717ca7bcdfc1e293258827b6705878f20185638
Now to make it a core contribution...
Updated by Gerrit Code Review over 1 year ago
- Status changed from Needs Feedback to Under Review
Patch set 1 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80658
Updated by Gerrit Code Review over 1 year ago
Patch set 2 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80658
Updated by Gerrit Code Review over 1 year ago
Patch set 3 for branch main of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80658
Updated by Gerrit Code Review over 1 year ago
Patch set 1 for branch 12.4 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80834
Updated by Gerrit Code Review over 1 year ago
Patch set 1 for branch 11.5 of project Packages/TYPO3.CMS has been pushed to the review server.
It is available at https://review.typo3.org/c/Packages/TYPO3.CMS/+/80835
Updated by Anonymous over 1 year ago
- Status changed from Under Review to Resolved
- % Done changed from 0 to 100
Applied in changeset cd067392ff7f6ba053d5724ec34c038da07096db.