So, I’ve discussed how to create a Kirby CMS theme with Twitter Bootstrap. And as is my habit, I always make a Bootstrap version of everything :) And there seems to be a new law about Twitter Bootstrap:

If a code is used on the web, there is a Twitter Bootstrap version of it.

There are Twitter Bootstrap versions of everything. I even wrote about it. So let’s focus on the next big thing (in my head) which I call Kirby CMS. Kirby CMS, as I’ve explained in the past, is a pretty easy-to-use content management system that is based on the “flat file” architecture where you don’t need to use a database to store your posts, settings, and other data.

Download & Preview

kirby-boot-preview

Download Preview

Twitter Bootstrap 3.0

bootstrap-3-0

I’ll be using the  Bootstrap 3.0 release for this tutorial. It’s as much of a tutorial to teach you about Kirby as it is about Bootstrap. Bootstrap 3.0 marks a new UI direction for bootstrap. Here are some nice additions:

  • simplified code
  • “flat” look

There is a lot of code that I haven’t really touched when building this theme but once Twitter releases a full 3.0 upgrade, I’ll be sure to fix that. The advantage of building with Bootstrap, at this point, is that it can easily be skinned with different bootstrap themes and you can even build your own bootstrap theme while you’re at it. Bootstrap 3.0 is not entirely ready for that so if you’re looking for an immediate solution, I suggest you follow along with an older version.

Kirby CMS

kirby

I’ve previously touched on creating a blog with Zurb Foundation. Well, this is a similar tutorial but quite different. My previous tutorial touched on the basics. This tutorial is meant to create a unique Bootstrap experience on Kirby.

Kirby, for those that don’t know, is a flat-file CMS that requires no database access. It uses PHP and markdown to create your blog. To see a quick example, check out my Foundation Kirby Theme.

Let’s start!

Setting Up

To setup, you’ll need Bootstrap, Kirby, and a server that allows PHP. The process is pretty simple for Kirby, just follow their documentation. As far as Bootstrap goes, fork the WIP Bootstrap 3.0 repo and compile it. I’d like to keep this vanilla so no bootstrap themes.

Having trouble compiling? If you get the following message:

variable @navbar-link-color is undefined on line 180 in file 'variables.less':
[179]: // Navbar brand label
[180]: @navbar-brand-color:               @navbar-link-color;
       -----------------------------------^
[181]: @navbar-brand-color-hover:         darken(@navbar-link-color, 10%);
[Done - Failed]

Go to the variables.less file and go to line 179. Select lines 179-182 (Navbar Brand Label) and move them below the “//Navbar links” sections (line 192 before you cut those lines out). Next, take lines 197-200 (Inverted Navbar Brand Label) and move them below (originally) line 209 (the Inverted Navbar Links block). Yuo should be able to compile right after.

Next, upload your bootstrap.css file along with the javascript plugins and fonts to “assets” in your Kirby installation. Put the css file in the stylesheets folder, javascript where appropriate, and create a “fonts” folder for your fonts. Let’s move onto creating the theme. If you don’t have it there yet, create an app.css file for stuff that doesn’t concern bootstrap.

Structure

Before we get into the nitty gritty, let’s define what we’ll build:

  • home page “marketing layout” with a jumbotron, and some product info
  • a blog page
  • posts page
  • page

All a blog will need!

Header

Let’s create a header file to include all of our javascript files, css, and setup our icons. If you’ve worked with Kirby, you’ll know the basic setup: snippets hold common files, templates hold template files, and all of that is located in the “site” folder.

Let’s add a header.php file in the snippets folder. This file will:

  • import bootstrap.css
  • import javascript files
  • setup the <head> tag
  • setup grid container
  • setup navbar

 

