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
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
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
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