Twig javascript in included child - symfony

I have a question regarding adding javascript to child elements. How do you do that?
I have this setup:
base.html.twig:
{% block content %}
{% endblock content %}
{% block script %}
{% endblock script %}
index.html.twig:
{% extends base.html.twig %}
{% include intro.html.twig %}
{% block content %}
<html></html>
{% endblock content %}
{% block script %}
<script></script>
{% endblock script %}
intro.html.twig:
{% block script %}
<script></script>
{% endblock script %}
I want to add more javascript files into the intro.html.twig file, but it doesn't append it to the script block in index.html.twig.
All help appreciated!
UPDATE
I want to send some parameters with intro.html.twig:
{% extends 'intro.html.twig' with {
'title': 'title',
'type': 'test',
} %}
is this possible using extends, or can I only use with with include?

index.html.twig
{% extends intro.html.twig %}
{% block content %}
<html></html>
{% endblock content %}
{% block script %}
{{ parent() }}
<script></script>
{% endblock script %}
intro.html.twig
{% extends base.html.twig %}
{% block script %}
<script></script>
{% endblock script %}

Related

Influence the twig included file on parent

I have a problem like this
But i can not use {% use %}
for example:
{# file1.twig #}
{% extends "main.twig" %}
{% block content %}content text{% endblock %}
{# main.twig #}
{% block content %}{% endblock %}
{% for widget in widgets %}
{% embed widget %}{% endembed %}
{% endfor %}
{% block js %}{% endblock %}
{# widget1.twig #}
{% block js %}
script1
{% endblock %}
{# widget2.twig #}
{% block js %}
script1
{% endblock %}
I want to be the result:
content text
script1
script2
I have a lot of files like file1.twig and widget1.twig
I can not use all the widgets in the all files.
Also, {{ parent() }} does not work for me
Is there another way?

Template does not always see its variables

I will first present to you the incriminated templates.
To begin with, I have my layout template with the JQuery. To avoid multiple "$(document).ready()" I placed a block after the general JavaScript.
{# layout.html.twig #}
<script type="text/javascript">
$(document).ready(function(){
//Some JS
{% block jquery %}
{% endblock %}
});
</script>
{# Some HTML & JS #}
<body>
<!-- Some HTML -->
<div>
{% block content %}
{% endblock %}
</div>
<!-- Some more HTML -->
</body>
It is extended by the template layout_cart.html.twig.
{# layout_cart.html.twig #}
{% extends 'AppBundle::layout.html.twig' %}
{% block content %}
<h1>{% block titre %}{% endblock %}</h1>
<div id="content-container">
{% block subcontent %}
{% endblock %}
</div>
{% endblock %}
Which is extended itself by panier.html.twig
{# panier.html.twig #}
{% extends AppBundle:layout_cart.html.twig #}
{# Some code #}
{% block jquery %}
// Some JavaScript
{% for produit in produits %}
// Generating some JavaScript
{% endfor %}
{{ dump(produits) }}
{% endblock %}
{% block subcontent %}
{% if produits is defined and produits|length > 0 %}
{{ dump(produits) }}
{# Interacting with the variables #}
{% endif %}
{% endblock %}
The dump in the jquery renders this :
<pre class='xdebug-var-dump' dir='ltr'>
<b>array</b> <i>(size=0)</i>
<i><font color='#888a85'>empty</font></i>
</pre>
While in the subcontent it renders my objects collection.
Am I missing something ?

Twig combine multiple blocks using USE

I have a problem and I'm trying to see if anyone has a solution for it.
I have a twig template that extends base:
{% extends "base.html" %}
{% use "element1.html" %}
{% use "element2.html" %}
{% block css %}
{{ parent() }}
{% endblock %}
{% block body %}{% endblock %}
{% block javascript %}
{{ parent() }}
{% endblock %}
element1.html and element2.html are almost the same
{# element1.html #}
{% block css %}
some css...
{% endblock %}
{% block body %}
some body html
{% endblock %}
{% block javascript %}
some javascript...
{% endblock %}
When the code runs, element2 overwrites element1, Is there a way to combine blocks, just like parent() combines base blocked with the main template?
Please name the blocks of element1 and element2 appropriately so that it does not override the other.
{% use "element1.html" with css as element1_css, body as element1_body, javascript as element1_js %}
{% use "element2.html" with css as element2_css, body as element2_body, javascript as element2_js %}
And now use appropriate blocks from element1 or element2 such as
{% block element1_css %}{% endblock element1_css %}

How to pass a block to an included template?

The structure of my Twig files looks like this:
- "skeleton_main"
- includes "skeleteon_header"
- render "block content"
- "skeleteon_header" should render "block breadcrumb"
- "partial"
- extends "skeleton_main"
- fills "block breadcrumb"
Now I can output "block breadcrumb" in "sekeleton_main" but it isn't passed to "skeleton_header". How can I access and render the block from within the included template? I tried using {% include '' with {} %} but without luck.
# skeleton_main
{% include 'header' %}
{% block content %}{% endblock %}
# header
{% block breadcrumb %}{% endblock %}
# partial
{% extends 'skeleton_main' %}
{% block breadcrumb %} Breadcrumb {% endblock %}
{% block content %} Content {% endblock %}
Maybe there's something wrong with this approach?
You are using include which does not permit overriding blocks.
Is there a reason to use include instead of extend ?
Another solution would be to use embed which does the same function as include, but permits overriding blocks at the same time:
http://twig.sensiolabs.org/doc/tags/embed.html
I think you have a wrong approch.
You should define header as a block, not as a separate template.
{# skeleton_main #}
{% block header %}
{% block breadcrumb %}{% endblock %}
{% endblock %}
{% block content %}{% endblock %}
{# partial #}
{% extends 'skeleton_main' %}
{% block breadcrumb %} Breadcrumb {% endblock %}
{% block content %} Content {% endblock %}

Override block within included template in Twig

Currently using Symfony2 and Twig, I'm trying to override block within an included template. Let me explain :
{# base.html.twig #}
{% block content %}{% endblock content %}
<!--Some html Code -->
{% block javascripts %}
<!--Some scripts included like jQuery-->
{% endblock javascripts %}
In a other file:
{# page.html.twig #}
{% extends 'base.html.twig' %}
{% block content %}
{% include 'form.html.twig' %}
{% endblock content %}
And finally:
{# form.html.twig #}
<form method="post" action="something">
</form>
{# I am trying somehow to override the "javascripts" block here,
unfortunately I didn't figured out how to to that
#}
{% block javascripts %}
{{ parent() }}
<!--Some JS here-->
{% endblock javascripts %}
Is there a way to do what I want ?
What you need here is multiple inheritance. But just like php, twig does not have multiple inheritance. And just like php has traits, twig has a palliative for this called use. Remember that twig is compiled to php. I think a block that is used in a use statement ends up compiled in a trait.
First, create your a "trait" with the blocks you want to reuse in different places:
{% block my_form %}
<form method="post" action="something">
</form>
{% endblock %}
{% block form_specific_javascript %}
<!--Some JS here-->
{% endblock}
Then, in your page template, call the "trait", and reuse the blocks:
{# page.html.twig #}
{% extends 'base.html.twig' %}
{% block content %}
{% use 'form.html.twig' %}
{{ block('my_form') }}
{% endblock content %}
{# override the javascript block #}
{% block javascripts %}
{{parent()}}
{{block('form_specific_javascript')}}
{% endblock %}
So as you see, you can't do it all from the form template, you have to do some
wiring in your page template. Still, calling a block is better than copy / pasting
its contents, isn't it ?
Since i was looking for the same answer and actually found the solution.
It lies within TWIG with the embed tag.
Available in twig version 1.8, embed tag allows us to "include" a template, which has its own defined blocks who can then be overriden.
More information here: http://twig.sensiolabs.org/doc/tags/embed.html
You could just simply include form.html.twig within the javascripts block
base.html.twig
{% block content %}
<!--Some html Code -->
{% endblock content %}
{% block javascripts %}
<!--Some scripts included like jQuery-->
{% endblock javascripts %}
page.html.twig
{% extends 'base.html.twig' %}
{% block javascripts %}
{{ parent() }}
{% include 'form.html.twig' %}
{% endblock javascripts %}
form.html.twig
<!--Some JS here-->
I have exactly the same problem. I was looking for solution, but I didn't find any. Unfortunately include, embed and use does not solve this problem. But I figured two possible workarounds.
Option 1 (simpler, but needs more code)
Separate form into two files _form.html.twig and _form_js.html.twig and import them in the appropriate blocks.
Option 2
Invert hierarchy of templates. Extend form directly from base.
# form.html.twig
{% extends 'layouts/base.html.twig' %}
{% block body %}
{{ block('page_header') }}
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script>
# ...
</script>
{% endblock %}
And then extend form in other templates like new and edit.
# new.twig.html
{% extends 'form.html.twig' %}
{% block page_header %}
# custom content here
{% endblock %}
Using your own files, this is the approach I used and it worked for me:
{# base.html.twig #}
{% block content %}
{% endblock %}
<!--Some html Code -->
{% block javascripts %}
<script>console.log('1st print')</script>
{% endblock %}
In other file:
{# page.html.twig #}
{% extends 'base.html.twig' %}
{% block content %}
<h1>Welcome to page.html.twig.</h1>
<p>Here is a form for you to complete:</p>
{{ block("content", "form.html.twig") }}
{% endblock %}
{% block javascripts %}
{{ parent() }}
<script>console.log('2nd print')</script>
{{ block("formjavascripts", "form.html.twig") }}
{% endblock %}
And finally:
{# form.html.twig #}
{% block content %}
<form method="post" action="something">
</form>
{% endblock %}
{% block formjavascripts %}
<script>console.log('3rd print')</script>
{% endblock %}
Please notice the use of block function, you can find more info here https://twig.symfony.com/doc/3.x/functions/block.html
Also notice I used "formjavascripts" you could have used "javascripts" as well because that is the block name being retrieved from forms.html.twig file.
Note: You could try using Block function again in forms.html.twig and see if you can do a 4th print and call a 4th twig file! (Not sure if this last thing will work though :P)

Resources