Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comma separated lists in django templates

If fruits is the list ['apples', 'oranges', 'pears'],

is there a quick way using django template tags to produce "apples, oranges, and pears"?

I know it's not difficult to do this using a loop and {% if counter.last %} statements, but because I'm going to use this repeatedly I think I'm going to have to learn how to write custom tags filters, and I don't want to reinvent the wheel if it's already been done.

As an extension, my attempts to drop the Oxford Comma (ie return "apples, oranges and pears") are even messier.

like image 797
Alasdair Avatar asked Aug 06 '09 01:08

Alasdair


4 Answers

First choice: use the existing join template tag.

http://docs.djangoproject.com/en/dev/ref/templates/builtins/#join

Here's their example

{{ value|join:" // " }}

Second choice: do it in the view.

fruits_text = ", ".join( fruits )

Provide fruits_text to the template for rendering.

like image 70
S.Lott Avatar answered Oct 16 '22 02:10

S.Lott


Here's a super simple solution. Put this code into comma.html:

{% if not forloop.last %}{% ifequal forloop.revcounter 2 %} and {% else %}, {% endifequal %}{% else %}{% endif %}

And now wherever you'd put the comma, include "comma.html" instead:

{% for cat in cats %}
Kitty {{cat.name}}{% include "comma.html" %}
{% endfor %}

Update: @user3748764 gives us a slightly more compact version, without the deprecated ifequal syntax:

{% if not forloop.first %}{% if forloop.last %} and {% else %}, {% endif %}{% endif %}

Note that it should be used before the element, not after.

like image 75
Michael Matthew Toomim Avatar answered Oct 16 '22 02:10

Michael Matthew Toomim


On the Django template this all you need to do for establishing a comma after each fruit. The comma will stop once its reached the last fruit.

{% if not forloop.last %}, {% endif %}
like image 42
Tommygun Avatar answered Oct 16 '22 02:10

Tommygun


I would suggest a custom django templating filter rather than a custom tag -- filter is handier and simpler (where appropriate, like here). {{ fruits | joinby:", " }} looks like what I'd want to have for the purpose... with a custom joinby filter:

def joinby(value, arg):
    return arg.join(value)

which as you see is simplicity itself!

like image 35
Alex Martelli Avatar answered Oct 16 '22 02:10

Alex Martelli