2015-11-02 25 views
10

Mam pętlę w szablonie jak tenprzerwy Wyjąć linii z Django szablonu

{% spaceless %} 
{% for lang_code, lang_name in LANGUAGES %} 
    <link hreflang={{ lang_code }} href="http://example.com/ 
    {% if lang_code|length > 2 %} 
     {{ some_path }} 
    {% else %} 
     {{ other_path }} 
    {% endif %} 
    "> 
{% endfor %} 
{% endspaceless %} 

która produkuje coś jak ten

<link hreflang="en-gb" href="http://example.com/ 
    some_path/ 
    "><link hreflang="de" ...> 

Czy to możliwe, aby ponownie napisać ten kod tak, że cała tag jest zapisany w jednym wierszu, tak jak?

<link hreflang="en-gb" href="http://example.com/some_path/"> 
<link hreflang="de" href="http://example.com/other_path/"> 
... 

P.S. Można to osiągnąć, jeśli klauzula if/else zostanie rozciągnięta na jedną linię, ale linia stanie się nieczytelna.

Odpowiedz

4

Znacznik spaceless usuwa spacje między znacznikami html, nie można go pobrać, aby usunąć spacje z tagów, co próbujesz zrobić.

Możesz zapobiec nowym wierszom, umieszczając klauzulę if/else w jednym wierszu, ale jak to się mówi, to sprawia, że ​​trudno jest je odczytać. Sugeruje to, że próbujesz wykonać zbyt wiele pracy w szablonach Django i że adresy URL powinny być zbudowane gdzie indziej.

Najprostszą opcją jest skonstruowanie listy znaczników (language_code, url) w widoku i przeglądanie ich w szablonie.

{% for lang_code, url in language_urls %} 
    <link hreflang={{ lang_code }} href="{{ url }}"> 
{% endfor %} 

Jeśli nie jest to wygodne, aby to zrobić w widoku jeszcze kilka opcji są:

  • procesor kontekst szablon (dobrze, jeśli korzystają z tych samych adresów URL w każdy widok
  • niestandardowy tag/filtr szablonu (dobry, jeśli są dynamiczne some_path i other_path)
+0

Pomyślałem: "oczywiście, django ma coś na pewno", ale nie, musisz zbudować własny niestandardowy filtr lub zrobić jak Alasdair pokazuje – doniyor

+0

@Alasdair, tak myślałem. Chyba będę musiał napisać templatetag, aby skonstruować mój URL i zachować szablon w czystości. Dzięki, przyjmuję twoją odpowiedź! – abudis

6

Potrzebowałem To samo, ponieważ używam szablonu do wygenerowania tematu wiadomości e-mail (nie HTML, więc {% spaceless %} jest bezużyteczny). W moim przypadku szablon przybrał wiele różnych przypadków, a wszystko musiało być napisane w jednym wierszu na około 500 znaków.

Więc w mentalności części {% spaceless %}, napisałem mój własny {% 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()) 

Należy pamiętać, że (celowo!) Zachowuje wszystkie whitespace wyjątkiem podziały wiersza.

Przykładem użycia do szablonu e-mail będzie wyglądać tak, zakładając, że powyższe jest załadowany moduł szablon o nazwie 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 %} 

Zauważ, że znacznik {% linebreakless %} musi być na pierwszej linii (i po dyrektywach {% load %}), aby zapobiec łamaniu linii w wygenerowanym pliku.

+0

Jeśli to zabrzmi niepotrzebnie skomplikowane dla przykładu użycia, który nakreśliłem, i myślisz, że można to rozwiązać za pomocą prostego 're.sub (r '\ s * \ n \ s *', '', render_subject_template). strip() 'po renderowaniu szablonu, masz absolutną rację. Tak właśnie zrobiłem i upuściłem tag szablonu, ale wciąż myślałem, że może to być przydatne dla kogoś, kto umieści go tutaj. –

+0

Skończyłem na pisaniu niestandardowego znacznika szablonu i przeniosłem całą logikę tam, ale lubię również twoje rozwiązanie. Dzięki! – abudis