Setting properties to use in a loop

SOLVE
Anthony_Noel
Member

Hello,

 

I want to define the width of a table that will contain 1-3 columns, defined by a repeater.

 

I could use loop.length to get the number of items in the loop, but I don’t want to repeat the whole table, just the nested table within it.

 

Is there a method for finding the number of items in a loop without first creating the loop?

 

What I’ve tried: creating a loop outside of the containing table and just using it to set the width variables, then closing the loop, with my actual loop for buiding the columns nested inside that table. 

 

I’ve since learned that I can’t call variables created within a loop, outside of that loop.

 

Here’s my code (some code from the link selector has been removed for simplicity):

 

 

<!-- COLUMNS -->
{% for item in module.image_block_repeater %}{% if loop.length == 3 %}{% set layoutWidth = "100%" %}{% set boxWidth = "33%" %}
{% elif loop.length == 2 %}{% set layoutWidth = "66%" %}{% set boxWidth = "48%" %}
{% else %}{% set layoutWidth = "33%" %}{% set boxWidth = "100%" %}
{% endif %}
{% endfor %}
<table class="imgRow" border="0" cellpadding="0" cellspacing="0" width="{{ layoutWidth }}" role="presentation">
<tr>   <td class="center">
       <center>
       {% for item in module.image_block_repeater %}
       <!-- COLUMN -->
       <table border="0" cellpadding="0" cellspacing="0" width="{{ boxWidth }}" align="left" role="presentation">
       <tr>    <td class="center" style="text-align: center;">
               <img src="{{ item.image.src }}" alt="{{ item.image.alt }}" width="170" height="170" class="portraitThumb">
               <p class="caption">{{ item.caption }}</p>
               <p><a href="{{ href }}">{{ item.link_text }}</a></p>
       </td>   </tr>
       </table>
       {% endfor %}
       </center>
</td>  </tr>
</table>

 

 

0 Upvotes
1 Accepted solution

Accepted Solutions
piersg
Solution
Key Advisor

Hi @Anthony_Noel, you could do one of two things.

 

One: separate the logic of layoutWidth and boxWidth like so:

 

<table class="imgRow" border="0" cellpadding="0" cellspacing="0" width="{% for item in module.image_block_repeater %}{% if loop.length == 3 %}100%{% elif loop.length == 2 %}66%{% else %}33%{% endif %}{% endfor %}" role="presentation">
<tr>   <td class="center">
       <center>
       {% for item in module.image_block_repeater %}
       <!-- COLUMN -->
       <table border="0" cellpadding="0" cellspacing="0" width="{% if loop.length == 3 %}33%{% elif loop.length == 2 %}48%{% else %}100%{% endif %}" align="left" role="presentation">
       <tr>    <td class="center" style="text-align: center;">
               <img src="{{ item.image.src }}" alt="{{ item.image.alt }}" width="170" height="170" class="portraitThumb">
               <p class="caption">{{ item.caption }}</p>
               <p><a href="{{ href }}">{{ item.link_text }}</a></p>
       </td>   </tr>
       </table>
       {% endfor %}
       </center>
</td>  </tr>
</table>

 

 

 

Or update an object variable that is outside your for loop with values defined within said loop:

 

{% set widths = {} %}
{% for item in module.image_block_repeater %}
  {% if loop.length == 3 %}{% do widths.update({'layoutWidth': '100%', 'boxWidth': '33%'}) %}
  {% elif loop.length == 2 %}{% do widths.update({'layoutWidth': '66%', 'boxWidth': '48%'}) %}
  {% else %}{% do widths.update({'layoutWidth': '33%', 'boxWidth': '100%'}) %}
  {% endif %}
{% endfor %}
<table class="imgRow" border="0" cellpadding="0" cellspacing="0" width="{{ widths.layoutWidth }}" role="presentation">
<tr>   <td class="center">
       <center>
       {% for item in module.image_block_repeater %}
       <!-- COLUMN -->
       <table border="0" cellpadding="0" cellspacing="0" width="{{ widths.boxWidth }}" align="left" role="presentation">
       <tr>    <td class="center" style="text-align: center;">
               <img src="{{ item.image.src }}" alt="{{ item.image.alt }}" width="170" height="170" class="portraitThumb">
               <p class="caption">{{ item.caption }}</p>
               <p><a href="{{ href }}">{{ item.link_text }}</a></p>
       </td>   </tr>
       </table>
       {% endfor %}
       </center>
