Twig links to current route but changing locale - symfony

I would add some links to differents locales versions in my existing website. It works quite well but it is pretty ugly^^
<li>
<a href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge(app.request.query.all|merge({_locale: 'es'}))) }}">
<img src="{{ asset('img/flags/es.jpg') }}" alt="es">
</a>
</li>
<li>
<a href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge(app.request.query.all|merge({_locale: 'fr'}))) }}">
<img src="{{ asset('img/flags/fr.jpg') }}" alt="fr">
</a>
</li>
Do you have an idea for doing it better ?

You may need this in many pages and/or more than one project. Here's a possible way based on what I've been using in some:
# app/config/config.yml
# ...
parameters:
# ...
app_locales: [en, es, fr]
twig:
# ...
globals:
locales: %app_locales%
# ...
Then a template for holding flags:
{# app/Resources/views/includes/_flags.html.twig #}
{% set route = app.request.attributes.get('_route') %}
{% set route_params = app.request.attributes.get('_route_params') %}
{% set params = route_params|merge(app.request.query.all) %}
{# You may want to not print a flag/link for current view, the "if" here let you handle it #}
{% for locale in locales if locale != app.request.locale %}
<li>
<a href="{{ path(route, params|merge({ _locale: locale })) }}">
<img src="{{ asset('img/flags/' ~ locale ~ '.jpg') }}" alt="{{ locale }}">
</a>
</li>
{% endfor %}
Finally include flags in any view:
{# app/Resources/views/base.html.twig #}
{% include 'includes/_flags.html.twig' %}

Related

Dynamic path symfony

I have this code:
href="{{ path('new') }}"
Now is necessary use one variable in this section:
href="{{ path(item.ruta) }}"
But this show a error:
An exception has been thrown during the rendering of a template
("Unable to generate a URL for the named route "" as such route does
not exist.").
How can solution this problem?
It seems that item.ruta is empty, so no route could be generated.
You could specifiy a fallback like this {{ path(item.ruta ? item.ruta : 'new') }} or if you want to stay on the current page you need to do something like descripted here: get current url in twig template?
{% if item.ruta %}
href="{{ path(item.ruta) }}"
{% else %}
href="{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) }}"
{% endif %}
or if you really want # only, then remove the path function call
{% if item.ruta %}
href="{{ path(item.ruta) }}"
{% else %}
href="#"
{% endif %}

show logo in drupal 8 custom theme

I'm very new to drupal 8 and I'm doing my first custom template, but I'm having some trouble at the very beginning.
I'm trying to get in the page.html.twig the site_logo, but that is always null. I've checked that in my block setting the checkbox "Toggle branding elements" is enabled.
The code is simply the following but no way to show the logo. What am I missing?
{% if site_logo %}
<a class="logo navbar-btn pull-left" href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">
<img src="{{ site_logo }}" alt="{{ 'Home'|t }}" />
</a>
{% endif %}
{% if site_name %}
<a class="name navbar-brand" href="{{ path('<front>') }}" title="{{ 'Home'|t }}" rel="home">{{ site_name }}</a>
{% endif %}
{% if site_slogan %}
<p class="navbar-text">{{ site_slogan }}</p>
{% endif %}
This code is within a standard page.html.twig template.
Sorry if this is a silly question, but we all need to start somewhere...
Thank you
Luca
There is no site_logo variable in page.html.twig, if you wish to customize site_logo you can use block--system-branding-block.html.twig

Recursive parsing of hierarchical Twig layout with parents, children, grandchildren

In my SF2 project I have an entity (Category) which I am representing in a hierarchical format with a parent at the top, followed by children, grandchildren etc.
The Category entity has a getChildren method, which works and returns Category entity objects.
I'm trying to work out a way to make this layout more dynamic, rather than having to explicitly set children and grandchildren variables within the template.
Is there a better way to do this?
<ul class="sortable">
{% for cat in cats %}
{% set children = cat.getChildren %}
<li id="menuItem_{{ cat.id }}">
<div data-id="{{ cat.id }}">
<span>{{ cat.name }}</span>
</div>
{% for child in children %}
{% set grandchildren = child.getChildren %}
<ul>
<li id="menuItem_{{ child.id }}">
<div data-id="{{ child.id }}">
{{ child.name }}
</div>
{% for grandchild in grandchildren %}
<ul>
<li id="menuItem_{{ grandchild.id }}">
<div data-id="{{ grandchild.id }}">
{{ grandchild.name }}
</div>
</li>
</ul>
{% endfor %}
</li>
</ul>
{% endfor %}
</li>
{% endfor %}
</ul>
so what you are trying to achieve is recursive parsing of a tree in twig right?
If so, have a look at macros
.
{% import _self as macros %}
{% macro showChild(object) %}
{% import _self as macros %}
<ul>
{% for child in object.children %}
{{ macros.showChild(child) }}
{% endfor %}
<li id="menuItem_{{ object.id }}">
<div data-id="{{ object.id }}">
{{ object.name }}
</div>
</li>
</ul>
{% endmacro %}
<ul class="sortable">
{% for cat in cats %}
{{ macros.showChild(cat) }}
{% endfor %}
</ul>
that's all :)
let me know if you need help
EDIT 1:
If you want to use the macro in another file, remove the "import _self" line and just import it with an alias in another file:
index.html.twig:
{% import 'macro_file_name.html.twig' as macros %}
then you can use the same notation to call it

How to use variables in Assetic

I searched a lot but could not find a solution to achieve this:
{% for i in 1..6 %}
<li>
{% image '#MyBundle/Resources/public/images/college/demo/facilities/thumbs/laboratory/'~i~'.jpg' %}
<img class="facThumb" src="{{ asset_url }}" alt="Facilitiy"/>
{% endimage %}
</li>
{% endfor %}
Name of the images should be dynamic. Please help.
The above code throws error:
Unexpected token "operator" of value "~"
Solution:
According to what #Nic posted (accepted answer), the only workaround seems to be this:
{% for i in 1..6 %}
<li>
<img src="{{ asset('bundles/digicreekil/images/college/demo/facilities/thumbs/laboratory/t'~i~'.jpg') }}" alt='demo'/>
</li>
{% endfor %}
You can't use variables in Assetic (and therefore in the {% image %} tag).
The reason is, according to Kris Wallsmith (creator of Assetic):
(...) that Assetic needs to be able to parse a Twig template and extract any assets that are defined there. This is not possible if you use a variable in the tag.
Christophe Coevoet adds:
The assets are dumped when using the CLI command for this, not when rendering the page. So you cannot use variables as you don't have their values.
See this GitHub issue for the complete conversation.
Remember that Assetic creates and optimizes the assets when you run app/console assetic:dump, not when the page is actually rendered. Therefore, it cannot know of any values, it can only work with static assets.
So if you want to work with dynamic assets, you'll have to do something like this:
{% for i in 1..6 %}
<li>
<img class="facThumb" src="{{ asset('images/college/demo/facilities/thumbs/laboratory/'~i~'.jpg') }}" alt="Facilitiy"/>
</li>
{% endfor %}
In this case, you can iterate through the numbers 1-6 and use the variable in the asset's URL because you're not using Assetic, but Twig's asset() function. asset() simply returns the full URL of the asset, it doesn't do any optimizations so it can be executed during runtime.
But if you want to use Assetic's optimizations and filters, you can also give it the static assets:
<li>
{% image '#MyBundle/Resources/public/images/college/demo/facilities/thumbs/laboratory/1.jpg' %}
<img class="facThumb" src="{{ asset_url }}" alt="Facilitiy"/>
{% endimage %}
</li>
<li>
{% image '#MyBundle/Resources/public/images/college/demo/facilities/thumbs/laboratory/2.jpg' %}
<img class="facThumb" src="{{ asset_url }}" alt="Facilitiy"/>
{% endimage %}
</li>
<li>
{% image '#MyBundle/Resources/public/images/college/demo/facilities/thumbs/laboratory/3.jpg' %}
<img class="facThumb" src="{{ asset_url }}" alt="Facilitiy"/>
{% endimage %}
</li>
(etc.)
This way, you'll have to copy the same code 6 times, but it allows you to use Assetic.

twig {% image string %} with concated string

I have code like that
{% for i in 1..25 %}
<li class="span4">
{% set screen = '#TfptPortfolioBundle/Resources/public/images/bekic/screen' ~ i ~ '.jpg' %}
<a href="#myModal" class="thumbnail" data-toggle="modal">{% image screen %}
<img src="{{ asset_url }}" alt="Młody Lider Innowacji" />
{% endimage %}</a>
</li>
{% endfor %}
But symfony throws an error "Unexpected token "name" of value "screen"" on lane
<a href="#myModal" class="thumbnail" data-toggle="modal">{% image screen %}
How can i concat string to use it as asset url?
So it works:
{% for i in 1..25 %}
<li class="span4">
{% set screen = 'bundles/tfptportfolio/images/bekic/screen' ~ i ~ '.jpg' %}
<a href="#myModal" class="thumbnail" data-toggle="modal">
<img src="{{ asset(screen) }}" alt="Młody Lider Innowacji" />
</a>
</li>
{% endfor %}
Obviously you must have executed the command app/console assets:install --symlink to create links on web directories.
EDIT:
Enter into a tag assetic a variable in the way you did is not possible.
To do this you must declare the variable in config.yml.
Here you can see the documentation: documentation assetic.
At the moment the only way is what I described above.

Resources