<!DOCTYPE html>
<html lang="en">
<head>

    <title><?= html($page->title()) ?></title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <?= css('/assets/stylesheets/bootstrap.css') ?>
    <?= css('/assets/stylesheets/app.css') ?>
    <?= js('/assets/javascripts/jquery.js') ?>
    <?= js('/assets/javascripts/bootstrap-affix.js') ?>
    <?= js('/assets/javascripts/bootstrap-alert.js') ?>
    <?= js('/assets/javascripts/bootstrap-button.js') ?>
    <?= js('/assets/javascripts/bootstrap-carousel.js') ?>
    <?= js('/assets/javascripts/bootstrap-collapse.js') ?>
    <?= js('/assets/javascripts/bootstrap-dropdown.js') ?>
    <?= js('/assets/javascripts/bootstrap-modal.js') ?>
    <?= js('/assets/javascripts/bootstrap-scrollspy.js') ?>
    <?= js('/assets/javascripts/bootstrap-tab.js') ?>
    <?= js('/assets/javascripts/bootstrap-tooltip.js') ?>
    <?= js('/assets/javascripts/bootstrap-popover.js') ?>
    <?= js('/assets/javascripts/bootstrap-transition.js') ?>
    <?= js('/assets/javascripts/bootstrap-typeahead.js') ?>
    <link rel="alternate" type="application/rss+xml" href="<?php echo url('rss') ?>" title="Blog Feed" />
    <meta content="width=device-width" name="viewport">
</head>

Okay cool, so we loaded up just about everything. Kirby has a cool syntax that allows you to echo out anything you need with <?= ?>. It’s as close to “templating language” as you get with Kirby. The “js” function automatically loads up the argument as javascript, css() does the same thing. Notice the order, I am loading up popover.js after tooltip.js because popover.js is an extension of tooltip.js.

<body>
    <div class="navbar navbar-inverse navbar-fixed-top">
        <div class="navbar-inner">
            <div class="container">
                <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="/kirby-boot"><?= html($site->title()) ?></a>
                <div class="nav-collapse collapse">
                    <ul class="nav">
                        <li><a href="/kirby-boot"><span class="glyphicon glyphicon-home"></span></a></li>
                        <?php foreach($pages->visible() AS $p): ?>

                        <?php if ($p->hasChildren() && $p->template() != 'blog'){ ?>
                        <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><?php echo html($p->title()); ?> <b class="caret"></b></a>
                            <ul class="dropdown-menu">
                                <?php foreach($p->children() AS $c): ?>
                                <li><a href="<?php echo $c->url(); ?>"><?php echo html($c->title()); ?></a></li>
                            <?php endforeach; ?>
                        </ul>
                    </li>
                    <?php } else{ ?>
                    <li><a href="<?php echo $p->url() ?>"><?php echo html($p->title()); ?></a></li>
                    <?php } ?>
                <?php endforeach; ?>
            </ul>
        </div>
    </div>
</div>
</div>

I’d go line by line, but let’s skip to the important stuff. Bootstrap still works (almost) the same way it used t when it comes to markup. By placing a container tag INSIDE the navbar, we’re able to have a top bar stretch across the screen and the menu within the grid. So how about the Kirby stuff?

<a class="navbar-brand" href="/kirby-boot"><?= html($site->title()) ?></a>

On line 36, you can see the first difference. The class for “brand” is now “navbar-brand”. Kirby allows you to set some global variables in your site.txt file in the contents folder. One of those variables is “title”. The syntax is pretty simple. Html makes sure the end result gets printed out as html, using the $site variable allows you to call up your global vars and using the variable as a function of the object will call it up.

Next, let’s stop by our home link in the menu:

 <li><a href="/kirby-boot"><span class="glyphicon glyphicon-home"></span></a></li>

Bootstrap now uses a glyphicon font. It requires you to add not only the specific icon class (glyphicon-home) but also a base glyphicon class for base coding.

The entire nav loop:

                    <ul class="nav">
                        <li><a href="/kirby-boot"><span class="glyphicon glyphicon-home"></span></a></li>
                        <?php foreach($pages->visible() AS $p): ?>

                        <?php if ($p->hasChildren() && $p->template() != 'blog'){ ?>
                        <li class="dropdown"><a href="#" class="dropdown-toggle" data-toggle="dropdown"><?php echo html($p->title()); ?> <b class="caret"></b></a>
                            <ul class="dropdown-menu">
                                <?php foreach($p->children() AS $c): ?>
                                <li><a href="<?php echo $c->url(); ?>"><?php echo html($c->title()); ?></a></li>
                            <?php endforeach; ?>
                        </ul>
                    </li>
                    <?php } else{ ?>
                    <li><a href="<?php echo $p->url() ?>"><?php echo html($p->title()); ?></a></li>
                    <?php } ?>
                <?php endforeach; ?>
            </ul>

