解析自定义模板标签内的Django自定义模板标签
我有一个工作的自定义模板标签。我想让我的Django管理界面用户将该模板标签放在一个flatpage中,并使其正确呈现。但是,当试图访问渲染的flatpage时,我得到一个500服务器错误。调试控制台打印TemplateSyntaxError: Invalid block tag: 'requesturl'
。有没有我不知道的自定义模板标签加载优先级?解析自定义模板标签内的Django自定义模板标签
这里是我的自定义模板标签:
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
我可以放弃这一进我的任何Django模板,定义URL(模板本身),它使用了requests
模块GET的内容指定网页并将其呈现在模板中:
{% extends "site_layout.html" %}
{% load requesturl %}
{% requesturl "http://textfiles.com/100/914bbs.txt" %}
太好了。现在,下一步是,我希望我的用户能够做到这一点在默认的Django通过下面的截图中添加模板标签中flatpages.content
场像flapages应用:
注意,我确保我使用了我的特定页面模板,而不是默认页面。
要评估标签I,请按照this SO answer中的步骤操作。在我尝试评估我自己的自定义模板标签之前,我使用内置的Django模板标签和过滤器进行了测试,并且它的工作方式类似于魅力。以下是双方的一个例子Django的内置模板过滤器(lower
)和标签(now
):
而且它是如何呈现:
然而,当我尝试并输入我自己的自定义模板标签,我得到了可怕的TemplateSyntaxError: Invalid block tag: 'requesturl'
。下面是我的简单页面解析模板标签:
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
我茫然,为什么我可以单独做的这两个部分,但当我尝试,并结合他们,我得到的错误:
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'
我能想到的唯一的事情就是我的自定义模板标签没有被注册到Django中,但是如果它直接嵌入在flatpages模板中,它为什么会起作用呢?是否有某种潜在的模板标签注册表或我的EvaluateNode
类没有做我认为正在做的事情?
在此先感谢!
这在我眼中并不是一个合适的解决方案,但是现在我已经部署了一个解决方法。我结束了使用预先存在的Django Server Side Includes模板标签{% ssi %}
并包括文件系统中的文件。我希望我的用户能够将文件包含在系统之外,但对于我的使用案例,我只能将包含Django安装本地文件包含在内。
有人可能会争辩说,我试图做的事情本来就是不安全的,并且强制我的用户只包含那些Django系统本地的文件更安全。它仍然不能回答我最初的问题,而是关于自定义模板标签注册和使用的问题,而不是实际的实际使用案例。