I want to write a custom url templatetag, that would also work with relative paths (and not only named patterns) and accepts list in arguments (which are later used to call a different view function - that's why I need the request object). This is my tag in template :
{% with '/views' (normally it's a var created in for loop) as link %}
<a href="{% url_for link params=('website','homepage') %}">Click</a>
{% endwith %}
and tag's code itself :
@register.simple_tag(takes_context = True)
def url_for(context, parser, token):
request = context['request']
bits = token.split_contents()
if len(bits) < 2:
raise TemplateSyntaxError("'%s' takes at least one argument"
" (path to a view)" % bits[0])
try:
if "/" in bits[1]:
bits[1] = unicodedata.normalize('NFKD', bits[1]).encode('utf-8', 'ignore')
try:
bits[1] = resolve(bits[1].replace("'","")).url_name
except Exception as e:
log.error('Exception when resolving url for tag: %s' % e)
viewname = bits[1]
except Exception as exc:
raise
args = []
kwargs = {}
asvar = None
bits = bits[2:]
if len(bits):
for bit in bits:
if 'params' in bit:
par = ast.literal_eval(bit.split('=')[1])
my_function(request, par[0], par[1])
break
from django.core.urlresolvers import reverse, NoReverseMatch
url = ''
try:
url = reverse(viewname, args=args, kwargs=kwargs, current_app=context.current_app)
except NoReverseMatch:
exc_info = sys.exc_info()
if settings.SETTINGS_MODULE:
project_name = settings.SETTINGS_MODULE.split('.')[0]
try:
url = reverse(project_name + '.' + view_name,
args=args, kwargs=kwargs,
current_app=context.current_app)
except NoReverseMatch:
six.reraise(*exc_info)
else:
raise
return url
Unfortunately right now the only thing I was able to achieve is TemplateSyntaxError at /: Could not parse the remainder: '('website','homepage')' from '('website','homepage')'
. Before that I was trying to monkeypatch the original url tag and URLNode but I had a bunch of different problems there. Any help with tackling this appreciated.
Template files are not Python. Thus, you can't do the tuple thing with your arguments. Instead, refactor the template tag to take this type of syntax:
{% url_for link params='website homepage' %}
Then you have to account for that when parsing the bits
variable in the template tag. It ultimately comes down to parsing strings.
https://docs.djangoproject.com/en/dev/howto/custom-template-tags/#writing-the-compilation-function
See the notes for "token.contents" and "token.split_contents()".
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.