Multi line string in Django 'include' statement

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-10 15:17:12

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!