Rudi Sherry
Rudi Sherry

Reputation: 123

Django tag to return an array in block tag

I have an array of string items I want to show in an HTML table and it seems like the simplest way in the template is the 'messages' form. I call them 'activities':

{% if activities %}
  <table class="activities">
    <tr>
     {% for activity in activities %}
       <td>{{ activity }}</td>
     {% endfor %}
    </tr>
  </table>
{% endif %}

I thought activities could be a simple tag that returns an array but I see from other stackoverflow answers (linked below) that this is for returning strings to be put in the template, not for returning values.

I don't need context or any parameters to this array, but it may appear in different formats on different pages so I don't want the tag to return the "innerHTML" of the table.

How do I do that? I tried the following in an extras file (and to verify it was being called I deliberately put syntax errors into it and sure enough they triggered when I went to this page, so I removed them):

from django import template

register = template.Library()

@register.simple_tag
def activities():
  return ("A", "B")
activities = register.simple_tag(activities)

I also tried with just the decorator, and with just the call to 'register' (both with and without the setting of the return value), and none worked. The table was always empty.

There are a lot of related questions on stackoverflow but each one seems tailor-made to a slightly different case and the closest, using inclusion_tag, seems rather over-engineered for this simple case.

Upvotes: 2

Views: 648

Answers (1)

Zbigniew Siciarz
Zbigniew Siciarz

Reputation: 91

If you're on Django >= 1.4, there is a simple way to create assignment tags. These store their return value in a template variable specified after as keyword. In your case, that would be:

{% get_activities as activities %}
{% if activities %}
  <table class="activities">
    <tr>
     {% for activity in activities %}
       <td>{{ activity }}</td>
     {% endfor %}
    </tr>
  </table>
{% endif %}

The code behind this tag is very simple. All that really matters is the assignment_tag decorator.

from django import template

register = template.Library()

@register.assignment_tag
def get_activities():
    return ("A", "B")

With Django versions older than 1.4 this is still doable, but requires more boilerplate code to create compilation function and a node class. In fact Django documentation describes this approach right before assignment_tag.

Upvotes: 2

Related Questions