1

I'm working on a sandboxed CMS so I can't run any pythonic code, other than versions of Jinja.

I am pulling my lists from a database where I split them based on having a field = a certain value.

{# rows = command to pull from db #}

{% set row_one = rows|selectattr('resource','equalto','One') %}
{% set row_two = rows|selectattr('resource','equalto','Two') %}
{# Sets my empty array #}
{% set newobj = [] %}

From here, console logging either Row one/two will result in showing me only those items that apply to their respective resource type.

My problem comes when I try to stuff those two in an array and then iterate over it to alternate the result.

Here is what I tried:

{% for row in rows %}
   {% newObj.update(row_one[loop.index0], row_two[loop.index0] %}
{% endfor %}

This seems to be throwing an error on newObj

Unknown tag 'newobj'

I had it stop throwing the error by using :

{% for row in rows %}
  {% set objs = newObj.update(marketingRows[loop.index0], salesRows[loop.index0], designRows[loop.index0]) %}
{% endfor %}

But this has proved to return nothing when console logging objs.


My desired result

{# example input #}
row_one = ['1', '2', '3', '4']
row_two = ['a', 'b', 'c', 'd']

{# desired output #}
objs =  ['1', 'a', '2', 'b', '3', 'c', '4', 'd']

I'm at a total loss here, any help is appreciated !

Community
  • 1
  • 1
knocked loose
  • 3,142
  • 2
  • 25
  • 46

1 Answers1

1

From personal experience, and since you are not able to run any python code, there is no easy way to accomplish this in jinja. Since jinja does not support zip, and max is not available until v2.10, so we need to improvise.

First, you need to get the longest length of either list.

{%- set row_one = ['1', '2', '3', '4'] -%}
{%- set row_two = ['a', 'b', 'c', 'd'] -%}
{%- set rows_combined = (row_one, row_two) -%}

{%- set lengths = [] %}
{%- for row in rows_combined -%}{%- if lengths.append(row|length)-%}{%- endif -%}{%- endfor -%}
{%- set max_length = (lengths|sort)[-1] -%}

Next, you need to do a nested loop. First iterating through the range of the max length and then rows_combined to grab the correct index of row_one and row_two.

{%- set rows = [] -%}    

{# Loops through a range of max_length #}
{%- for r in range(max_length) -%}
    {# Loops through the tuple containing row_one and row_two #}
    {%- for a in rows_combined -%}
        {# checks if a[r] exists if based on current index, if so appends it rows#}
        {%- if a[r] -%}{%- if rows.append(a[r]) -%}{%- endif -%}{%- endif -%}
    {%- endfor -%}
{%- endfor -%}

{{ rows }}

>>>['1', 'a', '2', 'b', '3', 'c', '4', 'd']

Tests with 3 lists instead of 2

{%- set row_one = ['1', '2', '3', '4'] -%}
{%- set row_two = ['a', 'b', 'c', 'd'] -%}
{%- set row_three = ['w', 'x', 'y', 'z'] -%}
{%- set rows_combined = (row_one, row_two, row_three) -%}

{%- set lengths = [] %}
{%- for row in rows_combined -%}{%- if lengths.append(row|length)-%}{%- endif -%}{%- endfor -%}
{%- set max_length = (lengths|sort)[-1] -%}
{%- set rows = [] -%}

{%- for r in range(max_length) -%}
    {%- for a in rows_combined -%}
        {%- if a[r] -%}{%- if rows.append(a[r]) -%}{%- endif -%}{%- endif -%}
    {%- endfor -%}
{%- endfor -%}
{{ rows }}

>>> ['1', 'a', 'w', '2', 'b', 'x', '3', 'c', 'y', '4', 'd', 'z']
Wondercricket
  • 7,651
  • 2
  • 39
  • 58
  • Wow this is incredibly well thought out! Thank you for this. I'm receiving an error invoking range though, so I'm not sure if it will run in our CMS :/, looking for solutions as we speak. Regardless, this will probably be the accepted answer because if someone isn't constrained by the sandbox, it should work perfectly! – knocked loose Dec 11 '17 at 21:55
  • @ether I'm not familiar with CMS, but `range` is native to jinja2, so I wonder why it's give you errors. When I get the chance, I will see if I can find an alternative to `range` – Wondercricket Dec 11 '17 at 22:02
  • Our docs say it's supported, but yet it keeps giving me the invoke function error , Appreciate your help on this ! – knocked loose Dec 11 '17 at 22:03