Incrementing a variable within a loop

1,040 views
Skip to first unread message

Brad Grant

unread,
Jun 26, 2014, 10:44:19 AM6/26/14
to nunj...@googlegroups.com
Hi all.  I'm trying to do some simple math in my template to increment a variable for knowing when to start a new column.  It does appear a variable can be incremented.
However, the code below does not appear to work:

        {%- set rows = 25 -%}
        {%- set rows = (rows+1) -%} {# this works; rows will be 26 #}
        {%- set maxRows = 25 -%}
        {% for item in thingList %}
            <!-- the line below always prints 26 -->
            <div>{{ rows }} </div>
            {% if rows == maxRows %}
                <div>max: would start new column here</div>
                {%- set rows = 0 -%}
            {% endif %}
            <div>{{ item }}</div>
            {%- set rows = (rows+1) -%} {# this appears to be a different variable as it is always 0 then 1 #}
            <!-- the line below always prints 1 2 -->
            <div>{{ row.activity }} {{ rows }} {{ rows+1 }}</div>
        {% endfor %}

So my question is why?  Am I doing something wrong with the scope, or is this feature not possible with nunjucks?
Thanks!

Andrew Hayward

unread,
Jun 26, 2014, 11:31:31 AM6/26/14
to nunj...@googlegroups.com
> So my question is why? Am I doing something wrong with the scope, or is this feature not possible with nunjucks?
> Thanks!

Funnily enough, I ran into a similar problem just yesterday. The solution I came up with was to use ranges and cyclers instead, to do something vaguely like the following [^1]...

```
{% set max_rows = 25 %}
{% set row_indexer = cycler(*range(max_rows)) %}

{% for item in thingList %}
{% set current_row_index = row_indexer.next() %}

{# You can either check if the current_row_index is 0,
which would be the start of a column... %}

{% if current_row_index == 0 %}
{# Do something at start of column #}
{% endif %}

{# ... or you can check if the current_row_index is the
last one available instead. #}

{% if current_row_index = (max_rows - 1) %}
{# Do something at end of column #}
{% endif %}
{% endfor %}
```

Hope that proves useful,

- Andrew


[1] Taken from my head - no guarantee it's functional code :)


-----
Andrew Hayward
Mozilla Foundation
London, UK

and...@mozillafoundation.org
IRC/Twitter/Skype - arhayward

http://andrewhayward.net

Brad Grant

unread,
Jun 26, 2014, 12:28:37 PM6/26/14
to nunj...@googlegroups.com
Thanks, Andrew!  That is a good idea and seems like it should work, however, it still does not.  The range does not seem to play nice within cycler.

If I use cycler on its own with a manual list [ cycler(0,1,2,3,4,5) ], it is ok.  The range returns the list of numbers fine.  But when I combine them, cycler.next() returns:  0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24.

I did notice you had an * before range which returned a parse error, so I removed it.

It does still appear as if scope is tricky in these templates.  If I put the call to cycler.next() further down in the loop and reassign its value to a variable initially set outside the loop, it creates a new variable instead of updating the initial one.

Here is an example of what I am describing:

{% set myvar = 10 %}
{% set rowIndexer = cycler(0,1,2,3,4,5,6,7,8,9,10) %}  {# NOTE: cycer(range(10)) does not work as next() will return entire list each time! #}


{% for item in thingList %}
    <div>{{ myvar }} will print 10 always here!</div>

    {%- set myvar = rowIndexer.next() %-}
    <div>{{ myvar }} will print the next value in the cycler list here!</div>
{% endfor %}

And a snippet of the output looks like:

    <div>10 will print 10 always here!</div>
    <div>0 will print the next value in the cycler list here!</div>
    <div>10 will print 10 always here!</div>
    <div>1 will print the next value in the cycler list here!</div>
    <div>10 will print 10 always here!</div>
    <div>2 will print the next value in the cycler list here!</div>
    <div>10 will print 10 always here!</div>
    <div>3 will print the next value in the cycler list here!</div>
Reply all
Reply to author
Forward
0 new messages