Reputation: 18387
I have a few values that I would like to pass into a filter and get a URL out of it.
In my template I have:
{% if names %}
{% for name in names %}
<a href='{{name|slugify|add_args:"custid=name.id, sortid=2"}}'>{{name}}</a>
{%if not forloop.last %} | {% endif %}
{% endfor %}
{% endif %}
In my templatetags I have:
@register.filter
def add_args(value, args):
argz = value.strip() + '-' + 'ARGS'
arglist = args.split(',')
for arg in arglist:
keyval = arg.split('=')
argz.join(keyval[0] + 'ZZ' + keyval[1])
argz.join('QQ')
return argz
The output URL should look like:
http://foo.org/john-smith-ARGScustidZZ11QQsortidZZ2
Where ARGS is the start of the arguments, ZZ is '=' and QQ is an '&' equivalent.
First of all: This would work, but I get the custid=name.id coming in the add_args(), where I want to have custid=11 to come in. How pass in the id as an id and not text.
Also, is there a way to just send in an array of key=>value like in PHP. In PHP I would build an array, let say:
arglist = array('custid' => $nameid, 'sortid' => $sortid );
Then I would pass the arglist as an argument to add_args()
and in add_args()
I would do
foreach( arglist as $key => $value)
$argstr .= $key . 'ZZ' . $value . 'QQ'.
Does anyone have a better way of making this work?
Note: if I have to pass all arguments as a string and split them up in the filter I don't mind. I just don't know how to pass the name.id as its value ...
Upvotes: 2
Views: 7185
Reputation: 61121
This "smart" stuff logic should not be in the template. Build your end-of-urls in your view and then pass them to template:
def the_view(request):
url_stuff = "custid=%s, sortid, ...." % (name.id, 2 ...)
return render_to_response('template.html',
{'url_stuff':url_stuff,},
context_instance = RequestContext(request))
In template.html:
....
<a href='{{url_stuff}}'>{{name}}</a>
....
If you need a url for a whole bunch of objects consider using get_absolute_url on the model.
Upvotes: 6
Reputation: 16095
You can't pass name.id
to your filter. Filter arguments can be asingle value or a single literal. Python/Django doesn't attempt any "smart" variable replacement like PHP.
I suggest you to create a tag for this task:
<a href='{% add_args "custid" name.id "sortid" "2" %}{{name|slugify}}{% end_add_args %}'>{{name}}</a>
This way you can know which argument is a literal value and which should be taken fron context etc... Docs are quite clear about this, take a look at the example.
Also if this name
is any way related to a model, say we want to get to the permalink, adding a method that returns the URL with the proper arguments might be the tidiest solution.
Overall, I would refrain putting too much logic into templates. Django is not PHP.
Upvotes: 4
Reputation: 882611
You're calling argz.join
a couple times and never assigning the results to anything: maybe you're operating under the misconception that the join
method of a string has some mysterious side effect, but it doesn't -- it just returns a new string, and if you don't do anything with that new string, poof, it's gone. Is that at least part of your problem...?
Upvotes: 3