Symfony2 Assetic + Twig Template JavaScript Inheritance - symfony

My problem:
I have 3 templates:
main.html.twig (main layout file)
layout.html.twig (a bundle specific layout override which contains some bundle specific JS tags)
create.html.twig (a page specific template file which also contains some page specific JS tags)
I am defining a block called 'javascript' in my base layout (main.html.twig), then overriding it (but calling {{ parent() }} in layout.html.twig. This works fine, and the JS tags from the main template file are still included above those in the layout.html.twig template.
I then do the same in the create.html.twig file, overriding the block as follows:
{% block javascripts %}
{{ parent() }}
{% javascripts '#BundleName/Resources/public/js/application.album.uploader.js'
'#BundleName/Resources/public/js/jquery.uploadify.js'
'#BundleName/Resources/public/js/swfuploadify.js' filter='?yui_js' %}
<script src='{{ asset_url }}' type='text/javascript'></script>
{% endjavascripts %}
{% endblock %}
At this point, instead of just overriding the javascript block in the parent (layout.html.twig) and including all the scripts defined in the templates above it, it does the following:
Dumps the <script> tags in the middle of the output (which causes an error, because in my main.html.twig file I am only including the jQuery library at the end of the HTML markup
Then it also dumps the scripts out along with the rest of the others (as I would expect it to)
I am not sure what is causing the scripts to be dumped in the middle of the create.html.twig template, and I'm also confused as to why they're being dumped to the screen twice (once in the middle of the create and then once at the bottom along with all the rest of my scripts from main.html.twig and layout.html.twig.
Has anyone got any ideas? Let me know if anything is unclear or if I can provide some more information.
EDIT:
File contents are below...
main.html.twig: https://gist.github.com/7f29353eaca0947528ce
layout.html.twig: https://gist.github.com/734947e9118b7765715e
create.html.twig: https://gist.github.com/c60c8d5c61e00ff86912
EDIT 2:
I've been having another look at the issue this morning and it looks as though its doing the same thing for stylesheets. I tried to define a new block called pagescripts in my layout.html.twig and then use the block in my create.html.twig but this had the same outcome, it just seems to dump the scripts and stylesheets wherever I use the
{% block pagescripts %}
(scripts here)
{% endblock}

I found the issue. In create.html.twig I was defining my {% block javascripts %} content inside inside my {% block content %}, so I assume Twig was rendering the output of the javascripts block inside the content block.
Moving the {% block javascripts %} content outside of the {% block content %} block fixed the issue.

Here is an example of main.html.twig:
<body>
{% block stylesheets %}
{% endblock %}
{% block jsscript %}
{% endblock %}
{% block content %}
{% endblock %}
</body>
into your create.html.twig
{% extends '::base.html.twig' %}
{% block jsscript %}
my javascript files...
{% endblock %}
{% block content %}
<h1>Create</h1>
<form action="{{ path('entity_create') }}" method="post" {{ form_enctype(form) }}>
{{ form_widget(form) }}
<p>
<button type="submit">Create</button>
</p>
</form>
{% endblock %}
If you still have issue, you can add a document ready function :
$(document).ready(function() {
// put all your jQuery goodness in here.
});

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

Rendering a block in extended -> included template

Problem
In navbar.html.twig I have a block that looks like this:
//navbar.html.twig
{% block back_link %}{% endblock %}
This navbar is included by my base.html.twig.
//base.html.twig
{% include navbar.html.twig %}
And then my page template extends the base.
//page.html.twig
{% extends base.html.twig %}
...
{% block back_link %} Things i want in the navbar. {% endblock %}
But the things I want in the navbar don't show up in the navbar, because it's included by the base, so there's no parent/child relationship there.
Question
What's a good (or any) way to let me override a block in an included template in an extended template?
if you understand your idea right, you want to have some reusable content for a navbar, separated to navbar.html.twig that will possible to use in several templates?
So you can do it with "use" http://twig.sensiolabs.org/doc/tags/use.html
In navbar.html.twig
//navbar.html.twig
{% block back_link %}{% endblock %}
In base.html.twig.
//base.html.twig
{% use '::navbar.html.twig' %}
{{ block('back_link') }}
In page.html.twig
{% extends '::base.html.twig' %}
{% block back_link %} Things i want in the navbar. {% endblock %}

Symfony2 Twig: embedding a template - Where to put JS

On some of my pages I want to embed a toolbar with some generic functionality like sharing, reporting and bookmarking. Currently I do it like this
{# page-detail.html.twig #}
{% extends 'layout.responsive.html.twig' %}
{% block content %}
{% include "toolbar/index.html.twig" with {'foo':'bar'} %}
{# further content... #}
{% endblock %}
As the features of the toolbar require some information about the context it's embedded in, I pass this information in the with-clause. So far so good.
Now, all the buttons are invoking some JavaScript on clicking. Modal windows are popping up, dialogs are displayed, etc. I would like to put the related JS inside the toolbar template but here is the problem:
All my JS-libraries are loaded at the bottom of the page before the closing body-tag. Means, in my toolbar template I have no access to them.
So I thought of the following solutions which I am not really happy with:
move the inclusion of the JS-libraries to the top (loading js slows down page display, also JS would be scattered)
put the respective JS in the javascripts-block in "page-detail.html.twig" (toolbar code is separated from the template code and mixed with the JS-Code needed there)
use the "embed"-Tag and define a JS-Block in the toolbar-Template (won't help as I can access the blocks in the embedding parent template only within the "embed"-Tag)
use the "use"-Tag instead. Well that sounds best so far, however, Code would look like this (assuming toolbar-template defines the blocks "toolbar_content" and "toolbar_js"):
Code:
{# page-detail.html.twig #}
{% extends 'layout.responsive.html.twig' %}
{% use "toolbar/index.html.twig" %}
{% block content %}
{% block toolbar_content %}
{{ parent() }}
{% endblock %}
{# further content... #}
{% endblock %}
{% block javascripts %}
{{ parent() }}
{% block toolbar_js %}
{{ parent() }}
{% endblock %}
... local JS
{% endblock %}
Also in this solution I cannot pass the environment variables anymore using the "with"-clause as it is now used for resolving name-conflicts of the blocks.
I feel like I am missing something. How is it done right? It seems like such a common task.
Additional information
I think not essential for the question but for more clarity, here is how my layout template looks like (not complete just the relevant blocks).
{# layout.responsive.html.twig #}
{% block stylesheets %}
{# bootstrap.css, custom.css, ... #}
{% endblock %}
{% block content %}
{% endblock %}
{% block javascripts %}
{# jquery, bootstrap, ... #}
{% endblock %}
And my toolbar:
{# toolbar/index.html.twig #}
<div class="toolbar btn-toolbar" role="toolbar">
<div class="btn-group" role="group">
<button type="button" class="btn btn-default" data-toggle="modal" data-target="#report">Report</button>
</div>
<!-- more buttons -->
</div>

extends in symfony from multiple children

I have a base.html.twig with the basic html.
In the 'base' I have a {% block body %}{% endblock %} and a {% block javascript %}{% endblock %}
I call a 'form.html.twig' file from the Controller and the template extends the base.html.twig.
The 'form' contains the <form> and </form> tags and can contain a random numbers of sub templates/form elements:
'{% block body %}
{% for template in templates %}
{% embed template %}{% endembed %}
{% endfor %}
{% endblock %}'
The 'template' is perhaps a customer.html.twig, confirm.html.twig, vehicle.html.twig etc. etc. and they all have {% block body %} and {% block javascript %} - now for the question:
The content in the template files aren't moved to the blocks body/javascript. How do I get twig/symfony to move the content in the template files to the respective areas in the 'base.html.twig'?
Thank you for your time.
You want to use the use twig tag instead of the embed tag like this
{% use template %}
See more info here:
http://twig.sensiolabs.org/doc/tags/use.html

Sonata Block - add javascript block

Is it possible to add a javascript block in a Sonata Block View like this ?
{% extends sonata_block.templates.block_base %}
{% block block %}
<!-- html -->
{% endblock %}
{% block javascripts %}
// javascript code
{% endblock %}
I couldn't make it works in this way as javascript block doesn't exist in template block base but present in my layout.

Resources