Project

General

Profile

Actions

Bug #81099

closed

Extension cannot override default (fallback) templateRootPaths/partialRootPaths/partialRootPaths

Added by Anonymous almost 7 years ago. Updated 8 months ago.

Status:
Resolved
Priority:
Must have
Assignee:
-
Category:
Fluid
Target version:
-
Start date:
2017-05-01
Due date:
% Done:

100%

Estimated time:
TYPO3 Version:
8
PHP Version:
7.1
Tags:
Complexity:
Is Regression:
Yes
Sprint Focus:

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

bhdummy.zip (7.2 KB) bhdummy.zip Riccardo De Contardi, 2017-08-02 13:03
cattura.png (17.3 KB) cattura.png Riccardo De Contardi, 2017-08-02 13:04

Related issues 3 (0 open3 closed)

Related to TYPO3 Core - Bug #79681: Configured Fluid template not foundClosedNicole Cordes2017-02-08

Actions
Related to TYPO3 Core - Bug #79290: Fluid cannot override default resolved paths if default paths existClosed2017-01-12

Actions
Has duplicate TYPO3 Core - Bug #79926: InvalidTemplateResourceException never thrownClosed2017-02-20

Actions
Actions #1

Updated by Anonymous almost 7 years ago

  • Related to Bug #79681: Configured Fluid template not found added
Actions #2

Updated by Anonymous almost 7 years ago

  • Related to Bug #79290: Fluid cannot override default resolved paths if default paths exist added

Updated by Riccardo De Contardi over 6 years ago

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!

Actions #4

Updated by Stephan Leithold over 6 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.

Actions #5

Updated by Urs Braem over 6 years ago

We seem to have this too in 8.7.6

Actions #6

Updated by Sebastian Iffland over 6 years ago

Unfortunately not fixed in 8.7.7

Actions #7

Updated by Mario Lubenka over 6 years ago

I can also confirm the issue described by Christian from 8.7.6 to 8.7.8.

Actions #9

Updated by Riccardo De Contardi over 6 years ago

  • Status changed from Needs Feedback to New
Actions #10

Updated by Claus Due about 6 years ago

  • Has duplicate Bug #79926: InvalidTemplateResourceException never thrown added
Actions #11

Updated by Riccardo De Contardi over 5 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]));
            }
        }
Actions #12

Updated by Krzysztof Napora over 5 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

Actions #13

Updated by Riccardo De Contardi over 5 years ago

  • Status changed from Needs Feedback to New
Actions #14

Updated by Christian Heindl over 5 years ago

Affects also 9.3. Problem still existing there.

Actions #15

Updated by Marti McFlight almost 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/
        }
    }
}
Actions #16

Updated by Riccardo De Contardi almost 4 years ago

Is this somehow related? #87737

Actions #17

Updated by Jennifer Hauß almost 4 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.

Actions #19

Updated by Christian Müller about 2 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
  }
}
Actions #20

Updated by Friedemann Altrock 11 months ago

This is still applicable to 10.4, 11.5, and presumably 12.5 as well.

The rabbit-hole goes deep.

  1. Back in 2015, somebody introduces a method sanitizePath to the class TemplatePaths, 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 to array_unique, which means that each path can only be contained once in the resulting array.
  2. During initialization of the Extbase MVC view, the following code is executed:
    1. 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.
    2. 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
    3. 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.
  3. Effectively, if you configured the extension path with your TypoScript at any other index but 0, it will get moved to index 0.
  4. 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.

Actions #21

Updated by Simon Praetorius 10 months 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?

https://github.com/TYPO3/Fluid/pull/805

Actions #22

Updated by Friedemann Altrock 8 months 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...

Actions #23

Updated by Gerrit Code Review 8 months 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

Actions #24

Updated by Gerrit Code Review 8 months 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

Actions #25

Updated by Gerrit Code Review 8 months 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

Actions #26

Updated by Gerrit Code Review 8 months 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

Actions #27

Updated by Gerrit Code Review 8 months 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

Actions #28

Updated by Anonymous 8 months ago

  • Status changed from Under Review to Resolved
  • % Done changed from 0 to 100
Actions

Also available in: Atom PDF