CPT项目的自定义顺序与其分页顺序不匹配

时间:2022-02-14 作者:hnnnng

我有一个CPT,我正在通过自定义字段的数值更改其顺序。我的自定义字段名为;订购;。我的CPT的顺序更改如下:

$posts = get_posts(array(
    \'posts_per_page\' => -1,
    \'post_type\'      => \'staff\',
    \'meta_key\'       => \'ordering\',
    \'orderby\'        => \'meta_value\',
    \'order\'          => \'ASC\'
));
CPT项目的排序工作正常,但当我单击一个CPT项目时,我看到分页仍遵循;“创建日期”;订购格式。是否有方法与CPT项目的排序方式相同来匹配分页排序?

我正在使用understrap_post_nav() 输出分页。

我试图用这些参数更改分页顺序,但没有成功:

understrap_post_nav($args = array(
    \'orderby\'        => \'meta_value\',
    \'meta_key\'       => \'ordering\',
    \'order\'          => \'ASC\',
    \'post_type\'      => \'staff\',
    \'posts_per_page\' => -1,
));
我相信understrap_post_nav() 代码来自此处:

https://github.com/understrap/understrap/blob/main/inc/template-tags.php
这是while循环:

https://github.com/understrap/understrap/blob/main/single.php
下面是我如何获得帖子的,我在我的自定义页面模板中获得这些帖子,名为about-page.php:

