Wordpress, Timber & Twitter Bootstrap

Wordpress is one of the most popular CMS blogging platforms on the internet today, with the latest updates it's really improved in terms of user experience for the admin user. However there is still one massive pain for developers in the template system....where there isn't really one!

Thankfully there is a great solution for this, by installing the Timber Wordpress plugin you can use the familiar Twig template language which separates the server side code from the view cleanly.

Looking out there there weren't many examples of templates for Timber, and none including Twitter Bootstrap...so I've decided to make one! Here is a guide on how to set it all up yourself:

1) First setup is to go to www.wordpress.org and download the package. Extract the files into a folder in your web server e.g. http://localhost:8888/wordpress-example/

2) Follow the installation instructions for Wordpress. Afterwards in the admin go to Plugins > Add New and search for 'Timber By Jared Novack + Upstatement'.

3) After installing the Timber plugin you will need to either:
a) create a new theme containing your templates
b) download my theme from Github and place it within your themes folder at:
/wp-content/themes/timber-bootstrap

4) Now you need to navigate in the admin to 'Appearance' and activate the theme.

Creating a Timber theme
To create a theme for Timber you can follow their starter template on Github. I've listed out some instructions on a different method where your template modules are sorted by functionality which is much better for larger projects!

1) First step is to create a new folder inside your Wordpress folders e.g:
/wp-content/themes/timber-bootstrap

2) Inside this folder create an index.php file which contains the code to switch the template based upon the page type:

if (!class_exists('Timber')) {
    echo 'Timber not activated. Make sure you activate the plugin in /wp-admin/plugins.php';
    return;
}
if (is_singular()) {
    $context = Timber::get_context();
    $context['menu'] = new TimberMenu();
    $context['post'] = new TimberPost();
} else {
    $context = Timber::get_context();
    $context['menu'] = new TimberMenu();
    $context['posts'] = Timber::get_posts();
}

if (is_single()) {
    $template = 'blog-post/blog-post';
} else if (is_page()) {
    $template = 'page/page';
} else if (is_home()) {
    $template = 'blog/blog';
} else if (is_category()) {
    $template = 'app/app';
} else if (is_tag()) {
    $template = 'app/app';
} else if (is_author()) {
    $template = 'app/app';
}
Timber::render('modules/'.$template.'.twig', $context);

3) If you want to support extra features such as thumbnails, you'll also need a functions.php file continaing the additional code. Here is an example adding thumbnails to your blog posts

add_theme_support('post-thumbnails');

4) Wordpress themes require a third file in your folder, which gives more information about your theme. Add a style.css with some comments:

/*
    Theme Name: Timber Bootstrap
    Description: Example template using Timber and Twitter Bootstrap together
    Author: kmturley
*/

5) Now you are ready to create some templates! I've decided to organise mine by functionality rather than type. This means the css, javascript and the template are grouped in the same folder (making it easier to move modules between projects). This is the structure i'm using:

modules/          --> modules grouped by functionality
      app/        --> main application module
            app.css
            app.js
            app.twig
      blog/       --> example blog module with css, js and template
            blog.css
            blog.js
            blog.twig

6) In the app.twig file I've put my base html template using content blocks which the other templates can override:

<!doctype html>
<html {{ site.language_attributes }}>
<head>
    <meta charset="{{ site.charset }}" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="description" content="{{ site.description }}" />
    <title>{{ site.title }}</title>
    <link rel="icon" href="{{ site.theme.link }}/img/favicon.ico" />
    <link href="{{ site.theme.link }}/libs/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="{{ site.theme.link }}/modules/app/app.css" rel="stylesheet" />
    {% block head %}
    {% endblock %}
</head>
<body class="app">
    <nav class="navbar navbar-inverse navbar-fixed-top">
        <div class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
                    <span class="sr-only">Toggle navigation</span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                    <span class="icon-bar"></span>
                </button>
                <a class="navbar-brand" href="{{ site.url }}">{{ site.title }}</a>
            </div>
            <div id="navbar" class="collapse navbar-collapse">
                <ul class="nav navbar-nav">
                    {% for item in menu.get_items %}
                        <li class="{{ item.classes | join(' ') }}"><a href="{{ item.get_link }}">{{ item.title }}</a></li>
                    {% endfor %}
                </ul>
            </div>
        </div>
    </nav>
    <div class="container">
        {% block content %}
            Template not found
        {% endblock %}
    </div>
    <script src="{{ site.theme.link }}/libs/jquery/jquery-1.11.2.min.js"></script>
    <script src="{{ site.theme.link }}/libs/bootstrap/bootstrap.min.js"></script>
    <script src="{{ site.theme.link }}/modules/app/app.js"></script>
    {% block foot %}
    {% endblock %}
</body>
</html>

7) Within your templates there are many useful tags you can use such as:
{{ site.title }} = output the site title
{{ site.url }} = link to the site root
{{ site.theme.link }} = output the theme folder url
{% block content %}{% endblock %} = create a named block which can be overriden by child templates

8) Create more templates!

Hopefully that's helpful, if you want to use my project as a starting point then i've put it here:
https://github.com/kmturley/timber-bootstrap