Block header in symfony, twig - symfony

I'm wondering...
If I have a website where I use two headers
header.homepage.html.twig - only used at main page
header.other.html.twig - used everywhere else
Which one should I put into
{% block header %} {% include 'main/header.?.html.twig' %} {% endblock header %}
in base.html.twig?
I'm almost sure that I can do whatever I want - in this case put header.other.html.twig there, as it is used more times. So I need only include header.homepage.html.twig once, in index. BUT I always see people around putting the main header of the page in base.
So my question is - Including the main header in base.html.twig is the best practice or some people do it out of habit?

Related

How to modify endblock content in symfony

I want to modify the content of the end block in the symfony. When I did inspect element at that time it is showing in model-footer. How can I modify footer content.
I want to change name from save order to save
The question is not clear but I think I know what you mean ...
Normally you have a block {% block footer%} {% endblock%} in your base.html.twig. To add content, go to the specified view by adding ...
{% block footer%}
// Your HTML Content
{% endblock%}

Using alternative (translated) titles in dynamic menus in Lektor

I'm new to Lektor and I've been using this snippet in my layout to dynamically generate menus
{% for content in site.get('/').children %}
<li>{{ content.title }}</li>
{% endfor %}
It works fine to produce the alt url accordingly to the alternative (language) selected, but the title is still shown only in the primary language of the content instead of the translated one.
That means that when a say french alt is selected (and present in the url), menus are still i.e. Main, Contact instead of the french translated version.
I know I can work around this using a databag to hold a language mapping for the menus, but that would require to duplicate the title information in the databag and then make sure it stays in sync with whatever is in content.title.
Ideally what I'm missing is a filter for title where you can specify the alt you want to use, or some other method that I'm not aware of?
Naive as it may be, I didn't realize that you can pass the alt parameter in site.get until after I looked at the source code. So the way to get the defined child pages for a certain language is:
{% for content in site.get('/', alt=alt).children %}
<li>{{ content.title }}</li>
{% endfor %}
And since we already specified the alt parameter in the get, we don't need to filter the url anymore for the current alt.

Silex - How to process template includes separately

I've got a Twig base template like so:
{% include "./partials/navigation.html" %}
<!-- Main Wrapper -->
<div id="wrapper">
{% block content %}{% endblock content %}
</div>
I also have a route controller which is outputting the response content to the page using twig:
return template->render('path/to/teplate', args());
where args[] array is all the data needed for this bit: (different on every page)
{% block content %}{% endblock content %}
However my sidebar is being built separately through a menu builder class, and now it needs to render the results of building the menu to my template and populating ./partials/navigation.html.
An easy solution for me is to just append the results of the Menu Builder to the returned response of every controller (I can use a base controller class to do this as this menu appears on every page). However something about this feels unclean as if I have to render the same header/footer every time as well I'll have to be append all 3 outputs to the response. (maybe that is okay?)
Is there a better way of rendering several includes worth of content which each need their own DB lookups and other server-side logic?
Yes. They are called sub requests. Read the documentation here.

Twig: render Symfony2 controllers which extend blocks in the parent template

Say I'm having a base template like this:
// Default/index.html.twig
{% block javascripts %}
<script>//some script</script>
{% endblock %}
<div>
{{ render(controller(MyControllerBundle:Default:header)) }}
</div>
{{ text }}
<div>
{{ render(controller(MyControllerBundle:Default:footer)) }}
</div>
And this renders controllers having these templates:
// Default/header.html.twig
Header content
{% block javascripts %}
<script>//some additional scripts from the header</script>
{% endblock %}
and
// Default/footer.html.twig
Footer content
{% block javascripts %}
<script>//some additional scripts from the footer</script>
{% endblock %}
Is it possible somehow to use the javascripts block from the rendered sub controllers in the parent template?
I want to have all javascripts cumulated in one place.
Rendering from bottom up with extending is no option here because the template consists of
multiple blocks that are rendered by different controllers.
Is this possible somehow? Or is there a better approach to this?
Anything is possible however design-wise it might not be a good idea.
The render tag is really useful when it comes down to scaling and it used as a way to isolate a request. Each render call is considered as a sub-request and a cache strategy can be applied to it.
I'd highly advise you to read this documentation about HTTP caching and especially the part that talks about Edge Side Includes (or ESI).
When you use the render tag, think of it as a module you want to include in multiple pages and eventually cache.
You shouldn't interact with the master request because the sub request is isolated for caching (depending on the place you embed the render tag, the master request will be different which means you might get some unexpected results).
First of all, I'd create a layout template that every other pages extends. The layout template will declare all the basic blocks (javascript, css, footer, header, <head>, <body> - you can abstract in more templates if you want).
If you have logic for your footer or header split them into Twig functions (or filters) and handle the logic in Twig but keep it light (if it's too complicated or too spaghetti that means there is another way).
Avoid having multiple Javascript or CSS files per page. If you have some css or javascript that appears on some pages but not all of them it's still probably a good idea to merge them into one file (less DNS calls on the client side and once it's cached it will be faster to load the page).
If you have a administrator.js kind-of file, then you could include it as a separate file but if most requests come from administrators then you might want to include it with all the other files.
If you didn't know you can combine assets (js or css) into one file: more info in the Symfony documentation.
I didn't answer your "how" question because I'd strongly advise you to not implement such a system however I believe I've shared good guidelines to make an informed decision.
when extending / rendering other content in TWIG you can call the parent block: http://twig.sensiolabs.org/doc/functions/parent.html
this means that you can leave default as it is and inside header / footer define
{% block javascripts %}
{{ parent() }}
{# other scripts #}
{% endblock javascripts %}
I would suggest that you have different block name for the footer - that way you can include scripts outside of the header.
Also, it might be best to keeps scripts in one place - that way you can use assetic rewrite's later down the line : http://symfony.com/doc/current/cookbook/assetic/asset_management.html#including-javascript-files
exactly what #Pazi says in the comment: Do you need a controller? It looks pretty simple to just include the template by itself, without using a controller.
You might use the include tag to include the subtemplates.
{% include 'MyControllerBundle:Default:header.html.twig' %}
For reusing the javascript block from the rendered sub controllers, you could create a base template that contains the javascripts block. Then extend that base template file in your header and footer. Or just including the base template in them should work, too.

is it possible in symfony2 to extend 2 templates?

I'm thinking to organize my base layout in symfony2 containing only 3 blocks: header, content, and footer. And I want to have one template for each block. The "content" template will be a template that will be empty, showing only the templates for every section, following the "3 levels" directives.
But I don't know how to include the header and footer template. I've done it creating "by pass" templates, so, for example, content extends footer, footer extends header, and header extends base, but it looks very bad.
Thanks.
you can use the embed tag, that combines the behaviour of include and extends. It allows you to include another template's contents, just like include does. But it also allows you to override any block defined inside the included template, like when extending a template,
but version 1.8 is required
The embed tag
You can't extend more than one template in Twig, it is illogical anyway.
You should use include, which is a bit different.
The common way is to have one base template, which will be extended by all the other ones, except the header and the footer that will be included in it.
base.html.twig:
...
<body>
{% include '::header.html.twig' %}
{% block body %}{% endblock %}
{% include '::footer.html.twig' %}
</body>
...
In the other templates, your bundles' views for example:
{% extends '::base.html.twig' %}
{% block body %}
Hello world!
{% endblock %}

Resources