Search code examples
wordpresstwigadvanced-custom-fieldstimber

How to set up custom post types and ACF fields in Timber


I am new to Timber/Twig/PHP and have a fairly specific requirement. I have a page-home.php / page-home.twig which displays a couple of ACF fields, testimonials as a custom post type, and the latest 3 blog posts.

I'm mostly fine with the Twig frontend part, but having difficulties with setting up the php template files.

I've read the Timber docs and got the impression that ACF is baked in, so that the field can just be called directly in Twig. Also checked Github and SO for similar issues but did not find an answer. There is a video on youtube that covers custom post types, but it is within a loop of only posts.

This is my page-home.php

echo 'page-home.php';

$context = Timber::get_context();
$context['page'] = new Timber\Post();

$templates = array('page.twig');
if (is_front_page()){

    $context['posts'] = Timber::get_posts('post_type=post&posts_per_page=3');
    $context['testimonials'] = Timber::get_posts('post_type=testimonials');

    // add your twig view to the front of the templates array
    array_unshift($templates, 'page-home.twig');
}

Timber::render( $templates, $context );


$image = get_field('hero_image');

echo '<pre>';
    var_dump( $image );
echo '</pre>';

page-home.php is showing 3 blog posts as expected, but returning a NULL value for the ACF field var_dump.

If I comment this line // $context['posts'] = new Timber\PostQuery($args); I get the var_dump of my image array, though it doesn't render in the Twig file.

This is the image in page-home.twig <div class="image image-overlay" style="background-image:url({{ Image(post.meta('hero_image')).src }})"></div> which returns blank.

Blog posts are being called as:

{% for post in posts %}
  {% include "blogpost-card.twig" %}
{% endfor %}

I am also unsure how to call a separate custom post type (testimonials) on the same page since the documentation does not provide that example.

I'm using the starter-theme installed through Composer. It would be great if the theme or the documentation provided an example of a page containing posts, custom posts and ACF fields since I guess this is a very common scenario. At least for those like myself who need a little extra help with the PHP side.


Solution

  • If you have {{ Image(post.meta('hero_image')).src }} in your Twig file, then Twig will look for the post variable. In your case, you define a post variable when you loop through your posts to display them as cards.

    {% for post in posts %}
        {% include "blogpost-card.twig" %}
    {% endfor %}
    

    However, you probably didn’t define a custom field called hero_image for your posts, but on the page where you display them. So, when you define your context and add the currently displayed post under page in the context, then you later need to access it through page as well, and not through post.

    $context = Timber::get_context();
    $context['page'] = new Timber\Post();
    
    <div
         class="image image-overlay"
         style="background-image:url({{ Image(page.meta('hero_image')).src }})"
    ></div>