Strip empty lines in rendered templates?

2,234 views
Skip to first unread message

Benjamin Buch

unread,
Mar 15, 2009, 3:13:17 PM3/15/09
to Django users
Hi,

is there a way to tighten up the output that Django renders?
Especially, remove the empty lines?

This template code:

<div>
{% for entry in entries %}
<p>{{ entry.title }}</p>
{% endfor %}
</div>

looks like this when rendered:

<div>

<p>Title 1</p>

<p>Title 1</p>

<p>Title 1</p>

</div>

I stumbled upon this middleware,
http://code.djangoproject.com/wiki/StripWhitespaceMiddleware,
but the discussion around it is somewhat dated,
and even the author states that there are some problems with it.
http://code.djangoproject.com/wiki/ContributedMiddleware

Is there any other way to handle it?

benjamin

Dougal Matthews

unread,
Mar 15, 2009, 3:20:16 PM3/15/09
to django...@googlegroups.com
Something like this might be able to help you?

http://www.davidcramer.net/code/369/spaceless-html-in-django.html

Dougal

---
Dougal Matthews - @d0ugal
http://www.dougalmatthews.com/




2009/3/15 Benjamin Buch <benni...@gmx.de>

Tim Chase

unread,
Mar 15, 2009, 3:34:44 PM3/15/09
to django...@googlegroups.com
> This template code:
>
> <div>
> {% for entry in entries %}
> <p>{{ entry.title }}</p>
> {% endfor %}
> </div>
>
> looks like this when rendered:
>
> <div>
>
> <p>Title 1</p>
>
> <p>Title 1</p>
>
> <p>Title 1</p>
>
> </div>

While it goes against my aesthetic tastes for making easy-to-read
templates (I much prefer my templates look like yours), you _can_
use the following:

<div>{% for entry in entries %}
<p>{{ entry.title }}</p>{% endfor %}
</div>

which gets you the aesthetic output with minimal fuss.

-tim


Benjamin Buch

unread,
Mar 16, 2009, 11:48:59 AM3/16/09
to django...@googlegroups.com
Thank you for your replies!

What I essentially want to do is:
1: Keep the template output readable for the frontend coder I'm
working with
2: Keep the templates readable for me.

@Dougal:
I think the solution you suggested is great when someone wants to keep
the size of the rendered template to a minimum.
But as it strips really all whitespace, all linebreaks and everything,
the result is perfectly machine readable
but nothing that would make my frontend coder be happy.

@Tim:
This solution would give me the desired output, but the templates get
less readable for me this way.

What I figured out:

I gave the StripWhitespaceMiddleware I mentioned a try,
and it works reasonably well.
It just strips empty lines but keeps the indentation the tags have in
the template,
so you've got reasonable control over how the rendered templates look
like.

The downsides I see so far are:
- You can't add empty lines to structure the rendered template
- Multiline output from template variables are not indented (e.g.
something like {{ entry.body|markdown }})

I have no solution for the add-empty-line-problem,
but I wrote a template tag that indents the output of a multiline
variable.
It's not perfect (it destroys all indentation that is output by
markdown..) but it works for me:

class IndentNode(Node):
def __init__(self, nodelist, indent_level):
self.indent_level = indent_level
self.nodelist = nodelist

def render(self, context):
rendered = self.nodelist.render(context)
lines = rendered.split('\n')
for i in range(len(lines)):
if lines[i]:
lines[i] = ' ' * int(self.indent_level) +
lines[i].strip(' ')
rendered = ''
for line in lines:
rendered += line + '\n'
return rendered

def do_indent(parser, token):
bits = token.contents.split()
try:
indent_level = bits[1]
except IndexError:
indent_level = 0
nodelist = parser.parse(('endindent',))
parser.delete_first_token()
return IndentNode(nodelist, indent_level)

You would use it like this:

{% indent 8 %}
{{ entry.body|markdown }}
{% endindent %}

An other solution I tried but rejected was to use Beatiful Soups
'prettify'-method in a middleware:

class BeautifulSoupMiddleware:
def process_response(self, request, response):
new_content = BeautifulSoup(response.content).prettify()
response.content = new_content
return response

But the output was a little to shaky, so I can't recommend it.


benjamin


Dougal Matthews

unread,
Mar 16, 2009, 12:37:15 PM3/16/09
to django...@googlegroups.com
You could adapt that middlewear to make it only stop blank lines I'm sure.

I use it for one website and its only used in the production version, in my settings for the dev version it doesn't include that middlewear so it doesn't effect any front end development.

Only thing to be aware of is it messes up some tags, like <textarea> and <code>

Dougal

---
Dougal Matthews - @d0ugal
http://www.dougalmatthews.com/




2009/3/16 Benjamin Buch <benni...@gmx.de>

Benjamin Buch

unread,
Mar 16, 2009, 12:45:01 PM3/16/09
to django...@googlegroups.com
Yes, you're right.

But as the SpacelessMiddleware uses djangos' strip_spaces_between_tags,
which strips all whitespace between tags and not just empty lines,
I think it would have been fiddly to adapt it without touching django
internals.
In this case it seemed easier for me to use StripWhitespaceMiddleware,
which did what I wanted.

benjamin

chachra

unread,
Mar 24, 2009, 2:11:34 PM3/24/09
to Django users
Would the {% spaceless %} template tag be helpful here ? I posted a
similar question, and someone responded saying that may be the way to
go.

Cheers!
Sumit

darryl.hebbes

unread,
Mar 26, 2009, 5:23:02 AM3/26/09
to Django users
Or simply remove the return after the forloop statement.

Like so.
<div>
{% for entry in entries %}<p>{{ entry.title }}</p>
{% endfor %}
</div>

should give you

<div>

<p>Title 1</p>
<p>Title 1</p>
<p>Title 1</p>

</div>



On Mar 15, 9:13 pm, Benjamin Buch <benni.b...@gmx.de> wrote:
> Hi,
>
> is there a way to tighten up the output that Django renders?
> Especially, remove the empty lines?
>
> This template code:
>
> <div>
> {% for entry in entries %}
> <p>{{ entry.title }}</p>
> {% endfor %}
> </div>
>
> looks like this when rendered:
>
> <div>
>
> <p>Title 1</p>
>
> <p>Title 1</p>
>
> <p>Title 1</p>
>
> </div>
>
> I stumbled upon this middleware,http://code.djangoproject.com/wiki/StripWhitespaceMiddleware,
> but the discussion around it is somewhat dated,
> and even the author states that there are some problems with it.http://code.djangoproject.com/wiki/ContributedMiddleware
Reply all
Reply to author
Forward
0 new messages