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.
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.
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.
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 %}
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!