Kirby Theme Loader

https://github.com/jenstornell/theme-loader

Why use themes?

Why use a theme you might wonder? Kirby does not work like that, or does it?

I’m planning to use the same setup for a new site in the future. Design, layout and some functions should be the same, but the content, blueprints and controllers should be different.

To have the common parts of the project as a theme and the unique parts in the “normal” folders I get the best of both worlds. I can copy the theme easy and only lift over the common things.

I’m using my theme loader on a site and it works really well. Good job with the register set guys!

Kirby Theme loader

Load and switch themes from /site/themes/.

Install

Add the folder theme-loader in site/plugins/.

Usage

  1. Add a folder called themes in site.
  2. Add a folder with your theme name like my-theme to themes.
  3. Add a filename that matches the theme name like my-theme.php.
  4. Add a c::get('plugin.theme.loader.name', 'my-theme') to activate the theme.

To sum up, the theme filepath would be like /site/themes/my-theme/my-theme.php

Making the theme

To make use of the theme loader you need to set stuff with the registry feature:

https://getkirby.com/docs/developer-guide/plugins/registry

Options

Name (required)

To activate a theme you need to add an option for it.

c::get('plugin.theme.loader.name', 'my-theme')

Root

If you don’t want to load the theme from site/themes you can change it.

c::get('plugin.theme.loader.root', kirby()->roots()->site() . DS . 'themes')

Requirements

Kirby 2.3

License

MIT

@Thiousi You make themes right? What do you think?

1 Like

You mean it loads my Theme automaticly?

I think I’m a little ahead of my time and I don’t think there are any themes that are using register set feature yet? I might be wrong.

But if they do use the register set for all the things, it would probably be quite simple to use it with the theme loader.

Let’s say you add these themes:

site/themes/blue
site/themes/red
site/themes/green

If you want to use the red theme you use this config:

c::get('plugin.theme.loader.name', 'red')

…or the green one, change it to…

c::get('plugin.theme.loader.name', 'green')

It’s not just a plugin, but also an idea of how themes can be built and used now and in the future.

For none developers I would recommend to wait and see what happends.

I didn’t get the gist of it before you put that last example in. So instead of setting a switch for instance in the panel dashboard and then doing an if statement to load different snippets, stylesheets and other assets, you would set it all in one place. This could be useful. I’ll play around with it and let you know!

So the theme loader is essentially a way to load themes as plugins are loaded with the register but set neatly in their own folder. I see where this is going. I’ve thought a lot about packaging themes in standalone plugins already with optional demo content and haven’t found out yet whether this is something people want.

For my personal use though I can see this being useful as I reuse a lot of code from theme to theme. I’ll have to give it a try. Not working on anymore themes at the moment though as I have some big projects and the next theme will be weeks in the making but hopefully a game changer :slight_smile:

1 Like

That came to my mind immediately when the extension registry shipped. Drupal theming has been a large part of my income for the last 10 years or so, so I totally get the benefits of pluggable themes. I didn’t sell themes per se, I did a lot custom theming for big/complex sites, but there was this “base theme” paradigm that was very useful: you choose a flexible generic theme, then create a child one with custom stuff.

I basically have given up on the idea of creating commercial Kirby themes because there’s no “theme” really. A Kirby theme is a site, and once you adapt it to your needs you can’t apply updates to the theme easily. If you screw up something…

I’m not sure the registry makes it possible (yet) to be honest, and shipping a good pluggable theme is ten times harder than building a custom one :slight_smile:
But it can be a good way to industrialize a bit if you build lots of sites.

1 Like

I should add that the lack of pluggable themes is part of Kirby’s beauty: you have to do custom templates and css with only what is required, so you can avoid the levels of abstraction and complexity of such themes. More craft and less out-of-the-box crap.

5 Likes

More craft and less out-of-the-box crap.

Yes!

More craft and less out-of-the-box crap.

Actually I totally agree with this! :slight_smile:

I will not try to convince you to move over to make themes. Instead I will try to explain my story why I got here in the first place. The day before yesterday I saw no need for a theme feature in Kirby.

My development process

1. Clone a site idea

I have an idea of a new site. It has the same kind of data/info like the current site, which I also have spent a lot of time on. So I thought, why not just copy it to the new one.

2. I can’t just clone the site folder

Even if it’s a similar site there are some differences in the site folder:

  • accounts - I don’t want to move them around too much.
  • blueprints - Some of the will be site specific and some are common for both sites.
  • cache
  • config - The config is unique for each site, like license and other stuff.
  • controllers - I use the controllers to tell the snippets what to do and they are unique for each site.
  • etc

In short, I can’t just clone the site folder. Maybe I could use a script or some Git solution to fetch only what I need for the new site, but I want the simplicity to just copy a folder.

3. Put only what I need in a folder

What are the common stuff that is needed for both sites?

  • blueprints - Not all of them, but some of them.
  • templates - Not all of them, but some of them.
  • snippets - In my case all of them because I feed them from the controllers.

So how can take them out of the site folder? The registry set in a plugin.

4. Bundle as a plugin

I built a plugin so all the common stuff (blueprints, templates and snippets) was loaded correctly and called it my-theme.

