What's the best way to build a tabs display in kirby

Hi, Like to use tabbed display on my site, what’s the best way to do this?
Does kirby have this built in, or are there any plugins?

Thanks
David

There are several ways, but the way ive done it in the past is to use subpages for each tab, and then just loop through them according to the markup of the tab system you are using. This is the tab script I used. You could also do it from a structure field.

I dont recall a plugin that can do it.

Thanks James, I’ll give this a go. Just to clarify, the subpage folders are under the root folder for the page and each tab has a separate url .

Thanks
David

You might also be interested in this:

While a ready to use script might be easier to use, this tutorial is about making tabbed interfaces accessible. Don’t know how far this is true for the solution suggested above.

It works with the keyboard out the box. Shouldn’t be to hard to add Aria attributes to to. It supports call backs, so adding aria selected to the active tab would not take much. There are other scripts out there that have it already but most of them depend on jQuery - i struggled to find an accesible one out of the box with no dependencies.

Sort of. You could in theory reach the individual tabs if you knew the URL to those sub pages. You can get round it with a route i think, and redirect direct hits to the page the tab system is on, and excluding these URLs from your sitemap. If you stored the tab content in a structure field, none of that is necessary.

My php coding skills are very weak, I’m trying to implement James’s solution, I have my sub-pages, each has it’s blueprint, so my question is what code would replace
<?= $page->text()->kirbytext() ?>
In a template that’s built from multiple blueprints?

Thanks
David

Assuming you have the javascript working, something like this should do it…

<!-- Set the content source to var so we dont repeat ourselves -->
<?php $tabsource = $page->children()->visible(); ?>

<!-- First loop for tab controls -->
<ul data-tabs class="tabs">
<?php foreach($tabsource as $tabs): ?>
	<li><a data-tab href="<?= $tabs->uid() ?>"><?= $tabs->title() ?></a></li>
<?php endforeach ?>
</ul>

<!-- Second loop for the tab content -->
<div data-tabs-content>
	<?php foreach($tabsource as $tabcontent): ?>

	<!-- Set active on first tab -->
	<?php if($tabcontent->is($tabsource->first())): ?>
		<div data-tabs-pane class="tabs-pane active" id="<?= $tabcontent->uid() ?>">
	<?php else: ?>
		<div data-tabs-pane class="tabs-pane" id="<?= $tabcontent->uid() ?>">
	<?php endif ?>
	
	<!-- Tab Content -->
	<?= $tabcontent->text()->kirbytext() ?>
	</div>
	<?php endforeach ?>
</div>

I set the first active tab the long way round, since you are learning it might make more sense to you. You can do that part in much less code with ternary operator, but one step at a time :slight_smile:

Also you do not need a blue print for each individual page in the site, only each unique page that has unique data to be stored. All of those subpages for the tabs can probably share the same blue print, unless you need to capture other data for a specific tab.

Thanks for this, I was just looking at the demo for the tabby tab script you sent me , this solution in Sojas link was more what I had in mind as a tabbed display.
p.s.
I guess with a little styling the tabby demo could look the same

You can use that script instead - the markup is pretty similar…

<!-- Set the content source to var so we dont repeat ourselves -->
<?php $tabsource = $page->children()->visible(); ?>
<div class="tabbed">
<!-- First loop for tab controls -->
  <ul>
	<?php foreach($tabsource as $tabs): ?>
		<li><a href="#<?= $tabs->uid() ?>"><?= $tabs->title() ?></a></li>
	<?php endforeach ?>
  </ul>
<!-- Second loop for the tab content -->
<?php foreach($tabsource as $tabcontent): ?>
  <section id="<?= $tabcontent->uid() ?>">
    <h2><?= $tabcontent->title() ?></h2>
    <?= $tabcontent->text()->kirbytext() ?>
  </section>
<?php endforeach ?>
</div>

And yes, tabby comes with literally just the styles needed to make it work. Making it look good is down to you :slight_smile:

