Reputation: 1957
I'm writing a checker program that checks Django templates. 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. Also I want to check that they have included {% load url from future %}
in their templates.
For example if my program parses the following Django template, I want it to raise an exception.
{% 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.
How can I elegantly solve this parsing problem?
render_to_response
). (This is important)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. Also I want to check every url
template tag and check if the first argument is quoted.
Bonus:
Upvotes: 9
Views: 4079
Reputation: 1180
You can also use the compile_string
method.
>>> 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.
Tested in Django 1.8 Alpha.
Upvotes: 4
Reputation: 4392
Next code still uses django, but it can check if syntax is correct:
>>> 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
Upvotes: 3
Reputation: 41950
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.
...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.
If your intention is to ensure Django 1.5 compatibility, this is pointless. 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.
And in versions prior to 1.5, it's much simpler just to put...
import django.template
django.template.add_to_builtins('django.templatetags.future')
...at the bottom of your settings.py
and be done with it. :-)
Upvotes: 9