Woodworking: Build your next WordPress site with Twig and Timber

October 19, 2017

We build sites on a variety of CMS platforms, including WordPress, Drupal, Craft and our own HiFi, but they all have something in common: Twig. Twig is a PHP-based templating system that helps us write faster, cleaner code across all the sites we build. It's easy to use, allowing us to focus on more complex development tasks or even take on a brand new CMS when the project or client calls for it (our most recent adventure: Grav).  Twig is produced by the same folks who bring you Symfony, Sensio Labs, and has extensive documentation and support.

We love using Twig for a number of reasons.  While PHP is powerful to be sure, it also has a level of inflexibility which hampers modern templating. Much like the separation of HTML for structure and CSS for presentation, Twig allows us to use PHP exclusively for data and logic while generating HTML and display via Twig.  

In addition to this essential separation, Twig is concise, easy to learn, and has a syntax built specifically for templating. This flexible and open architecture offers the ability to create your own language constructs if needed, but also includes automatic output escaping to keep your code safe. Twig also has a sandboxed mode that allows users access to a limited number of functions and filters keeping your templates safe from untested code. We are very focused on page speed and Twig helps us reduce load times by compiling templates down to optimized PHP.  These are just a few of the reasons, but it's safe to say we really love Twig. 

If you've worked with WordPress in the past, you may be giving me a Fry-level side eye right now.  Fret not!  While WordPress doesn't have native Twig support, you can still use Twig via a plugin that we discussed in a previous post about our favorite helpful WordPress plugins. To use Twig on WordPress, we rely on Jared Nova's excellent plugin, Timber.  Timber is well documented, well maintained, and updated in tandem with the WordPress core.  In addition to all the wonderful things Twig can do for template structure and extension, Timber also includes a number of other "bonus" features that helps make it even more powerful with WordPress sites.

For example, Timber wraps common WordPress data structures to add bonus functionality.  The primary Timber class is Timber\Post which provides easy access to post properties and methods and makes them available to Twig. My very favorite Timber\Post class method is preview:

post.preview($len = 50, $force = false, $read_more = 'Read More', $strip = true, $end = "…")

This tiny bit of code will look for a post excerpt and use that, otherwise, it will grab the first bit of content. Then, you can specify length, whether or not to force the excerpt to conform to the specified length, an automatic read more link with customizable text, whether or not to strip out formatting and any sort of ending punctuation desired.

Timber also has excellent baked-in image retrieval and manipulation. All you need to access a post thumbnail is post.thumbnail. The Timber\Image class also includes some powerful resizing options and a nifty method for creating a srcset:

<img src="/{{ post.thumbnail.src }}" srcset="{{ post.thumbnail.src|retina(1) }} 1x,
    {{ post.thumbnail.src|retina(2) }} 2x,
    {{ post.thumbnail.src|retina(3) }} 3x,
    {{ post.thumbnail.src|retina(4) }} 4x" alt="" />

Like the docs say, Timber\Image is the class you'll have the most fun with.  The Timber Image Cookbook has all the recipes you need for working with WordPress images.

The way Timber provides access to all the things you'll need to build your Twig templates is via context. Each PHP template starts with 

$context = Timber::get_context();

The context will return all sorts of useful things like the site name, the description, and your default navigation. Once the primary context has been established, you can perform any number of queries to add items to the context. For example, you'll want to grab all the posts:

$context['posts'] = Timber::get_posts();

You can pass complex WP_Query arguments into the get_posts method and pull whatever you need into the context. for use in your Twig templates. Once you've filled your context with all the items you'll need, it's time to render the context into a Twig template so you can start theming. 

Timber::render( 'index.twig', $context );

Once you've rendered your Twig template, it's time to start developing. Timber offers a suite of great methods in the Timber\Helper class to speed your processes including array manipulation and validators like is_true and is_odd or is_even.

We've mentioned our love of Advanced Custom Fields and it plays very nicely with Timber. The Timber folks have even provided a handy ACF Cookbook which covers everything from setting up your custom site options page to working with flexible layout fields and complex nested repeaters. You were already thinking of using ACF, so now you have one more reason to go all in.

Timber has a ton of useful WordPress shortcuts that will have you hooked in no time flat. 

We've always loved Twig, but the added functionality and ease we get by also leveraging Timber on WordPress projects has been a huge win for our process, and we think it would be great for yours, too.  Give Twig and Timber a try on your next build and let us know your thoughts!


Justin's avatar
Some of these have been updated. Here's the preview post class example currently:

{{ post.preview.length(10).read_more('read more) }}

Thanks for the write up!

Leave a comment