I'm trying to add divs to product descriptions in Shopify so that I can then create an accordion. Currently my code looks like this
In the .liquid file:
<div class="product-single__description rte">
{{ product.description }}
</div>
This is the output:
<div class="product-single__description rte">
<h2>TEXT</h2>
<h4>TEXT</h4>
<p><em>Text</em></p>
<h4>TEXT</h4>
<p>Text</p>
<h2>TEXT</h2>
<h4>Text</h4>
<p>Text</p>
<h4>TEXT</h4>
<p>Text</p>
<h4>TEXT</h4>
<p>Text</p>
<p><em>Text</em></p>
</div>
My goal is to insert a div wrapper and enclose the content from H2 to the next h2, so for example:
<div class="product-single__description rte">
<div class=“class_1”
<h2>TEXT</h2>
<h4>TEXT</h4>
<p ><em>Text</em></p>
<h4>TEXT</h4>
<p>Text</p>
</div>
<div class=“class_2”
<h2>TEXT</h2>
<h4>Text</h4>
<p>Text</p>
<h4>TEXT</h4>
<p >Text</p>
<h4>TEXT</h4>
<p>Text</p>
<p><em>Text</em></p>
</div>
</div>
The number of H2s and the content changes from product to product.
Well there are a few checks that you need to make before you do this.
First we will set a variable for the content:
{% assign content = product.description %}
After that we will check if the if there is a plain <h2>
in there
{% if content contains '<h2>' %}
// logic to add here
{% else %}
{{content}}
{% endif %}
(have in mind that if your h2 tags have any inline styles you will have to target <h2
instead)
If there is we will continue the logic inside the if
, but if there is not we will output the plain content in the else
statement.
So we are now in the // logic to add here
part here.
We will split the content by <h2>
like so:
{% assign content_arr = content | split: '<h2>' %}
We will check if you have some content before the first <h2>
since we don't want to loose it in that case, so we check it like so:
{% if content_arr[0] != '' %}
{{content_arr[0]}}
{% endif %}
We need to loop the rest of the items of the array.
Since we are splitting by <h2>
if there is no content before the <h2>
it will return an empty array for the first item and we don't need that one. So we will offset the for loop by 1 item:
{% for item in content_arr offset: 1 %}
// items here
{% endfor %}
Now we need to return the opening <h2>
tag (since we removed it from the content) and show the rest of the content.
It's easy as writing <h2>
before the {{item}}
:
<div class="class_{{forloop.index}}">
<h2>{{item}}
</div>
And that's all.
Here is the full code:
{% assign content = product.description %}
{% if content contains '<h2>' %}
{% assign content_arr = content | split: '<h2>' %}
{% if content_arr[0] != '' %}
{{content_arr[0]}}
{% endif %}
{% for item in content_arr offset: 1 %}
<div class="class_{{forloop.index}}">
<h2>{{item}}
</div>
{% endfor %}
{% else %}
{{content}}
{% endif %}