skip to Main Content

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

Answers


  1. 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

    Login or Signup to reply.
  2. 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 TwigEnvironment $twig The Twig environment.
     * @return TwigEnvironment
     */
    add_filter( 'timber/twig', 'add_to_twig' );
    function add_to_twig( $twig ) {
    
        // Adding functions as filters.
        $twig->addFilter( new TimberTwig_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 = TimberHelper::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;
    
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search