How can you make symfony look in non-standard directories to find the "best" (custom) Twig template to load for a bundle view?
The Symfony docs say by default it looks in two locations to override a Twig template
When the AcmeBlogBundle:Blog:index.html.twig is rendered, Symfony actually looks in two different locations for the template:
app/Resources/AcmeBlogBundle/views/Blog/index.html.twig src/Acme/BlogBundle/Resources/views/Blog/index.html.twig
But this is discussing how you would override a vendor bundle. In my case, I have native bundles in my /src/ that I want to overwrite on a per Design Template or Client specific basis. It needs to look in:
Client: /var/www/vhosts/{ID}/src
Template: /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src
Twig Loader has a convenient method to add paths:
$templatePath = '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/Resources/views';
$this->container->get('twig.loader')->prependPath($templatePath, 'template');
This allows me to register an alternative path to the template resources, so that I can render the template shell like this:
{% extends '@template/shell/shell.html.twig' %}
But what about when I want to overwrite a bundle template, e.g.
Original: /var/www/core/cms/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig
Custom: /var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src/Gutensite/MenuBundle/Resources/views/Menu.html.twig
How do I register a generic /src/ file so that Symfony looks in there for all references to Vendor Bundle paths, e.g. trying to render @GutensiteMenu/Menu.html.twig
will first look in the custom directory for 1) Client , 2) Template, 3) default bundle directory by that name.
Because my TemplateBundle/Templates/Admin/Resources/ are in a non-standard location, assetic won't dump them to the public directory (or create symlinks)... so I'm not sure how to dynamically make assetic find these files.
I'm also not sure how to load the assets that are in these other locations, e.g. this doesn't work:
{% stylesheets '@GutensiteTemplateBundle/Templates/Admin/Resources/public/css/site.css' %}
<link rel="stylesheet" href="{{ asset_url }}">
{% endstylesheets %}
Presumably because it's not dumped.
I am building a hosted CMS that is a core vendor which contain various bundles with controllers and templates, e.g. /Gutensite/CmsBundle
, Gutensite/ArticleBundle
.
Based on the selected "Design Template" for a site, a design template is referenced in a TemplateBundle, e.g. /TemplateBundle/Templates/Admin
(a template called "Admin"). The TemplateBundle need to be able to override the core controllers or views.
I have registered the Gutensite/TemplateBundle/Templates/Admin/src/ folder as an alternative namespace for the Composer app/autoload.php, so that controllers can be overwritten as long as they have the same Gutensite
namespace (and this works great):
// in my primary controller:
$loader = $GLOBALS['loader'];
$loader->add('Gutensite', '/var/www/core/cms/src/Gutensite/TemplateBundle/Templates/Admin/src', true);
NOTE: I could register every single template as a bundle, and that would theoretically allow me to override controllers and bundles using symfony's built in methods. But this would add a lot of "bundles" that aren't really traditional bundles. Also I need the above solution to point to alternative template paths, because I also need the ability to point to client's custom files located outside the normal symfony root directory (which I successfully do with the namespace auto loader paths for controllers).
You can use the path
option in the twig configuration, with the same namespace for 2 paths.
twig:
# ...
paths:
"%kernel.root_dir%/../src/Gutensite/MenuBundle/Resources/views": templates
"%kernel.root_dir%/../src/Gutensite/TemplateBundle/Templates/Admin/src/Gutensite/MenuBundle/Resources/views": templates
Then, using @templates/Menu.html.twig
will first look for Menu.html.twig
in MenuBundle, then in TemplateBundle.
That's this way that the TwigExtension
is registering paths so the loader is looking in app/Resources/views
and then in the bundle's views.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With