2014-11-21 217 views
1

我有一个工作的自定义模板标签。我想让我的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应用:

screenshot of flat page entry

注意,我确保我使用了我的特定页面模板,而不是默认页面。

要评估标签I,请按照this SO answer中的步骤操作。在我尝试评估我自己的自定义模板标签之前,我使用内置的Django模板标签和过滤器进行了测试,并且它的工作方式类似于魅力。以下是双方的一个例子Django的内置模板过滤器(lower)和标签(now):

Adding built-in template tags and filters to the flatpages content textarea

而且它是如何呈现:

The flatpage template tags rendered

然而,当我尝试并输入我自己的自定义模板标签,我得到了可怕的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类没有做我认为正在做的事情?

在此先感谢!

回答

0

这在我眼中并不是一个合适的解决方案,但是现在我已经部署了一个解决方法。我结束了使用预先存在的Django Server Side Includes模板标签{% ssi %}并包括文件系统中的文件。我希望我的用户能够将文件包含在系统之外,但对于我的使用案例,我只能将包含Django安装本地文件包含在内。

有人可能会争辩说,我试图做的事情本来就是不安全的,并且强制我的用户只包含那些Django系统本地的文件更安全。它仍然不能回答我最初的问题,而是关于自定义模板标签注册和使用的问题,而不是实际的实际使用案例。