问题
I'm trying to be DRY with my Django templates, and have some code that I mix with CSS for a simple hover-over popup. I'd like to reuse the code, but the contents of my popup will be HTML that may well span over multiple lines. Is it possible to stuff multi-line strings into a template variable?
I tried doing something funky with blocks and block.super but that only seems to work when extending (not include)
Here's an example of what I'd like to do. Is it possible?
index.html
<body>
<h2>My Popup</h2>
{% include "snippets/popup.html" with class="p" spantext="Hover me" popupdiv="""
<h2>This is a popup!</h2>
<ul>
<li>Something</li>
<li>Something else</li>
</ul>
"""
%}
</body>
snippets/popup.html
<div class="{{ class }}">
<span class='pointer'>{{ spantext }}</span>
<div class="popup">
{{ popupdiv }}
</div>
</div>
I know it's not possible to have multi-line template tags in Django, but is there any way round this, other than squashing all my div html onto one line, and escaping any quotes?
Cheers
回答1:
It turns out "Parsing until another template tag" is what I was after. http://www.djangobook.com/en/2.0/chapter09.html
Here's my code:
tags.py (in the templatetags folder)
from django import template
from django.template.loader import get_template
from django.template.base import Node, TemplateSyntaxError
register = template.Library()
class PopupNode(Node):
def __init__(self, nodelist, class_name, spantext):
self.nodelist = nodelist
self.class_name = class_name
self.spantext = spantext
def render(self, context):
popup_html = get_template("ordersystem/snippets/popup.html")
context.update({
'class' : self.class_name,
'spantext' : self.spantext,
'popupdiv' : self.nodelist.render(context)
})
return popup_html.render(context)
@register.tag('popup')
def show_popup(parser, token):
nodelist = parser.parse(('endpopup',))
tokens = token.split_contents()
if len(tokens) != 4:
raise TemplateSyntaxError("show_popup is in the format 'popup with class=X spantext=Y")
try:
context_extras = [t.split("=")[1].strip('"') for t in tokens[2:]]
except IndexError:
raise TemplateSyntaxError("show_popup is in the format 'popup with class=X spantext=Y")
parser.delete_first_token()
return PopupNode(nodelist, *context_extras)
Then within my html file I can just do:
{% popup with class_name=management spantext=Manage %}
<h2>This is a popup!</h2>
<ul>
<li>Something</li>
<li>Something else</li>
</ul>
{% endpoup %}
回答2:
The best way should be to create a templatetags in your module with an inclusion tag.
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/
So imagine your are YourModule yourModule with a folder templatetags and the file popup_tag.py
yourModule/
---- views.py
---- models.py
---- templates/
---- snippet/
---- popup.html
---- templatetags/
---- __init__.py
---- popup_tag.py
Your popup_tag.py could look like the following lines :
from django import template
register = template.Library()
def show_pop_up(class, span_text, popupdiv):
return {'class': class,
'span_text': span_text,
'pop_up_div': pop_up_div}
register.inclusion_tag('snippet/popup.html')(show_popup)
Then, you just have to call your tag in your template index.html.
{% load popup_tag %}
{% show_popup "class" "span_text" "popupdiv" %}
来源:https://stackoverflow.com/questions/21808878/multi-line-string-in-django-include-statement