Add Explicit Support for Multi-Section Pages

The ‘one-pager’ tutorial shows us how Kirby can be used to setup a single-page site, where the page has multiple sections.

All sites I do have more than one page - the site itself is usually divided into at least a ‘home’ page and a ‘blog’, and then it often might have other features required by the client, like a product catalog, event calendar, or forum. I don’t think I’ve ever done a single-page site, however in all my sites, I do need to have a ‘multi-section’ page, exactly as described in the ‘one-pager’ tutorial.

I’m currently doing my first two sites in Kirby, and both are going to be essentially ‘one-pager’ sites, with a blog. That is: the ‘home’ page will be divided into sections, layed out with sub-pages and snippets, and then there will also be a blog. I’ve managed to do the multi-sectioned homepage by slightly altering the instructions on the ‘one-pager’ tutorial - in my version, the pages that represent the sections are subpages of ‘home’, not at the top level of the site.

The whole process, however, made me feel as if ‘sectioned pages’ like that are “second-class citizens” in Kirby. The pages representing the different sub-sections of the parent are inserted as snippets in the parent’s template, and this has limitations - ie, snippets do not have their own controllers. Also, pages’ URLs are by default made available by the router, so all page sections end up with their own URL. In order to avoid the user reaching these URLs, the developer has to either setup redirection manually in the ‘default’ template for the site, or - if the default is already being used for another purpose - setup redirection in a template for each section page. It feels like a workaround.

Considering that multi-section pages are such a common use-case, perhaps setting them up could be made easier in the future, with a few alterations/additions to Kirby. For instance:

  • we create ‘section’ objects: they are basically page objects, but they DO NOT ROUTE - ie, they route to the error page, or another route specified by the developer in a special config. In the filesystem, sections might be indicated by a name starting with an underscore - so that, for instance, a directory called ‘contact’ would indicate a page, but one called ‘_contact’ would indicate a section, and would not be accessible directly via http.

  • a ‘page’ should then be able to have sections, sub-pages and files displayed in the panel.

  • sections can have their own templates, blueprints and controllers, perhaps stored in the site’s templates/blueprints/controllers folder in a sub-directory with the same name as their parent page’s.

  • the page object should be given a ‘sections()’ method, to fetch a collection of the page’s sections. The section object should be given a ‘render()’ method, that would run the section’s controller, then output the section’s template. This would enable us to do:

foreach($page->sections() as $section) {
  $section->render($optionalData);
}

I haven’t looked at the Kirby core code, so I cannot gauge whether this would be an incredible amount of work, or whether it would be realistic… but it’s worthwhile dreaming! :wink:

2 Likes

Well, haven’t thought this through, but the first thing that comes to mind is that it all depends what you want to include on your section page, sometimes your sections will only be part of a page, e.g. have a section of the last 5 blog articles or some of your projects etc, but also have a blog page and a projects page. Then using the blog etc. templates for the section page would interfere with the blog template for the blog page. Also, in such a case it wouldn’t make sense to make the blog page a child of some other page.

What I have in mind is a site structure like this:

- Home
  - _hero-banner
  - _about_us
  - _contact
- Blog
  - article1
  - article2
  - article3
  - ...
- Catalog
  - _specialpromo
  - _featuredproduct
  - product1
  - product2
  - product3
  - ..

“Home”, “Blog” and “Catalog” would be the top-level pages of the site.

The Home page is a multi-section page - its sections are: ‘hero-banner’, ‘about-us’ and ‘contact’.

The Blog page is a simple page, with sub-pages - ‘article1’, ‘article2’, ‘article3’, etc.

The Catalog page is a multi-section page (‘specialpromo’ and ‘featuredproduct’) with sub-pages (‘product1’, ‘product2’, ‘product3’, etc.).

While this is doable with Kirby at the moment, it does require jumping through hoops - because we must use pages as ‘sections’.

I’ve felt this need a couple times too. I think there is only a problem when we use “Kirby pages” as “sections” and don’t need them as standalone “web pages”.

I’m not sure we need as many changes as you explained, nor have a different kind of object. Technically almost all the pieces are already here. The “section” object you describe is basically a “page” without a URL.
It could be a new page option:

pages:
  template: project
  url: false

Then you could filter with something like:

$pages->children()->visible()->noUrl()

+ a way to visually identify/separate them in the panel of course.

Or something different and actually clever. This is just a wild idea, I really have no clue how it could be done :wink:
Perhaps it could be a plugin.

I think there is yet another use case: very complex blueprints that result in loooong forms.
We could feel the need to split split such a form for convenience. In this topic we discussed a way to split a long form into tabs or collapse them as an accordion (with a link to github with an implementation as an accordion).
In your structure _about_us and _contact on the home sound like contents that are not displayed anywhere else, in this case the tabs or collapsible form could be a solution.

3 Likes

@Malvese I agree: I think that a ‘section’ is basically a page with no URL route, and they need to be handled differently in the Panel.

In fact, there are 3 things that we should be able to do with ‘sections’:

  1. ‘Sections’ should not be routable - no URL route should be created for sections.

  2. ‘Sections’ should have their own section in the Panel sidebar, like ‘pages’ and ‘files’.

  3. We should be able to include a page’s sections in its template like a snippet. Unlike a snippet, however, ‘sections’ should also be able to have their own controller, that run when the section is rendered on the template.

