dynamic function in twig template - symfony

I would like to display some dynamic text on many twig-templates.
Instead of adding this variable to every Action , I would prefer to write it once and somehow add it to the templates like
{{ displaytext('ann') }}
How can I achieve this?

You can achieve this by creating a Twig Extension class.
Read more about this at http://symfony.com/doc/current/cookbook/templating/twig_extension.html

You can create a file with this variable and include it in the others files -> Twig includes
You can set variables for your included page as shown in the documentation:
{# template.html will have access to the variables from the current context and the additional ones provided #}
{% include 'template.html' with {'foo': 'bar'} %}
{% set vars = {'foo': 'bar'} %}
{% include 'template.html' with vars %}

Related

Symfony bundle inheritance and twig templates overriding

I have a third party bundle called VendorDeliveryBundle.
I want to override one of its twig templates that i called with this syntax in one of my App twig templates:
{% include '#VendorDelivery/Frontend/Booking/_delivery.html.twig' with { 'form': form } only %}
Like this it works, the vendor template is called.
But if i want to override this template by registering the overriding bundle in AppKernel (as described in https://symfony.com/doc/2.8/bundles/inheritance.html) and by creating:
App/DeliveryBundle/Resources/views/Frontend/Booking/_delivery.html.twig
this template doesn't override the vendor template.
But if i use this syntax instead
{% include 'VendorDeliveryBundle:Frontend:Booking/_delivery.html.twig' with { 'form': form } only %}
the template is overridden.
It seems that the # syntax doesn't work as expected.
So i'm wondering if it is a bug or a normal behavior considering this symfony documentation https://symfony.com/doc/2.8/bundles/inheritance.html:
The overriding of resources only works when you refer to resources with the #FOSUserBundle/Resources/config/routing/security.xml method. If you refer to resources without using the #BundleName shortcut, they can't be overridden in this way.
Thanks,
# in twig syntax is a feature called "namespaced paths". (documentation)
Use functionality of {% include 'Bundle:Folder:template' %} it is not the same thing as {% include '#Bundle\Folder\template' %}.
For sample, if you overriding fosub bundle:
{% include '#FOSUser/Security/login.html.twig' %} {# Will be fosub template #}
{% include '#User/Security/login.html.twig' %} {# Will be overrided template #}
{% include 'FOSUserBundle:Security:login.html.twig' %} {# Also will be overrided template #}
Also, i want to add, that if you want to override only a template (without global functionality as controllers, listeners, etc) you can added templates to you app directory. It is well described in this documentation

Twig and atomic pattern — Clean twig rendering

I'm trying to follow the atomic design pattern with twig.
When rendering a simple atom, I need to do something like:
{% include '#MyBundle/Resources/views/atoms/button/button.html.twig' with { href: '/section1', text: 'Example text' } only %}
This approach starts getting messy when the atom or component has more variables, or the directory structure is a bit more complex.
I'd be awesome to be able to do something like:
{% button('/section1','Example text') %}
I know that this can be achieved with a twig function, but I'm worried this pattern can get tricky with a larger code base.
Any experience around this? Cheers!
You can use macro structure. Read documentation: http://twig.sensiolabs.org/doc/tags/macro.html
{% macro button(href, text) %}
{% here you can place your template %}
{% endmacro %}
Then you will need only import your twig file with macro once. After that you can use construction like {% button('/section1','Example text') %}.

Drupal 8 include part template

I'm trying to use Drupal 8, with an own theme, due big structure differences for my requirements I have a page--front.twig.html and a page.twig.html, I would like to create template parts as used in phrozn oder in a normal Symfony2 project, for example a footer.html.twig and a header.html.twig. These templates are saved under a subdirectory /parts/
But wenn I call this templates as normal I just receive a string with the name of the template.
For example:
{# in page.html.twig or page--front.html.twig #}
{% include 'parts/footer.html.twig' %}
Returns the file name as string:
parts/footer.html.twig
It's possible to do that with Drupal 8?
You can include any part of your template files like this
{% include directory ~ '/parts/footer.html.twig' %}
or this
{% include '#mytheme/parts/footer.html.twig' %}
I strongly recommend you to create a reusable layout for pages that will give you greater flexibility when dealing with more pages and variants.
{# filename: page-layout.html.twig #}
{% block content%}
{{ page.content }}
{% endblock%}
{% block footer%}
{% include '#mytheme/parts/footer.html.twig' %}
{% endblock%}
So you can do something like this in another page
{# filename: page--front.html.twig #}
{% block footer%}
<div> I want to handle a different footer in here</div>
{% endblock%}
Finally, I found really helpful to dig into suggestions array and see what Drupal is trying to use.
Cheers.
it's possible using the name of the template in the path
{% include '#mytheme/parts/footer.html.twig' %}
thanks to https://drupal.stackexchange.com/questions/141066/drupal-8-include-part-template
Now that https://www.drupal.org/node/2291449 has been committed you can also do:
{% include 'footer.html.twig' %}

symfony2: index in individual form field for collection type

After hours of searching, I found a solution how to apply themes to individual fields for collection types here: symfony2: Applying theme to individual field for collection type (thanks #TroodoN-Mike).
So a custom theme for a collection type could be:
{% block _author_tags_entry_label %}
{# ... #}
{% endblock %}
The word "entry" replaces the row index, which works fine, but I need the Row index inside the custom block, something like {{ entry }}. Any hints?
Thanks
Chris
Ok, I found the solution. I wasn't aware of the fact, that you can pass custom variables to the form theme like this:
{{ form_row(form.field, {'customVariable': 'anyValue'}) }}

Nesting included Twig templates?

I'd like to pass the output of an included Twig template to another included Twig template as a parameter, like so:
{% include 'MyBundle:Default:tpl1.html.twig' with {'item': include 'MyBundle:Default:tpl2.html.twig'} %}
Unfortunately, this does not work as the syntax is invalid.
Any ideas how to nest templates like this / store the output of an included template in a variable?
Or is there an alternative way to accomplish what I want to do? I thought about defining blocks in the included template, but it does not seem to be possible to overwrite them from the "outer" template ...
Try settings the template's content in a variable:
{% set content %}
{% include 'foo' %}
{% endset %}
{% include 'bar' with {'item': content } %}
It should work.

Resources