Brighty
Brighty

Reputation: 393

How to cycle across 2 forloops within a django template

I have a django template where I need to cycle through a set of background colours across two different for loops. The cycle tag seems to be designed to be used either within one for loop or outside a for loop altogether. This is my code:

{% if global_adverts %}
        <span style="display:none">{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolors %}</span>
        {% for advert in global_adverts %}
            <div class="{% cycle adcolors %}">
                {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                    <p>{{ advert.text }}</p>
                {% if advert.url %}</a>{% endif %}
            </div>
        {% endfor %}
    {% endif %}
    {% with self.adverts.all as adverts %}
        {% if adverts %}
            {% for advert in adverts %}
                <div class="{% cycle adcolors %}">
                    {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                        <p>{{ advert.text }}</p>
                    {% if advert.url %}</a>{% endif %}
                </div>
            {% endfor %}
        {% endif %}
    {% endwith %}

Is there a way to do this without outputting the first item in the cycle before the first loop and having to hide it with css?

Upvotes: 2

Views: 772

Answers (3)

Loonie
Loonie

Reputation: 376

I feel that having the first {% cycle %} declaration outside of the loops is cleaner, I wouldn't have expected a declaration inside of conditional loops to work, and here's how to make it work:

{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolour silent %}

{% if global_adverts %}
    {% for advert in global_adverts %}
        <div class="{{ adcolours }}">
            {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                <p>{{ advert.text }}</p>
            {% if advert.url %}</a>{% endif %}
        </div>
        {% cycle adcolours %}
    {% endfor %}
{% endif %}
{% with self.adverts.all as adverts %}
    {% if adverts %}
        {% for advert in adverts %}
            <div class="{{ adcolours }}">
                {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                    <p>{{ advert.text }}</p>
                {% if advert.url %}</a>{% endif %}
            </div>
            {% cycle adcolour %}
        {% endfor %}
    {% endif %}
{% endwith %}

Since {% cycle adcolour %} is silent, we use {{ adcolour }} to print the current colour. We still need to use the silent {% cycle adcolour %} to step through the colours on each iteration.

Upvotes: 0

Brighty
Brighty

Reputation: 393

I have discovered that the following code gives the desired result:

{% if global_adverts %}
        {% for advert in global_adverts %}
            <div class="{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolours %}">
                {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                    <p>{{ advert.text }}</p>
                {% if advert.url %}</a>{% endif %}
            </div>
        {% endfor %}
    {% endif %}
    {% with self.adverts.all as adverts %}
        {% if adverts %}
            {% for advert in adverts %}
                <div class="{% cycle adcolours %}">
                    {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                        <p>{{ advert.text }}</p>
                    {% if advert.url %}</a>{% endif %}
                </div>
            {% endfor %}
        {% endif %}
    {% endwith %}

Upvotes: 1

YardenST
YardenST

Reputation: 5256

Just add silent

{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' as adcolors silent %}

It prevents the tag from outputting the value

EDIT AFTER COMMENT

If you need the cycle to continue for each loop just use cycle twice and change the order of the items in the second cycle:

{% if global_adverts %}
        {% for advert in global_adverts %}
            <div class="{% cycle 'advert-grey' 'advert-pale-blue' 'advert-green' 'advert-blue' %}">
                {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                    <p>{{ advert.text }}</p>
                {% if advert.url %}</a>{% endif %}
            </div>
        {% endfor %}
    {% endif %}
    {% with self.adverts.all as adverts %}
        {% if adverts %}
            {% for advert in adverts %}
                <div class="{% cycle 'advert-pale-blue' 'advert-green' 'advert-blue' 'advert-grey' %}">
                    {% if advert.url %}<a href="{{ advert.url }}">{% endif %}
                        <p>{{ advert.text }}</p>
                    {% if advert.url %}</a>{% endif %}
                </div>
            {% endfor %}
        {% endif %}
    {% endwith %}

Upvotes: 1

Related Questions