Embedding child pages in bootstrap nav tabs

Hopefully I’m asking this in the right place! I’ve been poking at template pages on local, trying to create a ‘listing’ style page that will embed child pages within the same folder into it. This might be better accomplished with a modular page, but when I tried that things went all sideways and looked worse than what I already had, so I panicked and retreated.

What I’m trying to do is place each child page into its own nav tab, so that whenever I add a new child page folder a new tab will appear automatically. I’m essentially going for something like this:

This way readers can decide which format works best for them and their accessibility needs in a way that feels seamless. I’ve been trying to accomplish this by hitting the Bootstrap4 theme with a hammer, and I feel like I’ve almost got it, but I can’t quite figure out what variables I should be using to actually make it work. I’ve been trying to use isFirst(), but… I don’t know if that actually works with child pages. And I’m also not very good at coding, in general.

What I’ve got in my template is this:

<ul class="nav nav-tabs" id="myTab" role="tablist">
    {% for child in collection %}
    <li class="nav-item">
	<a class="nav-link active" id="text-tab" data-toggle="tab" href="#{{ child.title }}" role="tab" aria-controls="{{ child.title }}" aria-selected="{{ isFirst(current.child) ? 'true':'false' }}">{{ child.title }}</a>
    </li>
    {% endfor %}
</ul>
<div class="tab-content" id="myTabContent">
    {% for child in collection %}
         <div class="tab-pane fade show active" id="{{ child.title }}" role="tabpanel" aria-labelledby="{{ child.title }}-tab">
	 <br />
             {% include 'partials/blorf.html.twig' with {'page': child} %}
         </div>
    {% endfor %}
</div>

The result of which isn’t actually functional. Neither tab is selected or selectable, and the contents of both children appear one right after the other underneath them instead of being contained within the tabs.

Is there an easy variable change I can make to get this working? Or should I be mangling another theme entirely?

@unpretty You’re close, but there are some issues causing trouble:

  • Using child.title for id’s might lead to invalid id’s when the title contains spaces or other invalid characters. The anchor (<a>) will then not be able to find the content.
    The child.slug is a better option for id’s.
  • For setting the initial active tab and content you should use the method collection.isFirst(child.path). See Collection Object Methods

The following should give you a functional tab using Bootstrap 4:

<ul class="nav nav-tabs" id="myTab" role="tablist">
    {% for child in collection %}
        {% set isFirst = collection.isFirst(child.path) %}
        <li class="nav-item">
            <a class="nav-link {{ isFirst ? 'active' : ''}}"
               id="{{ child.slug }}-tab"
               data-toggle="tab"
               href="#{{ child.slug }}"
               role="tab"
               aria-controls="{{ child.slug }}"
               aria-selected="{{ isFirst ? 'true' : 'false' }}"
            >
                {{ child.title }}
            </a>
        </li>
    {% endfor %}
</ul>
<div class="tab-content" id="myTabContent">
    {% for child in collection %}
        {% set show = collection.isFirst(child.path) ? 'show active' : '' %}
        <div class="tab-pane fade {{ show }}"
             id="{{ child.slug }}"
             role="tabpanel"
             aria-labelledby="{{ child.slug }}-tab"
        >
            <p>Content of {{ child.title }}</p>
        </div>
    {% endfor %}
</div>

Hope this helps…

2 Likes

It works perfectly!! :tada: Thank you so much, you’re an absolute lifesaver.

Yes I know… :angel: And it’s such a heavy burden to bear…