<?php
while ( have_posts() ) {
    the_post();
    get_template_part( \'loop-templates/content\', \'page\' );
}
?>
<div class="container" id="team-members-loop">                          
    <?php
    $posts = get_posts(array(
        \'posts_per_page\' => -1,
        \'post_type\'      => \'team-members\',
        \'meta_key\'       => \'ordering\',
        \'orderby\'        => \'meta_value\',
        \'order\'          => \'ASC\'
    ));

    if( $posts ): ?>
        
        <div class="row">
            <?php foreach( $posts as $post ):
                setup_postdata( $post );
            ?>
            <div class="col-sm-4">
                <a href="<?php the_permalink(); ?>" class="team-link">
                    <div class="card_image_container">
                        <div class="card_image" style="background-image:url(<?php the_field(\'thumbnail_photo\') ?>)"></div>
                    </div>
                    <div class="card_details">
                        <h4 class="card-title"><?php the_title(); ?></h4>
                        <h5 class="card-desc"><?php echo the_field(\'title\') ?></h5>
                    </div>
                </a>
            </div>
            <?php endforeach; ?>
        </div>
        <?php wp_reset_postdata(); ?>
    
    <?php endif; ?>
</div>

1 个回复
最合适的回答,由SO网友:Sally CJ 整理而成

是否有方法与CPT项目的排序方式相同来匹配分页排序?

正在使用的自定义分页函数(understrap_post_nav()) 正在使用默认函数在单发帖子之间导航,如previous_post_link()next_post_link() 它不支持自定义(POST)查询,因此需要自定义编码来实现您尝试的分页。

我能想到的一个简单方法是using offset 像这样:

在您的循环中about-page.php 模板,将自定义URL参数添加到post permalink。

只需使用您喜欢的任何名称,但在我的示例中(请参阅此答案底部的代码),参数名称是current_ordering.

该参数将在$posts 数组,其中包含自使用\'posts_per_page\' => -1 检索所有找到的帖子。一、 e.不会有LIMIT 子句添加到查询/SQL。

然后在单个帖子模板中single.php, 进行相同的查询,但仅从前一个帖子的偏移量处的帖子开始查询3个帖子,即。current_ordering - 1.

基本上,分页将基于上述3个帖子生成,分页链接也需要current_ordering 传递给下一个/上一个帖子的参数。

以下是一个工作示例,只需按照以下步骤操作即可:

中的about-page.php, 更改foreach( $posts as $post )foreach( $posts as $i => $post ) , i、 e.添加后索引/偏移($i).

然后更改<?php the_permalink(); ?><?php my_ordering_permalink( $i ); ?>.

在您的functions.php 文件中,添加该函数,该函数定义了输出包含current_ordering 参数:

/**
 * Display or retrieve the current post permalink with a current_ordering parameter added.
 *
 * @param int         $offset Required. The post\'s position/offset in the posts array.
 * @param WP_Post|int $post   Optional. The post object or ID. Default null for current post.
 * @param bool        $echo   Optional. Whether to echo or return the URL. Default true.
 *
 * @return void|string Void if `$echo` argument is true, the permalink URL `$echo` is false.
 */
function my_ordering_permalink( $offset, $post = null, $echo = true ) {
    $url = add_query_arg( \'current_ordering\', $offset, get_permalink( $post ) );

    if ( ! $echo ) {
        return $url;
    }
    echo $url;
}
  • 同样在函数文件中,添加该文件以输出分页:(您可以稍后自定义HTML标记)

    /**
     * Displays a (simple) pagination to navigate between singular posts in a custom posts query.
     *
     * @uses understrap_post_nav()
     *
     * @param string $sep    Optional. String to use between the next/previous links. Default \' \'.
     * @param string $before Optional. String to use before the pagination. Default empty.
     * @param string $after  Optional. String to use after the pagination. Default empty.
     */
    function my_ordering_post_nav( $sep = \' \', $before = \'\', $after = \'\' ) {
        // Use understrap_post_nav() if the URL parameter isn\'t set, or if we\'re not on a
        // single team-members CPT post page.
        if ( ! isset( $_GET[\'current_ordering\'] ) || ! is_singular( \'team-members\' ) ) {
            return understrap_post_nav();
        }
    
        $current = get_queried_object_id();
        $offset  = $_GET[\'current_ordering\'];
    
        $ids = get_posts( array(
            \'fields\'         => \'ids\',
            \'offset\'         => max( 0, $offset - 1 ),
            \'posts_per_page\' => 3,
            // the rest below should be the same as the one used with get_posts() in the
            // about-page.php template
            \'post_type\'      => \'team-members\',
            \'meta_key\'       => \'ordering\',
            \'orderby\'        => \'meta_value_num\',
            \'order\'          => \'ASC\',
        ) );
    
        if ( empty( $ids ) ) {
            return;
        }
    
        $current_index = array_search( $current, $ids );
        if ( false === $current_index ) {
            return;
        }
    
        $prev_index    = $current_index + 1;
        $next_index    = $current_index - 1;
        $links         = array();
    
        if ( isset( $ids[ $prev_index ] ) ) {
            $post_id = $ids[ $prev_index ];
    
            $links[] = sprintf( \'<a href="%s">&laquo; %s</a>\',
                esc_url( my_ordering_permalink( $offset + 1, $post_id, false ) ),
                esc_html( get_the_title( $post_id ) )
            );
        }
    
        if ( isset( $ids[ $next_index ] ) ) {
            $post_id = $ids[ $next_index ];
    
            $links[] = sprintf( \'<a href="%s">%s &raquo;</a>\',
                esc_url( my_ordering_permalink( $offset - 1, $post_id, false ) ),
                esc_html( get_the_title( $post_id ) )
            );
        }
    
        echo $before . implode( $sep, $links ) . $after;
    }
    
    understrap_post_nav(); 到my_ordering_post_nav();.

    仅此而已,但请记住my_ordering_post_nav() 函数必须与about-page.php 模板(传递给的参数get_posts()), 除了fields, offsetposts_per_page.

    其他注释\'posts_per_page\' => -1 相当于\'nopaging\' => true, 这可能会导致一个巨大的查询,如果不是完全关闭,可能会导致网站运行极慢,这取决于数据库是否能够处理帖子选择(在您的情况下,通过元值选择),因此使用posts_per_page 相反,使用您知道永远不会到达的高数字,但这可以由数据库处理,也不会导致超时(在大型数组或数据集上循环时会发生超时)。

  • 我正在通过自定义字段的数值更改其顺序-如果meta值是一个数字,那么应该使用\'orderby\' => \'meta_value_num\' 确保值按数字而不是字符串排序。那样的话,1, 3, 10, 2 将正确分类为1, 2, 3, 10 而不是1, 10, 2, 3 这就是将值排序为字符串时会发生的情况。

  • get_posts() 默认情况下抑制所有筛选器,因此我建议您添加\'suppress_filters\' => false 以确保插件可以过滤查询或运行特定操作(当然,这是有充分理由的)。

    您可能需要创建一个特定于您的CPT的帖子模板,即。single-team-members.php, 并编辑该文件以使用my_ordering_post_nav() 函数,这意味着您无需编辑single.php 文件

  • 英寸about-page.php, 而不是简单地if( $posts ), 您应该使用if( ! empty( $posts ) ) 检查或确保$posts/数组不为空。

  • 相关推荐

    change pagination url

    目前,我的分页页面URL为:http://www.example.com/category_name/page/2但我需要将此URL结构更改为:http://www.example.com/category_name/?page=2等有什么解决方案吗?