5๐
The spaceless
tag removes spaces between html tags, itโs not possible to get it to remove spaces within tags, as you are trying to do.
You can prevent newlines by putting the if/else clause on one line, but as you say, that makes it hard to read. This suggests to me that you are trying to do too much work in the Django templates, and that the urls should be constructed else where.
The simplest option is to construct a list of (language_code, url)
ย tags in the view, and loop through these in the template.
{% for lang_code, url in language_urls %}
<link hreflang={{ lang_code }} href="{{ url }}">
{% endfor %}
If itโs not convenient to do this in the view another couple of options are:
- a template context processor (good if you use the same urls in every view
- a custom template tag/filter (good if
some_path
andother_path
are dynamic)
14๐
I needed the same, because Iโm using a template to generate an email subject line (non-HTML, so {% spaceless %}
is useless). In my case, the template had taken on lots of different cases, and everything had to be written in a single line over about 500 characters.
So in the spirit of {% spaceless %}
, I wrote my own {% linebreakless %}
:
import six
from django import template
from django.template.base import Node
from django.utils.functional import allow_lazy
register = template.Library()
@register.tag
def linebreakless(parser, token):
nodelist = parser.parse(('endlinebreakless',))
parser.delete_first_token()
return LinebreaklessNode(nodelist)
class LinebreaklessNode(Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
strip_line_breaks = allow_lazy(lambda x: x.replace('\n', ''), six.text_type)
return strip_line_breaks(self.nodelist.render(context).strip())
Please note that it (intentionally!) preserves all whitespace except line breaks.
An example usage for an email template would look like this, assuming the above is loaded in a template tag module called linebreakless.py
:
{% load linebreakless %}{% linebreakless %}
{# Email subjects are (encoded) text, not HTML, so we don't need any autoescaping! #}
{% autoescape off %}
New Notification
โข
{% if flag %}
about this
{% else %}
about that
{% endif %}
!
{% endautoescape %}
{% endlinebreakless %}
Note that the {% linebreakless %}
tag has to be on the first line (and after the {% load %}
directives) to prevent any line breaks in the generated file.
1๐
An alternative is to use a Jinja2 template, which Django supports since 1.8. From Jinja2โs documentation on whitespace control:
If you add a minus sign (-) to the start or end of a block (e.g. a For tag), a comment, or a variable expression, the whitespaces before or after that block will be removed:
{% for item in seq -%} {{ item }} {%- endfor %}
Converting a template from Django to Jinja2 is not entirely straightforward. It may be worth it though if youโre using the template to build a text file rather than an HTML file.
1๐
If you just want to remove the nextline which is coming due to < br > tag then just use โ
{{value|striptags}}
This will remove the tags and output will be simple and style (also new line) free. Hope it works ๐
- Django REST Framework different depth for POST/PUT?
- How to test a model that has a foreign key in django?
- How to pass the remote IP to a proxied service? โ Nginx
1๐
I needed it and updated @Henrik โs answer to work with keep_lazy
@register.tag
def linebreakless(parser, token):
nodelist = parser.parse(('endlinebreakless',))
parser.delete_first_token()
return LinebreaklessNode(nodelist)
class LinebreaklessNode(Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
strip_line_breaks = keep_lazy(six.text_type)(lambda x: x.replace('\n\n', '\n'))
return strip_line_breaks(self.nodelist.render(context).strip())
- Django + uwsgi + nginx + SSL
- Celery: launch task on start
- Django datefield and timefield to python datetime
- Django: Change the DOM id at form field level
- Django and models with multiple foreign keys
0๐
Just wanting to throw out my own solution here, following much of what @henrik-heimbuerger provided above. This is a solution that effectively copy/pastes Djangoโs spaceless
tag (as of Django 3.2) and then adapts it slightly. This way, we benefit from it being "lazy" (@keep_lazy_text
). This function will also remove all whitespace and handles trailing spaces appropriately for HTML.
Iโm providing here in entirety to allow others to easily use this with a copy/paste themselves ๐
import re
from django import template
from django.template import Node
from django.utils.functional import keep_lazy_text
register = template.Library()
@register.tag
def whitespaceless(parser, token):
"""
Remove whitespace within HTML tags,
including tab, newline and extra space
characters.
Example usage::
{% whitespaceless %}
<p class=" test
test2
test3 ">
<a href="foo/">Foo</a>
</p>
{% endwhitespaceless %}
This example returns this HTML::
<p class="test test2 test3"><a href="foo/">Foo</a></p>
This affects all text within the
`whitespaceless` command without prejudice.
Use with caution.
"""
nodelist = parser.parse(('endwhitespaceless',))
parser.delete_first_token()
return WhitespacelessNode(nodelist)
class WhitespacelessNode(template.Node):
def __init__(self, nodelist):
self.nodelist = nodelist
def render(self, context):
return strip_whitespace(self.nodelist.render(context).strip())
@keep_lazy_text
def strip_whitespace(value):
"""
Return the given HTML with any newlines,
duplicate whitespace, or trailing spaces
are removed .
"""
# Process duplicate whitespace occurrences or
# *any* newline occurrences and reduce to a single space
value = re.sub(r'\s{2,}|[\n]+', ' ', str(value))
# After processing all of the above,
# any trailing spaces should also be removed
# Trailing space examples:
# - <div > Matched by: \s(?=[<>"])
# - < div> Matched by: (?<=[<>])\s
# - <div class="block "> Matched by: \s(?=[<>"])
# - <div class=" block"> Matched by: (?<==\")\s
# - <span> text Matched by: (?<=[<>])\s
# - text </span> Matched by: \s(?=[<>"])
value = re.sub(r'\s(?=[<>"])|(?<==\")\s|(?<=[<>])\s', '', str(value))
return value
- How to store an integer leaded by zeros in django
- Django (1.10) override AdminSite
- Failed: Database access not allowed, use the "django_db" mark, or the "db" or "transactional_db" fixtures to enable it
- Do I need to close connection in mongodb?