How to indent Django templates properly - django

I work in SublimeText 3. When writing Django templates I have a mixture of html and functions.
I like to indent my code so that block, if and other such statements are indented. For example:
Manual formatting
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
{% endblock %}
However, when I run any autoformatter HTML-CSS-JS-Prettify it ignores these brackets and treats them as text:
After formatting
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
{% endblock %}
Although plugins like Djaneiro give great tag highlighting, I haven't been able to find a way to get SublimeText to treat these as tags.
Has anyone had any luck?

This is a late answer, but I would like to mention a Django template formatter that I've created myself: DjHTML. You can install it using pip install djhtml.
Let's say template.html contains the following:
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
<script>
$(function() {
console.log("Password changed!");
});
</script>
{% endblock %}
Then running djhtml template.html will give the following output:
{% extends "accounts/base.html" %}
{% block content %}
<h1>Password changed</h1>
<p>Your password was changed.</p>
<script>
$(function() {
console.log("Password changed!");
});
</script>
{% endblock %}
It's easiest to use DjHTML as a pre-commit hook, so that templates will be automatically indented when you run git commit. Instructions on how to configure pre-commit can be found in the README.

There isn't one for sublime text as far as I can tell. I have no source I can quote on this, but I have basically searched nothing came up.
This discussion is by any means old, but active. I found this really old ticket about formatting standards for Django and it has been updated 9 Months ago to basically say they are "in favour of standards" and the proposed formatting for templates would be:
<ul>
{% for x in y %}
<li>{{ x }}</li>
{% endfor %}
</ul>
They also made a place happen that holds information about formatting guidelines in Django.
You might find this discussion interesting as well. It's old too, but it highlights the confusion about formatting in Django and the DIY solutions people came up with to cope.

Related

Parsing and using list item content via Twig

