symfony2: including inline javascript - symfony

I've added some javascript code below to show some photos using a slide show jquery plugin.
//parent template
{% block javascripts %}
<script src="{{ asset('http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js') }}" type="text/javascript"></script>
<script src="{{ asset('bundles/canalonesfrontend/js/slides.min.jquery.js') }}" type="text/javascript"></script>
{% endblock %}
//child template
{% block javascripts %}
{{ parent() }}
$(function(){
$("#slides").slides();
});
{% endblock %}
The problem: the code is shown in the web page directly:
Some content
$(function(){ $("#slides").slides(); });

you have to wrap with <script></script> tag around your code
//child template
{% block javascripts %}
{{ parent() }}
<script type="text/javascript">
$(function(){
$("#slides").slides();
});
</script>
{% endblock %}
I hope you understood the problem!

Related

using a dynamic class for the body tag

in my base.html.twig my body looks like this:
<body>
{% block header %}{% endblock %}
{% block body %}
{% endblock %}
{% block footer %}{% endblock %}
{% block javascripts %}
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
<script src="{{ asset('/js/bootstrap.min.js') }}"></script>
<script src="{{ asset('/js/remodal.min.js') }}"></script>
<script src="{{ asset('/js/script.js') }}"></script>
{% endblock %}
</body>
Since my files homepage.html.twig and subpage.html.twig extend the file base.html.twig, I would like to pass a class to the body tag.
E.g. in my file homepage.html.twig I want it to be <body class="home"> and in my subpage.html.twig file I want it to be <body class="subpage">.
Is it possible to simply pass a variable or something like that or would it be necessary to use a block for that?
I found out that the easiest way is to simply define a block like this:
<body class="{% block body_class %}sub_page{% endblock %}">
Then only in homepage.html.twig using:
{% block body_class %}homepage{% endblock %}

Variable " asset_url" does not exist

Not sure what's wrong but I can't include javascript and/or stylesheet files. Using Symfony3
{% block javascripts %}
{% javascripts
'#AppBundle/assets/js/jquery.js'
'#AppBundle/assets/bootstrap/js/bootstrap.min.js'
%}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
getting this error:
Variable " asset_url" does not exist in security/login.html.twig at line 32
Overall, the code should probably look like this:
{% block javascripts %}
{% javascripts
'#AppBundle/assets/js/jquery.js'
'#AppBundle/assets/bootstrap/js/bootstrap.min.js'
output='js/compiled/app.js' %}
<script type="text/javascript" src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
If it doesn't work then make sure that path to these files is correct.

Use array variable to load javascripts at bottom of the page

