martin schwartz
martin schwartz

Reputation: 951

Weird Shopify Liquid Forloop Behavior - Page Get's Messed Up When Using A Forloop Within A Tag Forloop

I've created a system for my client to be able to display a product details/specification table on product pages with product tags which works similar to the Supply theme's grouped filter tags eg. a product that has a tag "Brand_Philips" will automatically add a row to the table with the first column being "Brand" and the second "Philips".

I added an input in the theme settings_schema.json so my client should be able to add/remove and reorder the details, and all I have to do now is just loop thru the new setting and check if there is a matching tag and add it to the table, but for some reason when I loop the details within the tags loop everything works fine and when I loop the tags within the details the whole page get's messed up.

Here's my code:

In settings_schema.json:

{
  "name": "Sort Product Details",
  "settings": [
    {
      "type": "text",
      "label": "Type the product detail tags in a comma-separated list.",
      "id": "product_details",
      "info": "List items must be identical to the tag prefixes (no underscore), and have no spaces between commas.ie. Brand,Avarage Lifetime,Watts,Volts"
    }
  ]
}

In the product page I wrote this code:

{% assign marker = '_' %}
{% assign productDetails = settings.product_details | split: ',' %}
{% assign found = false %}
{% for tag in product.tags %}                             <!-- The tags loop -->
  {% for detail in productDetails %}                      <!-- The details loop -->
    {% if tag contains marker and tag contains detail %}  
      {% if found == false %}
        {% assign found = true %}
        <hr>
        <h3>Product Details:</h3>
        <table class="table-striped">
      {% endif %}
      {{ tag | replace: marker, ': </strong></td><td>' | prepend: '<tr><td><strong>' | append: '</td></tr>' }}
      {% if found and forloop.last %}</table>{% endif %}
    {% endif %}
  {% endfor %}
{% endfor %}

Notice that I loop details within the tags loop but when I loop the tags within the details loop my page get's all messed up.

Here's how my page looks normally:

enter image description here

And here's how my page looks when I loop the tags within the details loop:

enter image description here The reason I want it to loop the tags within the details loop is that I want my client to be able to reorder the details - and it should not display in its alphabetical order - the way the tag loop works.

Thanks in advance!

Martin.

Upvotes: 1

Views: 352

Answers (1)

martin schwartz
martin schwartz

Reputation: 951

After asking this question on the Shopify forums I got an answer and would like to share it here.

The reason why it all got messed up is that the closing </table> tag was only added at the end of the loop with this code {% if found and forloop.last %}</table>{% endif %} and when rendering only the tags that are included in the details it never reached the last tag.

So here is my fixed code:

{% assign marker = '_' %}
{% assign productDetails = settings.product_details | split: ',' %}
{% assign found = false %}
{% for detail in productDetails %}
  {% for tag in product.tags %}
    {% if tag contains marker and tag contains detail %}
      {% if found == false %}
        {% assign found = true %}
        <hr>
        <h3>Product Details:</h3>
        <table class="table-striped">
      {% endif %}
      {{ tag | replace: marker, ': </strong></td><td>' | prepend: '<tr><td><strong>' | append: '</td></tr>' }}
    {% endif %}
  {% endfor %}
  {% if found and forloop.last %}</table>{% endif %}
{% endfor %}

Note that the tag loop is in the details loop and the closing </table> tag is added in the end of the details loop.

Upvotes: 2

Related Questions