Snippets + Snippet Fallbacks

Just a quick idea, here.

I’ve been working in Twig a lot lately, and have come to like the way it handles include fallbacks.

Basically, you provide an array of possible partials to include, like this:

{% include ['try/this', 'try/that', 'try/last'] %}

The first one that exists is included.

The real benefit is when you don’t actually know what partials might be requested— for example, you might have a page type/template that you want to fetch different sidebars for:

{% include [
  'sidebars/' ~ page.template,
  'sidebars/default'
] %}

This way, you guarantee that one sidebar will get included, but you don’t have to manually update this if you add a custom sidebar for new page types/templates.

So, this morning, I adapted the snippet helper to handle things the same way:

function try_snippet($try, $data = [], $return = false) {
  $snippets = kirby::instance()->roots()->snippets();
  foreach ( $try as $snippet ) {
    $file = $snippets . DS . $snippet . '.php';
    if ( f::exists($file) ) {
      return tpl::load($file, $data, $return);
    } else {
      continue;
    }
  }
}

It’s used similarly, like this:

<? try_snippet([
  'header-layouts/' . $page->intendedTemplate(),
  'header-layouts/' . $page->template(),
  'header-layouts/default'
]) ?>

We’re guaranteed that if no snippets match the intendedTemplate or templates, the default header-layout (in this case) will be rendered.

This is also published as a Gist, in case you want to hack around with it!

5 Likes