Custom post types for Kirby with views

There is already a great tutorial for Kirby available which describes how to use Kirby with custom post types. You should read this first before we go on.

But there is a bit of redundance when it comes to displaying a single post and the complete article list: You have to do the HTML stuff twice.

Last year I learned a lot about ASP.NET MVC and get used to it's partial views. That's why I came up with the idea to built something like that with Kirbys snippets.

The snippet

Normally you would use the $page variable to access specific stuff within a snippet. That's fine for displaying a single post but when displaying the article list the $page does not "know" anything about the post you would like to display.
That's why we need something like a model. This is a simple variable we pass to the snippet which contains the actual object that contains the individual article data.

This is how the default view snippet for my blog posts looks like:

// /site/snippets/view-post-default.php
<?php  
    if(!isset($model))
        $model = $page;
?>
<section class="content post">  
    <?php snippet('page-hero', array('model' => $model)) ?>
    <article>
        <?php snippet('blog-post-header', array('model' => $model)) ?>

        <?php echo kirbytext($model->text()) ?>

        <?php snippet('blog-post-footer', array('model' => $model)) ?>
    </article>
</section>  

Article list and post view

In both, the article list and the single post view we just need to insert the view-snippet with the page-variable we want to display. That's the code for my article list:

// /site/templates/blog.php
<?php  
    $articles = $page->children()->visible()->flip()->paginate(10);
    foreach($articles as $a):
        if($a->template() == 'post.image'):
            snippet('view-post-image', array('model' => $a));
        elseif($a->template() == 'post.video'):
            snippet('view-post-video', array('model' => $a));
        else:
            snippet('view-post-default', array('model' => $a));
        endif;
    endforeach
?>

The single post view consists of only four lines of code:

// /site/templates/post.php
<?php snippet('page-header') ?>  
<?php snippet('page-navigation', array('injectBlogNavigation' => true)) ?>  
//This is the important part:
<?php snippet('view-post-default', array('model' => $page)) ?>  
<?php snippet('page-footer') ?>  

Easy, isn't it?