creating array from dynamically generated widgets

Key Advisor

I am using a Choice and Loop to allow the person editing to page to choose the number of background images they would like to make available to the page.


{% set bg_num = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] %}
{% choice "bg_num_choice" label="Number of Background Images", value="3", choices="{{ bg_num }}", export_to_template_context=True %}
{% for options in bg_num %}
     {% if loop.index <= widget_data.bg_num_choice.value %}
         {% image_src "bg_img" label="Background Image", unique_in_loop=True, export_to_template_context=True %}
     {% endif %}
{% endfor %}


As you can see, based on the number chosen this will enable that many Image src modules on the page.

The issue that I am having is that I now need to choose one of these at random (each time the page loads) and assign it to the div:


<div class="home_body_wrapper" style="background: url({{ Assign Here }});"> </div>


To do this I know that I need to collect the src values of the modules that are created into an array, then use the random filter to print the value where I need it. 

The problem is that I have to create the array dynamically. I cannot set the array values static because I would either have empty values or have to change the array based on how many images are used. 

How can I dynamically add these modules' values to an array?

1 Reply 1
Key Advisor

I gave up on trying to assign the dynamically created widgets to an array. Instead I decided to use the image slider widget which is more graceful in my opinion. 


So I create the slider widget, assign some images in the page editor for a test page using my template, the proceded to figure out how to get a random image from the slider to act as the background image each time to page loads. 


The funny thing is that in the HubL docs, there is a filter you can apply to for loops that is supposed to choose one random item from the sequence.

{# from docs #}
{% for content in contents|random %}
<div class="post-item">Post item markup</div>
{% endfor %}

This would have been perfect, except it doesn't work. I applied a few different filters to my loop which did what they were supposed to but were not useful in my case, however the random filter would not deliver any output... I haven't tested it with any other loops but it definetly does not work with image sliders. I checked the jinja2 docs and its correct there as well so I'm not sure what the issue is. 


I had to get a little created. I used the shuffle filter:

{# from docs #}
{% for content in contents|shuffle %}
<div class="post-item">Markup of each post</div>
{% endfor %}

This Randomizes the sequence... but it outputs the whole sequence. I only need one img src to output other wise it will break my inline styling. To fix this I nested an if statement within the loop to limit the output. Here's my code:

{% image_slider "background_images" label="Background Images", export_to_template_context=True %}

<div class="home_body_wrapper" style="background: url({% for slide in widget_data.background_images.slides|shuffle %} {% if loop.index <= 1 %}{{ slide.img_src }} {% endif %} {% endfor %}) center top no-repeat; background-size: cover;">

now when the page loads a random image's url from the sequence of images in the slider module is output in the background styling. 


I would have liked it if the random filter worked. I'm going to keep playing with it. This is the best possible options from where I'm sitting. Would love to get some input from other developers.