Visual Studio Code and Flask Jinja Templates - flask

I have recently switched to Visual Studio Code (previously used PyCharm) and am now facing a formatting problem.
With the following example html:
{% extends 'base.html' %}
{% block body %}
{{ super() }}
<div>Something</div>
{% endblock%}
after saving (I have turned on formatOnSave) I get the following:
{% extends 'base.html' %}{% block body %}{{ super() }}
<div>Something</div>{% endblock%}
I am using the editorconfig plugin and have stayed with the default user settings.
How can I configure VSC to not force Jinja blocks to be on a single line?

There's a known issue with trailing spaces.
You might try another extension dedicated to jinja: https://github.com/wholroyd/vscode-jinja

I have a temporary solution for that.
Use Better Jinja extension and add to jinja2 files .html.j2 extension.
You lose build-in HTML formatting but preserve jinja2 syntax :)

Related

VSCode: Auto Format on Save

I use last version of VSCode, I am on Windows10.
When I do the following:
{% extends 'base.html' %}
{% block content %}
<h1>Test About section</h1>
{% endblock %}
The code is automatically auto formatted when I save:
{% extends 'base.html' %} {% block content %}
<h1>Test About section</h1>
{% endblock %}
I am trying to deactivate it, but I have been unable to. This is what I've tried:
CTRL + Shift + P: 'Disable all Extensions' and also 'Disable all Extensions in Workspace'
In the Settings, the "editor.formatOnSave" is set to false (I have checked in User Settings, Settings for the Workpspace, Settings for Workspace JSON, etc)
Disabled Jinja and Prettier
Even tho I disabled my Extensions, when I hit [Save], the code is automatically formatted.
I am not sure where the settings get imported.
The project is new, I use Django, it's not linked to Git as well.
What I am doing wrong? I've been reading articles for the past hour but the issue keeps occurring, did I miss a setting or does a hidden setting get imported somewhere?

How to indent Django templates properly

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.

Escape jinja2 syntax in a jinja2 template

I serve dynamic pages from Jinja2 templates in Flask. Now I am defining client-side templates in say, Jinja2-clone Nunjucks inside a script tag. Problem is, the client-side templates has syntax like <% %> that Flask's Jinja2 interpreter may interpret instead of rendering verbatim.
How can I make the entire block of scripts render verbatim?
You can disable interpretation of tags inside a {% raw %} block:
{% raw %}
Anything in this block is treated as raw text,
including {{ curly braces }} and
{% other block-like syntax %}
{% endraw %}
See the Escaping section of the template documentation.

Writing eclipse templates

I am writing django templates in Eclipse->prefrences->templates, to autocomplete DJango templates. I wrote this
{% block ${cursor} %}
{% endblock %}
Now, when I request and do autocompletion, after typing {% the autocompletion is
{% {% block %}
{% endblock %}
While I would like
{% block %}
{% endblock %}
With cursor after block. How can I do this?
Instead of typing {% and selecting dj_for_empty, try typing dj_ and then auto-completing. It will behave the way you expect in that case.
BOTTOM-LINE: You auto-complete the templates into the editor based on the template name, not based on the template contents.
It appears that autocompletion has two sources: regular HTML tags (for which I can't find the definitions to change anywhere in Eclipse, sorry) and the templates themselves (which you correctly demonstrated in your comment with the screenshot).
Look at this image:
Instead of typing <t and triggering auto-complete, I typed t. You can see that there are entries with <> - indicating these are autocompletions based on the actual HTML tag - and entries with # - indicating these are autocompletions based on a template.
It appears templates are to be accessed by the name of the template. Notice that the template named table provides a complete <table> and not just the <table></table> that is autocompleted if you just type <tab and autocompletes.

Can we append to a {% block %} rather than overwrite?

In my core.html I have a block labeled javascript. It would be great if I can append more lines to this block without overwriting everything in it.
{% block javascript %}
{{ block.super }}
... more content ...
{% endblock %}
See: Django documentation - Template inheritance
Using block.super works fine when extending a template but not as well when including one, ie:
{% extends "base.html" %} vs. {% include "partial.html" %}
Say you want to include a template in the middle of your page and you'd also like it to add some javascript in a block at the end of the page: calling block.super in the included template will crash.
Cf. Django issues #7324, #12008, #13399 and the related update to the documentation. Cf. include tag note:
The include tag should be considered as an implementation of “render this subtemplate and include the HTML”, not as “parse this subtemplate and include its contents as if it were part of the parent”. This means that there is no shared state between included templates – each include is a completely independent rendering process.
Blocks are evaluated before they are included. This means that a template that includes blocks from another will contain blocks that have already been evaluated and rendered - not blocks that can be overridden by, for example, an extending template.
In that case I'd recommend using django-sekizai, wich allow you to do things like:
{% load sekizai_tags %}
⎧ <p>Some content</p>
<p>Some content</p> | {% addtoblock "js" %}
| <script type="text/javascript">
{% include "partial.html" %} -> ⎨ alert("Hello django-sekizai");
| </script>
<p>Some more content</p> ⎩ {% endaddtoblock %}
{% render_block "js" %}
From django-sekizai README:
The main reason I started this project was the lack of a good media (css/js) framework in django and the django-cms. Yes there is the Media class used in forms in django, but really that doesn't work that well. Usually the frontend guys want to decide on css and javascript files to be included and they don't want to have to edit Python files to change that neither did I want them to change my Python files. Therefor there was a need to allow you to edit contents of templates which are before or after the point where you are now. Also I wanted duplicates to be removed. As a result I wrote django-sekizai, which does exactly that. It's similar to blocks, just instead of inheriting them, you extend them.