简体   繁体   English

在自定义模板标签中解析Django自定义模板标签

[英]Parsing a Django custom template tag within a custom template tag

I have a working custom template tag. 我有一个工作的自定义模板标签。 I want to allow my Django admin interface users to put that template tag in a flatpage and have it render correctly. 我想让我的Django管理界面用户将模板标记放在平面中,并使其正确呈现。 However when trying to access the rendered flatpage I get a 500 server error. 但是,当尝试访问渲染的页面时,出现500服务器错误。 The debug console prints TemplateSyntaxError: Invalid block tag: 'requesturl' . 调试控制台将输出TemplateSyntaxError: Invalid block tag: 'requesturl' Is there some kind of custom template tag loading precedence that I am unaware of? 我没有意识到某种自定义模板标签加载优先级吗?

Here is my custom template tag: 这是我的自定义模板标签:

from django import template
import requests

register = template.Library()

def getrequest(url):
    """
    Simple request object
    to GET another file
    """
    try:
        r = requests.get(url)
    except requests.exceptions.RequestException as e:
        raise IOError(e)
    except requests.exceptions.HTTPError as e:
        raise IOError(e)

    if r.status_code != 200:
        raise IOError('Non 200 response returned')
    else:
        return r.content

@register.tag(name="requesturl")
def do_requesturl(parser, token):
    """
    tag usage {% requesturl object.textfield %}
    """
    try:
        tag_name, uri = token.split_contents();
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires a single URI string argument" % token.contents.split()[0]
    if not (uri[0] == uri[-1] and uri[0] in ('"', "'")):
        raise template.TemplateSyntaxError("%r tag's URI should be in quotes" % tag_name)
    return RequestUrlNode(uri[1:-1])

class RequestUrlNode(template.Node):
    def __init__(self, uri):
        self.uri = uri

    def render(self, context):
        try:
            pagecontent = getrequest(self.uri)
            return pagecontent
        except template.VariableDoesNotExist, template.TemplateSyntaxError:
            return 'Error rendering', self.uri

I can drop this into any of my Django templates, define a URL (in the template itself) and it uses the requests module to GET the content of the specified web page and render it in the template: 我可以将其放入我的任何Django模板中,定义一个URL(在模板本身中),它使用requests模块获取指定网页的内容并将其呈现在模板中:

{% extends "site_layout.html" %}
{% load requesturl %}
{% requesturl "http://textfiles.com/100/914bbs.txt" %}

Great. 大。 Now, the next step is that I want my users to be able to do this in the default Django flapages app by adding the template tag in the flatpages.content field like in the screenshot below: 现在,下一步是,我希望我的用户能够做到这一点在默认的Django通过添加模板标签中flapages应用flatpages.content场像下面的截图:

平面页面输入的屏幕截图

Note that I have ensured I am using my specific flatpages template and not the default. 请注意,我已确保使用的是特定的平面模板而不是默认模板。

To evaluate the tag I followed the steps in this SO answer . 为了评估标签,我遵循了此SO回答中的步骤。 Before I tried to evaluate my own custom template tag I tested with a built-in Django template tag and filter and it worked like a charm. 在尝试评估自己的自定义模板标签之前,我先使用内置的Django模板标签和过滤器进行了测试,它的工作原理很吸引人。 Below is an example of both a Django built-in template filter ( lower ) and tag ( now ): 以下是Django内置模板过滤器( lower )和标记( now )的示例:

向内置内容文本区域添加内置模板标签和过滤器

And how it renders: 以及渲染方式:

呈现的平面模板标签

However, when I try and input my own custom template tag in, I get the dreaded TemplateSyntaxError: Invalid block tag: 'requesturl' . 但是,当我尝试输入自己的自定义模板标签时,却得到了可怕的TemplateSyntaxError: Invalid block tag: 'requesturl' Below is my flatpage parsing template tag: 以下是我的页面解析模板标签:

from django import template

register = template.Library()

@register.tag(name="evaluate")
def do_evaluate(parser, token):
    """
    tag usage {% evaluate object.textfield %}
    """
    try:
        tag_name, variable = token.split_contents()
    except ValueError:
        raise template.TemplateSyntaxError, "%r tag requires a single argument" % token.contents.split()[0]
    return EvaluateNode(variable)

class EvaluateNode(template.Node):
    def __init__(self, variable):
        self.variable = template.Variable(variable)

    def render(self, context):
        try:
            content = self.variable.resolve(context)
            t = template.Template(content)
            return t.render(context)
        except template.VariableDoesNotExist, template.TemplateSyntaxError:
            return 'Error rendering', self.variable

I'm at a loss why I can do both parts of this separately, but when I try and combine them I get the error: 我无所适从为什么我可以分开做这两个部分,但是当我尝试将它们结合在一起时,我得到了错误:

File "/path/to/virtualenv/lib/python2.7/site-packages/django/template/base.py", line 332, in invalid_block_tag
raise self.error(token, "Invalid block tag: '%s'" % command)
TemplateSyntaxError: Invalid block tag: 'requesturl'

The only thing I can think of is that my custom template tag is not getting registered with Django, but then why would it work if it is embedded in the flatpages template directly? 我唯一能想到的是我的自定义模板标签未在Django中注册,但是如果直接将其嵌入到Flatpages模板中,为什么它会起作用? Is there some sort of underlying template tag registry or is my EvaluateNode class not doing what I think it's doing? 是否存在某种基础模板标签注册表,或者我的EvaluateNode类没有按照我的想法做?

Thanks in advance! 提前致谢!

This isn't an adequate solution in my eyes, but it is a workaround that I now have deployed. 在我看来,这不是一个适当的解决方案,但它是我现在已经部署的一种解决方法。 I ended up using the pre-existing Django Server Side Includes template tag {% ssi %} and including files from the file system. 我最终使用了预先存在的Django 服务器端包含模板标签{% ssi %}并包含了文件系统中的文件。 I had wanted my users to be able to include files outside of the system, but for my use case I can live with just including files local to the Django install. 我本来希望用户能够在系统之外包含文件,但是对于我的用例,我可以只包含Django安装本地的文件。

One could argue that what I was trying to do was inherently insecure anyway, and forcing my users to only include those files that are local to the Django system is much safer. 有人可能会说我试图做的是本质上不安全的,并且强迫我的用户只包括Django系统本地的那些文件要安全得多。 It still doesn't answer my original question which is more about custom template tag registration and use than about the actual practical use case. 它仍然无法回答我最初的问题,该问题更多的是关于自定义模板标签的注册和使用,而不是实际的实际用例。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM