I have two very simple templates like
index.html:
<html>
<head>
</head>
<body>
{% block content %}hello{% endblock %}
</body>
</html>
and details.html
{% extends "index.html" %}
{% block content %}{{ super() }} world{% endblock %}
but when i render a view with details.html i get this error
Could not parse the remainder: '()' from 'super()'
do i need some import somewere?
(templates are rendered properly until i use the super() function)
Django 1.7 and earlier do not support Jinja natively. Unless you've done something to use Jinja, your templates should be in Django template language, and you can't use Jinja.
Django 1.8 will have support for multiple template engines, and native support for Jinja2.
In Django template language, you can use {{ block.super }} to access the content of the block from the parent template.
Related
I have the following problem, there is a base template "base.html" which defines default header and body information, which will be used by other pages.
The base page contains the rendered parameter, which depends on the request time in a non trivial way.
base.html
<!DOCTYPE html>
<head>
...
{% block head_stuff %} {% endblock %}
...
</head>
<body>
...
<p>Parameter that depends on the request time</p>
...
{% block body_stuff %} {% endblock %}
...
</body>
</html>
The pages that use it look like:
a.html b.html c.html
{% extends "base.html" %}
{% block head_stuff %} ... {% endblock %}
{% block body_stuff %} ... {% endblock %}
What I'd like to do is to render a.html, b.html, c.html without passing informations about that parameter to these pages in their views or templates.
In absence of inheritance, one would call render function by passing the parameter to a context, but in this case no views are used to construct the base.html.
How can I approach this problem?
A context processor is a function that takes request as an argument and returns a dictionary. The contents of this dictionary are then appended to the context of every template. So if you had a context process or
def my_example(request):
return dict(
name="steve",
dynamic_thing=some_other_function()
)
Then the templates could access these using {{ name }} and {{ dynamic_thing }}
I have a conditional in a template used by several views which will include a js file if passed in by the view:
in the template:
{% if js_file %}
{% block inner_js %}
<script defer type="text/javascript" src="{% static js_file %}"></script>
{% endblock inner_js %}
{% endif %}
which is eg used by a view by:
.......
context = {'title': 'Sign up',
'form': form,
'js_file': 'js/supplier.js'}
return render(request, 'pages/signup.html', context)
This produces no errors in development, but when pushed to production I get the error:
ValueError at /users/example/
Missing staticfiles manifest entry for ''
If I remove the template if block above then this error dissapears (and works fine for those views which use the template without a js file).
I would rather not have to create a new version of the template for every view which uses a js file, is their a better way to fix this? (seems a bit of a weird error).
I don't believe you can conditionally include/exclude a block as you're doing. If you put the if tags inside the block, it will only include the <script> tag when the variable js_file is populated.
If you're conditionally including this block to override another block called inner_js in a template higher up, you can do something like this to achieve the same results:
{% block inner_js %}
{% if js_file %}
<script ...></script>
{% else %}
{{ block.super }}
{% endif %}
{% endblock inner_js %}
{{ block.super }} is the equivalent of calling Python's super in a class, and allows for block extensions in templates that extend a base.
I want to pass a model to template base.html.
I read about custom tags, and tried to execute this. It is not throwing any error, but is not working too.
My code:
base.html:
{% load staticfiles %}
{% load tags %}
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<ul class="dropdown-menu" role="menu">
{% for league in get_my_leagues %}
<li> ddddd {{ league.league_name }}</li>
{% endfor %}
</ul>
{% block content %}
{% endblock %}
</body>
</html>
Now, tags.py:
from django.template import Library
from login.models import League
register = Library()
#register.inclusion_tag('base.html')
def get_my_leagues():
return League.objects.all()
register.tag('get_my_leagues', get_my_leagues)
When you use {% for x in y %}, this expects that y is a context variable in your template, not a template tag.
What an inclusion tag does is that it renders a template (the one you pass as argument to the inclusion_tag decorator), and inserts the result where the inclusion tag is used.
You probably want to register get_my_leagues as a simple tag instead (or an assignment tag, if you're using Django older than 1.9), and use it like this:
{% get_my_leagues as my_leagues %}
{% for league in my_leagues %}
...
{% endfor %}
guys.
I'm here just to tell that i found a solution for my problem. I'm using Context Processors to do this job.
Thank you all for answers!
I know how to write a template tag which updates template context. But the update is available only just after the tag it self.
Is there a way to write custom django template tag which would result in global template context update, like using TEMPLATE_CONTEXT_PROCESSORS?
The template is rendered step by step (sequentially), and obviously the context modified by a template tag would be available only after the template tag were called, not before.
Why not to use a context processor?
Ended up using django sekizai tags
By using it you can do something like this:
{% load sekizai_tags %}
<head>
<script>
{% renderblock 'googls_dfp' %}
</script>
</head>
<body>
{% block content %}
{% addtoblock 'google_dfp' %}
alert('Script is initialized before the body loads of this html document.');
{% endaddtoblock %}
{% endblock %}
</body>
I currently have two apps:
app1/
app2/
templates/
app1.html
app2.html
In app1.html, I'm including app2.html:
<!-- app1.html -->
{% include "app2.html" %}
app2 has some dynamic content:
<!-- app2.html -->
{% app2_value %}
When I display app1.html, the value app2_value doesn't show up. What's the best way to handle the above in Django?
Django doesn't really process dynamic including like PHP or other languages do. Instead, you should have a base template, and use template inheritance and blocks to accomplish what you're trying to do.
So your app2.html would have the same dynamic content, but have a place for app1.html to either override or insert things.
app2.html:
{% block 'title' %}
{{ app2.title }}
{% endblock %}
{% block 'content' %}
{% endblock %}
App1's template can then extend App2's:
app1.html:
{% extends "app2.html" %}
{% block 'title' %}
Actually App 1!
{% endblock %}
{block 'content' %}
...
{% endblock %}
Unfortunately, include-handling is still new in Django and against best practices from what I've seen in the documentation and community.
In Django your views and your templates are decoupled from each other, so when you use {% app2_value %} in a template it will assume that was passed to it from the calling view.
So, to answer your question, to get that value to display, pass it to app1 template in whatever view you use to call it:
# app1 views.py
from django.shortcuts import render_to_response
import app2
def app1_view(request):
return render_to_response('app1.html', {'app2_value': app2.somevalue})
You can actually render a temple as a string and then send it to another template to be displayed. You would still need to send the variabels to the template you are rending as a string. A good use case would be to use the same template to render list or dicts in a special way.