Odpowiedzi:
Używać z:
{% with "shop/"|add:shop_name|add:"/base.html" as template %}
{% include template %}
{% endwith %}
shop_name
, więc jest niebezpieczne.
shop_name
przed przekazaniem go do kontekstu w widoku, get_context_data
upewnij się, że jest tłumaczony przy użyciu ugettext
zamiast ugettext_lazy
.
Nie używaj add
ciągów znaków, powinieneś zdefiniować niestandardowy tag, taki jak ten:
Utwórz plik: <appname>\templatetags\<appname>_extras.py
from django import template
register = template.Library()
@register.filter
def addstr(arg1, arg2):
"""concatenate arg1 & arg2"""
return str(arg1) + str(arg2)
a następnie użyj go, jak mówi @Steven
{% load <appname>_extras %}
{% with "shop/"|addstr:shop_name|addstr:"/base.html" as template %}
{% include template %}
{% endwith %}
Powód unikania add
:
Według dokumentów
Ten filtr najpierw spróbuje wymusić obie wartości na liczbach całkowitych ... Ciągi, które można wymusić na liczbach całkowitych, zostaną zsumowane, a nie połączone ...
Gdyby obie zmienne były liczbami całkowitymi, wynik byłby nieoczekiwany.
add
” po prostu nie używa str()
na pierwszym miejscu i nie działała w ogóle dla mnie, podczas gdy twoje rozwiązanie działa bezbłędnie
{% load <appname>_extras %}
Zobacz Łączenie ciągów w szablonach Django :
W przypadku wcześniejszych wersji Django:
{{ "Mary had a little"|stringformat:"s lamb." }}
"Mary miała małe jagnię."
Jeszcze:
{{ "Mary had a little"|add:" lamb." }}
"Mary miała małe jagnię."
Spójrz na add
filtr .
Edycja: możesz łączyć filtry, więc możesz to zrobić "shop/"|add:shop_name|add:"/base.html"
. Ale to nie zadziała, ponieważ ocena szablonu w argumentach zależy od tagu szablonu, a rozszerzenie nie.
Myślę, że nie możesz tego zrobić w szablonach.
Z dokumentów:
Tego znacznika można użyć na dwa sposoby:
{% extends "base.html" %}
(z cudzysłowami) używa wartości literału „base.html” jako nazwy szablonu nadrzędnego, który ma zostać rozszerzony.{% extends variable %}
używa wartości zmiennej. Jeśli zmienna ma wartość ciągu, Django użyje tego ciągu jako nazwy szablonu nadrzędnego. Jeśli zmienna zostanie przekształcona w obiekt szablonu, Django użyje tego obiektu jako szablonu nadrzędnego.Wygląda na to, że nie możesz użyć filtra do manipulowania argumentem. W widoku wywołującym musisz utworzyć instancję szablonu przodka lub utworzyć zmienną łańcuchową z poprawną ścieżką i przekazać ją z kontekstem.
Odpowiedź @ error jest zasadniczo poprawna, powinieneś do tego użyć tagu szablonu. Jednak wolę nieco bardziej ogólny tag szablonu, którego mogę używać do wykonywania wszelkiego rodzaju operacji podobnych do tego:
from django import template
register = template.Library()
@register.tag(name='captureas')
def do_captureas(parser, token):
"""
Capture content for re-use throughout a template.
particularly handy for use within social meta fields
that are virtually identical.
"""
try:
tag_name, args = token.contents.split(None, 1)
except ValueError:
raise template.TemplateSyntaxError("'captureas' node requires a variable name.")
nodelist = parser.parse(('endcaptureas',))
parser.delete_first_token()
return CaptureasNode(nodelist, args)
class CaptureasNode(template.Node):
def __init__(self, nodelist, varname):
self.nodelist = nodelist
self.varname = varname
def render(self, context):
output = self.nodelist.render(context)
context[self.varname] = output
return ''
a następnie możesz użyć go w ten sposób w swoim szablonie:
{% captureas template %}shop/{{ shop_name }}/base.html{% endcaptureas %}
{% include template %}
Jak wspomniano w komentarzu, ten znacznik szablonu jest szczególnie użyteczny w przypadku informacji, które są powtarzalne w szablonie, ale wymagają logiki i innych rzeczy, które rozgromią twoje szablony lub w przypadkach, w których chcesz ponownie wykorzystać dane przekazywane między szablonami przez bloki:
{% captureas meta_title %}{% spaceless %}{% block meta_title %}
{% if self.title %}{{ self.title }}{% endif %}
{% endblock %}{% endspaceless %} - DEFAULT WEBSITE NAME
{% endcaptureas %}
i wtedy:
<title>{{ meta_title }}</title>
<meta property="og:title" content="{{ meta_title }}" />
<meta itemprop="name" content="{{ meta_title }}">
<meta name="twitter:title" content="{{ meta_title }}">
Kredyt na tag captureas należy się tutaj: https://www.djangosnippets.org/snippets/545/
Praca z {% with %}
tagiem była dość kłopotliwa. Zamiast tego utworzyłem następujący znacznik szablonu, który powinien działać na ciągach i liczbach całkowitych.
from django import template
register = template.Library()
@register.filter
def concat_string(value_1, value_2):
return str(value_1) + str(value_2)
Następnie załaduj tag szablonu do szablonu u góry, korzystając z następujących czynności:
{% load concat_string %}
Następnie możesz użyć go w następujący sposób:
<a href="{{ SOME_DETAIL_URL|concat_string:object.pk }}" target="_blank">123</a>
Osobiście uważam, że jest o wiele czystszy w pracy.
W szablonach django nie można manipulować zmiennymi. Masz dwie opcje: albo napisz własny tag szablonu, albo zrób to w widoku,
extends
nie ma na to możliwości. Umieść całą ścieżkę szablonu w zmiennej kontekstowej i użyj jej, lub skopiuj istniejący znacznik szablonu i odpowiednio go zmodyfikuj.
I wiele konkatenacji:
from django import template
register = template.Library()
@register.simple_tag
def concat_all(*args):
"""concatenate all args"""
return ''.join(map(str, args))
I w szablonie:
{% concat_all 'x' 'y' another_var as string_result %}
concatenated string: {{ string_result }}