简体   繁体   English

如何解析模板标签的Django模板

[英]How to parse Django templates for template tags

Situation 情况

I'm writing a checker program that checks Django templates. 我正在编写一个检查Django模板的检查器程序。 For example I want to check if all Django templates that use url template tag, use it with quotes on first parameter so that it is Django 1.5 compatible. 例如,我想检查是否所有使用url模板标签的Django模板,在第一个参数上使用引号,以便它与Django 1.5兼容。 Also I want to check that they have included {% load url from future %} in their templates. 另外,我想检查他们的模板中是否包含{% load url from future %}

For example if my program parses the following Django template, I want it to raise an exception. 例如,如果我的程序解析以下Django模板,我希望它引发异常。

{% extends 'base.html' %}
<td>
  <a href="{% url first second %}">
  </a>
</td>

But this template should get parsed without exception. 但是这个模板应该毫无例外地进行解析。

{% extends 'base.html' %}
{% load url from future %}
<td>
  <a href="{% url 'first' second %}">
  </a>
</td>

I'm not limited to this simple example. 我不仅限于这个简单的例子。 I have other parsings to do. 我还有其他解析方法。 For example I want to check how many load template tags are present in the template. 例如,我想检查模板中存在多少个load模板标签。

Question

How can I elegantly solve this parsing problem? 我怎样才能优雅地解决这个解析问题?

  • I don't want to use regular expressions. 我不想使用正则表达式。
  • I this Django it self has some utilities in this regard. 我这个Django它自己在这方面有一些实用工具。 I think using them is a good idea, but I don't know how. 我认为使用它们是一个好主意,但我不知道如何。
  • I want to run the program separately from Django. 我想与Django分开运行程序。 So I don't want Django to run the program itself (with render_to_response ). 所以我不希望Django自己运行程序(使用render_to_response )。 ( This is important ) 这很重要

Code

Please show me some code that can solve the example I mentioned. 请告诉我一些可以解决我提到的例子的代码。 I want to detect whether {% load url from future %} is in the code. 我想检测代码中是否有{% load url from future %} Also I want to check every url template tag and check if the first argument is quoted. 另外,我想检查每个url模板标签,并检查是否引用了第一个参数。

Bonus : 奖金

  • I want to be able to see the rendered HTML that Django generates from this template, and do my HTML parsing on it. 我希望能够看到Django从这个模板生成的渲染HTML,并对其进行HTML解析。 (for example with PyQuery) (例如使用PyQuery)

You say... 你说...

I want to check if all Django templates that use url template tag, use it with quotes on first parameter so that it is Django 1.5 compatible. 我想检查是否所有使用url模板标签的Django模板,在第一个参数上使用引号,以便它与Django 1.5兼容。

...and... ...和...

I don't want to use regular expressions. 我不想使用正则表达式。

...because... ...因为...

the result of that might become a huge spaghetti code 结果可能会成为一个巨大的意大利面条代码

...but, frankly, writing a parser from scratch is likely to be even messier than using a regular expression. ...但是,坦率地说,从头开始编写解析器可能比使用正则表达式更麻烦。 I don't see what's so messy about a regex as simple as something like... 我不认为正则表达式如此简单,就像......

"{% *url +[^']"

...and I doubt there's a non-regex-based solution that's as terse as that. ......我怀疑有一种非正则表达式的解决方案就像那样简洁。

With regards to... 关于......

Also I want to check that they have included {% load url from future %} in their templates. 另外,我想检查他们的模板中是否包含{% load url from future %}

If your intention is to ensure Django 1.5 compatibility, this is pointless. 如果您的目的是确保Django 1.5的兼容性,那么这是毫无意义的。 According to the Django 1.5 release notes , the new-style url tag syntax is enabled by default, so the line {% load url from future %} won't have any effect. 根据Django 1.5发行说明 ,默认情况下启用了新式url标记语法,因此{% load url from future %}不会产生任何影响。

And in versions prior to 1.5, it's much simpler just to put... 在1.5之前的版本中,只需放置......就简单得多了......

import django.template
django.template.add_to_builtins('django.templatetags.future')

...at the bottom of your settings.py and be done with it. ...在settings.py的底部并完成它。 :-) :-)

You can also use the compile_string method. 您还可以使用compile_string方法。

 >>> from django.template.base import *
 >>> settings.configure()
 >>> compile_string("<a href='ab'></a>{% cycle 'row1' 'row2' as rowcolors %}", None)
 >>> [<Text Node: '<a href='ab'></a>'>, <django.template.defaulttags.CycleNode object at 0x10511b210>]

The compile string method is utilized by the Template class and is the method used to produce the node list. 编译字符串方法由Template类使用,并且是用于生成节点列表的方法。 Tested in Django 1.8 Alpha. 在Django 1.8 Alpha中测试过。

https://github.com/django/django/blob/1f8bb95cc2286a882e0f7a4692f77b285d811d11/django/template/base.py https://github.com/django/django/blob/1f8bb95cc2286a882e0f7a4692f77b285d811d11/django/template/base.py

Next code still uses django, but it can check if syntax is correct: 下一个代码仍然使用django,但它可以检查语法是否正确:

>>> from django.template import Template
>>> from django.template.defaulttags import URLNode
>>> t = Template("{% load url from future %}\n{% url projects_list company.slug %}")
>>> for node in t.nodelist:
...     if isinstance(node, URLNode):
...         for arg in node.args: print(arg)
... 
company.slug
>>> t2 = Template('{% load url from future %}\n{% url "projects_list" company.slug }')
>>> for node in t2.nodelist:
...     print(node)
... 
<django.template.defaulttags.LoadNode object at 0x32145d0>
<Text Node: '
{% url "projects_list" c'>
>>> 

As you see last node is not URLNode 如您所见,最后一个节点不是URLNode

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

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