Sensiolabs Insight : Twig templates should not contain business logic - symfony

I am actually running Sensiolabs Insight analysis on my Symfony 2.8 project.
I have a major issue with some of my Twig templates:
Twig templates should not contain business logic
The associated message is always the same :
Template too complex, depth of 10 is reached but only 5 is allowed.
For example this happens with the following template :
{% extends "FBNGuideBundle::layout.html.twig" %}
{% block title %}
{{ 'fbn.guide.page_title.bookmarks'|trans }}
{% endblock %}
{% block body %}
<div id="bookmarks" data-bookmark-ids="{{bookmarkIds|json_encode()}}">
{% if (restaurants|length > 0) %}
<div class="restaurants">
<h3>MES RESTOS</h3>
{% for bookmark in restaurants %}
<div class="bookmark" id="{{'bookmark-' ~ bookmark.id}}">
{{ bookmark.restaurant.name }}
<br>
<br>
<button>SUPPRIMER DES FAVORIS</button>
<br>
<hr>
</div>
{% endfor %}
</div>
{% endif %}
</div>
{% endblock %}
I tried to include in a separated file the code contained inside <div id="bookmarks"></div> and the depth has been reduced, but it is not a solution. I suppose that the problem is the access to some properties through several objects using getters (i.e bookmark.restaurant.slug).
I have a free plan so I am not able to access the documentation related to this warning. Anyone knows how to solve the problem ?
Thanks.

When you have too much logic in the view, you can put it in a custom Twig Extension. An advantage is that you don't need to duplicate the html if you are reusing that part in another page and of course, the code is more clear :)
In your case, you can write a new Twig Extension that renders all the bookmarks.
If you didn't build somethng similar till now, you can read about it here http://symfony.com/doc/current/templating/twig_extension.html

Related

app.user variable empty (or not available?) in twig custom error message

According to symfony docs, the variable app is available "everywhere" for twig templates. I want to use app.user in a custom error message, but this variable does not actually seem to be available within these templates while in prod mode; it IS available in dev mode.
Example code:
// project/templates/bundles/TwigBundle/Exception/error404.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{{ parent() }}
<div>
<h1>Page not found</h1>
<p>
Hello {{ app.user.name }}, {% <---- DOES NOT WORK %}
The requested page couldn't be located. Checkout for any URL
misspelling.
</p>
</div>
{% endblock %}
This is just a simple example, but illustrates the point. I've also tried to use
{% if is_granted('IS_AUTHENTICATED_FULLY') %}
// do something fancy
{% endif %}
and this also does not work. It also does not matter whether I extend base.html.twig or pull in the parent(), in all cases it does not work. I get no error messages at all. I have cleared by cache.
Any ideas about how to get this information to my template in prod mode?
I found in the documentation that the problem I describe is by design. From the docs:
Security & 404 PagesĀ¶
Due to the order of how routing and security are
loaded, security information will not be available on your 404 pages.
This means that it will appear as if your user is logged out on the
404 page (it will work while testing, but not on production).
The answer is to create my own exception controller (or extend the default ExceptionController).

Drupal 8 conditional syntax

I'm looking for the proper syntax with a Drupal 8 conditional display of a link. I've been reading the twig documentation, and it's a significant jump from the PHP templating days so it's slow going. I need to conditionally display a link within the footer of a view.
In the past, this would be straightforward, i.e:
<?php global $user;?>
<?php if (user_access('administer nodes')):?>
<div class="foo">Shorthand link for admins</div>
<?php endif;?>
Getting this to work in Twig has been difficult as I'm unfamiliar with the syntax. Do I need to declare global user in some capacity? From this link here, Symfony 2: How do I check if a user is not logged in inside a template?, it seems that all I'd need to do is:
{% if is_granted('ROLE_ADMIN') -%}
<div class="foo">Shorthand link for admins</div>
{% endif %}
But I get an error when trying to submit that. Is ROLE_ADMIN not defined? How do I get the Symphony? (correct?) roles as defined within the D8 installation? I'm not sure what I'm doing wrong. Any assistance is appreciated.
If you need to check a specific permission try
{% if user.hasPermission('administer nodes') %}
<div class="foo">Shorthand link for admins</div>
{% endif %}
If you try to check the current user is administer in TWIG file , you can use
{% if is_admin %}
<div class="foo">Shorthand link for admins</div>
{% endif %}

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' %}

Custom data collector for profile is visualy broken

I have created the custom data collector for profiler as described here http://symfony.com/doc/current/cookbook/profiler/data_collector.html .
Now everything is working correctly except of {% block panel %} in template which defines the content area for my information. I have everything in place but on the screen tha page is almost without styles so its visualy broken.
When I compare my panel page and some other from profiler the mine lacks of cca. 200 lines of styles that Symfony is adding to the page header to style the page. I miss style for #content as an example. I tried to clear cache and refreshed everything but still now way. Any idea what is going to be wrong here?
This is waht I see in the browser ...
EDITED: Template
{% extends 'WebProfilerBundle:Profiler:layout.html.twig' %}
{% block toolbar %}
{% endblock %}
{% block head %}
{% endblock %}
{% block menu %}
<span class="label">
<strong>NET.Notes</strong>
</span>
{% endblock %}
{% block panel %}
panel david
{% endblock %}
It is due to empty block of "head". Rust remove it or include parent block by {{parent()}}.
{% block head %}
{#if the web profiler panel needs some specific JS or CSS files #}
{% endblock %}

FOSUserBundle changing text on page depending on form

I'm very new to symfony2 and twig templating in general.
My question is related to the FOSUserBundle.
I have a base template which has 2 columns, {% block left %} and {% block right %}
I have created a new file: Base5/UserBundle/Resources/views/layout.html.twig
which extends my 2 column layout
{% extends '::base_2col.html.twig' %}
{% block left %}
I want this text to change depending on wether a login form, register form, profile page etc is displayed
{% endblock %}
{% block right %}
{{ block('fos_user_content') }}
{% endblock %}
as the actual form is rendered using {{ block('fos_user_content') }}, how can i change the text in the right panel depending on what form is displayed, ideally i want to use a different include, containing the various descriptions into texts for the diffirent form.
Any pointers would be very much appreciated.
Found out, just a question of duplicating the templates from the fosuserbundle views directory

Resources