A question which I am asking myself since a while:
Can anyone tell me if there is a difference in rendering a template with #-annotation or in colon-style:
#Acme/AcmeBundle/Default/index.html.twig
Acme:AcmeBundle:Default:index.html.twig
and if there is a difference what is it,
if not which is the newer/proper one and should be used accordingly?
Both namespaced templates and traditional template will work as expected in views but it wont work in controllers. Please check here
// namespaced templates will no longer work in controllers
$this->render('#App/Default/index.html.twig');
// you must use the traditional template notation
$this->render('AppBundle:Default:index.html.twig');
{# inside a Twig template, namespaced templates work as expected #}
{{ include('#App/Default/index.html.twig') }}
{# traditional template notation will also work #}
{{ include('AppBundle:Default:index.html.twig') }}
The namespaced syntax is faster.
Please refer this for more info
Related
I'm interested in the full list of all possible abilities Drupal-specific Twig has to work with files, i.e. reading, writing, copying, renaming etc. Including all the abilities Twig itself has regardless of CMS. So please don't remove the tag Twig.
Yet I just know about loading template partials like
{% include '#themename/header.html.twig' %}
It's an example of reading a file by its filesystem path
Can Drupal-specific Twig or Twig itself also rename a file? Or copy with renaming? And so on
I am using symfony 5.4.
I have a bundle located in my vendor folder that works fine.
I have created a LiveTwigComponent.
It works perfectly when the template file 'network_list.html.twig' is located in my 'templates/components' folder.
As the logic belongs to my Bundle, i have tried to move it to the 'src/Resources/views/components' folder.
If I do so, I have an error:
"Unable to find template "components/network_list.html.twig"
In my template, I call the component like this
{{ component('network_list') }}
I have tried to prefix with the bundle namespace as it works for the other templates I have in my bundle
{{ component('#MyFooBarBundle\\network_list') }}
and
{{ component('#MyFooBarBundle\\components\\network_list') }}
but doesn't work either, I have another error message
An exception has been thrown during the rendering of a template ("Unknown component "#MyFooBarBundle\components\network_list". The registered components are: network_list").
I suspect I may have to add a config line for twig to tell the bundle to look into my bundle subfolder and i didn't find any documentation about this.
What am i doing wrong ?
Thanks in advance
The default path is located in config/packages/twig.yaml, if you wish to change the default path you can do so here. If you want to add multiple locations, you can do so by adding them to the 'paths' section and defining the file type. The code below should work for your use case:
# config/packages/twig.yaml
twig:
default_path: '%kernel.project_dir%/templates'
paths:
'%kernel.project_dir%/assets/css': css
'%kernel.project_dir%/src/Resources/views/components': twig
You can customize the template used to render the component by passing it as the second argument to the AsTwigComponent attribute:
- #[AsTwigComponent('network_list')]
+ #[AsTwigComponent('network_list', template: '#MyFooBarBundle/network_list.html.twig')]
class NetworkListComponent
{
// ...
}
We use fractal.js with a twig engine to prototype websites. Fractal.js brings a handy functionality to be able to use handles in includes.
So instead of writing {% include 'templates/components/teaser/basicTeaser.twig' %}, you can just write {% include '#basicteaser' %}. See: https://fractal.build/guide/core-concepts/naming.html#referencing-other-items
Of course that relies on unique components names, which I am happy to have anyway.
Could anybody point me in the right direction on how to extend timber or twig to use such handles?
Many thanks!
Twig already offers the option to load templates from an array of directories rather than just one.
$loader = new \Twig\Loader\FilesystemLoader([$templateDir1, $templateDir2]);
Plus, before passing the loader to the environment object, you can add paths for custom namespaces, i.e.:
$loader->addPath($templateDir, 'admin');
Then you can use you namespace like this:
$twig->render('#admin/index.html', []);
https://twig.symfony.com/doc/3.x/api.html#built-in-loaders
I know this is an old question and this might not be relevant to the OP anymore, but we needed the same thing and developed a WordPress plugin to bridge Timber + Fractal. You can export your Fractal components to the components-map.json file, then the loader will read the map and convert those component names to file paths.
I just started to learn how to use Symfony which i believe is straight forward but i have a little problem with the templating engine. I want to include a static HTML fragment in one of my twig templates in Symfony (2.5.6). For now i created a static subfolder inside the resources directory (this might change but it definitely won't be inside the view folder). However i can't get this done, i always end up with an unable to find template error. I find the documentation on this subject a bit sparse (see http://symfony.com/doc/current/book/templating.html#including-other-templates) also the twig docs can't help me out on this one. I'm not even sure if i can use the magic #Bundle notation or if i have to reside in the view folder as ../ notation is not allowed within the include tag.
I tried the following (and a couple of variations):
{{ include('#FashionMediaBundle/Resources/static/pricing.html') }}
I guess symfony cannot handle raw html in include but i could use a php template without any template tags as well, so the question is just how to specify a location outside the view folder.
I know of http://github.com/kgilden/KGStaticBundle which will probably solve my issue but i can't believe that is not achievable with the default configuration.
EDIT: i just tried to include a regular template file from the very same directory specifying just the name of the template file (as done in the docs, see link above). Still i get an error also complaining it expects bundle:section:template.format.engine as its format. Is there an error in the docs?
Looks like the poster found the solution while I was typing. I guess I'll leave this here for just a bit.
Creating and using twig namespaces is discussed here: http://symfony.com/doc/current/cookbook/templating/namespaced_paths.html
By default, each bundles get's it's own namespace pointing to the views directory. You can add additional directories by adjusting app/config.yml
twig:
debug: %kernel.debug%
strict_variables: %kernel.debug%
paths:
"%kernel.root_dir%/../../cerad2/src/Cerad/Bundle/FashionMediaBundle/Resources/static": FashionMedia
Load the template with: '#FashionMedia/pricing.html'
I won't go into all the details but you can also use a compiler pass(http://symfony.com/doc/current/cookbook/service_container/compiler_passes.html) to add additional paths from inside the bundle itself without having to adjust config.yml:
class Pass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$bundleDirAction = $container->getParameter('cerad_api01__bundle_dir') . '/Action';
$twigFilesystemLoaderDefinition = $container->getDefinition('twig.loader.filesystem');
$twigFilesystemLoaderDefinition->addMethodCall('addPath', array($bundleDirAction, 'CeradApi01'));
}
}
Try this:
{{ include('FashionMediaBundle:Resources:static:pricing.html') }}
If you want to put this file in another directory I suggest you to use a symbolic link (I don't know if Twig can include a file which is not in the Resources directory).
I found the Solution!
In the twig configuration you can set paths and assign a name to them.
twig:
[... twig options here ...]
paths:
"%kernel.root_dir%/../[path to static]": static_pages
And then you can include them in
{% include "#static_pages/pricing.html.twig" %}
What's really the purpose of include with only in Twig:
{# only the foo variable will be accessible #}
{% include 'child.html.twig' with {'foo': 'bar'} only %}
Maybe some performance benefits? Or just only for avoid overriding variables in the included template? As documentation:
Included templates have access to the variables of the active context. You can disable access to the context by appending the only keyword.
When you include a template, it has access to all the variables available in the including template. If for some reason you don't want that, use the only keyword.
I haven't been in a situation when I needed that, but there might be reasons other than performance. For example, you could use it to avoid naming collisions in some scenarios.