Template does not always see its variables - symfony

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 ?

Related

How to exclude a twig partial from a base extend in Symfony on some pages only?

Is there a way to specify an "extend" in Twig to exclude one of its included partials ?
To better explain myself, here is my base.html.twig
<body>
{% include '/main/_navbar.html.twig' %}
{% block body %}
{% for flashError in app.flashes('success') %}
<div class="alert alert-success" role="alert">{{ message }}</div>
{% endfor %}
{% endblock %}
{% include '/main/_footer.html.twig' %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="{{ asset('script/app.js') }}"></script>
</body>
On my login page, I do not need my _navbar.html.twig partial. Is there a way to not include (exclude) it knowing my view extends from this base template ? Are there any "options" I could pass behind that extends ?
This is the code I use to extend my base template on my login page :
{% extends 'base.html.twig' %}
Just wrap the include you don't want to include in a seperate block, then override the block with empty content, e.g.
base.html.twig
<body>
{% block nav %}
{% include '/main/_navbar.html.twig' %}
{% endblock %}
{% block body %}
{% for flashError in app.flashes('success') %}
<div class="alert alert-success" role="alert">{{ message }}</div>
{% endfor %}
{% endblock %}
{% include '/main/_footer.html.twig' %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="{{ asset('script/app.js') }}"></script>
</body>
login.html.twig
{% extends "base.html.twig" %}
{% block nav %}{% endblock %}
demo

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?

Twig javascript in included child

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

Using TWIG variables from children template

Need to use a variable that is in the parent template.
I have layout:
<html>
<head>
</head>
<body>
{%block content %}
{% set com = 0 %}
DEFALUT CONTENT
{% endblock %}
</body>
</html>
And children template:
{% extends '::layout.html.twig' %}
{% block content %}
HOW USE LAYOUT VARIABLE HERE? LIKE: {{ com }}
{% endblock %}
Thanks in advance!
Use the parent() twig function.
{% extends '::layout.html.twig' %}
{% block content %}
{{ parent() }}
{{ com }}
{% endblock %}
The above code will render a template like :
<html>
<head>
</head>
<body>
{% block content %}
{% set com = 0 %}
DEFAULT CONTENT
{{ com }}
{% endblock %}
</body>
</html>

Is a Twig block empty? - Symfony 2

I have a twig template with the following block:
{% block dashboard %}
{% include "::user_dashboard.html.twig" %}
{% endblock dashboard %}
Later in that template, I want to set a class on a div based on whether or not there is anything in that block (i.e., by default, it will have the include above, but children of this template may override it and empty it out).
What I had (that somewhat worked) was ...
{% set _dashboard = block('dashboard') %}
{% set _mainWidth = ( _dashboard|trim is empty ? "no-dashboard" : "with-dashboard" ) #}
<div id="main" class="{{ _mainWidth }}">
The problem here is that whole dashboard block gets called twice. This wouldn't bother me too much except that block renders a few controller actions, i.e. ...
{% render "UserWidget:userAppMenu" %}
... and the code in that action is being called twice. For various reasons, not the least of which is performance, this messes with some of the stuff in that dashboard block.
So, my question is ... is there any way to tell if that block is empty without loading it twice? Is there something really simple I'm missing or is this even possible?
Thanks!
EDIT:
Here is my full template if it helps clarify things:
{% extends '::base.html.twig' %}
{% block layout %}
{% block header %}
{% include "::header.html.twig" %}
{% endblock header %}
<div id="container" class="row-fluid">
{% block dashboard %}
{% include "::user_dashboard.html.twig" %}
{% endblock dashboard %}
{% set _dashboard = block('dashboard') %}
{% set _mainWidth = ( _dashboard|trim is empty ? "no-dashboard" : "with-dashboard" ) %}
<div id="main" class="{{ _mainWidth }}">
<h1 class="page-title">{% block page_title %}{% endblock %}</h1>
{% block main_filters %}{% endblock %}
{% if app.session.flashbag.has('message') %}
<div class="alert alert-block alert-success">
<ul>
{% for flashMessage in app.session.flashbag.get('message') %}
<li>{{ flashMessage }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% if app.session.flashbag.has('warning') %}
<div class="alert alert-block alert-success">
<ul>
{% for flashWarning in app.session.flashbag.get('warning') %}
<li>{{ flashWarning }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% block body %}{% endblock %}
{% block footer %}
{% include "::footer.html.twig" %}
{% endblock footer %}
</div>
</div>
{% endblock layout %}
Here you can see on lines 11 and 15 - both of those actually seem to include and process what is in that include.
What about this? This way the block should only be rendered once, when you call block('dashboard').
{# at top of twig #}
{% set _dashboard = block('dashboard') %}
{# where ever you include your block #}
<div>
{{ _dashboard|raw }}
</div>
{# and your main #}
{% set _mainWidth = ( _dashboard|trim is empty ? "no-dashboard" : "with-dashboard" ) #}
<div id="main" class="{{ _mainWidth }}">

Resources