Tutorials

Table of contents
Close

How to create a repeater with HubL

This article uses an experimental technique that is being deprecated and is not currently supported.

While templates generally have a fixed number of editable modules or flexible areas that let you add modules at the page level, you can also use HubL to create a repeater section. This type of section allows users can determine how many how many predefined modules to print. This is useful for simple repeatable sections that can be controlled by the user, where a full blog listing might be too complex.

This tutorial goes through coding a choice module that allows the user to choose how many images with captions to print on a page. This implementation uses custom variables, a for loop, an if statement, export_to_template_context, and unique_in_loop.

This tutorial is designed for use in a locked HTML module, HubL template module, or coded template. To implement in a custom module, you will need to modify the code, as shown here.

Define a sequence of options

To begin, we are going to define a set of options that we will not only uses as the basis of our choice module's choices, but also as the sequence that we iterate through. In this example, we want the user to be able to print between 1 to 10 sets of modules on the page. You can learn more about variable syntax, here.


{% set my_options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] %}    

Create a choice field that uses those options

Next, create a choice module. Within the choices parameter, print the my_options variable. Please note that variables are interpolated in some module parameters, but not within module names. Additionally, add the export_to_template_context=True parameter

{% set my_options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] %}
{% choice "repeats" label="Number of modules to print", value="1", choices="{{ my_options }}", export_to_template_context=True %}

Create a loop that iterates through options

After declaring the choice module, set up a for loop that loops through the my_options sequence.


{% set my_options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] %}
{% choice "repeats" label="Number of modules to print", value="1", choices="{{ my_options }}", export_to_template_context=True %}
{% for options in my_options %}

{% endfor %}

Limit loop with if statement

Add an if statement, nested within the for loop, that limits the number of times the loop will iterate to the value specifed by the choice module. You can retrieve the choice module's value with widget_data.repeats.value.


{% set my_options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] %}
{% choice "repeats" label="Number of modules to print", value="1", choices="{{ my_options }}", export_to_template_context=True %}
{% for options in my_options %}
    {% if loop.index <= widget_data.repeats.value %}
        
    {% endif %}
{% endfor %}

Print module with unique_in_loop=True parameter

Finally, we can declare the modules that we want to print with each iteration of the loop. In order for each module to be unique, we need to add the parameter unique_in_loop=True. This parameter appends the module name with the current loop iteration number, ensuring that it is unique. This example prints a linked_image module and a text module with each iteration. You could add additional modules or markup to suit your needs.


{% set my_options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] %}
{% choice "repeats" label="Number of modules to print", value="1", choices="{{ my_options }}", export_to_template_context=True %}
{% for options in my_options %}
    {% if loop.index <= widget_data.repeats.value %}
                {% linked_image "repeated_image" label="Repeated image", alt="Photo of Brian Halligan", src="//cdn2.hubspot.net/hub/53/file-733888619-jpg/assets/hubspot.com/about/management/brian-home.jpg", unique_in_loop=True %}
                {% text "repeated_caption" label="Repeated caption", value="Insert caption here", unique_in_loop=True %}
    {% endif %}
{% endfor %}

Create content from template

Finally, we are ready to publish our template and create a page. The choice module will be available in the Edit Modules section of the content editor. Changing the value of the module will dynamically update how many modules render on the page. Once you choose the number of modules and you refresh the editor, you can edit each module's content independently.

repeater.gif
Please note that after updating the number of modules to render on a page in the editor, you will need to refresh the editor before these new modules will become editable.

Use in custom modules

This tutorial is designed to work at the template level rather than within a custom module. You can make the technique work within a custom module using a choice field; however, there is no way to make it automatically take the values defined in the my_options sequence. Additionally, you will have to edit the values of the modules printed using the Edit Modules pane, rather than directly on the content editor.

The example below shows code that would be used in a custom module with a choice field called "repeats". You would need to manually  update the values in that choice module to be 1-10, using the UI.


{% set my_options = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] %}

{% for options in my_options %}
    {% if loop.index <= widget.repeats %}
                {% linked_image "repeated_image" label="Repeated image", alt="Photo of Brian Halligan", src="//cdn2.hubspot.net/hub/53/file-733888619-jpg/assets/hubspot.com/about/management/brian-home.jpg", unique_in_loop=True %}
                {% text "repeated_caption" label="Repeated caption", value="Insert caption here", unique_in_loop=True %}
    {% endif %}
{% endfor %}