We already covered our home button. What’s next? We call up a list of “visible” pages. Visible pages are numbered pages within content:

content

Anything without a number is an “invisible” page. Anyways, so we used the object $pages and its visible() function to call up all of our visible pages. The loop will go through these. Each of our $p objects also has some functions associated with them, like so:

<?php if ($p->hasChildren() && $p->template() != 'blog'){ ?>

We used the functions hasChildren and template to check if the current link has children (so we can create dropdowns) and if it uses the blog template. If it does use the blog template, we don’t want it to show children because blog posts are counted as “child pages”.

<?php foreach($p->children() AS $c): ?>
<li><a href="<?php echo $c->url(); ?>"><?php echo html($c->title()); ?></a></li>
  <?php endforeach; ?>

Next, we’ll call up those children and run them through another loop.

Remember that each of these objects is capable of calling up its base functions for url, title and so on. Since you can setup each post with custom variables, you’re able to call those up as well, at any moment.

Here’s the visual result:

navbar-bootstrap

You can already see the differences between Bootstrap 3.0 and Bootstrap 2.3.0. See the flat look? :)

Home Page

Now that we’re done with the menu, let’s jump on the home page. For the homepage, I’d like to mimic the marketing layout look from Bootstrap 2.3:

marketing-theme

Which means we’ll need a “hero” unit (now called jumbotron) and setup the basic grid. Create a new file called home.php in your site/templates folder.

<?php snippet('header') ?>
<div class="jumbotron masthead text-center">
<div class="container">
<?= kirbytext($page->jumbotron()) ?>
</div>
</div>
<div class="container">
<section class="row" id="main-content">
<div id="content-area">
<div class="row">
    <div class="span4">
    <?= kirbytext($page->col1()) ?>
    </div>
        <div class="span4">
    <?= kirbytext($page->col2()) ?>

    </div>
        <div class="span4">
    <?= kirbytext($page->col3()) ?>
    </div>
</div>
<hr />
<div class="row">
<div class="span12">
<?= kirbytext($page->text()) ?>
</div>
</div>

</div>
</section>
</div>
<?php snippet('footer') ?>

Sweet. You’ll notice a few things I did. First, the jumbotron:

<div class="jumbotron masthead text-center">
<div class="container">
<?= kirbytext($page->jumbotron()) ?>
</div>
</div>

“Jumbotron” is the new hero unit. By placing the container INSIDE the jumbotron, you’re creating a 100% wide spanning hero unit with text fitting within the container width. I also centered the text and added a masthead class. Masthead is NOT part of bootstrap but it IS used on getbootstrap.com. Masthead basically adds a 70px padding on the top and 45px padding on the bottom and eliminates the bottom margin. This enables the fixed-top menu to not overflow onto the content. Also, note that I added the jumbotron text into a jumbotron variable. I’ll show you how it looks in the content in just a bit.

<div class="row">
    <div class="span4">
    <?= kirbytext($page->col1()) ?>
    </div>
        <div class="span4">
    <?= kirbytext($page->col2()) ?>

    </div>
        <div class="span4">
    <?= kirbytext($page->col3()) ?>
    </div>
</div>
<hr />
<div class="row">
<div class="span12">
<?= kirbytext($page->text()) ?>
</div>
</div>

This little bit will split the area right under the jumbotron into three columns. Again, I added each column as its own variable. We’ll have full spanning text underneath. Also, note that I included the footer snippet even though we haven’t created one yet. To create the content and take advantage of the home.php template, go to content/home and create a home.txt file.

Title: KirbyBoot Theme

----

Text:
Lorem ipsum dolor sit amet,...text

----
jumbotron: 
<h1>KirbyBoot Theme</h1>
This is a Kirby Theme with the Twitter Bootstrap implementation. It has a simple blog implementation as well. 

