Any way to make {% extends '...' %} conditional? - Django - python

I would like to share a template between AJAX and regualr HTTP calls, the only difference is that one template needs to be served with the base.html html, the other one without.
Any idea?

The other answers require you to pass an additional context variable. But as long as you can access the request object, there is no need:
{% extends request.is_ajax|yesno:"app/base_ajax.html,app/base.html" %}
I found this to be much more convenient.

Use a variable.
{% extends base_template %}
and in your view, set it to "base.html" in your view, or a new "ajax.html" file which just provides the block and nothing else.

{% extends override_base|default:'base.html' %}
P.s. I know this is an old question, but I found it when searching for an answer. Maybe it'll help someone else with the same problem.

You can use {% extends variable %}
Pass a variable base template name in when you create the context in the view.
http://docs.djangoproject.com/en/dev/ref/templates/builtins/?from=olddocs#extends

Related

Trouble with "extends" can be only used once in Django template

I originally thought I would use {% extends ["filename.html"] %} to take html I've written in a template and put it into my main file, but since you can only use "extends" once, how can I have it so that my sidebar.html and slider.html are like snippets that can be put into my main html file, which I've called list.html
Here's an image of what things look like now: http://imgur.com/K5XKAcQ
Here's an image of the error: http://imgur.com/Uqs3iQo
Use "extends" like referencing a base class. Multiple-inheritance isn't supported (directly). To include snippets of code in your content, use "include":
{% extends "layout.html" %}
{% include "sidebar.html" %}
{% include "slider.html" %}
See: https://docs.djangoproject.com/en/dev/ref/templates/builtins/
You can use include in the main template
Rather than adding a tag in the sidebar.html, in filename.html, add:
{% include "sidebar.html" %}
You can use an include statement. Also, see here.

Change Django Template Inheritance Dynamically?

I have a template with the following: {% extends "main/main-template.html" %}
I also want a template with the exact same thing, only instead it {% extends "main/main-template-quick.html" %} It seems like a violation of DRY to just copy and paste the same code into a new file, just so I can change the template. Is there any way to select the super-template dynamically?
If not, is there a good way to do the following: Reuse the same {% block %} and its content with a different template. At the same time, not violating DRY.
I'm also open to other template languages that may be able to do this.
If you check the docs you'll see that extends accepts a variable too.
{% extends variable %} uses the value of variable. If the variable
evaluates to a string, Django will use that string as the name of the
parent template.
So you can easily determine the appropiate base template in your view and pass it to your template.
And if you want to reuse a chunk of html in different contexts than the include tag is your friend.
Django allows for display the parent templates block content using {{ block.super}}.
This allows you to insert the parent's block contents.
{% block content %}
{{ block.super }}
{% endblock content %}
block.super was designed to allow you to
Reuse the same {% block %} and its content with a different template.

Flask and jinja2 include tag

How to do it "include tag" in jinja2. I need to output a block of articles in the base template. And they work in children.
views.py
Articles.query.filter_by(name=name).first()
base.html
{% block content %}
Content base
{% endblock %}
---{{ this_articles_tag }}----
children.html
{% extends 'base.html' %}
{% block content %}
Content children
{% endblock %}
---{{ output Articles }}----
Django in this "include tag", how to do it in jinja2? (Without using context_processor)
If you need to include another template in the template, just use include in Jinja. But if you are talking about template tags (in Django I remember I liked them a lot), then in Flask only your mentioned context_processor is the way to go. Which I think is not a bad thing at all.
Edit:
Easiest way to get context processor registered as a function is pointed in the documentation.
But if you want something more fancy, like dynamic loader or you will load your functrion from different places, then you can define your own decorator function, which basically wraps the function which returns dictionary:
def example_templatetag():
def get_something():
return get_want_you_want_from_db()
return dict(get_something=get_something)
Then where you create your Flask app object you can easily register this function:
app.context_processor(example_templatetag)
And then in a template you can use is like:
{% set data_you_wanted=get_something() %}
{{ data_you_wanted }}
But maybe for you the way mentioned in documentation will be more than enough ;)

Django template check for empty when I have an if inside a for

I have the following code in my template:
{% for req in user.requests_made_set.all %}
{% if not req.is_published %}
{{ req }}
{% endif %}
{% empty %}
No requests
{% endfor %}
If there are some requests but none has the is_published = True then how could I output a message (like "No requests") ?? I'd only like to use Django templates and not do it in my view!
Thanks
Even if this might be possible to achieve in the template, I (and probably many other people) would advise against it. To achieve this, you basically need to find out whether there are any objects in the database matching some criteria. That is certainly not something that belongs into a template.
Templates are intended to be used to define how stuff is displayed. The task you're solving is determining what stuff to display. This definitely belongs in a view and not a template.
If you want to avoid placing it in a view just because you want the information to appear on each page, regardless of the view, consider using a context processor which would add the required information to your template context automatically, or writing a template tag that would solve this for you.

Jinja's loop variable is not available in include-d templates

I have code similar to the following in one of my jinja template
{% for post in posts %}
{% include ["posts/" + post.type + ".html", "posts/default.html"] %}
{% endfor %}
which is supposed to render each post inside the posts collection, depending on the .type of the post. I have a different template setup for each post.type. And for those I don't have a template, it reverts to the default post template.
Now, I want the index of the post being displayed from bottom, inside the post templates, which is provided by loop.revindex. But for some reason, if I use loop.revindex inside the post template, I get a error saying UndefinedError: 'loop' is undefined.
So, is loop not available in the included templates? Is this by design? Am I doing something wrong with how I organised my templates for this to be not available?
Edit Okay, I came up with a workaround, in the for loop, before I include my template, I do
{% set post_index = loop.revindex %}
and use post_index inside the post template. Not ideal, but seems like the only way. I still want to know your solutions though.
Edit 2 One other thing, I am able to access the post variable inside the included template, but not the loop variable.
If might be possible with the {% with %} statement.
Try this:
{% with %}
{% set loop_revindex = loop.revindex %}
{% include ... %}
{% endwith %}
Instead of using loop.revindex in the included template, use loop_revindex.
Another option is to pass the entire loop variable into the included template by setting a local variable to loop
{% for post in posts %}
{% set post_loop = loop %}
{% include ["posts/" + post.type + ".html", "posts/default.html"] %}
{% endfor %}
This gives you access to all of the loops properties, and, to me, makes it more clear in the included template what the variable is.

Categories

Resources