DEV Community

Cover image for Timber - 4 reasons to love it
Maciej Palmowski
Maciej Palmowski

Posted on

Timber - 4 reasons to love it

More than a year ago - Timber has become one of the basic tools I use in every WordPress based project. Here I'll try to show you why.

Timber - what is it?

The most basic definition would be that it's just Twig for WordPress. But that's not entirely true. Timber also adds many cool features like integrations with plugins (ACF, co-authors or WooCommerce) and filters for easy image resizing and manipulation.
At this moment it's available as plugin or library, but soon we'll drop the plugin support.

It brings order to your code

When you use Timber you have to separate logic from the view. Thanks to this we're avoiding WordPress's spaghetti coding like this:

<div class="wrapper">
<?php
$args = [ 'posts_per_page' => 3, 'post_type' => 'post' ];
$posts = get_posts( $args );

if ( $posts ) {
  echo '<div id="posts">';
  foreach( $wpisy as $post ) {
    $post = setup_postdata();
    echo '<p><a href="'. get_the_permalink().'">'.get_the_title().'</a></p>';
  }
  echo '</div>';
}

$args = [ 'posts_per_page' => 3, 'post_type' => 'page' ];
$pages = get_posts( $args );

if ( $pages ) {
  echo '<div id="strony">';
  foreach( $pages as $post ) {
    $post = setup_postdata();
    echo '<p><a href="'. get_the_permalink().'">'.get_the_title().'</a></p>';
  }
  echo '</div>';
}
?>
</div>

Of course, we can be sure that in real life this code would be much more complicated and less readable.

With Timber it would look like this:
archive.php

<?php
$context = Timber::get_context();

$args = [ 'posts_per_page' => 3, 'post_type' => 'post' ];
$context['posts'] = Timber::get_posts( $args );

$args = [ 'posts_per_page' => 3, 'post_type' => 'page' ];
$context['pages'] = Timber::get_posts( $args );

Timber::render( 'views/archive.twig', $context );

archive.twig

<div class="wrapper">
{% if posts %}
  <div id="posts">
  {% for post in posts %}
    <p><a href="{{ post.link }}">{{ post.title }}</a></p>
  {% endfor %}
  </div>
{% endif %}

{% if pages %}
  <div id="pages">
  {% for post in pages %}
    <p><a href="{{ post.link }}">{{ post.title }}</a></p>
  {% endfor %}
  </div>
{% endif %}
</div>

As you see - it's much easier to read. Also, it's easier in terms of using brackets and curly brackets. I always had some problems in PHP + HTML in some situations.

Alt Text

It has a great Advanced Custom Fields Integration

I love ACF with all my heart but with Timber, I loved it much more:

In every example, the Timber version is a bit shorter and more readable.

// Normal input
// without Timber
<?php the_field( 'nazwa' ); ?>

// with Timber
{{ post.meta('nazwa') }}

// Image
// without Timber
$img = wp_get_attachment_image_src( get_field( 'image' ), 'large' );
echo $img[0];

// without Timber
{{ Image( post.image ).src( 'large' ) }}

// Repeater
// without Timber
if( have_rows('repeater_field_name') ):
    while ( have_rows('repeater_field_name') ) : 
        the_row();
        the_sub_field('sub_field_name');
    endwhile;
endif;

// with Timber
{% if post.meta( 'repeater_field_name' ) %}
  {% for field in post.meta( 'repeater_field_name' ) %}
    {{ field.sub_field_name }}
  {% endfor %}
{% endif %}

Images

Earlier I mentioned about image filters for resizing and manipulation. Now it's time to take a closer look at them.
First of all - resizing:

{{ Image( post.image ).src | resize( 400, 400 ) }}

With this one line we get a 400x400px image.
We can of course use image sizes defined by WordPress:

{{ Image( post.image ).src( 'medium' ) }}

If we would like to generate few images for srcset we can do this with this code:

<img src="{{ Image( post.image ).src | resize( 400, 400 ) }}"
 srcset="{{ Image( post.image ).src | resize( 400, 400 ) }} 1x,
 {{ Image( post.image ).src | resize( 800, 800 ) }} 2x">

If you would like to learn more - check the documentation.

Twig Filters

What I really hate about PHP is the moment when I have to use multiple functions on one variable. For example:

  • first, we want to remove spaces with trim()
  • next change '-' to '_' with str_replace
  • and make a hash of it with md5

We can do it in two ways:

<?php
$foo = ' some variable';

// multiple bracket version
$foo = md5( str_replace( ' ', '-', trim( $foo ) ) );

// multiple line version
$foo = trim( $foo );
$foo = str_replace( ' ', '-', $foo );
$foo = md5( $foo );

In most cases I forget about some bracket or it takes three lines. With Timber, it's much easier. First I have to create one extra filter thought:

<?php
// functions.php
add_filter('timber/twig', 'add_to_twig');
function add_to_twig( $twig ) {
    $twig->addFilter( new \Twig\TwigFilter( 'md5', function( $text ){
        return md5( $text );
    } ) );
    return $twig;
}
?>

// our phrase
{{ foo | trim | replace({ ' ', '-' }) | md5 }}

Conclusion

I hope that those examples have shown how much Timber can simplify the WordPress code. Personally, it really made me like WordPress even more. I hope you'll give Timber a try.

Have you tried Timber or any other templating system (for example Blade)?

Discussion (0)