Timber Logo

You are reading the documentation for Timber v2.x. Switch to the documentation for Timber v1.x.

A single post

Let’s look at a singular post template in more detail, because echoing a post’s title with {{ post.title }} is not the only thing you can do.

In this guide, we’re looking at a typical blog post. You can use most of the things we show here for other post types, too.

single.twig

<article>

<header>
<h1>{{ post.title }}</h1>

<p>
Posted by {{ post.author.name }} <span>&bull;</span>
<time
datetime="{{ post.date('Y-m-d H:i:s') }}"
>
{{ post.date }}</time>
<p>
</header>

<section>
{{ post.content }}
</section>

</article>

In this example, you see that we can also use post.author, post.date and of course, post.content to actually display a post’s content.

The {{ post }} variable in Twig is not an array, it’s a PHP object. More specifically, it’s an instance of Timber\Post. When you look at the documentation for Timber\Post, you see what else you can access.

If you look for title in that post object in PHP, you will see that it’s actually not a property, but a function.

In Twig, we don’t have to write {{ post.title() }} including the parentheses, we can simply use {{ post.title }} to call the function and echo out what it returns. If this is still all confusing to you, then don’t worry. You don’t have to completely understand this just yet.

When you dump the post object with {{ dump(post) }}, you will see that there are properties that you might find familiar:

  • post.post_title
  • post.post_content
  • post.post_excerpt

These are properties that a Timber post inherits from WP_Post. They are the raw values directly from the database. You should only use these if you really need the raw value. Otherwise, you should use the methods provided by Timber, because Timber runs these values through the proper filter hooks:

  • post.title will use post.post_title and apply the the_title filter.
  • post.content will use post.post_content and apply the the_content filter. The the_content filter will convert WordPress block markup into HTML or convert shortcodes.

Apart from the post title and content, we can also access the assigned author of a post through {{ post.author }}. The author is another Timber object. It’s not a post object though, but a Timber\User object. We can get the result of the name method through {{ post.author.name }}. This displays the name of the author.

There’s also {{ post.date }}, but we won’t go into details about it here, because that’s a whole other chapter. You can read more about it in the Date/Time Guide.

If you want to display a post’s image, you can access it through {{ post.thumbnail }}. The thumbnail is yet another Timber object, a Timber\Image object.

single.twig

<img
src="{{ post.thumbnail.src }}"
alt="{{ post.thumbnail.alt }}"
>

But you probably don’t want to use the full size of an image. Use any registered size for your image by passing a parameter to the src() function:

<img
src="{{ post.thumbnail.src('large') }}"
alt="{{ post.thumbnail.alt }}"
>

There’s much more to images. Learn everything you need to know in the Images Guide.

Terms and categories #

When you want to list all the categories that the blog post is assigned to, then you can use the post.terms() function in Twig:

<ul>
{% for term in post.terms({ taxonomy: 'category' }) %}
<li>
<a href="{{ term.link }}">{{ term.title }}</a>
<li>
{% endfor %}
</ul>

We just used a for-loop here. This works a little different than foreach in PHP.

And here, we have yet another Timber object. Each term is a Timber\Term object. For terms, you also have methods like title or link. To learn more about how terms are handled in Timber, refer to the Terms Guide.

Add your own data #

This is what a PHP template for a singular post in Timber looks like:

single.php

$context = Timber::context();

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

For very basic themes, this is all you need to start working. But for more advanced functionality, you might have to add your own data. For that, you can add your data to $context.

Here’s an example where you would call a function to calculate the reading time for a post.

$context = Timber::context();
$post = $context['post'];

$context['reading_time'] = reading_time($post);

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

Now, you can head on to the next chapter about Post Archives.

If you want to know more about advanced methods to extend Timber, you can learn about it in the Extending Timber Guide.