why do we not use {{ }} while removing hardcoded urls in django? - django

<li>{{ question.question_text }}</li>
here we use {{ }} tag as question.id is a variable but,
<li>{{ question.question_text }}</li>
when we remove the hardcoded url from our template why we do not use {{ }} around the question.id?

{% %} denotes a template tag and anything inside are, kind of, treated as python code. Look at it as a kind of escape. Whereas {{ }} escapes variables themselves so you can use the values.
See the docs for more: https://docs.djangoproject.com/en/dev/topics/templates/#the-django-template-language

Related

Do errors in BoundField.errors and BoundField.help_text need to be escaped in a template in Django?

Do errors in BoundField.errors and BoundField.help_text need to be escaped in a template in Django? My guess is yes because both the errors and the help_text are no place for HTML code. However, I am a bit confused after I saw the following two snippets of code in the documentation of Django.
Snippet A:
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
Snippet B:
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
(Snippet A can be found at near here, and Snippet B can be found near here)
For Snippet A, I don't think the escape filter is needed because Django's default template engine escapes the string representation of any variable value by default.
For Snippet B, I don't think the safe filter should be used because help_text is no place for any HTML code.
Is my understanding incorrect, or are these two snippets of demo code in Django's documentation problematic the ways I indicated?
Escape-Filter
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
This snippet from the docs is a bit misleading, I think. As you stated before, yes, usually auto-escaping takes place. The documentation (here) of escape says:
Applying escape to a variable that would normally have auto-escaping applied to the result will only result in one round of escaping being done. So it is safe to use this function even in auto-escaping environments.
This could be useful if you have no control about the parent templates and somewhere in the HTML is {% autoescape off %}. But I think this is a very anusual case.
Safe-Filter
The safe-filter is the opposite. It tells django that no escaping is needed there, if autoescaping is enabled. So because the help text has usually no characters which needs to get escaped, the author of this snippet rates it as safe content and tells django not to use autoescaping - if it is enabled at all.
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }} {{ field }}
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
{% endfor %}
From my experience, I see no reason why to go without autoescaping and therefore no need for these to filters most of the time.

Separator Between Multiple Variables in Django Template (DTL)

Given three or more variables in my DTL template what is the most convenient way to assure that an interpunct is always between two variables?
<div>{{ person.name }} · {{ person.phone }} · {{ person.city }}</div>
Expected:
<div>John · 1234567 · New York</div>
<!-- {{ person.city }} is null or empty-->
<div>John · 1234567</div>
Is there an easy way to solve this with built-in functionality? I try to avoid writing custom Django filters/template tags.
You can't do this easily in Django template language. Either pass a list of non-empty values from your view, e.g. ["John", "1234567"], or write a custom tag or filter so that you can do something like {% interpunct person.name person.phone person.city %} or {{ person|display_person }}.
You can (ab)use the cycle tag for this purpose. Place it in front of each list item, then use it to emit nothing on first pass, then the separator thereafter. Use in a for loop is straightforward. Use outside needs this pattern:
{% cycle '' '|' '|' '|' as itemsep silent %}
{% if foo %}
{{ itemsep }}{% cycle itemsep %}
Foo!
{% endif %}
{% if bar %}
{{ itemsep }}{% cycle itemsep %}
Bar!
{% endif %}
{% if foobar %}
{{ itemsep }}{% cycle itemsep %}
FooBar!
{% endif %}
Or, miss the silent complexity by just using an extra ''
{% cycle '' '' '|' '|' '|' as itemsep %}
{% if foo %}
{% cycle itemsep %}
Foo!
{% endif %}
...

Using braces in blocktrans

How can I escape {{ or }} inside a blocktrans tag?
Solutions like {% verbatim %) or {% templatetag openvariable %} are not allowed inside a blocktrans tag.
I think you can do it like this:
{% blocktrans with verbatim="your verbatim {{ text }}" %}
Some stuff including {{ verbatim }}.
{% endblocktrans %}
This will preserve the braces around {{ text }}

Django template link with if else statement