As always visit [http://getkirby.com](http://getkirby.com) for more information or [my blog](http://antjanus.com)

**Make sure you purchase a Kirby CMS license before you start using it!**
<div class="text-center"><a href="#" class="btn btn-primary btn-large">Download</a></div>

----

col1: 
##Sample Ad or Affiliate
<a href="https://billing.stablehost.com/aff.php?aff=1602"><img src="http://cdn.stablehost.com/banner40-2.gif" border="0" class="img-circle"></a>

----

col2: 
##My Stuff
Go check out my blog for more tutorials and news and goodies and all kinds of cool stuff!

<a href="http://antjanus" class="btn btn-success btn-block">My Blog</a><a href="http://twitter.com/antjanus" class="btn btn-info btn-block">Twitter</a><a href="https://www.facebook.com/AjFreelancer" class="btn btn-primary btn-block">Facebook</a><a href="https://plus.google.com/104969195856868123183" class="btn btn-danger btn-block">Google Plus</a>

----

col3: 
##Sign Up!
<form class="form-horizontal"><div class="control-group"><input type="text" placeholder="name"></div><div class="control-group"><input type="text" placeholder="email"></div><div class="control-group"><input type="submit" class="btn btn-primary" placeholder="name"></div></form>

Since we’re running most of these variables through kirbytext to display it, any breaks in the text will create a <br /> tag so you basically have to smush all your html together. Result:

home

So that’s done :) Let’s get do the “regular” page now.

Page Template

I liked the way the jumbotron looked like on the home page so I’ll carry it over to the page template. Create (or modify) default.php in site/templates.

<?php snippet('header') ?>
<div class="jumbotron masthead text-center">
<div class="container">
<h1><?= kirbytext($page->title()) ?></h1>
</div>
</div>
<div class="container">
<section class="row" id="main-content">
<section id="content-area" class="span8">
<?= kirbytext($page->text()) ?>
</section>
<aside class="span4" id="sidebar">
<?= snippet('sidebar') ?>
</aside>
</section>
</div>
<?php snippet('footer') ?>

Again, added footer just for good measure. And a sidebar on top of it. The code is very self-explanatory. If your page errors out, create a footer.php and a sidebar.php in site/snippets and just leave it blank until we get to it. Anyways, I substituted the title for the jumbotron content. Here’s my result (note, I already have a sidebar in place):

about

Looking good so far BUT because I’m basically reworking my older foundation theme, it’s time to tackle the sidebar. It looks strange and not well styled!

Sidebar and Footer

Go to your snippets folder site/snippets and create sidebar.php and footer.php if you haven’t already. Got it? Good. Open up the sidebar. Also, open up your app.css file and add the following stuff in there:

.first-widget{
margin-top: 0;
}

.widget{
margin-bottom: 14px;
}

This will ensure we have proper (ish) spacing. Next, let’s add a small welcome message to the sidebar:

<div class="widget first-widget"><p><img src="http://antjan.us/post/assets/images/author.jpg" class="author-image" width="50px" height="50px" alt="Author Image"> <?= $site->biography ?></p>
<p>Be sure to subscribe to my <a href="<?php echo url('/rss') ?>">RSS feed</a>!</p></div>

So what does all this mean? Creating “widgets” or sidebar sections is now as easy as creating a wrapping div with the “widget” class. The code right above will create a little intro.

Let’s first add a “newsletter signup” and recent posts.

<div class="widget">
  <h5>Subscribe To My Newsletter</h5>
  <form>
    <div class="input-append">
        <input class="span7" type="text">
        <input type="submit" class="span5 btn" value="Subscribe">
        </div>
  </form>
</div>

That’s the newsletter part done. Note that the old “prepend” and “append” styling is gone. For the time being, Bootstrap doesn’t have any styling for this part (at the time of writing this article, we’re on an early release candidate!). I manually add <hr /> to create lines but you can easily use the border CSS property.

<div class="widget">
<h5>Recent Articles</h5>
<ul class="list-unstyled">
 <?php foreach($pages->find('blog')->children()->visible()->flip()->limit(5) as $article): ?>
<li><a href="<?= $article->url() ?>"><?= html($article->title()) ?></a></li>
<?php endforeach ?>
</ul>
</div>
<hr />

