views:

1397

answers:

3

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 ...

+1  A: 

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...?

Alex Martelli
good catch! I typed everything in ... missed the assignment. Also new to python. Try to get away from PHP, but I find Django's learning curve very very steep. It is a moving target as APIs are constantly changing and being deprecated and phased out.
VN44CA
PHP is not Django. You cannot compare the two. First you learn python. Then you learn Django. Why bring PHP-like mentality into Django web framework?
drozzy
PHP is used to explain the expected behavior. So, I know what I want, I know how it is done in PHP, now trying to find out how I can leave PHP behind and move to PyDj.
VN44CA
+2  A: 

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.

muhuk
VN44CA
I'm not sure if I understand what you mean by `translate`? It is already django-template.
muhuk
just don't know what your line will do and in what order. I tried it and it didn't work.
VN44CA
Oh, it doesn't work unless someone implements it. That is basically the idea for a custom template tag. I didn't give an implementation.
muhuk
+3  A: 

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.

drozzy
things like sort id are outside the object model. So, I guess they have to be passed in. And if I have to pass args here and there, I might just pass it to the filter. all I am trying to do is to do http://foo.com/some-slugy-stuff-ArgsID22Sort2/. This way, every link knows what do load and if you copy and paste and email to friends they can see exactly what you want them to see. Trust me, I know how to do it the Django way. I guess noone knows or bothered to lean how to pass in multiple args to a filter. Thanks for your replay though!
VN44CA
Why use args to complicated tags instead of using named urls?
drozzy