Skip to content

Instantly share code, notes, and snippets.

@fsboehme
Forked from jimmydo/collapsespacestag.py
Last active June 8, 2018 13:11
Show Gist options
  • Save fsboehme/291e9de4824874e9866c6e56aa815b03 to your computer and use it in GitHub Desktop.
Save fsboehme/291e9de4824874e9866c6e56aa815b03 to your computer and use it in GitHub Desktop.
collapsespaces is a Django template tag that collapses whitespace characters between tags into one space. This fork also strips leading whitespace on any new line and any whitespace between HTML attributes (e.g. id="foo" class="bar").
"""
collapsespaces is a Django template tag that collapses whitespace characters between tags into one space.
It is based on Django's 'spaceless' template tag (spaceless is different in that it completely removes whitespace between tags).
Why is this important?
Given "<span>5</span> <span>bottles</span>", collapsespaces will preserve the space between the two span elements--spaceless will not.
In a web browser:
"<span>5</span> <span>bottles</span>" renders as "5 bottles"
"<span>5</span><span>bottles</span>" renders as "5bottles"
"""
import re
from django import template
from django.utils.encoding import force_unicode
from django.utils.functional import allow_lazy
register = template.Library()
def collapse_spaces_between_tags(value):
"""Returns the given HTML with whitespaces collapsed to one space."""
# Collapse all leading spaces at the beginning of a line (credit: https://djangosnippets.org/snippets/547/)
value = re.sub(r'\n\s+', '\n', force_unicode(value))
# Collapse whitespace between attributes inside HTML tags (thanks to https://regex101.com/)
value = re.sub(r'\s+([\w-]*?=\"[^\"]*?\")', r' \1', force_unicode(value))
# Collapse whitespace between tags
value = re.sub(r'\s+<', r' <', force_unicode(value))
value = re.sub(r'>\s+', r'> ', force_unicode(value))
return value
collapse_spaces_between_tags = allow_lazy(collapse_spaces_between_tags, unicode)
class CollapseSpacesNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
return collapse_spaces_between_tags(self.nodelist.render(context).strip())
def collapsespaces(parser, token):
"""
Collapses whitespace between HTML tags into one space.
Example usage::
{% load collapsespacestag %}
{% collapsespaces %}
<p>
<a href="foo/"
class="bar">
Foo
</a>
</p>
{% endcollapsespaces %}
This example would return this HTML::
<p> <a href="foo/" class="bar"> Foo </a> </p>
"""
nodelist = parser.parse(('endcollapsespaces',))
parser.delete_first_token()
return CollapseSpacesNode(nodelist)
collapsespaces = register.tag(collapsespaces)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment