Timber - 4 reasons to love it
Tags: wordpress, twig
Published: 2020-01-23 23:10:21

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](https://pl.wordpress.org/plugins/timber-library/) or [library](https://github.com/timber/timber), 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:
```php
<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
<?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**
```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](https://thepracticaldev.s3.amazonaws.com/i/xwqpn97qt1yvl3h92zdo.png)
## 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.
```php
// 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:
```twig
{{ 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:
```twig
{{ Image( post.image ).src( 'medium' ) }}
```
If we would like to generate few images for srcset we can do this with this code:
```html
<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
<?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
<?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](https://github.com/timber/timber) a try.

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