Is there any option to extend the tornado web template with the option inside the html template
{% code %}
# Python code
{% end %}
No, there is no such option. Tornado's templates are fairly liberal in allowing python code directly in the template, especially with the {% set %} directive (which can include any single-line statement, not just a variable assignment), but it is not possible to use multi-line statements except for the ones that have corresponding template directives ({% for %}, {% if %}, {% try %}, and {% while %})
Related
I am learning to use flask-bootstrap extension in my app. But when I copied demo html codes from getbootstrap, it didn't work as the official site demonstrated. So I overwrote the head block and scripts block in my base template, then it works nicely.
Like this
{% extends 'bootstrap/base.html' %}
{% block head %}
(my own head...)
{% endblock %}
{% block scripts %}
(my own scripts...)
{% endblock %}
Is it okay to overwrite bootstrap/base.html’s own head and scripts like this? What effects it will leave?
it will completely replace the base blocks.
To keep the existing blocks but add your own to them, you should use super():
{% block head %}
{{ super () }}
(your head)
{% endblock %}
This will keep the originals... you can do the same in any other blocks.
See more here: http://jinja.pocoo.org/docs/2.10/templates/#super-blocks
I'm altering an existing web interface to view ROBOT doc libraries, which uses a mixture of jinja (Python inside HTML) and HTML. I have never worked with jinja or HTML before and am having issues getting even a simple test case to work. When the browser loads the docs, I want our project's directory structure for the docs to be preserved to make finding things easier, and so I want to use jinja to create the dir structure. Here is a snippet of the code I'm working with:
{% extends "base.html" %}
{% block body %}
<div class="well" id="left">
<ul class="list-group list-unstyled">
{% set collection_list = [] %}
{% for collection in data.hierarchy %}
{% if collection.collection_id|string == data.collection_id|string %}
{% do collection_list.append(collection.path) %}
{% else %}
{% for link in collection.path_chain %}
<li>
<label class="tree-toggler nav-header"
title="file path: {{collection.path}}">{{link}}</label>
<ul class="list-group tree collapse"
id={{link}}>
</ul>
{% endfor %}
</li>
{% endif %}
...there's more after that, but this is where I hit the error. It sets the collection_list var fine, and the if statements work, but when it goes to execute the 'do' statement it fails with:
TemplateSyntaxError: Encountered unknown tag 'do'. Jinja was looking for the following tags: 'elif' or 'else' or 'endif'. The innermost block that needs to be closed is 'if'.
I don't believe this is an unclosed loop or something because if I replace the do statement with a simple test print statement, it works. Does anyone know what I'm doing wrong?
From the template documentation:
Expression Statement
If the expression-statement extension is loaded, a tag called do is available that works exactly like the regular variable expression ({{ ... }}); except it doesn’t print anything. This can be used to modify lists:
{% do navigation.append('a string') %}
You need to enable the Expression statement extension for this to work.
You didn't show how you load the Jinja2 environment, but loading extensions takes place via the extensions argument to the Environment() class:
jinja_env = Environment(extensions=['jinja2.ext.do'])
I have a very basic template (basic_template.html), and want to fill in the with data formatted using another partial template. The basic_template.html might contain several things formatted using the partial template.
How should I structure the code in views.py?
The reason I am doing this is that later on the will be filled using Ajax. Am I doing this right?
You can do:
<div class="basic">
{% include "main/includes/subtemplate.html" %}
</div>
where subtemplate.html is another Django template. In this subtemplate.html you can put the HTML that would be obtained with Ajax.
You can also include the template multiple times:
<div class="basic">
{% for item in items %}
{% include "main/includes/subtemplate.html" %}
{% endfor %}
</div>
You can do this using a block. Blocks are a Django Template tag which will override sections of a template you extend. I've included an example below.
basic_template.html
<body>
{% block 'body' %}
{% endblock %}
</body>
template you want to include: (i.e. example.html)
{% extends 'basic_template.html' %}
{% block 'body' %}
/* HTML goes here */
{% endblock %}
views.py:
return render_to_response(template='example.html', context, context_instance)
Doing this will load basic_template.html, but replace everything inside of {% block 'body' %} {% endblock %} in basic_template.html with whatever is contained within {% block 'body' %} {% endblock %}.
You can read more about blocks and template inheritance in the Django Docs
There are mainly 2 ways (2 easy ones)
1:
In base html put
{% include "myapp/sub.html" %}
And just write html code inside your sub.html file
2:
https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance
I just wanted to add differences of extend and include.
Both template and include can use models inserted in current app.
Template is for global usage by your any app. Include is for use in certain apps.
For ex: you want to insert Image Slider to your homepage and about page but nowhere else. You can create Slider app with its own model for convenience and import its model and include in that pages.
If you used template for this example, you would create 2 templates one with slider and everything else other template have.
I am trying to use the templatetag described in SO answer: https://stackoverflow.com/a/6217194/493211 in a project using Django 1.4.3 (with Python 2.7.2).
I adapted it like this:
from django import template
register = template.Library()
#register.filter
def template_exists(template_name):
try:
template.loader.get_template(template_name)
return True
except template.TemplateDoesNotExist:
return False
So that I could use it like this in another template:
{% if 'profile/header.html'|template_exists %}
{% include 'profile/header.html' %}
{% else %}
{% include 'common/header.html' %}
{% endif %}
This way, I could have avoided using solutions such as changing the order of my apps in INSTALLED_APPS.
However, it does not work. If the template does not exist, then the exception is raised within the stack/console but it is not propagated up to get_template(..) (from inside this statement), and thus not to my foolish API. Hence, this blows up in my face during the rendering. I uploaded the stacktrace to pastebin
Is this a wanted behavior from Django?
I ended up stop doing foolish things as is. But my question would remain.
What about a custom tag? This doesn't provide the full functionality of include but seems to meet the needs in the question.:
#register.simple_tag(takes_context=True)
def include_fallback(context, *template_choices):
t = django.template.loader.select_template(template_choices)
return t.render(context)
Then in your template:
{% include_fallback "profile/header.html" "common/header.html" %}
I found some kind of an answer to my question so I am posting it here for future refence.
If I use my template_exists filter like this
{% if 'profile/header.html'|template_exists %}
{% include 'profile/header.html' %}
{% else %}
{% include 'common/header.html' %}
{% endif %}
and if profile/header.html does not exist, then the TemplateDoesNotExist gets strangely propagated at page load and I get a server error. However, if instead, I use this in my template:
{% with 'profile/header.html' as var_templ %}
{% if var_templ|template_exists %}
{% include var_templ %}
{% else %}
{% include 'common/header.html' %}
{% endif %}
{% endwith %}
Then, it works like a charm!
Obviously, I could have used
django.template.loader.select_template(['profile/header.html','common/header.html'])
in the view (from this SO answer). But I am using a CBV which I wanted to keep rather generic and this was called from the main template. And also I thought it would be nice to have my site working if this apps goes down for whatever reason. If this seems silly to you, please leave a comment (or yet a better answer).
I am using jinja2 with my django application, I am working on porting some existing django templates over to jinja2. For the most part I am not having any issues; however, I have a statement like so in one of my django templates:
{% blocktrans %}
<p>Some stuff here</p>
{% endblocktrans %}
This causes jinja2 to become very unhappy. I have looked far and wide to see if there is an equivalent of the "blocktrans" tag for jinja2. All I can find is that enabling gettext let's you use:
{{ trans("Some String") }}
This is useful for short strings like in the title tag, but not for blocks. What am I missing, any help would be appreciated!
Use {% trans %} and its complement {% endtrans %} once the i18n extension is enabled.