Again, the syntax from Bootstrap changed a bit here. Instead of “unstyled”, you need to use the class “list-unstyled”. Bootstrap has become a bit more verbose here. And last one, my ads:

<div class="widget">
  <h5>Sponsors</h5>
  <div class="row">
    <div class="span6">
        <a href="https://billing.stablehost.com/aff.php?aff=1602" class="th"><img src="http://cdn.stablehost.com/banner40-4.gif" border="0"></a>
    </div>
    <div class="span6">
        <a href="http://tracking.maxcdn.com/c/38985/56503/378" class="th"><img src="http://adn.impactradius.com/display-ad/378-56503" alt="" width="125" height="125"></a>
      </div>
  </div>
</div>

Simple as hell. Done. Let’s move on to the footer! Create, or open, your footer.php file in /site/snippets folder

<div class="container">
<div class="row">
<section class="span8">
<a href="http://antjanus.com"><img src="/logo.png" style="height:50px"></a>
</section>
</div>
</div>
</body>
</html>

Since I used the footer without closing any tags in my other templates, I took this opportunity to close body and html. Here, you can create whatever kind of footer you want. I decided to skip it since it’s just like the sidebar and even my own site (this site) doesn’t have a footer. Results:

sidebar

Blog

Let’s see what the blog page can offer us. Create, or open, a blog.php file in your site/templates folder. I’ll be using our default.php file as a starting point. When you make a blog page in the /content make sure you create a blog.txt file inside to take advantage of the template. It should have a title and text.

<?php snippet('header') ?>
<div class="jumbotron masthead text-center">
<div class="container">
<h1><?= kirbytext($page->title()) ?></h1>
    <?= kirbytext($page->text()) ?>
</div>
</div>
<div class="container">
<section class="row" id="main-content">
<section id="content-area" class="span8">
    <?php
    $articles = $page->children()->visible()->flip()->paginate(5);
$pagination = $articles->pagination;
$range = 10;
    ?>
 <?php foreach($articles as $article): ?>

  <article>
    <h3><a href="<?= $article->url() ?>"><?= html($article->title()) ?></a></h3>
    <span class="label"><?= $article->date('Y-m-d') ?></span>

    <p><?= excerpt($article->text(), 200) ?></p>
    <a href="<?= $article->url() ?>">Read more…</a>
  </article>
<hr />
  <?php endforeach ?>
  <div class="pagination-centered">
<ul class="pagination">
  <?php if($pagination->hasPrevPage()): ?>
  <li><a class="prev" href="<?php echo $pagination->prevPageURL() ?>">&laquo;</a></li>
  <?php else: ?>
  <li class="disabled"><a class="prev" href="<?php echo $pagination->prevPageURL() ?>">&laquo;</a></li>
  <?php endif ?>

  <?php if(isset($range) && $pagination->countPages() > 1): ?> 
    <?php foreach($pagination->range($range) as $r): ?>
    <li class="<?php echo ($pagination->page() == $r) ? 'disabled' :  '' ?>" ><a class="range" href="<?php echo $pagination->pageURL($r) ?>"><?php echo $r ?></a></li>
    <?php endforeach ?>
  <?php endif ?>

  <?php if($pagination->hasNextPage()): ?>
  <li><a class="next" href="<?php echo $pagination->nextPageURL() ?>">&raquo;</a></li>
  <?php else: ?>
  <li class="disabled"><a class="next" href="<?php echo $pagination->nextPageURL() ?>">&raquo;</a></li>
  <?php endif ?>
</ul>
</div>
</section>
<aside class="span4" id="sidebar">
<?= snippet('sidebar') ?>
</aside>
</section>
</div>
<?php snippet('footer') ?>

Okay, so the code is pretty much the same as my foundation theme with a few adjustments. I’m not going to go through every line but I will touch on a few things. First, note that I added the page text into the jumbotron and since the jumbotron is set to show text in the center, it actually ends up looking well.

