I think there is a simpler approach you can try which uses either markdown templates or JS to get tab behavior, rather than both.
See a navbar I added to my Jekyll site.
Here the result
The navbar is created in the includes file and uses pages that exist.
Each button points to a different markdown page.
So About button points to about.md which is /about.html for example.
Clicking on the button loads that page. This is a typical Jekyll approach.
If I wanted a tab to look different because it is selected, then I could add an if statement in the includes file which says use “selected” in the class if page.name equals to the item.name of the for loop. And then use CSS to make the button look different
I would recommend checking out Minima theme as well in this demo.
You can set your navbar using a custom value in your config or you can let the menu be created from a sorted list of pages.
If you would rather use the JS approach to avoid page loads, then I would do it like this all on one page.
<nav>
<div id="btn-a" class="tab-selected">Tab A</div>
<div id="btn-b">Tab B</div>
<div id="btn-c">Tab C</div>
</nav>
<div id="content">
<div id="content-a" class="show">
Text for first section
</div>
<div id="content-b" class="hide">
Text for second section
</div>
<div id="content-c" class="hide">
Text for third section
</div>
</div>
To avoid setting selected and styling on your navbar you could even turn that into a radio selector since that is built into HTML and only one element is selected at a time. And you can use CSS to make your radio buttons more like traditional buttons or tabs.
Add JS to the navbar. Whenever there is a click on the entire nav element, then update the content.
For example when Tab B is clicked, you know the id is tab-b. So you set the class of all the content sections to be “hide” except the one with ID of content-b gets the class show instead.
Also a reminder that Jekyll markdown or html is rendered at build time as static HTML. On a given page, jekyll will go through your if statement exactly once and find only one item selected and that will never change based on user input such as selecting things.
{% if page.tab_title1 is "selected" %}
{% include en/platform/kinetic.md %}
{% elsif page.tab_title2 is "selected" %}
{% include en/platform/melodic.md %}
{% else %}
{% include en/platform/foxy.md %}
{% endif %}
A reason to use an if statement in a layout would be perhaps if the page frontmatter has a path to a logo image then you render that img tag otherwise you use a default logo. Or to make exactly one nav element look selected on each page, as in my first response.
If my HTML response I also made sure to render all the sections that could be shown, using user interaction on the tab button to determine which section is hidden or not. As JS can only show content that Jekyll put that as HTML.
To reiterate, Jekyll just outputs what becomes dump HTML to be served as static assets. On one of my sites, I build locally with Jekyll to create _site directory of images, html etc. And then use FTP to copy the site directory to a server. The server then serves the contents I sent it and it knows nothing of how to run liquid or Jekyll but that’s ok because there are no if statements or frontmatter in the html.
When using GH Pages and Netlify and other tools, the concept is the same. Code for Jekyll is separated from the build output. The difference is the site directory output built on GH Pages gets put someone internally on GH Pages so there is no FTP.
I used the first article from w3schools - How to Create Tabs last week and it worked a treat.
I however wasn’t able to keep the text as markdown while using the tabs. I think either Jekyll or I had a trouble differentiating what was markdown and what was HTML. I rendered content from three XML files into formatted text which was output in each of three tabs.
the XML files required a few if and for statements and which the code I had written seemed to break some of the markdown rendering (probably my fault.) I got it sorted by just using HTML.
It is possible to mix html and markdown but it can be impractical if you do things like classes.
This will render markdown as expected
<div class="foo">
- A
- B
- C `ls`
</div>
Note that the markdown must not be indented otherwise it will turn into code blocks. And there must be white space on either side to separate from the tag. Actually only the top whitespace matters but for readability I do both.
Here is my way to add class to the markdown (Kramdown).
See below code.
#1 The code below only works when the parse option ({::options parse_block_html=“true” /}) is defined as true, so that the markdown inside the block level won’t be ruined.
#3 You can add class to the one line string to the markdown format using {: .class_name}
This looks very simple, but only problem is that I can only add a class to one string. I don’t know the reason. I guess there is some way to wrap whole contents…
# Title (#title)
{: .class_name}
fdsafasfas
```
They all works great for me
Yeah when you iterate over site.pages, jekyll has no concept of directories.
But you can split a path of a page by / and count the pieces to get the depth. So you can find all pages at say level 2 down because they have the same depth.
And then you can find “child” pages by filtering to pages which have a common item.dir path as the current item’s tab.dir value.
My fractal project supports nesting of content dynamically. My layouts and includes files effectively allow a page to show only the pages directly below it. Then each page then shows its pages directly below it and so on.
There are also conversations on the forum here.
I would recommend you solve your problem using simple output like making bullet point output that looks a like a tree of all pages on a single page. Then you go a step further and turn that into tab structure on the page.