I have a template filter based on the django docs at https://docs.djangoproject.com/en/1.8/howto/custom-template-tags/. For the life of me I can't see any difference in my usage and theirs, and am slowly going insane. I have a working tag I got on a forum as such:
myproject/index/templatetags/add_get_parameter.py:
from django.template import Library, Node, resolve_variable
register = Library()
class AddGetParameter(Node):
def __init__(self, values):
self.values = values
def render(self, context):
req = resolve_variable('request', context)
params = req.GET.copy()
for key, value in self.values.items():
params[key] = value.resolve(context)
return '?%s' % params.urlencode()
@register.tag
def add_get(parser, token):
pairs = token.split_contents()[1:]
values = {}
for pair in pairs:
s = pair.split('=', 1)
values[s[0]] = parser.compile_filter(s[1])
return AddGetParameter(values)
This one, add_get
on lines 8-9, works, whereas shorten_title
on line 4 doesn't work:
myproject/templates/index/silo.html:
{% load bootstrap add_get_parameter extras %}
...other stuff...
{% for article in articles %}
<div class="col-md-4 article-link">
<div class="panel panel-default hover">
<div class="panel-heading"><h4 class="url-link">{{ article.title|shorten_title }}</h4></div>
<div class="panel-body">
<p> <span class="url-text">{{ article.url }}</span></p>
<a href="{% url 'index:edit-article' article.id %}"><div class="article_button">Edit</div></a>
<a href="{% add_get archive=article.id %}"><div class="article_button"><p>Archive</p></div></a>
<a href="{% add_get delete=article.id %}"><div class="article_button">Delete</div></a>
<div style="margin-top:8px;">
{% for tag in article.tags.all %}
<p class="tag">{{ tag.name }}</p>
{% endfor %}
</div>
</div>
</div>
</div>
{% endfor %}
Here's the villian:
from django.template import Library
register = Library()
@register.filter
def shorten_title(title):
length = len(title)
new = title
if length > 65:
new = title[0:65] + "..."
return new
register.filter('shorten_title', shorten_title)
He's been so rude I double registered him, just to see what happens (he doesn't work registered once as a decorator or afterward, and doesn't work registered twice).
{{ article.title }}
works, but {{ article.title|shorten_title }}
breaks the page with:
django.template.base.TemplateSyntaxError
TemplateSyntaxError: Invalid filter: 'shorten_title'
'Index' is definitely registered and working, and the page works when I delete the filter from that article.title tag.
Usually when I get a stubborn error I missed something small, but following the docs word for word has me baffled (I've written several working filters before). Is this filter bad, or is there maybe something else in my page that causes the issue? Thanks
You need to make sure you import the file with register.filter('shorten_title', shorten_title)
before you render the template. Since that call happens outside of any functions it is run when you import the module. This has the side effect of registering it so that it will be available in your templates afterwards.