Displaying Wordpress custom post type by first letter with Timber (twig)

前端 未结 1 1925
[愿得一人]
[愿得一人] 2021-01-27 07:45

I use Timber for Wordpress and I would like to create a dictionary system like that : https://wordpress.stackexchange.com/questions/119163/displaying-custom-post-type-by-first-l

相关标签:
1条回答
  • 2021-01-27 08:27

    It’s a good idea to get all posts at once. By adding the orderby parameter, you can already put them into the correct order for the letter-sorting. I’d use title and not name for the sorting and to define the first letter, because name/post_name is a URL-safe string (used in permalinks) might be different from the actual title of the post.

    You get the posts through Timber::get_posts(), so that you don’t have to rely on The Loop. You get an array with posts that you can work with, before you render it through a Twig file. This is much more direct than the method you linked to, because you don’t have to rely on additional functions and query resets.

    lexique.php

    $posts = Timber::get_posts( array(
        'post_type' => 'lexique',
        'posts_per_page' => -1,
        'orderby' => 'title',
        'order' => 'ASC',
    ) );
    
    $posts_by_letter = array();
    
    // Sort posts by letter
    foreach ( $posts as $post ) {
        $first_letter = substr( $post->post_title, 0, 1);
    
        // Create array for letter if it doesn’t exist
        if ( ! isset( $posts_by_letter[ $first_letter ] ) ) {
            $posts_by_letter[ $first_letter ] = array();
        }
    
        $posts_by_letter[ $first_letter ][] = $post;
    }
    
    $context['posts_by_letter'] = $posts_by_letter;
    
    Timber::render( [ 'lexique.twig' ], $context );
    

    Display only letters for existing posts

    lexique.twig

    <dl>
    {% for letter, posts in posts_by_letter %}
        <dt>{{ letter }}</dt>
    
        {% for post in posts  %}
            <dd><a href="{{ post.link }}">{{ post.title }}</a></dd>
        {% endfor %}
    {% endfor %}
    </dl>
    

    Because you have a nested array, you have to do two for-loops. The first loop goes through the letters (which are the keys of the outer array). The value assigned to a letter key is another array, containing all the posts starting with that letter. To display the post titles as links, you use the second for-loop.

    Display all letters from A to Z

    If you want to generate a list of all letters from A to Z and display existing posts, you can use range and check if posts exists for that letter in posts_by_letter.

    Additionally you can use range to create a list of anchor links that lets a visitor jump to a specific letter.

    lexique.twig

     {# Anchor links to jump to letter #}
     {% for letter in range('A', 'Z') %}
         <a href="#{{ letter }}">{{ letter }}</a>
     {% endfor %}
    
     <dl>
     {% for letter in range('A', 'Z') %}
         <dt><a id="{{ letter }}">{{ letter }}</a></dt>
         {% if posts_by_letter[letter] is defined %}
             {% for post in posts_by_letter[letter]  %}
                 <dd><a href="{{ post.link }}">{{ post.title }}</a></dd>
             {% endfor %}
         {% endif %}
     {% endfor %}
     </dl>
    
    0 讨论(0)
提交回复
热议问题