</td>  </tr>
</table>

 

View solution in original post

6 Replies 6
natsumimori
Community Manager

Hi @Anthony_Noel ,

 

I will tag in some top contributors in the Developers' Forum- @Jsum and @tjoyce , would you mind taking a look?

0 Upvotes
piersg
Solution
Key Advisor

Hi @Anthony_Noel, you could do one of two things.

 

One: separate the logic of layoutWidth and boxWidth like so:

 

<table class="imgRow" border="0" cellpadding="0" cellspacing="0" width="{% for item in module.image_block_repeater %}{% if loop.length == 3 %}100%{% elif loop.length == 2 %}66%{% else %}33%{% endif %}{% endfor %}" role="presentation">
<tr>   <td class="center">
       <center>
       {% for item in module.image_block_repeater %}
       <!-- COLUMN -->
       <table border="0" cellpadding="0" cellspacing="0" width="{% if loop.length == 3 %}33%{% elif loop.length == 2 %}48%{% else %}100%{% endif %}" align="left" role="presentation">
       <tr>    <td class="center" style="text-align: center;">
               <img src="{{ item.image.src }}" alt="{{ item.image.alt }}" width="170" height="170" class="portraitThumb">
               <p class="caption">{{ item.caption }}</p>
               <p><a href="{{ href }}">{{ item.link_text }}</a></p>
       </td>   </tr>
       </table>
       {% endfor %}
       </center>
</td>  </tr>
</table>

 

 

 

Or update an object variable that is outside your for loop with values defined within said loop:

 

{% set widths = {} %}
{% for item in module.image_block_repeater %}
  {% if loop.length == 3 %}{% do widths.update({'layoutWidth': '100%', 'boxWidth': '33%'}) %}
  {% elif loop.length == 2 %}{% do widths.update({'layoutWidth': '66%', 'boxWidth': '48%'}) %}
  {% else %}{% do widths.update({'layoutWidth': '33%', 'boxWidth': '100%'}) %}
  {% endif %}
{% endfor %}
<table class="imgRow" border="0" cellpadding="0" cellspacing="0" width="{{ widths.layoutWidth }}" role="presentation">
<tr>   <td class="center">
       <center>
       {% for item in module.image_block_repeater %}
       <!-- COLUMN -->
       <table border="0" cellpadding="0" cellspacing="0" width="{{ widths.boxWidth }}" align="left" role="presentation">
       <tr>    <td class="center" style="text-align: center;">
               <img src="{{ item.image.src }}" alt="{{ item.image.alt }}" width="170" height="170" class="portraitThumb">
               <p class="caption">{{ item.caption }}</p>
               <p><a href="{{ href }}">{{ item.link_text }}</a></p>
       </td>   </tr>
       </table>
       {% endfor %}
       </center>
</td>  </tr>
</table>

 

View solution in original post

tjoyce
Recognized Expert | Platinum Partner

@Anthony_Noel  - I wrote a tutorial on updating variables outside of a for loop here 

https://community.hubspot.com/t5/CMS-Development/How-to-change-a-variable-outside-of-a-for-loop-Scop...

 

 

 

natsumimori
Community Manager

Thank you @piersg and @tjoyce !

@Anthony_Noel please check out their advices!

AnthonyNoel
Participant

Thank you all! 

 

Both options look doable, but is the second more useful if I my templates have several of these repeater blocks? ie, I can define the object once and reuse it more easily?

 

0 Upvotes
piersg
Key Advisor

Yes, you can define once and re-use.