我有一个有效的自定义模板标记。我想允许我的Django管理界面用户将该模板标签放在平面页面中并使其正确呈现。但是,当尝试访问渲染的平面页面时,我收到500服务器错误。调试控制台打印TemplateSyntaxError: Invalid block tag: 'requesturl'
。是否有某种自定义模板标记加载优先级,我不知道?
这是我的自定义模板标记:
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
模块获取指定网页的内容并在模板中呈现它: / p>
{% extends "site_layout.html" %}
{% load requesturl %}
{% requesturl "http://textfiles.com/100/914bbs.txt" %}
大。现在,下一步是我希望我的用户能够在默认的Django襟翼应用中通过在flatpages.content
字段中添加模板标记来执行此操作,如下面的屏幕截图所示:
请注意,我确保使用的是我的特定flatpages模板,而不是默认模板。
要评估标记,我按照this SO answer中的步骤操作。在我尝试评估自己的自定义模板标签之前,我使用内置的Django模板标签和过滤器进行测试,它就像一个魅力。以下是Django内置模板过滤器(lower
)和标记(now
)的示例:
它是如何呈现的:
然而,当我尝试输入我自己的自定义模板标签时,我得到了可怕的TemplateSyntaxError: Invalid block tag: 'requesturl'
。下面是我的flatpage解析模板标记:
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
类没有做我认为它正在做的事情?
提前致谢!
答案 0 :(得分:0)
这不是我眼中的适当解决方案,但这是我现在部署的解决方法。我最终使用预先存在的Django Server Side Includes模板标记{% ssi %}
并包含文件系统中的文件。我希望我的用户能够在系统之外包含文件,但对于我的用例,我可以只使用包含Django安装本地文件。
有人可能会争辩说,我试图做的事情本质上是不安全的,并且强迫我的用户只包含那些Django系统本地的文件更安全。它仍然没有回答我原来的问题,这个问题更多地是关于自定义模板标签的注册和使用,而不是实际的实际用例。