Twig Custom Extension - call parent() in extending block - symfony

is there any way to call parent() function in extending block in the template of the custom extension?
In my base.html.twig I have block footer_javascript and in my custom extension I would like to add some JS to this block but I need to ensure that original block footer_javascript will be extended not overwritten. I tried this:
custom_extension.html.twig:
{# some html/twig code, not really important #}
{% block footer_javascript %}
{{ parent() }}
{# some javascript for this custom twig extension #}
{% endblock footer_javascript %}
but of course, I get
Calling "parent" on a template that does not extend nor "use" another
template is forbidden
base.html.twig - base template with block structure:
{# base html/twig structure, not really important %}
{# block which will be extended/overwriten in templates which extends this base.html.twig #}
{% block footer_javascript %}
{% endblock footer_javascript %}
extended.html.twig - template which extends base.html.twig; in this template I am using custom twig extension:
{% extends "::base.html.twig" %}
{# some html/twig ... #}
{{ custom_extension(entity) }}
{% block footer_javascript %}
{{ parent() }}
{# javascript used for extend.html.twig #}
{% endblock footer_javascript %}
Is there any way to extend base footer_javascript in my custom extension template?

To use parent(), you have to extend the template.
Your custom_extension.html.twig has to extend base.html.twig like extended.html.twig.
EDIT:
If you're using 2 templates with <body>, you don't have to use {{ parent() }}, but instead put your js in a twig that you will include in your block.

Related

Adding page specific js using timber twig

I have a twig file that extends base
{% extends "base.twig" %}
{% block content %}
<div> all articles </div>
{% for blog in blog_articles %}
<div><i> {{blog.post_title }}</i></div>
{% endfor %}
{% endblock %}
base.twig has an include for my global js and in my article.twig above i want to be able to add template specific JS that will appear below the global js that is in an include in base.twig
Can this be done?
To answer my own question i did this
in the base.twig
{% include 'globaljs.twig' %}
{% block javascript %}{% endblock %}
Then in the article.twig where i call the javascript block i just add my page scripts. simple

Include Twig template which Extends

I am rendering a Twig template as below:
$this->render('base.html.twig');
The content (simplified) of this Twig template looks as below:
{% block headers %}
...
{% endblock %}
{% block pagecontent %}
...
{# I want to include another template (A) here #}
{# I want to include another template (B) here #}
{% endblock %}
{% block footers %}
...
{% endblock %}
I have another Twig template which I am not rendering, but I want to include in the above template (where I have placed my Twig comment). The content is as follows:
{% extends '::base' %}
{% block headers %}
{{ parent() }}
{% endblock %}
{% block pagecontent %}
{{ parent() }}
...
{% endblock %}
I want to eventually render several Twig templates inside of base.html.twig.
Is what I am attempting to do achievable, and if so, how do I achieve it?
You just need to render child template (the one extending base.html.twig).
Change in your controller:
$this->render('child_template_extending_base.html.twig');
Replace child_template_extending_base with your real template name.
You can also embed another controllers views in your template with this code:
{{ render(controller(
'AppBundle:Article:recentArticles',
{ 'max': 3 }
)) }}
Read more about this feature here: http://symfony.com/doc/current/book/templating.html#embedding-controllers
base.html.twig
{% block headers %}
...
{% endblock %}
{% block pagecontent %}
...
{# I want to include another template (A) here #}
{# I want to include another template (B) here #}
{% endblock %}
{% block footers %}
...
{% endblock %}
Your controller:
$this->render('base.html.twig');
Normally, $this->render('view.html.twig'); accepts only one twig.
If you want to have several templates, you can build it like this:
view.html.twig
{% extends '::base' %}
{% block pagecontent %}
{# Controller function with template 1 #}
{{ render(controller('AppBundle:Article:recentArticles',{ 'max': 3 })) }}
{# Controller with template 2 #}
{{ render(controller('AppBundle:Article:relatedArticles',{ 'max': 4 })) }}
{% endblock %}
ANOTHER POSSIBLE SOLUTION IS :
You can break one block into several blocks.

Twig simple overriding with include

I have a simple Twig template, were I wan to override a block from the include.
base.html.twig:
{% block razem %}
{% include '_ga.code.html.twig' %}
{% endblock %}
_ga.code.html.twig:
{% block wspolny %}
should be common
{% endblock %}
{% block googleAnalitics %}
for overridden
{% endblock %}
success.html.twig
{% extends 'base.hmtl.twig' %}
{% block razem %}
{{ parent('wspolny') }}
{% block googleAnalitics %}
overriding part
{% endblock %}
{% endblock %}
Where is the error? http://twigfiddle.com/jsuk6a
I expected to render something like this:
should be common
overriding part
In twig you can not override blocks in a include. For this you have to use embed, but have to do this in the using template, not in the base one.
base.html.twig:
{% block razem %}{% endblock %}
_ga.code.html.twig:
{% block wspolny %}
should be common
{% endblock %}
{% block googleAnalitics %}
for overridden
{% endblock %}
success.html.twig
{% extends 'base.hmtl.twig' %}
{% block razem %}
{% embed '_ga.code.html.twig' %}
{% block googleAnalitics %}
overriding part
{% endblock %}
{% endembed %}
{% endblock %}
I think that the best way to override a block and reuse some others is to extend the base template where you want to perform an overriding (maybe adding some code to the pre-existing one) and to apply the so called horizontal reuse:
Horizontal reuse is an advanced Twig feature that is hardly ever needed in regular templates. It is mainly used by projects that need to make template blocks reusable without using inheritance.
Starting from that point, you should simply use the base.html.twig template and extend _ga.code.html.twig as follows:
success.html.twig
{% extends '_ga.code.hmtl.twig' %}
{# Simply use base - without overriding #}
{% use 'base.hmtl.twig' %}
{% block googleAnalitics %}
overriding part
{% endblock %}
If you want to make an overload of a single block you could also use the parent() function; so, you can add some other information to an extended block.
If you need something more complex you should go for dynamic inheritance.
{% extends ['base.html.twig', '_ga.code.html.twig'] %}

Twig use function multiple parameter

I am looking for using function "{% use %}" with multiple parameter in twig template.
all page template
{% use "common.html.twig" with
container as containerParent,
title as titleParent
%}
{# Some code ... #}
common.html.twig
{% block title %}{{ block(titleParent) }} - Admin{% endblock %}
{% block container %}
{# Some code ... #}
{{ block(containerParent) }}
{# Some code ... #}
{% endblock %}
When I tried that, my block container and title are not modified.
Maybe I didn't understood the doc ? http://twig.sensiolabs.org/doc/tags/use.html
I just want have access to function twig {{ parent() }} in my twig file which is included by {% use ... %}
Any suggestion ?
Sorry for my English, I am learning it...

How to get source of twig block in twig template?

I have following twig block in template which extends main layout:
{% block abc %}
{{ name }}
{% endblock %}
next I have a head block in the same template. I want to pass block abc as template for twig.js:
{% block head %}
<script type="text/html" id="template-abc">
{{ blocksource('abc') }}
</script>
{% endblock %}
so the rendering result is:
{{name}}
How can I do this?
I tried building "blocksource" function in twig extension, but I don't know how to access block source form here.
function blocksource( Twig_Environment $env, $blockname) {
$source = ???;
return $source;
}
Use verbatim tag, it will do what you want.
{% verbatim %}
{{ things_you_want_to_show_as_twig_template }}
{% endverbatim %}
Everything inside this tag will not be interpreted by twig engine.
You can read more on that in twig documentation.

Resources