Let’s check out our “loop” because that’s the most complicated thing in the entire template.

    <?php
    $articles = $page->children()->visible()->flip()->paginate(10);
    $pagination = $articles->pagination;
    $range = 5;
    ?>
 <?php foreach($articles as $article): ?>

  <article>
    <h3><a href="<?= $article->url() ?>"><?= html($article->title()) ?></a></h3>
    <span class="label"><?= $article->date('Y-m-d') ?></span>

    <p><?= excerpt($article->text(), 200) ?></p>
    <a href="<?= $article->url() ?>">Read more…</a>
  </article>
<hr />
  <?php endforeach ?>

So, here’s the thing. Kirby is super simple in this aspect. The first variable $articles will call the $page variable and through it, we get its children (our posts), show only the visible ones (marked with a number), flip the order (so that it’s descending), and paginate with 10 articles per page. Next, we create a new $pagination variable that holds our pagination data. We set the range of pagination for 5 so that only 5 pages at a time show up. Next, we have our foreach loop which is pretty self-explanatory.

Kirby has an excerpt() function that cuts down on the text shown to a specified number of characters.

Let’s move onto pagination:

  <div class="pagination-centered">
<ul class="pagination">
  <?php if($pagination->hasPrevPage()): ?>
  <li><a class="prev" href="<?php echo $pagination->prevPageURL() ?>">&laquo;</a></li>
  <?php else: ?>
  <li class="disabled"><a class="prev" href="<?php echo $pagination->prevPageURL() ?>">&laquo;</a></li>
  <?php endif ?>

  <?php if(isset($range) && $pagination->countPages() > 1): ?> 
    <?php foreach($pagination->range($range) as $r): ?>
    <li class="<?php echo ($pagination->page() == $r) ? 'disabled' :  '' ?>" ><a class="range" href="<?php echo $pagination->pageURL($r) ?>"><?php echo $r ?></a></li>
    <?php endforeach ?>
  <?php endif ?>

  <?php if($pagination->hasNextPage()): ?>
  <li><a class="next" href="<?php echo $pagination->nextPageURL() ?>">&raquo;</a></li>
  <?php else: ?>
  <li class="disabled"><a class="next" href="<?php echo $pagination->nextPageURL() ?>">&raquo;</a></li>
  <?php endif ?>
</ul>
</div>

I’ve always hated pagination but this is pretty simple. We also have bootstrap styling for this part, that’s totally awesome.

First, we used our $pagination variable we setup earlier. Through that, we can check if this current page has a previous page. If you look at the code, you’ll see that if we don’t have a previous page, we add the disabled class. Same thing goes for next page.

Outside of that, you have the actual page loop:

  <?php if(isset($range) && $pagination->countPages() > 1): ?> 
    <?php foreach($pagination->range($range) as $r): ?>
    <li class="<?php echo ($pagination->page() == $r) ? 'disabled' :  '' ?>" ><a class="range" href="<?php echo $pagination->pageURL($r) ?>"><?php echo $r ?></a></li>
    <?php endforeach ?>
  <?php endif ?>

Bleh, yeah, I don’t like it either. That’s because I’m using a ternary operator in the class. It will add the “disabled” class IF we’re on current page.

Result:

blog

Blog Article

Last but not least, we have the post article. Create a blogarticle.php file in your site/content and a blogarticle.txt file within your first blog post. I’m just going to copy/paste the default.php file and add a placeholder for a commenting system like:

  • Disqus
  • Livefyre
  • Facebook Comments
<?php snippet('header') ?>
<div class="jumbotron masthead text-center">
<div class="container">
<h1><?= kirbytext($page->title()) ?></h1>
</div>
</div>
<div class="container">
<section class="row" id="main-content">
<section id="content-area" class="span8">
<?= kirbytext($page->text()) ?>
<!-- add commenting system -->
</section>
<aside class="span4" id="sidebar">
<?= snippet('sidebar') ?>
</aside>
</section>
</div>
<?php snippet('footer') ?>

And that’s it! Here’s the result (with LiveFyre):

kirby-boot-article

Wrapping It Up

There you go! And now you have a complete Kirby CMS theme based on Bootstrap 3.0. If you decide to use my Kirby Theme or follow my tutorial to create your own theme, let me know! I’d love to hear about it!

Download & Preview

Download Preview