カスタムループのページ付けを修正するにはどうすればよいですか?
4 回答
- 投票
-
- 2015-11-09
ページネーションを使用したカスタムループにこのコードを使用します:
<?php if ( get_query_var('paged') ) { $paged = get_query_var('paged'); } elseif ( get_query_var('page') ) { // 'page' is used instead of 'paged' on Static Front Page $paged = get_query_var('page'); } else { $paged = 1; } $custom_query_args = array( 'post_type' => 'post', 'posts_per_page' => get_option('posts_per_page'), 'paged' => $paged, 'post_status' => 'publish', 'ignore_sticky_posts' => true, //'category_name' => 'custom-cat', 'order' => 'DESC', // 'ASC' 'orderby' => 'date' // modified | title | name | ID | rand ); $custom_query = new WP_Query( $custom_query_args ); if ( $custom_query->have_posts() ) : while( $custom_query->have_posts() ) : $custom_query->the_post(); ?> <article <?php post_class(); ?>> <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3> <small><?php the_time('F jS, Y') ?> by <?php the_author_posts_link() ?></small> <div><?php the_excerpt(); ?></div> </article> <?php endwhile; ?> <?php if ($custom_query->max_num_pages > 1) : // custom pagination ?> <?php $orig_query = $wp_query; // fix for pagination to work $wp_query = $custom_query; ?> <nav class="prev-next-posts"> <div class="prev-posts-link"> <?php echo get_next_posts_link( 'Older Entries', $custom_query->max_num_pages ); ?> </div> <div class="next-posts-link"> <?php echo get_previous_posts_link( 'Newer Entries' ); ?> </div> </nav> <?php $wp_query = $orig_query; // fix for pagination to work ?> <?php endif; ?> <?php wp_reset_postdata(); // reset the query else: echo '<p>'.__('Sorry, no posts matched your criteria.').'</p>'; endif; ?>
出典:
-
ページ付けを使用したWordPressカスタムループ
I use this code for custom loop with pagination:
<?php if ( get_query_var('paged') ) { $paged = get_query_var('paged'); } elseif ( get_query_var('page') ) { // 'page' is used instead of 'paged' on Static Front Page $paged = get_query_var('page'); } else { $paged = 1; } $custom_query_args = array( 'post_type' => 'post', 'posts_per_page' => get_option('posts_per_page'), 'paged' => $paged, 'post_status' => 'publish', 'ignore_sticky_posts' => true, //'category_name' => 'custom-cat', 'order' => 'DESC', // 'ASC' 'orderby' => 'date' // modified | title | name | ID | rand ); $custom_query = new WP_Query( $custom_query_args ); if ( $custom_query->have_posts() ) : while( $custom_query->have_posts() ) : $custom_query->the_post(); ?> <article <?php post_class(); ?>> <h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></h3> <small><?php the_time('F jS, Y') ?> by <?php the_author_posts_link() ?></small> <div><?php the_excerpt(); ?></div> </article> <?php endwhile; ?> <?php if ($custom_query->max_num_pages > 1) : // custom pagination ?> <?php $orig_query = $wp_query; // fix for pagination to work $wp_query = $custom_query; ?> <nav class="prev-next-posts"> <div class="prev-posts-link"> <?php echo get_next_posts_link( 'Older Entries', $custom_query->max_num_pages ); ?> </div> <div class="next-posts-link"> <?php echo get_previous_posts_link( 'Newer Entries' ); ?> </div> </nav> <?php $wp_query = $orig_query; // fix for pagination to work ?> <?php endif; ?> <?php wp_reset_postdata(); // reset the query else: echo '<p>'.__('Sorry, no posts matched your criteria.').'</p>'; endif; ?>
Source:
-
- 2016-12-17
いつものように素晴らしいチップ.これの補足として、ページに添付されたグローバルページテンプレートを「イントロテキスト」に使用し、その後にページングするサブクエリが続く状況を考えてみます.
上記のように
paginate_links()を使用しますが、ほとんどがデフォルトです(かなりのパーマリンクがオンになっています)ページネーションリンクはデフォルトで mysite.ca/page-slug/page/#
になります.これはすばらしいですが、WordPressが認識しないため、404
エラーがスローされます.その特定のURL構造について、実際には「page-slug」の子である「page」の子ページを探します.ここでの秘訣は、
/page/#/
構造を受け入れ、それをクエリ文字列に書き換える特定の「疑似アーカイブページ」ページスラッグにのみ適用される気の利いた書き換えルールを挿入することです. WordPressは理解できます.つまり、mysite.ca/?pagename=page-slug&paged=#
です.pagename
とpaged
ではなくname
とpage
に注意してください(これは文字通り何時間もの悲しみを引き起こし、ここでこの答えを動機付けました! .リダイレクトルールは次のとおりです:
add_rewrite_rule( "page-slug/page/([0-9]{1,})/?$", 'index.php?pagename=page-slug&paged=$matches[1]', "top" );
いつものように、書き換えルールを変更するときは、管理バックエンドの[設定]> [パーマリンク]にアクセスしてパーマリンクをフラッシュすることを忘れないでください.
このように動作する複数のページがある場合(たとえば、複数のカスタム投稿タイプを処理する場合)、ページスラッグごとに新しい書き換えルールを作成しないようにすることができます.識別したページスラッグに対して機能する、より一般的な正規表現を記述できます.
1つのアプローチは以下のとおりです.
function wpse_120407_pseudo_archive_rewrite(){ // Add the slugs of the pages that are using a Global Template to simulate being an "archive" page $pseudo_archive_pages = array( "all-movies", "all-actors" ); $slug_clause = implode( "|", $pseudo_archive_pages ); add_rewrite_rule( "($slug_clause)/page/([0-9]{1,})/?$", 'index.php?pagename=$matches[1]&paged=$matches[2]', "top" ); } add_action( 'init', 'wpse_120407_pseudo_archive_rewrite' );
デメリット/警告
このアプローチの欠点の1つは、ページスラッグのハードコーディングです.管理者がその疑似アーカイブページのページスラッグを変更した場合、あなたは乾杯します-書き換えルールは一致しなくなり、恐ろしい404を取得します.
この方法の回避策を考えることができるかどうかはわかりませんが、何らかの形で書き換えルールをトリガーしたのがグローバルページテンプレートであると便利です.いつの日か、他の誰もその特定のナッツを割ったことがなければ、私はこの答えを再訪するかもしれません.
Awesome as always Chip. As an addendum to this, consider the situation whereby you are using a global page template attached to a Page for some "intro text" and it's followed by a subquery that you want to be paged.
Using paginate_links() as you mention above, with mostly defaults, (and assuming you have pretty permalinks turned on) your pagination links will default to
mysite.ca/page-slug/page/#
which is lovely but will throw404
errors because WordPress doesn't know about that particular URL structure and will actually look for a child page of "page" that's a child of "page-slug".The trick here is to insert a nifty rewrite rule that only applies to that particular "pseudo archive page" page slug that accepts the
/page/#/
structure and rewrites it to a query string that WordPress CAN understand, namelymysite.ca/?pagename=page-slug&paged=#
. Notepagename
andpaged
notname
andpage
(which caused me literally HOURS of grief, motivating this answer here!).Here's the redirect rule:
add_rewrite_rule( "page-slug/page/([0-9]{1,})/?$", 'index.php?pagename=page-slug&paged=$matches[1]', "top" );
As always, when changing rewrite rules, remember to flush your permalinks by visiting Settings > Permalinks in the Admin back-end.
If you have multiple pages that are going to behave this way (for example, when dealing with multiple custom post types), you might want to avoid creating a new rewrite rule for each page slug. We can write a more generic regular expression that works for any page slug you identify.
One approach is below:
function wpse_120407_pseudo_archive_rewrite(){ // Add the slugs of the pages that are using a Global Template to simulate being an "archive" page $pseudo_archive_pages = array( "all-movies", "all-actors" ); $slug_clause = implode( "|", $pseudo_archive_pages ); add_rewrite_rule( "($slug_clause)/page/([0-9]{1,})/?$", 'index.php?pagename=$matches[1]&paged=$matches[2]', "top" ); } add_action( 'init', 'wpse_120407_pseudo_archive_rewrite' );
Disadvantages / Caveats
One disadvantage of this approach that makes me puke in my mouth a little is the hard-coding of the Page slug. If an admin ever changes the page slug of that pseudo-archive page, you're toast - the rewrite rule will no longer match and you'll get the dreaded 404.
I'm not sure I can think of a workaround for this method, but it would be nice if it were the global page template that somehow triggered the rewrite rule. Some day I may revisit this answer if no one else has cracked that particular nut.
-
ポストセーブをフックし、ページのメタキー `_wp_page_template`の下にアーカイブテンプレートがあるかどうかを確認してから、別の書き換えルールとフラッシュルールを追加できます.You could hook post save, check if the page has your archive template under the meta key `_wp_page_template`, then add another rewrite and flush rules.
- 1
- 2016-12-17
- Milo
-
- 2017-01-13
query_posts()
を介してメインループクエリを変更しました.ページネーションが機能しないのはなぜですか.どうすれば修正できますか?すばらしい答え作成されたチップは今日修正する必要があります.
しばらくの間、メインクエリの実行直後にグローバルな$wp_the_query
と等しくなる$wp_query
変数があります.これがチップの答えの一部である理由です:
メインクエリオブジェクトをハックする
はもう必要ありません. 一時変数を作成すると、この部分を忘れることができます.
// Pagination fix $temp_query = $wp_query; $wp_query = NULL; $wp_query = $custom_query;
これで、次のように呼び出すことができます:
$wp_query = $wp_the_query;
またはさらに良いと呼ぶことができます:
wp_reset_query();
他のすべてのチップの概要はそのままです. そのquery-reset-partの後で、
f($wp_query)
であるページネーション関数を呼び出すことができます—それらは$wp_the_query
グローバルに依存します.
ページネーションの仕組みをさらに改善し、
query_posts
関数により多くの自由を与えるために、私はこの可能な改善を作成しました:I have modified the main loop query via
query_posts()
. Why isn't pagination working, and how do I fix it?Great answer Chip created needs to be modified today.
For some time we have$wp_the_query
variable that should be equal to the$wp_query
global just after the main query executes.This is why this the part from the Chip's answer:
Hack the main query object
is not needed anymore. We can forget this part with creating the temporary variable.
// Pagination fix $temp_query = $wp_query; $wp_query = NULL; $wp_query = $custom_query;
So now we can call:
$wp_query = $wp_the_query;
or even better we can call:
wp_reset_query();
Everything other Chip outlined stays. After that query-reset-part you can call the pagination functions that are
f($wp_query)
, — they depend on$wp_query
global.
In order to further improve the pagination mechanics and to give more freedom to the
query_posts
function I created this possible improvement: -
- 2018-03-06
global $wp_query; $paged = get_query_var('paged', 1); $args = array( 'post_type' => '{your_post_type_name}', 'meta_query' => array('{add your meta query argument if need}'), 'orderby' => 'modified', 'order' => 'DESC', 'posts_per_page' => 20, 'paged' => $paged ); $query = new WP_Query($args); if($query->have_posts()): while ($query->have_posts()) : $query->the_post(); //add your code here endwhile; wp_reset_query(); //manage pagination based on custom Query. $GLOBALS['wp_query']->max_num_pages = $query->max_num_pages; the_posts_pagination(array( 'mid_size' => 1, 'prev_text' => __('Previous page', 'patelextensions'), 'next_text' => __('Next page', 'patelextensions'), 'before_page_number' => '<span class="meta-nav screen-reader-text">' . __('Page', 'patelextensions') . ' </span>', )); else: ?> <div class="container text-center"><?php echo _d('Result not found','30'); ?></div> <?php endif; ?>
global $wp_query; $paged = get_query_var('paged', 1); $args = array( 'post_type' => '{your_post_type_name}', 'meta_query' => array('{add your meta query argument if need}'), 'orderby' => 'modified', 'order' => 'DESC', 'posts_per_page' => 20, 'paged' => $paged ); $query = new WP_Query($args); if($query->have_posts()): while ($query->have_posts()) : $query->the_post(); //add your code here endwhile; wp_reset_query(); //manage pagination based on custom Query. $GLOBALS['wp_query']->max_num_pages = $query->max_num_pages; the_posts_pagination(array( 'mid_size' => 1, 'prev_text' => __('Previous page', 'patelextensions'), 'next_text' => __('Next page', 'patelextensions'), 'before_page_number' => '<span class="meta-nav screen-reader-text">' . __('Page', 'patelextensions') . ' </span>', )); else: ?> <div class="container text-center"><?php echo _d('Result not found','30'); ?></div> <?php endif; ?>
カスタム/セカンダリクエリをテンプレートファイル/カスタムページテンプレートに追加しました.メインのクエリループのページ付けを使用する代わりに、WordPressにページ付けにカスタムクエリを使用させるにはどうすればよいですか?
補遺
query_posts()
を介してメインループクエリを変更しました.ページネーションが機能しないのはなぜですか.どうすれば修正できますか?