I am experimenting with using Grav to create my next website. One of the things I would be able to do is to build a unordered list using data provided in Grav frontmatter from the Grav page that uses the template. Here is how I am trying to do this
---
sectionone:
listitems: "['Benefit 1','Benefit 2','Benefit 3']"
---
and then in the template somehow do the following
{% block featurelist %}
<ul>
{% set items = {{page.header.sectionone.consumers.benefits|json_decode}} %}
{% for item in {{}} %}
<li>{{item}}</li>
{% endfor %}
</ul>
{% endblock %}
However, Twig does not like this and reports back an error along the lines of
Twig_Error_Syntax
A hash key must be a quoted string, a number, a name, or an expression enclosed in parentheses (unexpected token "punctuation" of value "{".
with the offending line being my {% set items = ... } statement. I am clearly doing something wrong here but I am a Twig newbie so I fail to see what that might be.
{% block featurelist %}
<ul>
{% set items = page.header.sectionone.consumers.benefits|json_decode %}
{% for item in items %}
<li>{{item}}</li>
{% endfor %}
</ul>
{% endblock %}
I figured this out eventually. Grav documentation is by and large very good. However, the documentation on page headers/frontmatter appears to be somewhat incomplete. There is no full description of the entire syntax that is understood by the frontmatter processor. In order to define an array in front matter all you need to do is the following
---
sectionone:
benefits:
- 'Benefit 1'
- 'Benefit 2'
- ...
---
In essence the standard markdown syntax for an unordered list. Grav's twig processor appears to convert this to a PHP array - no parsing required!

Django block not showing up

So, originally I was using {% include}, and that was working fine, then I wanted to try out {% block}, and its not showing the nav.html content anymore. I've been trying to figure this out for about 15 minutes now, and it looks like its the same as I've seen everyone else do it. This is my code, what am i doing wrong?
<html>
<body>
It is now {{ current_date }}
{% block content %} {% endblock %}
</body>
</html>
this block of code being the current_datetime file.
{% extends 'current_datetime.html' %}
{% block content %} <h1>this is a test</h1> {% endblock %}
and this block of code being nav.html. I'm 100% sure that I'm naming the extends file correctly since I copied the name from the views file.
It seems you got stuck with you inheritance and how things have to work.
extends is used for inheritance. But you are trying to include one code snippet into another and that's the work for include.
You are not rendering nav.html. You are rendering current_datetime.html as you mention in the comments, that's why block works not as you expected. The code is correct, but your login is a little bit incorrect. Basically I want to point out that nav mustn't extend current_datetime.html. It has to be included in it.

How to mark string for translation in jinja2 using trans blocks

I am using django and jinja2 and have something like this in one of my html pages
<p><strong>Q. {{ _("What products will you accept?") }}</strong></p>
<p class="style3"><strong>A: </strong>{% trans myurl=request.url('start') %}A list of qualifying devices is available once you start your trade-in estimate. <a href= {{myurl}}>Click here</a> to learn what your old device is worth.</p>{% endtrans %}
When I run django-admin.py makemessages, "What products will you accept?" is the only string that gets processed. I thought that wrapping a string with the {% trans %} block also marks that string or is this a wrong statement?
What is the best technique to mark that second string (it's tricky because of the request.url variable)
I've tried {{ _("A list of qualifying devices is available once you start your trade-in estimate. <a href= {{ request.url('start') }}>Click here</a> to learn what your old device is worth.")|safe }} but then the link doesn't work properly.
To translate a block like that you need to use the {% blocktrans %} template tag,
{% blocktrans with myurl=request.url('start') %}
A list of qualifying devices is available once you start your trade-in estimate. <a href= {{myurl}}>Click here</a> to learn what your old device is worth.</p>
{% endblocktrans %}
However, I'm not sure you can call a function like that anywhere in a template like you are attempting.
Consider instead passing myurl in as a template variable, and then using smaller chunks of text. This increases reuse of the translations - especially for small common blocks like "Click here".
{% blocktrans %}
"A list of qualifying devices is available once you start your trade-in estimate."
{% endblocktrans %}
<a href= {{myurl}}>{% trans "Click here" %}</a>
{% trans "to learn what your old device is worth." %}
Also, when using HTML and template tags, try and keep them correctly nested. For example, in your code you would have:
<p>... {% blocktrans %}... </p>{% endblocktrans %}
Instead try to nest them like so:
<p>... {% blocktrans %}... {% endblocktrans %}</p>
This is especially useful for IDEs that can auto indent and fold content and helps readability.

Django template inclusion

The template inheritance page on the django site doesn't really solve my problem (Django 1.2).
My base page looks like:
...
<div class="grid_12" id="content">
{% block content %}{% endblock %}
</div>
...
{% block javascript %}{% endblock %}
I have another template that defines content for these:
{% block content %}
animated sidebar
{% endblock %}
...
{% block javascript %}
alert('hello');
{% endblock %}
This is something like an animated sidebar, so I don't want to extend the base template since it's auxiliary to the main content of the page. If I just use "include", the entire thing is put where the "include" tag is placed - as a result the javascript doesn't run because it's included before one of its dependencies.
What's the best way to solve this?
EDIT
Sorry, I didn't make myself clear.
I have my content pages which render a template that extends "base.html". In "base.html" I want to include a sidebar template that needs to append blocks in "base.html". So I've tried just putting include "sidebar.html" into "base.html", but it just inserts the whole thing where the "include" tag is. What I want it to do is append the blocks in "base.html", which may themselves have been populated by "page.html".
Maybe it's important to say that "sidebar.html" is entirely static - i.e. there's no callable associated with it. So perhaps this question should really be "How can I include a static template into base.html so it will append to blocks in base.html regardless of the output of the actual view that processes the request?"
I think you mean you want to append to a block? You can put {{ block.super }} where you want the inherited content to go. e.g.:
{% block javascript %}
{{ block.super }}
alert('hello');
{% endblock %}
You should only use {% block foo %} tags to extend blocks in a base template, so I'm not clear what you mean when you say you don't want to extend it.
The code, as you've entered it, should render to
...
<div class="grid_12" id="content">
animated sidebar
</div>
...
alert(hello)
Unless you want to append the content (as in Matt's answer) it's not clear what you want to happen.
You shoud be using something like jQuery to trigger execution only after the page is fully loaded. Include jQuery library in the document header and then somewhere:
$(document).ready(function() {
//your code goes here
});

How do I DRY up common text in a Django template?

I have some static text that needs to show up at 2 locations within a template.
For example:
<div>
{% if something %}
This is a static text
{% else %}
Something else happened
{% endif %}
</div>
... more html
<span>
{% if something %}
This is a static text
{% else %}
Something else happend
{% endif %}
</span>
I can do the above by duplicating the above text at 2 different locations in my template file(as shown above).
I could also create a model which will store the text(This is DRY but cost a call to the DB for a simple task)
I'm thinking of using include template but that's probably not the best way to achieve my goal.
What's the best way to do it?
Definitely use Inclusion Tags:
http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags
The tag file would either be something super simple like just the text "This is a static text" or the entire block:
{% if something %}
This is a static text
{% else %}
Something else happened
{% endif %}
"something" can be passed as a variable to the template tag so you can use that entire block in a variable way.
I use the django internationalization to do that. So in my apps/template I just write the key, and in the .po files is the value of the keys.
{% load i18n %}
<div>
{% if something %}
{% trans "static" %}
{% else %}
{% trans "something else" %}
{% endif %}
</div>
And in my .po file:
msgid "static"
msgstr "This is a static text"
msgid "something else"
msgstr "Something else happened
Besides useful for multi-language, it's much easier for copy writing just in case you want to change it in the future because you can just look unto one file instead of browsing several templates.
There are several ways, but it probably depends on what the text is and how often it will be used. It's hard to recommend a specific choice without full details
Create a custom template tag (this one makes the most sense based on how you've described your problem above).
Create a base template which has the text in it at the correct location and then inherit off of it for your "2 locations"
Put the static piece of text in a settings file and pass it to the template renderer via Context (probably not the best idea, but depending on what you're doing it could be a possibility)
You could use flatblocks : http://github.com/zerok/django-flatblocks
or chunks : http://code.google.com/p/django-chunks/
Those may be overkill for your problem, since they store your snippets in the database, but they add the benefit of making it possible to edit them via the admin.
{% load chunks %}
<div>
{% if something %}
{% chunk "something" %}
{% else %}
{% chunk "something_else" %}
{% endif %}
</div>
There are lots of forks or similar projects, for example:
http://bitbucket.org/hakanw/django-better-chunks/
http://github.com/bartTC/django-generic-flatblocks
I have a file like Java properties that I use for all of my resource strings. I just serve up the one that I want. Keeping these in one place also makes translating easy.
Ex.:
welcome_msg="hello user!"
thank_you="thank you"
goodbye_msg="goodbye, " + thank_you
If the included text gets bigger, use an 'include' tag.
{% include "myapp/helptext.html" %}
GrtzG