Nested Sections!

JAS_Technology
Shopify Expert
84 0 52

Hi fellow Shopify geeks. So I set out to build a way to have a configurable sidebar section, with blocks, defined WITHIN a collection section. That doesn't work right? But wait, maybe it can. Curious about people's thoughts on this technique. I've simplified the code a bunch to demonstrate what I'm doing but the idea is that the main section has a token in its content (e.g. "%%SIDEBAR-1%%"), which then gets replaced with the full content of another section. Here is my code of /templates/collection.liquid

{% capture sidebar_content_1 %}{% section 'sidebar-1' %}{% endcapture %}
{% capture sidebar_content_2 %}{% section 'sidebar-2' %}{% endcapture %}

{% capture collection_template_content %}
    {% section 'collection' %}
{% endcapture %}

{% assign collection_template_content = collection_template_content | replace: "%%SIDEBAR-1%%", sidebar_content_1 %}
{% assign collection_template_content = collection_template_content | replace: "%%SIDEBAR-2%%", sidebar_content_2 %}

{{collection_template_content}}

The front end of the site loads perfectly and the theme editor loads with the ability to configure both sections with their own set of settings and blocks. Magic! 

The only issue I'm seeing is that the theme editor "thinks" there is an HTML syntax error somehwere even though I validated the HTML and all is good. I'm pushing forward with this but I would love to hear thoughts and see if somebody can think about why the theme editor has this error. I'm thinking it's eyes are just crossed.... 

Happy to hear about your crazy ideas.
Replies 32 (32)
JAS_Technology
Shopify Expert
84 0 52

Ok. Found a way around this! Added this code after nested sections captures:

{% assign sidebar_content1 = sidebar_content1 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}
{% assign sidebar_content2 = sidebar_content2 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}

 

Happy to hear about your crazy ideas.
Codeblade
New Member
1 0 0

@JAS_Technology wrote:

The only issue I'm seeing is that the theme editor "thinks" there is an HTML syntax error somehwere even though I validated the HTML and all is good. I'm pushing forward with this but I would love to hear thoughts and see if somebody can think about why the theme editor has this error. I'm thinking it's eyes are just crossed.... 


 

 

I found a solution to this issue.

 

It looks like Shopify Editor creates a wrapper div for sections like this:

<div id="shopify-section" class="shopify-section" data-theme-editor-section="{&quot;id&quot;:&quot;section&quot;,&quot;type&quot;:&quot;section&quot;,&quot;disabled&quot;:false}"></div>

data-theme-editor-section - throws an error on the backend for nested sections. So to resolve this I simply modified the code like this:

 

{% assign sidebar_content1 = sidebar_content1 | replace: 'data-theme-editor-section="{"id":"sidebar_content1","type":"sidebar_content1","disabled":false}"', '' %}

To find the correct string for data-theme-editor-section, right-click view source on the customization page, and you'll find the attribute added within the HTML. I hope this helps someone out.

tim
Shopify Expert
3078 180 1124

Nice trick Jonathan!

From the point of view of the theme Customizer they are not nested, but rather one after another, but it's a clever idea to "inject" the rendered result of one section into another.

Now with 
 
Mehul_Tech
Shopify Partner
1 0 0

HI Jonathan

Please give me also the Json of schema of sections

khedaywi
Shopify Partner
32 0 0

Nice workaround! 

RustyDev
Shopify Partner
12 0 4
{% assign sidebar_content_1 = sidebar_content_1 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}

Just a heads up, the corrected code above is missing a "_" : sidebar_content_1

MaxDesign
Shopify Expert
145 4 51

This is gold! Thank you for taking the time to share, 2 years later it's still useful!

I wonder if there is any cons doing this, else this could be in the documentation, this is a must-have feature and can be very handy in a few situations.

In my case I built a FAQ section and needed to insert it inside (not after) a contact page section. With some liquid and javascript workarounds I can tweak the layout and make my FAQ section look the way I want it inside the contact page.

I had a few trials before making this work, here's my code if some people are looking for more examples (inside "page.contact.liquid" template):

{% capture faq-page %}{% section 'faq-tabs' %}{% endcapture %}
{% assign faq-page = faq-page | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}

{% capture contact-us-content %}
    {% section 'contact-us' %}
{% endcapture %}

{% assign contact-us-content = contact-us-content | replace: "%%faq-tabs%%", faq-page %}

{{ contact-us-content }}

And then I included :

 

%%faq-tabs%%

 inside my "contact-us.liquid" section file.

It was already well explained but it's always better with more examples.
Cheers 🙂

 

Reach out to me at admin@maxdesign.expert
asad16
New Member
3 0 0
but i am still getting this error!
 
