{% spaceless %} tag for Jinja templates?
Django has a useful {% spaceless %}
tag that strips extra whitespace from HTML.开发者_运维百科
My templates are producing a lot of whitespace and it's too much of a pain to add the {%-
and -%}
everywhere to do whitespace control. Has anyone seen a filter like {% spaceless %}
for Jinja, or maybe {% htmltidy %}
, so that I could view clean HTML while developing?
There is a jinja2 extension that achieves this effect, authored by the jinja2 developer
https://github.com/mitsuhiko/jinja2-htmlcompress
I had this problem when I wanted to print inline-block level elements without separation between them (for example to render a fluid grid of blocks), but I wanted a clean looking markup.
jinja2-htmlcompress strips whitespace between HTML tags, but also between jinja tags and variables. That is not ideal because it forces you to use workarounds such as {{ ' ' }}
or hardcoded html entities such as
.
coffin's spaceless tag looks like the ideal solution, but it adds a dependency (django) and a lot of unnecessary functionality.
If you only want to use Django's spaceless tags, you can use the following code which I've adapted from coffin:
jinja_extensions.py
# -*- coding: utf-8 -*-
from jinja2 import nodes
from jinja2.ext import Extension
import re
class SpacelessExtension(Extension):
"""
Removes whitespace between HTML tags at compile time, including tab and newline characters.
It does not remove whitespace between jinja2 tags or variables. Neither does it remove whitespace between tags
and their text content.
Adapted from coffin:
https://github.com/coffin/coffin/blob/master/coffin/template/defaulttags.py
"""
tags = set(['spaceless'])
def parse(self, parser):
lineno = parser.stream.next().lineno
body = parser.parse_statements(['name:endspaceless'], drop_needle=True)
return nodes.CallBlock(
self.call_method('_strip_spaces', [], [], None, None),
[], [], body,
).set_lineno(lineno)
def _strip_spaces(self, caller=None):
return re.sub(r'>\s+<', '><', caller().strip())
Wherever you define your jinja2 environment
extensions=['path.to.jinja_extensions.SpacelessExtension']
Usage example
<style>
*, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
.features {
text-align: center;
}
.features div {
display: inline-block;
text-align: left;
width: 25%;
padding: 20px;
}
/* A style to help us identify the blocks */
.features div:nth-child(odd) {
background: #f5f5f5;
}
@media only screen and (max-width: 319px) {
/* For small screens, display a single feature per line */
.features div {
width: 100%;
}
}
</style>
{% spaceless %} {# We remove whitespace between these inline-block tags without affecting the markup #}
<div class="features">
<div>
<h2>Feature 1</h2>
<p>Content</p>
</div>
<div>
<h2>Feature 2</h2>
<p>Content</p>
</div>
<div>
<h2>Feature 3</h2>
<p>Content</p>
</div>
<div>
<h2>Feature 4</h2>
<p>Content</p>
</div>
<div>
<h2>Feature 5</h2>
<p>Content, second line on desktop</p>
</div>
</div>
{% endspaceless %}
Result with spaceless
Result without spaceless (notice that the invisible whitespace has moved the fourth block to the next line)
{% filter trim %}
is equivalent to {% spaceless %}
.
{% filter replace("\t", " ")|replace(" ", " ")|replace(" ", " ")|replace(" ", " ")|replace("\n ", "\n")|replace("\n\n", "\n") %}
I use this to replace multiple spaces by only one separator. Not nice but efficient without extension.
I am doing:
{% filter trim %}
... code ...
{% endfilter %}
精彩评论