I don’t believe that you can do all three things without creating a ‘section’ object/class. Nevertheless, as you pointed out, a ‘section’ is basically a ‘page’, with very few changes. This may mean that a ‘section’ class could be relatively easy to write - it might be a simple extension to the existing ‘page’ class. I don’t really know how much work it would be to write it, to be honest, because I haven’t looked at the Kirby code! :blush:

1 Like

I came to the forums to make the same suggestion. I think a little added functionality to the panel - to allow it to view subpages as sections - would make much more sense.

The only crucial change I can see would be the way pages and sections are displayed in the panel. Sections, structurally, would still be subfolders of that page. But, there would be no need to edit information on them (they are just there for organization) - better to have immediate access to their subpages.

I recently used Kirby to build a site for Tunica Magazine. The structure of the magazine content is something similar to:

Magazine/
  - Issue 3
     - Portfolios
         - Artist A
         - Artist B
         - Artist C
     - Interviews
         - Interview A
         - Interview B
         - Interview C
     - Articles
         - ...
     - Essays
         - ...

For each issue, all portfolios, interviews, articles and essays appear on each page. There is no issue-3/portfolios/ page, but there is a issue-3/portfolios/artist-a/. (there is no portfolios template, just issue and artist)

When explaining this to the client, I needed to explain to them that adding the Portfolios page to the issue wasn’t actually creating a page, but was a necessary step. This and the redundancy of seeing a Portfolios page with no editable content felt somewhat hack-y and unprofessional.

I think the panel would feel much better if this was possible. The actual structure of the files would not have to be changed - just the way they are displayed in the panel.

In Kirby a “page” is clearly some content + a URL. There are workarounds to emulate “sections” but when you create a page in the panel a URL is required. It can be ignored, as it autocompletes with a sensible path, but it’s still there.
But is a useless URL that big a deal?

  • If we never link to these “sections” nobody should land there, not even search engines because I believe they follow links. I don’t think they will ever try to index “/issue3/portfolios” out of nowhere.
  • Even if they did, and for the few visitors who edit URLs manually, we can route these sections to another page or serve a 403 or 404. This is what is explained in the One pager tutorial in the Docs, so let’s call it the official way :wink:

@SQBiz Your pages like “Portfolios” are not really required, you could just add subpages to the issue itself (I assume they have separate blueprints, so you could still filter them). But I understand the way you used them creates a nicer display in the Panel.
Being able to distinguish different blueprint in the sidebar would be nice. Just listing them by blueprint type would be very useful. I think for me at least if would void the need for sections.
If you keep these “sections” you could use the subpage builder to create them automatically every time an new issue is added, and avoid the hassle of creating them manually for your editors.

Following the one-page tutorial still creates URLs for the sections. If I have a ‘home’ page with an ‘about’ section I end up, by default, with a ‘home/about’ URL. Custom routes are needed to actually route such requests to an error page. It is not a neat solution.

Most importantly: pages are conceptually different from sections. A page should be able to have BOTH sections and sub-pages, and both types of objects should be able to be displayed in the panel.

Hello! Some time ago I developed a basic support for Multi-Section pages for my own use. I’ve taken some ideas from this post and I’ve created the ‘Section Plugin’ for Kirby CMS, please visit the repo here.

The plugin cover almost all the features exposed here, but definitely would be great if @bastianallgeier offers native support for multi-sections pages.

I’ve used and tested the plugin here and it works like a charm.

Note: this is in beta, Definitely I’m a noob with the php performance and I don’t know if there is a better way to achieve this, ideas are welcome.

PS: Sorry for my english

2 Likes

Looks great! Love the rendering functions.
The only minor inconvenient I see is that the underscore before the template name is visible in the Panel. I can also be a problem if we already use the same naming scheme for some reason.
A possible solution may be a list of “section” templates in config.php so the files can be named any way we like:

c::set('sections', array(
  'hero-header',
  'services',
  'team'
));

A remark on the routing, it would seem great if the page slug is prefixed by a # to indicate a section instead of a page. Let’s say you have /article and a child section #intro, the child could be routed to ./article/#intro. All the section template needs is an in attribute on the container element.

A late post, but to me it seems having a variety of sections is instrumental to get truly editorial webpages (like magazines offer)

You can already do this:

Let’s say your “one-pager” page is /article (with the template article.php) and it has a child page named /article/intro (with the template section.php). To change the URL to the section in all links, you can then create a page model named site/models/section.php with the following content:

<?php

class SectionPage extends Page {
  public function url() {
    return $this->parent()->url() . '#' . $this->uid();
  }
}
3 Likes

It amazes me what can be done out of the box, I’m from a front end side so routing is not my strong suit, but this helps a lot. Thank you.

Still however, a specific ‘sections’ content type (besides files and pages) with automated routing (folders can start with a #) and specific blueprints/snippets would be a great addition.

Mainly because now the blueprint folder specifically will become somewhat messy* (and sections could use their own default). Also for clients the distinction between inline sections and child pages would become more clear. And if I’m not mistaken, there needs to be a route for each section template.

* I’m talking about several articles - like case studies - which are one pagers, yet part of a larger system which soon ends up with a plethora of blueprints and templates.

You might be interested in the kirby-builder plugin by @timoetting https://github.com/TimOetting/kirby-builder