Liquid error (line 2): Cannot render sections inside sections
 
{% capture video_1 %}
{% section 'video' %}
{% endcapture %}
{% assign vid = video_1 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}
 
MaxDesign
Shopify Expert
145 4 51

@asad16 Some information is lacking in your code.

Say you have a section "random-section", and you want to insert inside it a section named "video".
In your case, you should go for something like this (beware, this code goes inside a template file, not inside a section file😞 

 

{% capture video_1 %}{% section 'video' %}{% endcapture %}
{% assign vid = video_1 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}
{% capture random_section %}{% section 'random-section' %}{% endcapture %} {% assign random_section = random_section | replace: "%%insert-video-section%%", vid %}
{{
random_section }}

And then you include inside your "random-section" :

 

%%insert-video-section%%

 
Hope it makes sense,
Cheers

Reach out to me at admin@maxdesign.expert
asad16
New Member
3 0 0

Thanks Buddy! it was really helpful!

asad16
New Member
3 0 0

@MaxDesign 


@MaxDesign wrote:

@asad16 Some information is lacking in your code.

Say you have a section "random-section", and you want to insert inside it a section named "video".
In your case, you should go for something like this (beware, this code goes inside a template file, not inside a section file😞 

 

{% capture video_1 %}{% section 'video' %}{% endcapture %}
{% assign vid = video_1 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}
{% capture random_section %}{% section 'random-section' %}{% endcapture %} {% assign random_section = random_section | replace: "%%insert-video-section%%", vid %}
{{
random_section }}

And then you include inside your "random-section" :

 

%%insert-video-section%%

 
Hope it makes sense,
Cheers



but can you explain (how to/where to) add  %%insert-video-section%%

in my randon section

MaxDesign
Shopify Expert
145 4 51

but can you explain (how to/where to) add  %%insert-video-section%%

in my randon section

Just paste

%%insert-video-section%%

where you want the section to be, it's up to you where you need the section to appear in your other section. I presume you have knowledge in html/css, (and eventually liquid) if you want to do this by your way with little issues, else you might need to reach out to someone with more expertise.

I can't explain better here, maybe someone else would.
Best of luck,
Max 

Reach out to me at admin@maxdesign.expert
Leysam
Shopify Partner
37 2 33

Brilliant idea. I tried this using blocks.  I've been finding a solution for a nested block for years but no luck, until I read about this yesterday.

 

The Idea is the same as what is posted here... but instead of adding the text

%%section-replacer%%

 

directly to the section file I added it using blocks and condition. This way you can sort the position of the nested section in the page

 

{% for block in section.blocks %}
    {% case block.type %}
        {% when 'your-gallery' %}
            <!-- hack that shit-->
            %%YOUR-GALLERY%%

        {% else %}
            Normal blocks code....
    {% endcase %}
 {% endfor %}

 

Here are the results in admin 😉

 

We add the nested section using blockWe add the nested section using block

 

This way we can sort the position of the nested section along with the blocks. 

 

for-post2.png

 

 

 

 

Leysam | The Shopify Guy  

 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - Email me at edwardwindtalker@gmail.com or add me on Skype: samypogs
MaxDesign
Shopify Expert
145 4 51

Hi everyone,

My question is a bit more advanced. How would you use this "hack" on the home page? I need to do this with a section that can only be loaded through presets, so it's a dynamic section that is not fetched from a template file, it is only in a section file.

I'm thinking about it and I don't see a clear (nor clean) way trough.

Thank you hips,
Max

Reach out to me at admin@maxdesign.expert
csmits
Tourist
11 0 3

Hi, I'm using this technique to use a section in other sections/pages.
I'm wondering if anyone has a solution to the following issue:

When I {% capture %} the section I want to nest into another, the section doesn't appear in the theme customizer so its settings cannot be adjusted.
So I have to call the to-be-nested section with the {% section 'to-be-nested-section' %} tag.

This causes the section to render on the page, even when you hide it with css by wrapping the {% section %} with a <div style="display:none"></div> tag, ofcourse.

Depending on the size of the to-be-nested-section, this could be a problem. The to-be-nested-section is rendered at least twice on the page. Is there any way to prevent the first call to {% section %} to actually rendering the liquid in it, except the {% schema %} tag of course?

Hopefully someone understands my problem and can help me!

mextest_Admin
Shopify Partner
4 0 0

Any way to add a parameter?

We would like to design a way to display a product, with its image, title, price etc. This would be our ideal code (to be inserted in pages, blog articles etc):

%%product%sku1%%

%%product%sku2%%

Is it doable? 

MaxDesign
Shopify Expert
145 4 51

@mextest_Admin you can add parameters in snippets, but you can't do that with sections to start with, so let's forget about nested sections. Then depending on your use case, your section could reference some snippets and you can list some variables (say section settings) as parameters on the render tag.

Reach out to me at admin@maxdesign.expert
g33kgirl
Shopify Partner
331 96 118

How would we add this code to a .json template file? 

If you found my answer helpful, please LIKE and ACCEPT.
buymeacoffee.com/g33kgirl
If you're not comfortable with code, please modify code files at your own risk.
MaxDesign
Shopify Expert
145 4 51

@g33kgirl I tried to think of some ways to achieve that but I don't think it's possible, unless someone comes with a clever idea, you'll have to sticky to .liquid template files to nest sections

Reach out to me at admin@maxdesign.expert
partdev
Shopify Partner
6 1 4

I solved it by creating a new section, pasted the code of the section that I wanted to include and in the new section I entered the parameters that I wanted to pass.
In my case I created a new section called landingpage and I wanted to put the product-recommendations section in the landingpage section, here are all the steps:
1- I created a new product-recommendations-2 section
2- I pasted the content of product-recommendations into product-recommendations-2
3- In product-recommendations-2 I entered the parameters I wanted to pass, in my case productid with value 663093294020,
therefore instead of
"productId": {{product.id | json}},
I replaced with
"productId": 663093294020,
4- Finally in the landing page template I inserted the following code

{% section 'landingpage'%}

{% capture landingpage_1%} {% section 'landingpage'%} {% endcapture%}
{% assign landpage = landingpage_1 | replace: 'class = "shopify-section"', 'class = "shopify-section-nested"'%}

{% capture product_recommendations%} {% section 'product-recommendations-2'%} {% endcapture%}
{% assign product_recommendations = product_recommendations | replace: "%% insert-product-recommendations %%", landpage%}

{{product_recommendations}}

I hope I have been helpful.

MaxDesign
Shopify Expert
145 4 51

@partdev wrote:

I solved it by creating a new section, pasted the code of the section that I wanted to include and in the new section I entered the parameters that I wanted to pass.
In my case I created a new section called landingpage and I wanted to put the product-recommendations section in the landingpage section, here are all the steps:
1- I created a new product-recommendations-2 section
2- I pasted the content of product-recommendations into product-recommendations-2
3- In product-recommendations-2 I entered the parameters I wanted to pass, in my case productid with value 663093294020,
therefore instead of
"productId": {{product.id | json}},
I replaced with
"productId": 663093294020,
4- Finally in the landing page template I inserted the following code


Online store 2.0 templates are in json formatting. For instance your main product page template would be "product.json" and you can't write liquid in those pages. What did you try to achieve here? If you can write liquid in your landing page template, then you are using the legacy liquid template which fortunately still supports the nested section trick, but do not benefit Online store 2.0 features. 

Reach out to me at admin@maxdesign.expert
partdev
Shopify Partner
6 1 4

In my case I solved the problem of passing a parameter and I explained how to do. I am not using a 2.0 template.

lspoor
Shopify Partner
6 1 1

Just following up here. I'm finding that encapsulating a section within capture tags, prevents the section from then showing up in the Theme Customiser, which means you cannot then add any blocks to this section. I'm trying to use this within the product.liquid template. Anybody experienced this?

 

 

{% capture badges %}
  {% section 'pdp-badges' %}
{% endcapture %}

 

 

lspoor
Shopify Partner
6 1 1

I'm just following up on this issue.

 

I have some data which is a string, I'm passing it into a section with the following method:

{%- liquid
assign myData = 'data],[data],[data'

capture header
section 'header
endcapture

assign header = header | replace: '%%DATA%%', myData
-%}

 

Then within 'sections/header.liquid' I have the following

{% capture replaced_data %}
%%DATA%%
{% endcapture %}

{%- liquid
    assign data = replaced_data | split: '],['

    echo data[0]
-%}

Now based off that, you'd expect the first `data` to be printed out, but infact the following is printed out

data],[data],[data

 

For some reason I'm no longer able to do any manipulation with this data once its in the 'sections/header.liquid' file. I've even tried doing a replace on the `],[` but it just doesn't take effect.

 

Anybody experienced similar?

igar
New Member
2 0 0

First of all thank very much for this information, it was very necessary

How can I do it with 3 section? 

For example, I have this code that I use your code and I have the section "newsletter" inside of section "list-collection-template": 

{% capture section3 %}{% section 'newsletter' %}{% endcapture %}
{% assign sect = section3 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}

{% capture collection3 %}{% section 'list-collection-template' %}{% endcapture %}
{% assign collection3 = collection3 | replace: "%%insert-newsletter-section%%", sect2 %}

{{ collection3 }}

In template of list-collection-template I call --> %%insert-newsletter-section%%

Until here all right but when I want to add this "double section" in other section for example, I want add inside of the section "collection-template", the section "list-collection-template" but I cant, we will have a error. 

 

{% capture section2 %}{% section 'list-collections-template' %}{% endcapture %}
{% assign sect = section2 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}

{% capture collection2 %}{% section 'collection-template' %}{% endcapture %}
{% assign collection2 = collection2 | replace: "%%insert-list-collections-template-section%%", sect %}

{{ collection2 }}


Any answer for this problem??

Thanks, 

Igar.

 

MaxDesign
Shopify Expert
145 4 51

Hi @igar 

There is a mistake in your first code because "sect2" refers to nothing.

Your second code seems fine. Juste make sure you have this code in the template file that calls {% section 'collection-template' %}. So you have to replace {% section 'collection-template' %} with your last piece of code, and inside {% section 'collection-template' %}, you insert "%%insert-list-collections-template-section%%" (without  quotation).

Also with the newer editor we got last month, you may have to do this in order to avoid the html error message :

{% assign sect = section2 | replace: 'data-shopify-editor-section', '' %}

instead of :

{% assign sect = section2 | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}

but I'm not sure if there are consequences removing this attribute. I have not experienced any issue personnally. 

Reach out to me at admin@maxdesign.expert
igar
New Member
2 0 0

This is how I tried and it shows the Newsletter in the section "list-collections-template".
Captura.PNG

But not in the second call in section "collection-template"

Captura.PNG

milosdjoric
New Member
1 0 0

Hi, did you found out what is problem in second example?

chiragramjibhai
Shopify Partner
12 0 1

This is really helpful.

Using this concept I was able to change the sequence of sections from the customiser.

sections/a.liquid file (and two more for b.liquid and c.liquid)

 

<div >

	Section A
  
</div>



{% schema %}
  {
    "name": "Section A",
    "settings": [

	]
  }
{% endschema %}

{% stylesheet %}
{% endstylesheet %}

{% javascript %}
{% endjavascript %}

 

 

sections/seq.liquid file

 

<div class="page-width">
  
{% if section.settings.id_a == "1"%}%%a%%{% endif %}
{% if section.settings.id_b == "1"%}%%b%%{% endif %}
{% if section.settings.id_c == "1"%}%%c%%{% endif %}

{% if section.settings.id_a == "2"%}%%a%%{% endif %}
{% if section.settings.id_b == "2"%}%%b%%{% endif %}
{% if section.settings.id_c == "2"%}%%c%%{% endif %}

{% if section.settings.id_a == "3"%}%%a%%{% endif %}
{% if section.settings.id_b == "3"%}%%b%%{% endif %}
{% if section.settings.id_c == "3"%}%%c%%{% endif %}

</div>
{% schema %}
  {
    "name": "Section Main",
    "settings": [
	{
         "type": "select",
         "id": "id_a",
         "label": "Order A",
         "options": [
           {
             "group": "value",
             "value": "1",
             "label": "1"
           },
           {
             "group": "value",
             "value": "2",
             "label": "2"
           },
           {
             "group": "value",
             "value": "3",
             "label": "3"
           }
         ],
         "default": "1",
         "info": "text"
      },
{
         "type": "select",
         "id": "id_b",
         "label": "Order B",
         "options": [
           {
             "group": "value",
             "value": "1",
             "label": "1"
           },
           {
             "group": "value",
             "value": "2",
             "label": "2"
           },
           {
             "group": "value",
             "value": "3",
             "label": "3"
           }
         ],
         "default": "1",
         "info": "text"
      },
{
         "type": "select",
         "id": "id_c",
         "label": "Order C",
         "options": [
           {
             "group": "value",
             "value": "1",
             "label": "1"
           },
           {
             "group": "value",
             "value": "2",
             "label": "2"
           },
           {
             "group": "value",
             "value": "3",
             "label": "3"
           }
         ],
         "default": "1",
         "info": "text"
      }
	]
  }
{% endschema %}

{% stylesheet %}
{% endstylesheet %}

{% javascript %}
{% endjavascript %}

 

 

 

template/page.sequence.liquid file

 

{%capture one%}{% section 'a' %}{%endcapture%}


{%capture two%}{% section 'b' %}{%endcapture%}


{%capture three%}{% section 'c' %}{%endcapture%}

{% capture collection_template_content %}
    {% section 'seq' %}
{% endcapture %}

{% assign one = one | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}
{% assign two = two | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}
{% assign three = three | replace: 'class="shopify-section"', 'class="shopify-section-nested"' %}



{% assign collection_template_content = collection_template_content | replace: "%%a%%", one %}
{% assign collection_template_content = collection_template_content | replace: "%%b%%", two %}
{% assign collection_template_content = collection_template_content | replace: "%%c%%", three %}




{{collection_template_content}}

 

 

 

But still not able to get rid of the html error in the customiser.........Screenshot 2021-06-01 at 10.20.03 PM.png

made4Uo
Shopify Partner
3366 634 960

This is already answerer by Max_design. Check on his previous replies

We are volunteering to help    |      Likes and Accept as Solution  will be much appreciated.✌
Having trouble?  Hire us! For fast reply, shoot us a message using chat at Made4Uo.com

Check how to sell everywhere with Shopify POS. Keep your stuffs private. Refrain from giving unnecessary access to your store.
MaxDesign
Shopify Expert
145 4 51

After a few hours of relentless trials & errors, I found a way to nest sections with both json and liquid templates (including home page). It works seamlessly but it's still unsupported, it's more tricky to set up, and the editor experience for nested sections looks less future proof for json templates (e.g. breaking change in the way the editor generate sections). So considering this, here's how I did it:

 

1) Modify {{ content_for_layout }} in theme.liquid

 

{%- comment -%}
This code alters {{ content_for_layout }} to enable section nesting.
If you nest your section on a json template, assign the template(s) name(s) in {{ myNested-section-json-templates }}.
Insert <myNested-section></myNested-section> in the main section (where you want the nested section).
For simplicity, replace myNested-section of this code snippet with your-nested-section-name.
{%- endcomment -%}     
          
{%- assign myNested-section-json-templates = 'product, blog, ...' -%} 
{%- capture myNested-section %}{% section 'myNested-section' -%}{%- endcapture -%}
{%- assign myNested-section = myNested-section | replace: 'data-shopify-editor-section=', 'data-section-nested data-shopify-editor-section-nested=' | replace: 'class="shopify-section"', 'class="shopify-section-nested"' -%}
          
{%- if request.design_mode -%}
    {%- if myNested-section-json-templates contains request.page_type -%}<div id="shopify-section-myNested-section"></div>{%- endif -%}
{%- endif -%}
        
{{- content_for_layout | replace: '<myNested-section></myNested-section>', myNested-section -}}   

 

 

2) Add script in the nested section (required for a decent design experience in shopify editor with json templates)

 

