I need to output a portion of client-side handlebars templates, which has tags similar to twig's 'say' tags:
<script type="text/x-handlebars">
{{#view App.MyView}}
<h1>Hello world!</h1>
{{/view}}
</script>
And twig attempts to parse these templates. How do I prevent it? Is it possible to mark a section of a template as plain text?
There is raw tag for this purpose:
<script type="text/x-handlebars">
{% raw %}
{{#view App.MyView}}
<h1>Hello world!</h1>
{{/view}}
{% endraw %}
</script>
Update
As raw tag is deprecated use verbatim instead.
{% raw %} deprecated
{% verbatim %}
<ul>
{% for item in seq %}
<li>{{ item }}</li>
{% endfor %}
</ul>
{% endverbatim %}
Source: http://twig.sensiolabs.org/doc/tags/verbatim.html
For bigger blocks of templates I would suggest to move those script templates into a separate file/files (where I suppose they should be to make all more structured).
Then render templates in your twig by using source command {{ source('uploadables-js.html') }} (IMPORTANT, no 'use' or 'include').
To not litter templates with raw or verbatim tags, one can change lexar options to not conflict with client side template engines:
...
$lexer_options = [
'tag_variable' => ['{~', '~}'],
];
$lexer = new Twig_Lexer($twig, $lexer_options);
$twig->setLexer($lexer);
Related
In my base template, I have a list of object that I loop through to populate my navbar link to others templates. When I extend my base template with another template I have an error saying that this variable does not exist.
base.html.twig
<head>
....
</head>
<body>
{% block navbar %}
{% for e in event %}
<li>
{{ e.getName() }}
</li>
{% endfor %}
{% endblock %}
</body>
What's the best way to use the event object in every controller/template ?
I am using Ajax in my Django project to implement some simple searching. In my template folder, I have created an html file called "ajax_search.html" where I write how I want my objects to be displayed on a page. Right now it looks like this:
{% if puzzles.count > 0 %}
{% for puzzle in puzzles %}
<a href="{% url 'puzzle' puzzleID=puzzle.id %}">
{{puzzle.title}}
</a>
<br>
{% endfor %}
{% elif search_len < 3 %}
{% else %}
No puzzles match the search
{% endif %}
This works fine, but I wanted to style it to look better. Is there any way I could import some CSS into this template?
Thank you!
Is it possible to override a template block from a twig extension? How do I do it?
Edit:
I have a block in my master layout template, it is called {% block emailMenu %}, the question is, is it possible to override this block, not from another template but from inside a twig custom function?
I guess I'm confused as the best way to handle my situation, my email menu will change from page to page depending on several factors, and I thought of making a twig function to be called from the layout or from another template, the reason I am thinking along these lines is to keep my other templates free from a lot of logic, logic that I'd rather have with pure PHP. Any thoughts would be appreciated.
You can just render additional controller (not a twig extension) which renders own template (possibly dependent on the page), which overrides base template block.
I think, overriding block from twig extensions - it is not the twig purposed for.
You must create a base template:
{# src/BW/MainBundle/Resources/views/Main/base.html.twig #}
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}Test Application{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li>Home</li>
<li>Blog</li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block body %}{% endblock %}
</div>
</body>
</html>
And then extends parent template with extends keyword:
{# src/Acme/BlogBundle/Resources/views/Blog/index.html.twig #}
{% extends 'BWMainBundle:Main:base.html.twig' %}
{% block title %}My cool blog posts{% endblock %}
{% block body %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
Also read this docs about templating in Symfony using Twig.
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.
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.
});