single-custom.phpのWP_Queryページネーション


16

私がやろうとしていること:

WP_Querysingle-custom-post-type.phpテンプレートファイルでページネーションを設定する

私がやった事

1)「authors」という投稿タイプを作成しました。その投稿タイプ内の各投稿は個々の著者です。

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
ピーターグースン

2
無関係ですが、エコーする必要はありませんthe_title()
Pieter Goosen

2
されて'meta_value' => $author_id言及したドロップダウンリストから充填されていますか?また、ドロップダウンから各著者を選択すると、最初の10件の投稿が正しく表示されますか?
スティーブンS.

1
それ$author_query->have_posts()が返さtrueれ、$author_query実際に投稿が含まれていることを確認しましたか?
カイザー

回答:


17

2つの問題があります。

最初の問題

この線

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

単一のポストビューでは、URLにが含まれている場合、'/page/XX/'WordPressの変数セットはで'page'あり、ではないため、失敗します'paged'

'page'代わりに使用すると考えるかもしれ'paged'ませんが、'page'変数が複数ページの単一の投稿に使用されることを意図している場合(ページ区切りを使用<!--nextpage-->)、投稿が複数ページではない場合、WordPressはリクエストをリダイレクトするため、それも機能しませんなしのURLへ'/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'クエリ変数を正しく設定します。

第二の問題

next_posts_link()そしてprevious_posts_link()両方のチェックは、if ( ! is_single() )改ページを表示します。

さて、is_single()これらの機能は期待どおり動作しないことができるので、あなたは、「著者」タイプの単一のポストにあるので、あなたのケースでは真です。

次の3つの可能性があります。

  1. query_postsメインクエリをオーバーライドするために使用します(実際に推奨されません
  2. ページis_single()に対してfalse であるため、カスタム投稿タイプの代わりにカスタムページテンプレートを使用します。コードはそこで機能します。
  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を使用しています。
シェーン

1
@Shaneは、WPMLが何らかのコードを機能させないフィルターを実行しているようです。しかし、これは非常に大きなプラグインであるため、何千行ものコードを調べて、どこに問題があるのか​​を理解することはできません。WPMLサポートに聞いてみてください。
gmazzap

@Shane WPMLサポートフォーラム -上記で機能する場合(これが想定されます)、解決策としてマークしてください。とにかく、WPMLの競合はトピックから外れている/このサイトの範囲外です。
カイザー

主にページネーションの問題を解決するのに役立ったため、素晴らしい答えです。私は同様のタスクを実行しており、ループする2番目の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
回答ありがとうございます!残念ながら、それは何の違いももたらさないようです。ページネーションのリンクが表示されない
シェーン

1
スティーブン、なぜそれが役立つのですか?はい、これはグローバルなコンテキストからそれをもたらしますが、今のところあなたはそれで何もしていません。グローバルをオーバーライドする場合は、を使用します$GLOBALS['paged'] = get_query_var( 'paged' );。それ以外の場合は、グローバルコンテンツのみを使用します。
カイザー

@Shane Hmm、テンプレートページは静的なフロントページとして使用されていますか?
スティーブンS.

いいえ、カスタム投稿タイプの単一の投稿テンプレートとしてのみ使用されています。クエリをから$author_queryに変更$wp_queryしてみたところ、ページネーションが表示されたように見えましたが、クリックするとページが更新され、複数のページがあっても実際には次のページに移動しません。これらの変更を反映するように回答を更新しました。
シェーン

1
php.netの説明はそれほど悪くはありません。とで遊んでみることをお勧めglobal$GLOBALSます。少しvar_dump()、いくつかの機能とあなたは大丈夫です。少し試行錯誤してそれを本当に理解するには、およそ 半時間必要です。これは、関数とクラス、およびOOPアプローチ全体をよりよく理解するのに役立ちます。そして、それは明らかに名前空間の理解により近づきます:)
kaiser
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.