Search code examples
wordpress-themingtimber

Should I use $post = Timber::query_post() or $post = new TimberPost() in single wordpress template?


I've read on the official Timber repository that general question about usage should be posted here.

I'm new to Timber/Twig and I have a a very "basic" question.

On the starter theme I've seen that in the single.php the $post variable that get passed to the $context is setted up with

$post = Timber::query_post()

while the page.php it is setted up with

$post = new TimberPost();

So, when I need to setup a single-cpt.php what method should I use? Timber::query_post() or new TimberPost()?

I've tried both of them and both of them are working, but what's the right way to do it?

Thanks!

PS: I've seen that in the index.php the $context['post'] is being setup with new Timber\PostQuery(). Does this basically reproduce the standard loop of the template hierarchy?


Solution

  • I understand there can be quite some confusion about which methods to use. Currently, there are a lot of ways to do it, and all that you’ve tried should work.

    With the upcoming version 2 of Timber, we try to unify this and we will deprecate some of the methods that are still around. So, here’s how you should do it from now on.


    Update March 2020 – We’ve gone back and forth as to how the new API for 2.x should like and we’ve come up with a solution that is pretty much fixed. Some things will change there, you can check out this pull request if you want to learn more.

    Until then, here’s our recommended way of doing things:


    Get a single post

    $post = new Timber\Post();
    

    $post = Timber::get_post();
    

    Get a collection of posts

    $post = new Timber\PostQuery();
    

    $post = Timber::get_posts();
    

    If you want to use pagination with your posts, you will still have to use Timber\PostQuery:

    $post = new Timber\PostQuery();
    

    (In Timber 2.x Timber::get_posts() will work with pagination, but not in 1.x yet.)

    The standard loop

    I've seen that in the index.php the $context['post'] is being setup with new Timber\PostQuery(). Does this basically reproduce the standard loop of the template hierarchy?

    Yes!

    In fact, if you don’t pass any arguments to PostQuery(), you don’t even have to set $context['posts'], because Timber does that already for you in Timber::get_context().

    index.php

    <?php
    use Timber\Timber;
    
    $context = Timber::get_context();
    
    Timber::render( 'index.twig', $context );
    

    Use namespaced class names

    Currently, you might still see TimberPost() instead of Timber\Post(). For version 1, all Timber classes were namespaced, so the recommended way to do it from now is to use the namespaced class names in PHP, e.g. Timber\Term instead of TimberTerm.

    But! In Twig, you’d still use the non-namespaced version:

    {% set post = Post(post_id) %}
    

    or

    {% set post = TimberPost(post_id) %}
    

    I hope this clears things up.