admin-plugins author calendar category facebook post rss search twitter


The best and most reliable WordPress plugins


Plugin Author: Jared Novack + Upstatement

Those familiar with other frameworks such as Ruby on Rails or Laravel probably have some experience with a templating language as well. Technically, the WordPress API provides a loose templating language, but Timber takes this one step farther by making PHP Twig templates available as WordPress templates, and makes the process of developing maintainable and modular themes a lot simpler.

What’s It Do?

The Timber plugin simply ensures that your WordPress install will communicate well with Timber templates and themes. Enabling the plugin won’t do much initially, but it will allow you to develop themes using the Timber framework, and the Twig template engine. This makes things like creating basic WP_Query loops, accessing functions and the WordPress API and extending templates a lot simpler.

This is just a very, very basic introduction to the plugin. There is some pretty great documentation out there for really diving in. There is an assumed knowledge of WordPress theming to get started, but I thought it might be nice to introduce what I think is a handy tool.

How’s It Work?

The first thing to do is install and activate the Timber plugin. Noting much will change, but you will be able to begin using the framework. The easiest way to get started is to download the starter theme, drag it into your themes folder, and start building off of it. That’s what we’ll be doing here.

If you open up the Timber starter theme folder, you will see all of the usual suspects for theming, an index.php, single.php, functions.php file, etc. However, the contents of these are very different. Let’s start with a single post, something that everyone should be familiar with. Open up the single.php file. Instead of your usual query and template code, you will see this:

$context = Timber::get_context();
$context['posts'] = Timber::get_posts();
$templates = array('index.twig');
if (is_home()){
    array_unshift($templates, 'home.twig');
Timber::render($templates, $context);

Let’s break that down. First, you have to set up your two objects “Timber::get_context()”. You then use this to set up your loop and post content, and specify a twig template for it. Assigning [‘posts’] = Timber::get_posts(); sets up a simple get_posts(); query with a single line. If you want to customize this query, that is more then possible, but let’s keep it basic for now. The next step is to specify your template file. This theme sets up a simple array in the $templates variable to check whether or not the page is an index page or static home page. If it’s an index page it will use the “index.twig” file, static home page will use the “home.twig” file, but we’ll be using the index.twig file. Then we simply add the context and template variable to “Template::render” object. This will use the get_posts context you set up and apply it to the “index.twig” file where you can do your actual templating.

So where’s the “index.twig” file? Open up the views folder, and you will see a whole list of .twig template files. Open up index.twig to get started with the theming.

For those unfamiliar, Twig is a PHP template engine, much like Mustache or Handlebars, which attempts to simplify the PHP syntax and remove some logic from the template itself. That is why we set up our query outside of the template and then render the template using our query context. That way, if we want to use the same query with a different template, or different queries on the same template, we can do so without having to create an entirely duplicate page with only a few small tweaks. It makes a lot of sense and can greatly improve the speed of development and reduce redundancy.

So, back to the index.twig file. The first line will be:

{% extends "base.twig" %}

This means that instead of having to rewrite the most basic parts of your site that are reused over and over, you can simply make a master template (base.twig) and extend only the small section of a page that needs to be different. Open up the “base.twig” file to see what I am talking about. There’s a lot going on in this file, but you can see that basically it is setting up the reusable components of your page. There is an {% include 'html-header.twig' %} tag at the end of the page, which adds the basic section to the file. There is also the first section of the header, and the footer included in this file. That way, you can edit all of this content in the same place, without having to constantly move back and forth between header.php, footer.php and content.php. It’s all together.

The most relevant part of this page is this section:

{% block content %}
  Sorry, no content
{% endblock %}

Blocks are chunks of data and content that can be “filled in” when they are extended by other templates. So basically, the base file is looking for a block labeled “content” to replace what is in there. If no such block is found, then it will fill it in with the text “Sorry, no content.” So if we switch back over to our “index.twig” file, you will see that right under “extends base.twig” we see {% block content %} and that the file ends with {% endblock %}. This means that the contents of the index.twig file will replace the “block content” section in “base.twig.” Everything else will remain the same, so all we have to do is theme the section that’s actually changing. Next up you will see a very basic loop:

{% for post in posts %}
    {% include ['tease-'~post.post_type~'.twig', 'tease.twig'] %}
{% endfor %}

Now what we are doing is calling the loop itself, and then saying if we are in a custom post type, search for “tease-” + “custom-post-type-name” + “.twig”. Otherwise, use the tease.twig template to actually show our content. Let’s open up this file now to see how we are actually going to be laying everything out. The actual “tease.twig” template is very simple, with only a tiny bit of code in the content block:

<h2 class="h2"><a href="{{}}">{{post.title}}</a></h2>

{% if post.get_thumbnail %}
    <img src="{{post.thumbnail.src}}" />
{% endif %}

This is where Timber makes things really simple. Instead of having to “echo” out parameters from the WordPress post API’s we can use a shortcut syntax to access anything from the individual post object and wrap it in double brackets. So {{post.title}} is the equivalent of and simpler. And accessing contents that are a little more complicated is even easier. {{post.thumbnail.src}} is the equivalent of roughly this:

$url = wp_get_attachment_url( get_post_thumbnail_id($post->ID) );
<img src="<?php echo $url; ?>

Or something a bit more complicated. And you can use the Twig language to set up simple “if” loops without having to keep opening and closing PHP tags.

And that, in a nutshell, is how you create a very basic index file. I’ve just very barely scratched the surface of what Timber is actually capable of. It allows for complex routing, a la Ruby on Rails and Node/Express, improved and extremely simplified template caching, and has all sorts of syntax shortcuts for really simple and common problems. It’s hard for me to even explain everything that it does, but if you are a theme developer it is worth checking out the documentation, and flipping through. Chances are, Timber is addressing many problems you find yourself coming across again and again.

Costs, Caveats, Etc.

Timber is an open source project that is hosted on GitHub. This means the project is always growing, and there are lots of ways to get involved. It is intended for developers with a pretty good knowledge of WordPress theming and PHP. If you do run into a problem, you can post an Issue on the GitHub page or visit the plugin’s official page for documentation, screencasts and examples.


Did you like this post?

About this Plugin
Get the latest

Signup for our newsletter to get plugin tips, and see what's coming down the pipe.

Plugin Categories