Drupal 8 include part template - drupal

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

Related

Sensiolabs Insight : Twig templates should not contain business logic

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

Symfony 3 : Unable to use Twig in "Create your First Page in Symfony"

I'm trying the example in the tutorial. So I created the necessary twig-file in the right directory.
{# app/Resources/views/lucky/number.html.twig #}
{% extends 'base.html.twig' %}
{% block body %}
<h1>Lucky Numbers: {{ luckyNumberList }}</h1>
{% endblock %}
But if I open the page I get the error
Looks like you try to load a template outside configured directories (../base.html.twig) in lucky\number.html.twig at line 2
Anyone who can help me out?
Firstly remove the ".twig" from "base.html.twig".
Then check that the file "base.html.twig" is at the root of views folder.
In case it is in a nested folder then nested folder is also specified in extends command (check documentation).

Twig the same block in different included files

I have problem with included files. In my layout.html.twig I have scripts.js at the end body section before {% block script %}{% endblock %}. When file extending layout and use script block, its ok, but when use this block and include file whose use the same block, then is problem. Rendered page has all javascripts, but in different places.
For example:
page.html.twig
...
There is page.html.twig
{% include 'file.html.twig' with {'something': 'something'} %}
After include file.html.twig
..
{% block script %}
<script src="file1.js"></script>
{% endblock %}
file.html.twig
There is file.html.twig
{% block script %}
<script src="file2.js"></script>
{% endblock %}
Then rendered page look like this:
There is page.html.twig
There is file.html.twig
<script src="file2.js"></script>
After include file.html.twig
<script src="file1.js"></script>
I want have all javascript files in one place, one by one.
I think you should try to 'embed' instead of 'include'.
http://twig.sensiolabs.org/doc/tags/embed.html
With embedded, you can choose blocks to include.
Ps : If you override a block, you can get the parent block content in using parent() :
{% block script %}
{{ parent() }}
{% endblock script %}
The {% block %} tag and the inheritance system work only with layouts and {% extends %}. It is not meant to be used with includes, so the script block in your included file.html.twig does not merge with page.html.twig.
One solution would be to set a an argument to you included file.
file.html.twig
{% if get == 'content' %}
There is file.html.twig
{% endif %}
{% if get == 'script' %}
<script src="file2.js"></script>
{% endif %}
page.html.twig
...
There is page.html.twig
{% include 'file.html.twig' with {'something': 'something', 'get': 'content'} %}
After include file.html.twig
..
{% block script %}
<script src="file1.js"></script>
{% include 'file.html.twig' with {'something': 'something', 'get': 'script'} %}
{% endblock %}
You will need to conform to a standard practice when dealing with included templates and inheritance (you can invent your own standard).
Try to compartmentalize your includes, I usually have a directory called 'partials' for includes, and 'fragments' for renders. Each one belonging to a single collection of controller views.
One way I dealt with a similar problem to what you are having was to use a base template which covered the requirements of a specific set of views, each view template would extend it. It may be somewhat wasteful to include the javascripts and stylesheets for the entire collection of views for a specific controller, but it is a) more efficient that including all assets everywhere and, b) I manage the view specific assets under a single base template.
So long as the views have a dependency on that base template the structure wouldn't break.
Think of Twig templates as PHP classes (they compile to classes anyway). A class can inherit from one chain of parents. What you are trying to do is treat two sub-classes as a single child of a super class, overriding the same method at the same time. Simply can't be done. An include is closer to a child property, with is own rules and properties. The included template is less dependent on the includer than vice-versa, so it is impossible for it to inherit from it conventionally.

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.

One django template not picking CSS, other templates are fine

I have two django templates in my one folder. The template for the url localhost:8000/people picks CSS correctly which is located at /m/css/style.css
The other template for the url localhost:8000/people/some-name in the same folder is trying to retrieve CSS from people/m/css/style.css
Why is this second template not picking CSS like the first one?
My erring second template is like this:
{% extends "base.html" %}
{% block page_title %}{{ entry.name }} | {{ block.super }}{% endblock %}
{% block main %}
<h1>{{ entry.name }}</h1>
{{ entry.body|linebreaks }}
{% endblock main %}
As you can see there's nothing in the template that could cause problem.
It looks to me like your templates are looking for a stylesheet located at ../m/css/style.css. That's why the template in /people works - /people/../m/css/style.css refers to /m/css/style.css. However, /people/some-name/../m/css/style.cssrefers topeople/m/css/style.css`, not the desired address.
Make sure the templates are looking for /m/css/style.css - emphasis on the very first / character.

Resources