Digging into Timber

Over these past few days I have been working with a plugin for WordPress called Timber.

What is Timber?

Timber is WordPress plugin that integrates twig with WordPress. It helps make a fully customised WordPress theme fast, with highly maintainable code.

Unlike typical WordPress templates, you write your HTML using the powerful Twig tempting engine, separate to your PHP logic. This keeps templates clean and easier to read.

How does it work?

If we were making a new blog post template. We would have single.php file and a single.twig file.

The contents of single.php would look like this:

<?php
    $data = Timber::get_context(); 
    $data['foo'] = 'Bar!';
    $data['post'] = new TimberPost();
    Timber::render('single.twig', $data);
?>

And the contents of single.twig would be:

<div class="post">
    <h1 class="title">{{ post.post_title }}</h1>
    <p>{{ post.post_content }}</p>
</div>

This is a very simple example but hopefully you can see how easy it is to read. No <?php ?> tags cluttering up the templates.

What is it doing?

Let’s start with single.php. The variable name $data is an array which contains the site details that are collected using Timber::getcontext();. On the next line we add to the $data array with an index of foo. We can can echo out this statement in our single.twig by using {{ foo }}. If we wanted to set $data['foo'] to an array we could have this:

$data['foo'] = [
    'bar' => 'foo bar'    
];

and this would be echoed out in our twig file by typing {{ foo.bar }}, returning ‘foo bar’.

On the next line we have: $data['post'] = new TimberPost();

This sets the index post to a post object, giving us the ability to get the data of the post. We can see all of the items available in the array by using {{ post | print_r }}, and you can access them with the dot notation, e.g. {{ post.post_title }}.

Now on to single.twig — what is it for?

single.twig is a HTML template that echoes out the valid information using the handlebar notation, e.g. {{ var.index }}. var is the index in your $data, so in this case it would be $data['var'], and it would be equal to:

[
    'index' => 'somevalue'
]

This would echo out somevalue onto the screen.

How would I add this into a project and use it?

Firstly, install the plugin on WordPress and activate it. Now you’re ready to start writing WordPress templates with Twig.

Next, in your theme directory make a folder called views. This is where all of your Twig files will go.

We only really need to add one PHP file, index.php. There are many ways to implement a Twig into your themes; but I find this way the simplest. In index.php:

<?php
/**
 * The main template file.
 */

// Set up page data
$data = Timber::get_context();

if (is_singular()) 
{
    $data['post'] = new TimberPost();
} 
else
{
    $data['posts'] = Timber::get_posts();
    $data['pagination'] = Timber::get_pagination();
}

if (is_single()) 
{
    $data['page'] = 'single';
    $template = 'single';
}
elseif (is_page()) 
{
    $data['page'] = 'page';
    $template = 'page';
}
elseif (is_home()) 
{
    $data['page'] = 'home';
    $template = 'index';
}
elseif (is_category())
{
    $data['archive_title'] = get_cat_name(get_query_var('cat'));
    $data['archive_description'] = term_description();
    $data['page'] = 'category';
    $template = 'category';
}

This is checking what type of page you’re trying to navigate to, and rendering a relevant Twig file. These Twig files will need to exist in your theme, so in our views folder we should have:

Views/
    single.twig
    page.twig
    home.twig
    category.twig

Within these files you can place your HTML template you want and echo out the variables as you want.

To make it more efficiant, we can remove the need for requiring the header and footer in each template. To do this we need to create a new file base.twig:

<!DOCTYPE html>
<html>
<head>
    <title>{{ site.title }}</title>
    {{ function('wp_head') }}
</head>
<body>
    <main>
        {% block content %}{% endblock %}
    </main>
    <aside>
        {{ function('get_sidebar') }}
    </aside>
    {{ function('wp_footer') }}
</body>
</html>

This is going to be our base template that our views will extend. To use base.twig, in one of our files, say single.twig, we can add this:

{% extends 'base.twig' %}

{% block content %}
    <!-- content here -->
{% endblock %}

What is {% block content %}?

Blocks are used for inheritance, and act as both placeholders and replacements at the same time. These can be overwritten in a file that extends upon another. In our case, most files extend base.twig and overwrite the content block.

How to use it for a blog post

We can use the above example in for our single.twig file. Within the content block we can add all of our content we want echoed out. Lets say we want the title, we can add {{ post.post_title }}. We could do the same with the content: {{ post.post_content }}. Simple right?

What else can we add? You can echo out everything accessible to post by {{ post | print_r }}, as we discussed earlier.

For the date, we can also apply formatting by piping it through the date function: {{ post.post_date | date('F j, Y') }}.

For the post thumbnail we can do something slightly different and add an if statement to check if there is one present. This is good practice so we don’t end up with empty image tags:

{% if post.thumbnail %}
    <img src="{{ post.thumbnail.src }}" alt="Thumbnail for {{ post.post_title }}">
{% endif %}

Lets add all this together to make a blog post template.

{% extends 'base.twig' %}

{% block content %}
    <h1>{{ post.post_title }}</h1>
    <p>Posted {{ post.post_date | date('F j, Y') }}</p>

    {% if post.thumbnail %}
        <img src="{{ post.thumbnail.src }}" alt="Thumbnail for {{ post.post_title }}">
    {% endif %}

    {{ post.post_content }}
{% endblock %}

Compare this to a typical WordPress approach:

<?php
// Set some vars before usage.
$thumb_id  = get_post_thumbnail_id($post->ID);
$thumb_url = wp_get_attachment_url($thumb_id);
?>

<h1><?php the_title() ?></h1>
<p>Posted <?php the_time('F j, Y') ?></p>

<?php if (!empty($thumb_url)):?>
    <img src="<?php echo $thumb_url; ?>" alt="Thumbnail for <?php the_title(); ?>" >
<?php endif; ?>

<?php the_content(); ?>

Conclusion

As you can see, even from a basic template, Twig is very powerful. It’s a great thing to add to WordPress as it helps to make an easy maintainable theme. The plugin is also extremely well documented.

Want to know a little more about us?

We are a friendly bunch and love talking all things WordPress. Whether you’re using one of our open source projects, want to discuss a blog article or hire us for your next project, we would love to hear from you.

Contact us