It worked beautifully and I was very proud of how well it worked.

That means that I have now separated all my common stuff from the unique stuff that I left behind in site.

My plugin structure now looked kind of like this:

site/plugins/ga/
site/plugins/my-theme/
site/plugins/revisions/
site/plugins/snippy/

5. Theme loader

site/plugins/my-theme/ felt wrong for me because I have a theme in the plugins folder.

site/themes/my-theme/ was much more appealing to me, so I created a quick and very dirty plugin for it which I used myself for a couple of hours. I called it theme-loader.

It worked well and I decided to clean it up and make it public to see the response to it. It was kind of like I expected… :slight_smile:

  • Don’t get it
  • Don’t want it
  • Not ready yet
  • Bloat!

Two days ago I did not ever think I would need a theme feature in Kirby… but now…

I get it, I want it, I’m ready for it… and… best of all… my theme is not bloat! It’s a f**g piece of art! :smiley: :wink:

What you describe seems pretty close to the Drupal module “Features”. It’s a way to ship some functionality made of different pieces (templates, modules…) like a “blog” or “photo gallery”, packaged as a single element.

Features (the module) came with its own bag of hurt, but the concept was interesting. I have not tried Drupal 8’s version though.

Maybe. I don’t have a UI, but yes, the controllers control which pieces should be used and even what data they should have.

I still use this solution:

A simplified version would be something like this:

<?php
return function($site, $pages, $page) {
  return array(
    'sidebar' => array('news', 'ratings'),
    'main' => array('content1', 'content2', 'table1'),
    'content1' => array('about'),
  );
};

In real life it looks more like this on my site:

<?php
return function($site, $pages, $page) {
  return array(
    'snippets' => [
      'main' => [
        [
          'wrap' => 'section',
          'snippet' => 'facts'
        ],
        [
          'wrap' => 'section',
          'snippet' => 'reviews'
        ],
        [
          'wrap' => 'section',
          'snippet' => 'contact'
        ],
        [
          'wrap' => 'section',
          'snippet' => 'service'
        ],
        [
          'wrap' => 'section',
          'snippet' => 'action'
        ],
      ],
    ],
    'facts' => [
      [
        'label' => 'Belopp',
        'value' => interval('old_customer_min', 'old_customer_max'),
      ],
      [
        'label' => 'Identifiering',
        'value' => single('verify_ways'),
      ],
      [
        'label' => 'Inkomstkrav',
        'value' => single('year_income_min'),
      ],
      [
        'label' => 'Betalningsanmärkning',
        'value' => single('accepted_payment_mark'),
      ],
    ],
    'content' => kirbytext( $page->seo_content() ),
    'excerpt' => kirbytext( $page->excerpt() ),
    'type' => $page->category(),
    'footer' => [
      'affiliate-beautifier'
    ],
  );
};
1 Like

Where did it go? Still looking for a ‘kirby theme development best practices’ tutorial, what do you recommend as good starting point?

Cheers!

In the end it was not that good for me so I removed it. If you want to develop themes, you can get inspiration from here: https://github.com/jenstornell/kirby-themes

Personally I created my own starting point based on Plainkit with a bunch of plugins already loaded and Laraval Mix to handle the Sass and Postcss etc. Im not ready to release it yet but theres a similar setup by @pedroborges called Kirby Boilerplate.

Mine goes further then his, as I have a whole set of common blueprints and stuff setup ready for pagination. I did not modify the default folder locations either.

It is a good idea to use domain based configs, that way you can turn certain plugins off on local domain, but have them on in production. Note that the configs inherit from config.php so you do not have to redeclare everything in the domain configs, just the specific thing you want to override.

Thanks for your input, which is really appreciated - check out my StarterKit while you’re at it. But thanks for mentioning / reminding me of the Kirby Boilerplate by @pedroborges!

I meant advice (hence ‘best practices’) or a starting point for developing an ‘isolated’ theme, you know …

  • as plugin (pro & con?)
  • as complete Kirby install for download (like beforementioned Starterkit)

My first guess would be that, when relying on specific plugins / fields (or ‘addons’ generally speaking), the second approach is preferable.

@jenstornell:
-label:commercial does the trick for me :sun_with_face:

The problem you have is that Kirby is designed to do whatever. It’s tricky to have one cap fits all heads scenario.

I don’t build themes, but i do build sites in similar industries so they are largely similar. For those sites, I have a base theme if you like, that sets up 70% of the sites theme. From there, I add specifics for each site.

I think the best way is to use git submodules in your theme, and leave kirby out of it so that it pulls in kirby, the panel, and any required plugins on checkout. However, this requires that the user is familar with Git.

This is something ive been wrestling with myself lately, because i want to start making themes to sell, but have as painless as possible for someone to setup, with minimal computer knowledge.

An approach i have been tinkering with is using Slush (Like yeoman but much simpler) to deliver the theme. Ive got it checking out Kirby and then replacing folders with the theme automatically from a single command, and becuase you can get it to ask the user questions, if they run it again, you can have it just update kirbys core and not touch the theme. I know some of that is duplicating what Kirby CLI can do, but i have never been able to get Kirby CLI to work reliably.