Using Djangos template language I would like to pass HTML generated through the template language into an included template like in the following simplified example:
field.html
<input name="input_name" />
<div>{{ input_desc_html }}</div>
form.html
{% with input_name="test" input_desc_html=... %}
... should read {% for this in that %} {{ this }} {% endfor %}
{% include 'field.html' %}
{% endwith %}
Obvioulsy there is something missing at ... and I do not know how to advance from here. Is this approach even possible and if yes, how?
If not, what else would you suggest? I thought about using blocks and extending field.html, but it seems to me that this needs every field in its own file - or can I have local templates?
Related
A little question to jinja2 templating:
I want to create a reusable template to include and then overwrite blocks. Macros do not let me write junks of HTML easily as parameters do they? Say I want to reuse an include several times and am using BIG junks of HTML in blocks that I want to dynamically assign
how would I do it?
certainly not with macros I guess, or am I wrong?
{% render_foo('bar',2) %} is fine
{% render_foo('<table><tr><th>something</th><th>somethingelse</th></tr><tbody><tr>....etc') %} is not fine any more is it
"what do you really want to do?"
yes, what I told you, I have a way I create containers for my data. The container is ALWAYS the same. The content is completely different on each usage. Once a table. Once a bootstrap component. Once a form.
The surrounding elements are always the same
to reproduce the simple error this is what I did:
{% include 'full_section.html' %}
{% block fullsection %} <table><tr><th>something</th><th>somethingelse</th></tr><tbody><tr>....etc{% endblock %}
{% include 'full_section.html' %}
{% block fullsection %} <form>//some cool LONG big form </form>{% endblock %}
full_section.html contents just for completeness, it is a lot more complex in reality
<div class="my_cool_full_section">
{% block full_section %}{% endblock %}
</div>
TemplateAssertionError: block 'fullsection' defined twice
I found the answer well hidden in the jinja2 docs
http://jinja.pocoo.org/docs/2.9/templates/#block-assignments
so you use a macro and a block assignment e.g. like this:
{% set section_content %}
<table><tr><td>etc</td> <td>etc</td> <td>etc</td></tr></table>
<table><tr><td>etc</td> <td>etc</td> <td>etc</td></tr></table>
<table><tr><td>etc</td> <td>etc</td> <td>etc</td></tr></table>
{% endset %}
{{ render_full_size_section(section_content) }}
{% set section_content %}
aaaaaaaaaaa
{% endset %}
{{ render_full_size_section(section_content) }}
wonder what they were doing pre 2.8... dark dark middle age
then in the macro:
{% macro render_full_size_section(content) %}
<div class="mycoolsection">
{{ content | safe }}
</div>
{% endmacro %}
i am a new to django, and i'm trying to execute a django code in an html template, but it is showing the same error and i dont know how to make it work. I am trying to read some files and find the one that contains the string. This is the code in the template:
{% if documents %}
<ul>
{% for document in documents %}
{% if 'TheString' in open('document.docfile.url').read() %}
<li>{{ document.docfile.name }}</li>
{% else %}
<li></li>
{% endif %}
{% endfor %}
</ul>
{% else %}
<p>No documents available.</p>
{% endif %}
The error is the following:
TemplateSyntaxError at /subir/
Could not parse the remainder: '('document.docfile.url').read()' from 'open('document.docfile.url').read()'
What could it be, or am i doing it wrong? Thanks in advanced.
Your problem is you are trying to use Python code in the template, like your open() call.
Django templates don't work like that - you can only use a very limited set of syntax, and the syntax is not the same as Python.
Everything inside {{ }} and {% %} needs to be special Django template syntax, not Python code.
See the Django Template language documentation for the full details.
You can't use code like this in a template directly see the documentation for available template tags and filters. From what I can tell by the code you have posted in your view.py you'll need something like this:
docs=[]
for document in documents:
if 'TheString' in open('/path/to/document').read():
docs.append(document)
after passing docs to the template you could do this in the template:
{% for doc in docs %}
<li>{{ document.docfile.name }}</li>
{% empty %}
<p>No documents available.</p>
{% endfor %}
I'd need to look at what you are passing from the view to be sure of this, but I'd gladly assist in further help with further information if this doesn't help.
I would like to make a sequence of variables within a for loop such as name0, name1, .... How do I do that? Thanks.
{% for i in '1234567890' %}
{% if name{{forloop.counter0}} %}
...
{% endif %}
...
{{name{{forloop.counter0}}}}
...
{% endfor %}
is as simple as
{{ name }}{{ forloop.counter0 }}
for the if, you should use the "with" statement:
{% with name|add:forloop.counter0 as if_test %}
{% if if_test %}
... <!-- do whatever you need to do here -->
all this must be inside your for loop
As you can see, the Django templating language tries hard to keep you from doing what you're trying to do, encouraging you to do your data processing in your view code, instead of your templates. For your example, in your view code, you might try doing:
context['names'] = [name for name in names[:10]]
...instead of creating individual variables for each name.
Then in your template:
{% for name in names %}
{% if name %}
...
{% endif %}
...
{{name}}
...
{% endfor %}
As far as I can tell, that would have the same effect as your code, but you would be doing your aggregation of the names in the view, instead of the template. If I'm reading the intent of your code wrongly, please provide more context, but it doesn't seem like you're doing anything that requires template logic.
I have an internationalized Django 1.3 site and want to do this:
{% include "snippets/button.html" with button_text=_("Logout {{ user.username }} now") %}
And snippets/button.html looks like this:
<button
type="{{ button_type|default:_('submit') %}"
class="all_my special classes"
{% if button_title %} title="{{ button_title }}"{% endif %}>
<span class=ui-button-text>{{ button_text|default:_("Submit") }}</span>
</button>
The only way I can see to do this is something like:
{% include "snippets/button.html" with button_text="Logout "|add:user.username|add:" now" %}
But this is not acceptable as the strings to translate need to include where the variable substitution will occur. I have seen Interpolate Django template include variable but that doesn't cover this usage.
I think your best bet in this case is to add the already translated string to your context.
In your views.py:
...
'button_text': _("Logout {} now").format(user.username),
...
Then in your template:
{% include "snippets/button.html" with button_text=button_text %}
Something like this may let you go on:
{% blocktrans with value|filter as myvar %}
This will have {{ myvar }} inside.
{% endblocktrans %}
from here http://www.djangobook.com/en/1.0/chapter18/
It should work with includes, but I haven't tested.
This is my template tag in a forloop
{{ product.feature_set.all.1.value }}
i want to change the number 1 to the forloop.counter. is this posible?
like:
{{
product.feature_set.all.forloop.counter.value
}}
It does not work like that, but is there a way to do this?
This doesn't make sense. You should be looping through the queryset itself.
{% for feature in product.feature_set.all %}
{{ feature }}
{% endfor %}
Since #Daniel's answer doesn't satisfy you, I thought you might want to try writing a custom filter. Here is a rough draft:
#register.filter
def custom_m2m(queryset, forloop_counter):
return queryset[forloop_counter].value
You can use it in your template like this:
{% for ... %}
{{ product.feature_set.all|custom_m2m:forloop.counter }}
{% endfor %}