0
votes

I'm new to both WP and Twig/Timber. I'm working on a website where I need to display a number next to a WP post as such:

  1. First post
  2. Second post
  3. Third post

…And so on

I couldn't find any information on how to do it. Can I achieve this with Twig/Timber? Also, I don't know much about it, but if it's recommended to use ACF for that, I would be open to it.

Thank you

Edit: I would like to display post number(s) both on a page which contains all the blog posts and on each post page.

Edit 2: I'm hoping there is a robust solution which would account for deleted posts

2
Why don't you just use an ol or a css counter?DarkBee
So you have an overview page and then another page which display the number of the post? I'd guess u'd have to create an extra field for your posts first and store it in the databaseDarkBee

2 Answers

1
votes

You could use a Twig filter to query a custom post number index which is saved in a transient: the order is currently set to the menu order and transient is cached for 1 minute.

Twig

{{ post.id|get_post_number }}

php

/**
 * Adds functionality to Twig.
 * 
 * @param \Twig\Environment $twig The Twig environment.
 * @return \Twig\Environment
 */
add_filter( 'timber/twig', 'add_to_twig' );
function add_to_twig( $twig ) {

    // Adding functions as filters.
    $twig->addFilter( new Timber\Twig_Filter( 'get_post_number', 'get_post_number_by_id' ) );

    return $twig;
}

/**
 * Get post number from ID, based on menu order.
 *
 * @param [type] $id
 * @return void
 */
function get_post_number_by_id( $id ) {

    // Check we have a string
    $target_id =  strval( $id );

    // Save quesry and index in transient
    $post_number_index = Timber\Helper::transient(
        'get_post_number_by_id',
        function () {

            // Update parameters to match desired search order
            $args = array(
                'orderby'    => 'menu_order',
                'posts_per_page' => -1,
                'post_status'    => 'publish',
            );

            // Query
            $posts = get_posts( $args );
            if ( !empty( $posts ) ) {
                
                // Store list
                $data = [];
                
                // Set post numer count
                $count = 0;

                // build index.
                foreach( $posts as $post ) {
                    $data[ $post->ID ] = array(
                        'post_id' => $post->ID,
                        'post_number' => ++$count,
                    );
                }

                return !empty( $data ) ? $data : false;
            }
            return false;
        },
        MINUTE_IN_SECONDS
    );

    // Retrun post number
    if ( !empty ( $post_number_index ) && array_key_exists( $target_id, $post_number_index ) ) {
        return $post_number_index[ $target_id ]['post_number'];
    }

    return false;

}
0
votes

This is something that exists in Twig's loop variable that should make it super-easy:

https://twig.symfony.com/doc/3.x/tags/for.html#the-loop-variable