I have some invisible sub-pages (no prepended number), how do I generate yml, txt and php files for
invisible blueprints or do I create the php manually with the correct file name?

Correct me if I’m wrong, but I have a feeling that there is still a missing link:

  • blueprint: defines which fields are in a page (and some additional settings for the page and for files)
  • content files: if you create a page in the Panel with a given blueprint, that page gets a content file name with the same name as the blueprint, e.g article.yaml ==> article.txt. etc.
  • templates: The content file name determines which template from (/site/templates) will be used to render that page in the page, that mean /site/templates/article.php will render that page with the content filename article.txt. Only if there is no such template, then the default.php template will be used.

This happens no matter if this page is visible or invisible, because this status is just a flag that serves to sort and to filter these page. “Invisible” pages are not really invisible, they can still be accessed via their URL. As a consequence, there are no special blueprints for invisible pages.

Having said that, you can of course disable sorting and making a page visible via a blueprint setting.

By default, every page that you create via the Panel is created as an “invisible” page, i.e. without the prepended number. Only if you change the status to visible is the number that you defined via the blueprint (zero for alphabetical sorting, date for data based sorting, default number) prepended.

If you really want to make a page inaccessible in the browser, you either have to put some rewrite code into the template or create a route that reroutes this invisible page somewhere else, to the parent page, to the home page or the error page.

Thanks for your reply, The problem is there’s no yml file is output and therefore no txt file.
Why isn’t a yml file output for invisible files.

I’m afraid I don’t understand. Why is there no yaml file? You always have to select a blueprint when you create a new page in the Panel. If there is only the default blueprint, then all pages will be created with this default blueprint.

There is never any “yaml file output”, you have to create a yaml file in a text editor and put that into site/blueprints.

Note that blueprints are only needed if you use the Panel (they are used to create the form you fill in in the Panel). They are completely irrelevant if you don’t use the Panel and create your content files manually.

Sorry, I’m confused the yaml file is a blueprint and is based on the template name, but the txt file name is based on the Title field in the blueprint correct? So yes I have the yaml file but it’s not generating a txt file.
Is it possible to manually create a txt file from a blueprint yml file?

I’m sorry, I don’t understand what the problem is. Maybe we are misunderstanding each other because we are using these terms differently.

Are you telling me that if you go into the Panel and create a new page (i.e. you click on Add button, fill in the page create form with a title and select a template and then click OK, that this page is not created. That is, if you then go into your Finder or Explorer and look at the file tree, there is no new folder with a text file in it?

I’ve created a sub-folder with the name of the txt file (without .txt) but when I click save in the panel no txt file is output although I get smiley saying it’s been saved.
I’m assuming I need to create the folder otherwise there’s no indication where to save the txt file.

Sorry for wasting your time (and mine) I see it created the folder with the txt file, but not in the subfolder I created, do I need to relocate the folder manually to the correct place?

When I create a page in the Panel, under Title there’s the URL, how can I change this to include a sub-folder (of an existing folder) - so that the txt file is saved there?

If you want to create subfolders for an existing page, you have to go into that page in the Panel and then choose Add from the sidebar.

The blueprint for that main page must allow the creation of subpages. Please have a look at the Starterkit. There are several main pages, three of which have subpages, projects, blog and contact. Studying the structure of the Starterkit and the files that are used to create that structure, i.e. the blueprints for the Panel and the templates for the frontend, is the best you can do to understand how it works.

And yes, the Panel creates a new folder with a text file in it when you create a new page.

Thanks Sonja, I think I’ve got it now.
1 more question, can I create a page with just a title, where the content is tabs each tab containing a subfolder template?
ok I’ve checked out projects in the starterkit and that seems to answer my question. I understand that the numbering of the txt files starts from 1 within each folder.

Yes, have a look at the projectstemplate in the Starterkit, it displays all the subfolders (project -a … project-e). The same can be done with any other markup, in your example with the tabs (and without the links to the subpages).