I would like to use a kind of global array to define what javascripts should be loaded at the end of the page. This way, I can dynamically add javascript files.
The problem is that the base template is being rendered first. Imagine this base html:
{% set javascriptList = [ 'js/vendor/jquery-1.10.1.min.js', 'js/vendor/bootstrap.min.js', 'js/main.js' ] %}
<!DOCTYPE html>
<head>
<title>my project</title>
</head>
<body>
{% block container %}
content goes here
{% endblock %}
{% block javascripts %}
{% for js in javascriptList %}
<script src="{{ asset(js) }}"></script>
{% endfor %}
{% endblock %}
</body>
</html>
Then I would have a page, something like this:
{% extends base.html.twig %}
{% block container %}
<h1>Demo</h1>
Bla bla
Code I want to reuse:
{% include 'code-with-js.html.twig' %}
{% endblock %}
Then my code-with-js.html.twig would be:
<div id="DemoContent">
Some content, with a tooltip thingy maybe.
</div>
{% set javascriptList = javascriptList|merge(['js/tooltip.js']) %}
So, using this setup, I can make sure that the correct javascript is being added, when the piece of html is being included.
But, this doesn't work of course. The base html is rendered first, so the element will be added to the javascriptList array after it has been rendered. My approach must be wrong.
In my project this reusable code is actually a form with some extra buttons that insert content to the textarea's (so a tinyMCE, but much much much more simplistic). I would like to reuse this code on several pages (create, update).
Any thoughts are welcome!
First of all I recommend you to add a javascript block in your base.html.twig :
You can add a block in your base.html.twig after your script load :
{% block javascripts %}
{% for js in javascriptList %}
<script src="{{ asset(js) }}"></script>
{% endfor %}
{% endblock %}
<script type="text/javascript">
{% block afterJavascriptLoad %}
{% endblock %}
</script>
With inheritance you'll be able to execute javascript after all script load in nested template :
{% extends base.html.twig %}
{% block afterJavascriptLoad %}
//Your code to be executed after base.html script load
{% endblock %}
Having html code and javascript code is not a very good practice. For exemple if you have 3 tinyMCE redactor in your page, you'll load 3 times tinyMCE.
For me the best way is to have your template like this :
base.html.twig:
{% block container %}
content goes here
{% endblock %}
{% block javascripts %}
{% for js in javascriptList %}
<script src="{{ asset(js) }}"></script>
{% endfor %}
{% endblock %}
{% block afterJavascriptLoad %}
//Your code to be executed after base.html script load
{% endblock %}
pageWithTinyMCE.html.twig :
{% extends base.html.twig %}
{% block container %}
<h1>Demo</h1>
Bla bla
Code I want to reuse:
{% include 'code-without-js.html.twig' %}
{% set javascriptList = javascriptList|merge(['js/tooltip.js']) %}
{% endblock %}
{% block afterJavascriptLoad %}
//Custom javascript for the page
{% endblock %}

Adding JS and CSS cleanly from included Twig templates

I'm looking to find out if there's a clean way to add JS and CSS from included templates.
So, for example, if layout.html.twig has:
{% include 'GenericBundle:Generic:page.html.twig' with {'data': data} %}
...
{% block javascript %}
{% javascripts
'#GenericBundle/Resources/public/js/app/jquery/jquery.min.js'
'#GenericBundle/Resources/public/js/lib/bootstrap/bootstrap.min.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{% endblock %}
And in the generic bundle page I'd like to include some more Javascript but add it to the established Javascript block to keep to HTML and JS best practices.
Is there a clean way to do this? I'm using Symfony2, and could probably cludge together a solution using Singletons and such, but I'd rather a cleaner method if there's one available.
I know I'm a little late to the party, but with Twig 1.2, you can utilize the use tag and the block function:
GenericBundle:Generic:page.html.twig
{% block javascripts %}
<script src="..."></script>
{% endblock %}
{% block included_content %}
Bar
{% endblock %}
layout.html.twig
{% use 'GenericBundle:Generic:page.html.twig' with javascripts as page_javascripts %}
{% block javascript %}
{% javascripts
'#GenericBundle/Resources/public/js/app/jquery/jquery.min.js'
'#GenericBundle/Resources/public/js/lib/bootstrap/bootstrap.min.js'
%}
<script src="{{ asset_url }}"></script>
{% endjavascripts %}
{{ block('page_javascript') }} // Don't forget the 'braces'
{% endblock %}
...
{{ block('included_content') }} // Don't forget the 'braces'

Directory Path in Twig

In my twig file i have a JS method that needs a path to flash files located in web/bundles/bm/swf/.. I don't need to load a specific file just point the method to that path.
{% block javascripts %}
{{parent()}}
<script type="text/javascript" src="{{ asset('bundles/bm/js/soundmanager2.js') }}"></script>
<script>
soundManager.url = ''; < needs the path to web/bundles/bm/swf/
soundManager.onload = function() { }
</script>
{% endblock %}
Any idea?
{% block javascripts %}
{{parent()}}
<script type="text/javascript" src="{{ asset('bundles/bm/js/soundmanager2.js') }}"></script>
<script type="text/javascript">
soundManager.url = '{{ asset('bundles/bm/swf/')}}';
soundManager.onload = function() { }
</script>
{% endblock %}

Resources