Lets say I have code in template like this:
<a href="#">
{% if request.user.first_name or request.user.last_name %}
{{ request.user.first_name }} {{ request.user.last_name }}
{% else %}
{{ request.user }}
{% endif %}
</a>
Problem with this code is that it adds trailing space to link, so link looks like link_ with underline at the end.
How do I remove such trailing spaces? {% spaceless %} tag doesn't quite help here because it only removes spaces between tags.
I actually found simple solution for my problem.
<a href="#">{% spaceless %}
{% if request.user.first_name or request.user.last_name %}
{{ request.user.first_name }} {{ request.user.last_name }}
{% else %}
{{ request.user }}
{% endif %}
{% endspaceless %}</a>
By placing spaceless tag inside it strips the string it gets. Placing outside
As a possible variant of decision:
http://www.soyoucode.com/2011/minify-html-output-django
Or you could try to create your own tag if there are no such tags:
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
Quick workaround: Use html comments to "escape" the unnecessary whitespace.
Probably better solution: Create a template tag that holds this conditional.
Seconding the usage of a single template tag - it'd be good (and pretty easy) to remove this logic from the template.
Although, doesn't just using {{ request.user }} give exactly the same result as what you're doing here?
Instead of if-else block try to use shorter version:
{{ user.get_full_name|default:user.get_username }}

How to escape liquid template tags?

This sounds very easy, however I couldn't find it anywhere in the docs. How can I write {% this %} in a liquid template, without it being processed by the engine?
it is possible to disable liquid processing engine using the raw tag:
{% raw %}
{% this %}
{% endraw %}
will display
{% this %}
For future searchers, there is a way to escape without plugins, use the code below:
{{ "{% this " }}%}
and for tags, to escape {{ this }} use:
{{ "{{ this " }}}}
There is also a jekyll plugin for this which makes it a whole lot easier: https://gist.github.com/1020852
Raw tag for jekyll. Keeps liquid from parsing text betweeen {% raw %}
and {% endraw %}
Reference
BTW:
If you want to display {{ "{% this " }}%}in Jekyll, you can code like this:
{{ "{{ " }}"{{ "{% this" }} " }}{{ "}}%}
To escape {{ "{{ this " }}}}use:
{{ "{{ " }}"{{ "{{ this" }} " }}{{ "}}}}
You can escape liquid tags in Jekyll posts using {% raw %} {% endraw %} i.e
{% raw %}
{% for post in site.posts %}
{{ post.content }}
{% endfor %}
{% endraw %}
will produce
{% for post in site.posts %}
{{ post.content }}
{% endfor %}
There is another option: to use HTML special characters codes for replacing the curly braces with its matching codes:
replace each { with {
replace each } with }
For more details about this solution see:
http://www.tikalk.com/devops/curly_brances_workaround/
I found a omnipotent way to display any text with curly braces. You can assign plain text to a variable, and display it.
{% assign var = "{{ sth }}" %}
{{ var }}
As mentioned here also, plain {% raw %} and {% endraw %} are only the second best solution since those are shown if you look up the Markdown on normal github.com.
The best way is to put {% raw %} and {% endraw %} in HTML comments:
<!-- {% raw %} -->
something with curlky brackets like { this } and { that }
<!-- {% endraw %} -->
Due to the HTML comments it is seen by Github as a comment. In Github pages the raw tags will prevent the parsing of the curly brackets in between the tags.
I tried {% raw %} something {% endraw %} ,
and {{ "{% this " }}%}. But they both don't work.
finally, my working answer is
{{ "{%" xxx }} something }}.
My code:
{{ "{%" }} extends 'xadmin/base_site.html' %}
{{ "{%" }} block nav_form %}
<h3>{{ "{{" }} title }}</h3>
{{ "{%" }} for i in context1 %}
<p>{{ "{{" }} i }}</p>
{{ "{%" }} endfor %}
{{ "{%" }} endblock %}
The result:
{% extends 'xadmin/base_site.html' %}
{% block nav_form %}
<h3>{{ title }}</h3>
{% for i in context1 %}
<p>{{ i }}</p>
{% endfor %}
{% endblock %}
Allows output of Liquid code on a page without being parsed.
{% raw %}{{ 5 | plus: 6 }}{% endraw %} equals 11.
{{ 5 | plus: 6 }} equals 11.
For more details about this solution see: https://www.shoplazza.dev/docs/theme-tags