WP_Query分页on single-custom.php


16

我要做什么:

WP_Query在single-custom-post-type.php模板文件中设置分页

我做了什么

1)创建了一个称为“作者”的帖子类型。该帖子类型中的每个帖子都是一位作者。

2)标准编辑帖子屏幕页面包含一个下拉列表,其中列出了作者自定义帖子类型的所有帖子(作者)。

3)创建了single-authors.php模板,该模板使用下拉菜单中的作者元数据查询所有帖子,因此结果是分配了相同作者(类似于存档)的帖子列表:

<?php

// set the "paged" parameter (use 'page' if the query is on a static front page)
global $paged;

/*We need this here to add and maintain Pagination if Template is assigned to Front Page*/
if ( get_query_var( 'paged' ) ) {
    $paged = get_query_var('paged');
} elseif ( get_query_var( 'page' ) ) {
    $paged = get_query_var( 'page' );
} else {
    $paged = 1;
}

$args = array(
    'posts_per_page'    =>  10,
    'meta_key'          => 'author_select',
    'meta_value'        => $author_id,
    'paged'             => $paged,
);

$temp = $wp_query;
$wp_query = NULL;

$wp_query = new WP_Query($args);

?>

<?php if( $wp_query->have_posts() ) : ?>    
    <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
    <?php // Successfully outputs the results of the above query, so I've omitted the code from this example. ?>

    <?php endwhile; ?>

<div class="single_navigation"> 
    <?php if( get_adjacent_post( false, '', true ) ) { ?>
        <span class="prev"><?php previous_post_link( '&lt; %link' ) ?></span>
    <?php } ?>

    <?php if( get_adjacent_post( false, '', false ) ) { ?>
        <span class="next"><?php next_post_link( '%link &gt;' ) ?></span>
    <?php } ?>
    </div><!--/single navigation-->
<?php endif; ?>

<?php
    $wp_query = null;
    $wp_query = $temp;
    wp_reset_query();
?>

我所坚持的

分页链接不会出现。我进行了一些研究,发现它们使用了$wp_query变量,但是,当我将查询变量更改为时$wp_query,出现了链接,但是当单击时却没有执行任何操作。

知道我要去哪里错了吗?

编辑:

为了回答您的一些问题,我的查询成功输出了我正在查询的帖子,$ author_id已经具有我未包含在此代码段中的值。同样,我在while循环中省略了实际的内容输出,因为那不是问题。问题是我需要对单个帖子中已经存在的内容进行分页。

此功能的目的是允许帖子具有自定义作者(内置用户系统之外),并且此模板的目的是输出给定作者(已在工作)的所有帖子。


3
格式正确的问题的支持者,尽管您没有描述为什么要这样做,但它是否与当前作者框相关联?
汤姆·J·诺维尔

1
我真的同意@TomJNowell。+1
Pieter Goosen 2014年

2
无关,但不必回声the_title()
Pieter Goosen 2014年

2
是否'meta_value' => $author_id从下拉列表中提到?通过下拉列表选择每位作者时,前十条帖子显示正确吗?
Stephen S.

1
您确定$author_query->have_posts()返回true的内容$author_query确实包含任何帖子吗?
kaiser 2014年

Answers:


17

您有2个问题。

第一个问题

线

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

将失败,因为在单一发布视图中,当URL包含时'/page/XX/',WordPress设置的变量为'page'和not 'paged'

您可能会考虑使用'page'而不是'paged',但是这也不起作用,因为一旦'page'变量打算用于多页单数帖子(使用进行页面分隔<!--nextpage-->),并且帖子不是多页,则WordPress将重定向请求到没有网址'/page/XX/'

当您命名查询变量时,会发生这种情况 $wp_query

解决方案是通过删除负责该功能的功能来防止该重定向,即 'redirect_canonical'连接到'template_redirect'

因此,在您的functions.php添加:

add_action( 'template_redirect', function() {
    if ( is_singular( 'authors' ) ) {
        global $wp_query;
        $page = ( int ) $wp_query->get( 'page' );
        if ( $page > 1 ) {
            // convert 'page' to 'paged'
            $wp_query->set( 'page', 1 );
            $wp_query->set( 'paged', $page );
        }
        // prevent redirect
        remove_action( 'template_redirect', 'redirect_canonical' );
    }
}, 0 ); // on priority 0 to remove 'redirect_canonical' added with priority 10

