在Wordpress结果中按字母顺序过滤自定义帖子类型

问题描述

我正在处理自定义帖子类型档案,我想添加一个A-Z过滤菜单。 我设法在这个线程(Create alphabetical Pagination in wordpress)下工作了,但是我不明白我的初始页面(/ exposants)如何显示所有结果。

<div class="exposant__filter" id="exposants">
        <a href="/exposants/#exposants"><?PHP _e('Tout','festival'); ?></a>

    <?PHP 
        $posts = get_posts(array(
            'numberposts' => -1,'post_type' => 'exposant','orderby' => 'title','order' => 'ASC',)); 
        
        $firstLetters = array();
        foreach($posts as $post) {
            $title = $post->post_title;
            $startingLetter = substr($title,1);
            $dupeFirstLetters[] = $startingLetter;
            $firstLetters = array_unique($dupeFirstLetters);
            sort($firstLetters);
        }
        foreach($firstLetters as $letter) {
            echo "<a href=\"?lettre=$letter\">$letter</a>";
        }
        if(!empty($_GET['lettre'])) {
                $letter = $_GET['lettre'];
        }
        else {
            $letter = $firstLetters[0];
        } ?>
    </div>      

    <?PHP
    $exposantsArchive = new WP_Query(array(
        'posts_per_page' => -1,)); ?>

    <div class="row row--2col u-m-top--8">

        <?PHP   
        while($exposantsArchive->have_posts()) {
            $exposantsArchive->the_post(); 
            
            $first_letter = strtoupper(substr(apply_filters('the_title',$post->post_title),1));
            
            $logo = get_field('logo');
            
            if($first_letter == strtoupper($letter)) { ?>
            <div class="exposant__thumb col--padding-right">
                <div class="exposant__logo">
                    <img src="<?PHP echo $logo['url'] ?>" alt="<?PHP echo $logo['alt'] ?>">
                </div>
                <div class="exposant__thumb-content">
                    <h2 class="heading--as-h4 heading--no-margin"><?PHP the_title(); ?></h2>
                    <?PHP 
                    $related = get_field('pieces_liees');
                    if($related) {
                        echo '<p class="exposant__categories">';
                        foreach ($related as $k=>$category) { 
                            if($k) echo '/';
                            ?>
                            <a href="<?PHP echo get_the_permalink($category); ?>"><?PHP echo get_the_title($category); ?></a>
                        <?PHP }
                     }
                ?></p>
                    <p class="exposant-thumb__excerpt"><?PHP echo wp_trim_words( get_field('description'),16,'...' ); ?></p>
                    <a href="<?PHP the_permalink(); ?>" class="btn"><?PHP _e('Plus de détails','festival'); ?></a>
                </div>
            </div>

            <?PHP
        }
    } 
        wp_reset_postdata() ?>
    </div>

我想我不得不替换else {$ letter = $ firstLetters [0];},但是我不知道要做什么。

在此先感谢您的宝贵支持

编辑!

这是最终能完美工作的解决方案!

所以在functions.PHP

<?PHP
add_filter( 'posts_where','tomtom_posts_where',10,2 );
function tomtom_posts_where( $args,$wp_query_obj )
{
    global $wpdb;
    $starts_with = $wp_query_obj->get( 'starts_with' );
    if ( $starts_with ) {
        $args .= ' AND ' . $wpdb->posts . '.post_title LIKE \'' . esc_sql( $wpdb->esc_like( $starts_with ) ) . '%\'';
    }
    return $args;
}

这是页面

<?PHP

    /**
     * Outputs an alphabetic paginator.
     *
     * @return void
     */
    function tomtom_output_alphabetic_paginator() {
            $posts = get_posts( array(
                    'numberposts' => -1,'post_type'   => 'exposant','orderby'     => 'title','order'       => 'ASC',) ); 
                    
            $firstLetters = array();
            foreach ( $posts as $post ) {
                    $title              = $post->post_title;
                    $startingLetter     = substr( $title,1 );
                    $dupeFirstLetters[] = $startingLetter;
            }

            $firstLetters = array_unique( $dupeFirstLetters );
            sort( $firstLetters );

            echo "<a href=\"/exposants/#exposants\">" . __('Tout','festival') . "</a>";
            foreach ( $firstLetters as $letter ) {
                    echo "<a href=\"?lettre={$letter}#exposants\">{$letter}</a>";
            }
    }

    /**
     * Gets an array of exposant custom post types.
     *
     * @return array
     */
    function tomtom_get_exposants() {
            $args = array(
                    'posts_per_page' => -1,);
            if ( !empty( $_GET['lettre'] ) ) {
                    $args['starts_with'] = $_GET['lettre'];
            }
            $wp_query = new WP_Query( $args );
            return $wp_query->get_posts();
    }       

    /**
     * Outputs links related to exposant custom post type object.
     *
     * @return void
     */
    function tomtom_output_related( $related ) {
            foreach ( $related as $k => $category ) { 
                    if ( $k ) {
                            echo ' / ';
                    }
                    echo "<a href=\"" . get_the_permalink( $category ) . "\">" . get_the_title( $category ) . "</a>";
            }
    }

    ?>
    <div class="exposant__filter" id="exposants">   
            <?PHP tomtom_output_alphabetic_paginator(); ?>
    </div>

    <?PHP $exposantsArchive = tomtom_get_exposants(); ?>
    <div class="row row--2col u-m-top--8">
    <?PHP foreach ( $exposantsArchive as $exposant ): ?>
            <?PHP $logo = get_field('logo',$exposant->ID); ?>
            <?PHP $related = get_field('pieces_liees',$exposant->ID); ?>
            <?PHP $description = get_field('description',$exposant->ID); ?>

            <div class="exposant__thumb col--padding-right">
                    <div class="exposant__logo">
                            <img src="<?PHP echo $logo['url'] ?>" alt="<?PHP echo $logo['alt'] ?>">
                    </div>
                    <div class="exposant__thumb-content">
                            <h2 class="heading--as-h4 heading--no-margin"><?PHP echo $exposant->post_title; ?></h2>
                            <?PHP if ( $related ): ?>
                            <p class="exposant__categories">
                                    <?PHP tomtom_output_related( $related ); ?>
                            </p>
                            <?PHP endif; ?>
                            <p class="exposant-thumb__excerpt"><?PHP echo wp_trim_words( $description,20,'...' ); ?></p>
                            <a href="<?PHP get_permalink( $exposant->ID ); ?>" class="btn"><?PHP _e( 'Plus de détails','festival' ); ?></a>
                    </div>
            </div>
    <?PHP endforeach; ?>
    </div>