{%- if request.design_mode -%}
<script>
(function ShopifyEditor() {
  document.addEventListener('shopify:section:load', sectionLoad);
  document.addEventListener('shopify:section:select', sectionLoad);
  document.addEventListener('shopify:block:select', sectionLoad);
  document.addEventListener('shopify:block:deselect', sectionLoad);
 
  function sectionLoad(e) {
    let id = e.detail.sectionId;
    let nestedSection = document.querySelector(`#shopify-section-${id}[data-section-nested]`);
    let shopifySection = document.querySelector(`#shopify-section-${id}:not([data-section-nested]):not(:empty)`);

    /* this is to prevent the false-positive "HTML error found" warning */
    e.target.classList.remove('shopify-section');
    e.target.classList.add('shopify-section-nested');
    e.target.setAttribute('data-shopify-editor-section-nested', e.target.getAttribute('data-shopify-editor-section'));
    e.target.removeAttribute('data-shopify-editor-section');
      
    /* for json templates, this will relocate the placeholder section where the nested section should be. This is needed for a decent editor experience */
    if(nestedSection && shopifySection) nestedSection.parentNode.replaceChild(shopifySection, nestedSection);
      
    /* since associated javaScript that runs when the page loads don't run again in the editor, don't forget to re-init your section scripts with your own code. More info here: https://shopify.dev/themes/architecture/sections/integrate-sections-with-the-theme-editor */

  }
})();
</script>
{%- endif -%}

 

 

3) You're done.

 

It can look a little sketchy, but I've tried a few different things with more simple approaches, and for some reasons I don't fully grasp, the nested section would load properly, but the section settings would either not show in the editor pannel, either show (multiple times) and not update in real time unless saving. So this is for now the best I could come up with.

 

Feel free to try it & improve it (I'm sure there's room for it)! This is probably not a must-have, but sometimes, it is very handy to be able to nest sections since it can offer an easier and more intuitive customizing experience for merchants!

 

Reach out to me at admin@maxdesign.expert
marclesgomez
New Member
2 0 0

I also need this for store, that actually help me in adding schema.