现在WordPress将不再重定向,并将正确设置 'paged'查询var。

第二个问题

next_posts_link()previous_posts_link()都检查if ( ! is_single() )以显示分页。

现在, is_single()对于您而言,这是对的,因为您处于“作者”类型的单个帖子中,因此这些功能无法按预期工作。

您有3种可能性:

  1. 使用query_posts覆盖主查询(真推荐)
  2. 使用自定义页面模板而不是自定义帖子类型,因为is_single()页面不正确,您的代码将在那里工作。
  3. 编写自己的分页功能并使用

这是解决方案编号3的代码:

function my_pagination_link( $label = NULL, $dir = 'next', WP_Query $query = NULL ) {
    if ( is_null( $query ) ) {
        $query = $GLOBALS['wp_query'];
    }
    $max_page = ( int ) $query->max_num_pages;
    // only one page for the query, do nothing
    if ( $max_page <= 1 ) {
        return;
    }
    $paged = ( int ) $query->get( 'paged' );
    if ( empty( $paged ) ) {
        $paged = 1;
    }
    $target_page = $dir === 'next' ?  $paged + 1 : $paged - 1;
    // if 1st page requiring previous or last page requiring next, do nothing
    if ( $target_page < 1 || $target_page > $max_page ) {
        return;
    }
    if ( null === $label ) {
        $label = __( 'Next Page &raquo;' );
    }

    $label = preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label );
    printf( '<a href="%s">%s</a>', get_pagenum_link( $target_page ), esc_html( $label ) );
}

并像在这样使用它single-authors.php

my_pagination_link( 'Older Entries', 'next', $author_query );
my_pagination_link( 'Newer Entries', 'prev', $author_query );

很详细的答案,谢谢!这适用于网站的英语一侧,但在法语一侧,分页链接没有任何作用,它们只会刷新页面。我正在使用WPML。
Shane

1
@Shane似乎WPML运行一些过滤器来阻止代码工作。但是它是一个很大的插件,因此我无法挖掘成千上万行代码来了解冲突所在。尝试询问WPML支持。
gmazzap

@Shane WPML支持论坛 -如果以上适用(我假设),请将其标记为解决方案。无论如何,WPML冲突不在本站点的讨论范围之内。
kaiser 2014年

很棒的答案,主要是因为它帮助我解决了分页问题。我一直在做类似的任务,并创建了第二个WP_Query进行循环。我打电话the_posts_pagination却不得不在这个问题列出来取原wp_query的副本:wordpress.stackexchange.com/questions/216821/...
亚历山大Holsgrove

1
您是正确的@HongPong,固定,谢谢。
gmazzap

0

基于另一个类似的WPSE问题“ 分页不起作用wp_query自定义字段值 ”,我建议将其添加global $paged;到模板文件的开头:

global $paged;
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

1
感谢您的回复!不幸的是,它似乎没有任何区别。分页链接没有出现
Shane

1
史蒂芬,为什么要帮忙?是的,这可以从全局的角度来看待它,但是到目前为止您还没有做任何事情。如果要覆盖全局,请使用$GLOBALS['paged'] = get_query_var( 'paged' );。否则,只使用globals内容。
kaiser 2014年

@Shane Hmm,模板页面是否用作静态首页?
Stephen S.

不,它仅用作自定义帖子类型的单个帖子模板。我确实尝试将查询从更改$author_query$wp_query,这似乎使分页出现,但是当我单击它时,页面会刷新,即使有多个页面,实际上也不会转到下一页。我已经更新了我的答案以反映这些更改。
Shane

1
php.net的解释是没有那么糟糕。我建议只global和and 一起玩$GLOBALS。的var_dump(),一些功能就可以了。要通过一点尝试/错误真正了解它,您将获得大约。需要半个小时。这将帮助您更好地了解函数与类以及整个OOP方法。显然,它将使您更加了解名称空间:)
kaiser 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.