解决方法

如果我对问题的理解正确,那么这是您代码的稍微优化的版本。为清楚起见,我已尽可能自由地将您的php和html分离。

未经测试,可能需要进行一些调整,但总的来说,我希望这可以解决问题!

在您的functions.php文件中添加此代码,这将允许您按首字母过滤数据库查询:

add_filter( 'posts_where','tomtom_posts_where',10,2 );
function tomtom_posts_where( $args,$wp_query_obj )
{
    global $wpdb;
    $starts_with = $wp_query->get( 'starts_with' )
    if ( $starts_with ) {
        $args .= ' AND ' . $wpdb->posts . '.post_title LIKE \'' . esc_sql( $wpdb->esc_like( $starts_with ) ) . '%\'';
    }
    return $where;
}

然后:

<?php

/**
 * Outputs an alphabetic paginator.
 *
 * @return void
 */
function tomtom_output_alphabetic_paginator() {
    $posts = get_posts( array(
        'numberposts' => -1,'post_type'   => 'exposant','orderby'     => 'title','order'       => 'ASC',) ); 
        
    $firstLetters = array();
    foreach ( $posts as $post ) {
        $title              = $post->post_title;
        $startingLetter     = substr( $title,1 );
        $dupeFirstLetters[] = $startingLetter;
    }

    $firstLetters = array_unique( $dupeFirstLetters );
    sort( $firstLetters );

    echo "<a href=\"/exposants/#exposants\">" . __('Tout','festival') . "</a>";
    foreach ( $firstLetters as $letter ) {
        echo "<a href=\"?lettre={$letter}\">{$letter}</a>";
    }
}

/**
 * Gets an array of exposant custom post types.
 *
 * @return array
 */
function tomtom_get_exposants() {
    $args = array(
        'posts_per_page' => -1,'post_type' => 'exposant','orderby' => 'title','order' => 'ASC',);
    if ( ! empty( $_GET['lettre'] ) ) {
        $args['starts_with'] = $_GET['lettre'];
    }
    return new WP_Query( $args );
}

/**
 * Adds fields to an exposant custom post type object.
 *
 * @param WP_Post $exposant Exposant custom post type.
 * @return void
 */
function tomtom_hydrate_exposant( &$exposant ) {
    $exposant->logo        = get_field( 'logo',$exposant->ID );
    $exposant->related     = get_field( 'pieces_liees',$exposant->ID );
    $exposant->description = get_field( 'description',$exposant->ID );
}

/**
 * Outputs links related to exposant custom post type object.
 *
 * @return void
 */
function tomtom_output_related( $exposant ) {
    if ( ! isset( $exposant->related ) ) {
        tomtom_hydrate_exposant( $exposant );
    }
    foreach ( $exposant->related as $k => $category ) { 
        if ( $k ) {
            echo '/';
        }
        echo "<a href=\"" . get_the_permalink( $category ) . "\">" . get_the_title( $category ) . "</a>";
    }
}

?>
<div class="exposant__filter" id="exposants">   
    <?php tomtom_output_alphabetic_paginator(); ?>
</div>

<?php $exposantsArchive = tomtom_get_exposants(); ?>
<div class="row row--2col u-m-top--8">
<?php foreach ( $exposantsArchive as $exposant ): ?>
    <?php tomtom_hydrate_exposant( $exposant ); ?>
    
    <div class="exposant__thumb col--padding-right">
        <div class="exposant__logo">
            <img src="<?php echo $exposant->logo['url'] ?>" alt="<?php echo $exposant->logo['alt'] ?>">
        </div>
        <div class="exposant__thumb-content">
            <h2 class="heading--as-h4 heading--no-margin"><?php echo $exposant->post_title; ?></h2>
            <?php if ( $exposant->related ): ?>
            <p class="exposant__categories">
                <?php tomtom_output_related( $exposant->related ); ?>
            </p>
            <?php endif; ?>
            <p class="exposant-thumb__excerpt"><?php echo wp_trim_words( $exposant->description,16,'...' ); ?></p>
            <a href="<?php get_permalink( $exposant->ID ); ?>" class="btn"><?php _e( 'Plus de détails','festival' ); ?></a>
        </div>
    </div>
<?php endforeach; ?>
</div>