a paid nerd
a paid nerd

Reputation: 31532

{% 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?

Upvotes: 29

Views: 18886

Answers (5)

Thomas Decaux
Thomas Decaux

Reputation: 22691

I am doing:

{% filter trim %}
... code ...
{% endfilter %}

Upvotes: 2

Mr Hyde
Mr Hyde

Reputation: 3413

There is a jinja2 extension that achieves this effect, authored by the jinja2 developer

https://github.com/mitsuhiko/jinja2-htmlcompress

Upvotes: 19

Filandre
Filandre

Reputation: 41

{% 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.

Upvotes: 4

Quolonel Questions
Quolonel Questions

Reputation: 6978

{% filter trim %} is equivalent to {% spaceless %}.

Upvotes: 7

Joel Santirso
Joel Santirso

Reputation: 161

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

with

Result without spaceless (notice that the invisible whitespace has moved the fourth block to the next line)

without

Upvotes: 9

Related Questions