`{% include "blah.html" with x="..." only %}` with default value for x - django

In a template, I am using an include like this:
{% include "blah.html" with x="..." only %}
and I can use x in blah.html.
Now, I would like blah.html to set a default value for x if it is not passed by the "parent" template:
{% include "blah.html" only %}
Since there is apparently no builtin template tag to set a variable in a template, I don't know how this could be achieved...

Related

Use function in Django Include Tag?

I'm trying to pass a value into a template via an include tab, like so:
{% include "shared/page_title.html" with text=local_time_format(job.date, user.timezone, "M j P") %}
So basically, i want the text value to be the result of calling local_time_format (a filter function) with job.date (context object value) and a user property and the final argument.
Getting Could not parse the remainder error-- how to fix?
You can prep values for an include like so:
{% with text=today|date:"D d M Y" %}
{% include "shared/page\_title.html" with text=text%}
{% endwith %}

Variable not expanded inside an included selmer template

I have a top-level template where I want to use a "fragment" template inside a for cycle but I'm not able to pass in the variable value:
{% for item in coll %}
{% include "fragment.html" with name="slack" item=item %}
{% endfor %}
item and name is then used in the fragment.html template:
<div>
<label>
<input
title="{{item.id}}"
id="{{name}_{{item.id}}_active"
name="{{name}}-{{item.id}}_active"
...
/>
While the name parameter is expanded properly (its value is hardcoded in the parent template), the item parameter is not (its value is passed in as is).
Do I need to use a different syntax for that or it's just not supported?
The include tag splices in the included template. This means that any variables within scope of the parent template will be available to the included template. The with operator allows you to supply default values, which are not interpreted. Saying item=item is effectively saying item|default:"item", which is to say that item is redefined as "item".
See https://github.com/yogthos/Selmer#including-templates

Django. How to kind of "spread" object when passing as with parameter to include?

I have a component which i include like that:
{% include "components/item_link.html" with target="_blank" href=link.href icon=link.icon text=link.text %}
There are lots of repetitions of link.. Is there a way to "spread" object and include it like that?
{% include "components/item_link.html" with target="_blank" ...link %}
Assign the link variable directly like:
{% include .... link=link %}
Then in the included template use their single values as:
link.href
link.icon
link.text
If you can't modify the included template code, you can create an intermediate template which assigns the above variables and call the original include with their respective href=link.href icon=link.icon text=link.text so you avoid to repeat everything every time you use it.
Update
Add a link parameter, you can still use the parameters but then in the included template you can also detect if link is set when the parameter isn't set.
For example:
{% include "components/item_link.html" with target="_blank" link=link %}
in components/item_link.html:
<a href="{%if href%}{{href}}{%elif link%}{{link.href}}{%endif%}> ...

Django's {% include with var="val" %} updates context

I just figured out, that if you include subtemplate using with, variables will be available in base template. Very easy to reproduce:
Test: {{ test }}
{% include "tpl.txt" with test="passed" %}
Test: {{ test }}
Output:
Test:
Test: passed
Is it a bug?
UPD. I must say that inside tpl.txt there is inclusion tag with take_context=True. Also this inclusion tag do this:
#register.inclusion_tag('my_tag.txt', takes_context=True)
def my_tag(context):
context.update({'new': 'key'})
return context
If you don't update context, or if you do context['new'] = 'key' it works as expected. If you do update - all the variables you pass to {% include %} using with become available later in template. Still it's kind of wierd, because variables become available in parent template, and not updated keys ("new") become available, but {% include %} variables. The problem is localized though.

Conditional include tag in Django

I've ran into very strange behavior of Django template system. I have a template file, namely test.html, which recursively includes itself:
{% include "test.html" %}
Of course, such template has no chance to be rendered, since there is no finishing condition. OK, let's try the following:
{% if test_false %}{% include "test.html" %}{% endif %},
where test_false is a variable passed to template and equal to False.
One expects that it just will not include anything, but it does:
RuntimeError at /test/
maximum recursion depth exceeded while calling a Python object
I don't get it. Include tag can take arguments from current context, so I doubt it is executed before any other part of the page. Then why does it ignore condition tag?
Django has optimization that include templates that are given by constants at compilation.
Set name of template to variable and include it in that way:
{% include test_template %}
Django will not be able to use it's optimization and your code should work.
Like Thomasz says, Django can only make this optimization if the path is defined as a constant string in the including template - like so:
{% include "test.html" %}
But I would rather not have to put the template path in the context from Python code.
So here is a slightly more self contained way of achieving the same result - wrap the include in a with:
{% with "test.html" as path %}
{% include path %}
{% endwith %}