やりたいこと
こんなカンジで各ページに手動でOrderをセットする
- page1000 (order: 1000)
- page1001 (order: 1001)
- page1002 (order: 1002)
- page2000 (order: 2000)
page1001を開くと、ページ下部に
<- page1000 page1002 ->
とページ送りが設置されている。
やる
いくつかのテーマをながめてみると、下記2つのファンクションで実装されていることがわかった。
中を追っていくと、両方ともget_adjacent_post(…)を呼んでおり、うまいことfilterなるものを設定すれば挙動を変えられそうな気がする。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
/** * Filters the WHERE clause in the SQL for an adjacent post query. * * The dynamic portion of the hook name, `$adjacent`, refers to the type * of adjacency, 'next' or 'previous'. * * @since 2.5.0 * @since 4.4.0 Added the `$taxonomy` and `$post` parameters. * * @param string $where The `WHERE` clause in the SQL. * @param bool $in_same_term Whether post should be in a same taxonomy term. * @param array $excluded_terms Array of excluded term IDs. * @param string $taxonomy Taxonomy. Used to identify the term used when `$in_same_term` is true. * @param WP_Post $post WP_Post object. */ $where = apply_filters( "get_{$adjacent}_post_where", $wpdb->prepare( "WHERE p.post_date $op %s AND p.post_type = %s $where", $current_post_date, $post->post_type ), $in_same_term, $excluded_terms, $taxonomy, $post ); /** * Filters the ORDER BY clause in the SQL for an adjacent post query. * * The dynamic portion of the hook name, `$adjacent`, refers to the type * of adjacency, 'next' or 'previous'. * * @since 2.5.0 * @since 4.4.0 Added the `$post` parameter. * * @param string $order_by The `ORDER BY` clause in the SQL. * @param WP_Post $post WP_Post object. */ $sort = apply_filters( "get_{$adjacent}_post_sort", "ORDER BY p.post_date $order LIMIT 1", $post ); |
テーマ hueman (3.3.2)の場合
注:get_adjacent_postの引数で$post(及び$taxonomy)が指定できるのはWordPress4.4.0から
なのでそれ以前はglobalのpostを使用する必要あり
Child Theme Configuratorというのを使って子テーマ(hueman-child)を作成
wp-content/themes/hueman-child
├── functions.php <- 自動で作成される。ここにフィルターを定義する。
├── page.php <- このテーマの固定ページにはページ送りが無いので、親テーマからコピーして変更
├── parts
│ └── post-nav.php <- 投稿の場合ここでページ送りを作成しているので、固定ページ用の処理を追加
├── screenshot.png
└── style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
<?php // Exit if accessed directly if ( !defined( 'ABSPATH' ) ) exit; // BEGIN ENQUEUE PARENT ACTION // AUTO GENERATED - Do not modify or remove comment markers above or below: function get_previous_page_where( $where, $in_same_term, $excluded_terms, $taxonomy, $post) { global $wpdb; return $wpdb->prepare( " WHERE p.ID != %s AND p.post_parent = %s AND ( p.menu_order < %s OR p.menu_order = %s AND p.post_date < %s ) AND p.post_type = %s AND p.post_status = 'publish'", $post->ID, $post->post_parent, $post->menu_order, $post->menu_order, $post->post_date, $post->post_type); } function get_next_page_where($where, $in_same_term, $excluded_terms, $taxonomy, $post) { global $wpdb; return $wpdb->prepare( " WHERE p.ID != %s AND p.post_parent = %s AND ( p.menu_order > %s OR p.menu_order = %s AND p.post_date > %s ) AND p.post_type = %s AND p.post_status = 'publish'", $post->ID, $post->post_parent, $post->menu_order, $post->menu_order, $post->post_date, $post->post_type); } function get_previous_page_sort($sort, $post) { return "ORDER BY p.menu_order DESC, p.post_date DESC LIMIT 1"; } function get_next_page_sort($sort, $post) { return "ORDER BY p.menu_order ASC, p.post_date ASC LIMIT 1"; } // END ENQUEUE PARENT ACTION |
実験として、同じ親ページを持つページだけを送りの対象にした。
(post_parentを指定)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
<?php get_header(); ?> <section class="content"> <?php hu_get_template_part('parts/page-title'); ?> <div class="pad group"> <?php while ( have_posts() ): the_post(); ?> <article <?php post_class('group'); ?>> <?php hu_get_template_part('parts/page-image'); ?> <div class="entry themeform"> <?php the_content(); ?> <div class="clear"></div> </div><!--/.entry--> </article> <?php if ( hu_is_checked('page-comments') ) { comments_template('/comments.php',true); } ?> <?php endwhile; ?> <?php if ( 'content' == hu_get_option( 'post-nav' ) ) { get_template_part('parts/post-nav'); } ?> </div><!--/.pad--> </section><!--/.content--> <?php get_sidebar(); ?> <?php get_footer(); ?> |
13行目を追加
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php if ( is_single() ): ?> <ul class="post-nav group"> <li class="previous"><?php previous_post_link('%link', '<i class="fa fa-chevron-left"></i><strong>'.__('Previous story', 'hueman').'</strong> <span>%title</span>', true); ?></li> <li class="next"><?php next_post_link('%link', '<i class="fa fa-chevron-right"></i><strong>'.__('Next story', 'hueman').'</strong> <span>%title</span>', true); ?></li> </ul> <?php elseif ( is_page() ): ?> <?php add_filter( 'get_previous_post_where', 'get_previous_page_where', 10, 5 ); add_filter( 'get_previous_post_sort', 'get_previous_page_sort', 10, 2 ); add_filter( 'get_next_post_where', 'get_next_page_where', 10, 5 ); add_filter( 'get_next_post_sort', 'get_next_page_sort', 10, 2 ); ?> <ul class="post-nav group"> <li class="previous"><?php previous_post_link('%link', '<i class="fa fa-chevron-left"></i><strong>'.__('Previous story', 'hueman').'</strong> <span>%title</span>', false); ?></li> <li class="next"><?php next_post_link('%link', '<i class="fa fa-chevron-right"></i><strong>'.__('Next story', 'hueman').'</strong> <span>%title</span>', false); ?></li> </ul> <?php endif; ?> |
3, 4行目でxxx_post_linkのお尻の引数をtrueにした。(投稿のページ送りを同カテゴリーに制限)
6-16行目で固定ページ用のフィルターをセット
下記の用に表示
投稿ページ:同カテゴリー制限、投稿時刻昇順
固定ページ:同親ページ制限、Order(menu_order)昇順
テーマ customizr (3.4.36)の場合
注:get_adjacent_postの引数で$post(及び$taxonomy)が指定できるのはWordPress4.4.0から
なのでそれ以前はglobalのpostを使用する必要あり
customizrの場合、固定ページのページ送りがサポートされており、UIからオプションをONにする。
ただ、このままだと固定ページのソートが投稿時刻になっているので、Order(menu_order)に変更する。
さっきhuemanで実装した”投稿のページ送りを同カテゴリーに制限”について
- Restrict the post navigation to the same category
を見るとtc_previous_single_post_link_args、tc_next_single_post_link_argsという引数を定義すると制御できるように書いてあるけど、呼び出し元のczr-front.phpで前後投稿の存在判定をこの引数と関係なく行っているので、下記のように空のボタンが表示されてしまう。
- czr-front.phpは結構でかいファイルなのでいぢりたくない
- 同カテゴリーに縛らなくていい気がしてきた
ので、投稿ページはそのまま(同カテゴリー制限なし)、固定ページも同親ページ制限は実装せず、ソートのみOrder順に変更する。
Child Theme Configuratorというのを使って子テーマ(customizr-child)を作成
wp-content/themes/customizr-child
├── functions.php <- 自動で作成される。ここにフィルターを定義する。
├── screenshot.png
└── style.css
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
<?php // Exit if accessed directly if ( !defined( 'ABSPATH' ) ) exit; // BEGIN ENQUEUE PARENT ACTION // AUTO GENERATED - Do not modify or remove comment markers above or below: add_filter('tc_show_post_navigation', 'add_filter_for_page'); function add_filter_for_page ( $post_nav_enabled ) { if ( is_page() ) { add_filter( 'get_previous_post_where', 'get_previous_page_where', 10, 5 ); add_filter( 'get_previous_post_sort', 'get_previous_page_sort', 10, 2 ); add_filter( 'get_next_post_where', 'get_next_page_where', 10, 5 ); add_filter( 'get_next_post_sort', 'get_next_page_sort', 10, 2 ); } return $post_nav_enabled; } function get_previous_page_where( $where, $in_same_term, $excluded_terms, $taxonomy, $post) { global $wpdb; return $wpdb->prepare( " WHERE p.ID != %s AND ( p.menu_order < %s OR p.menu_order = %s AND p.post_date < %s ) AND p.post_type = %s AND p.post_status = 'publish'", $post->ID, $post->menu_order, $post->menu_order, $post->post_date, $post->post_type); } function get_next_page_where($where, $in_same_term, $excluded_terms, $taxonomy, $post) { global $wpdb; return $wpdb->prepare( " WHERE p.ID != %s AND ( p.menu_order > %s OR p.menu_order = %s AND p.post_date > %s ) AND p.post_type = %s AND p.post_status = 'publish'", $post->ID, $post->menu_order, $post->menu_order, $post->post_date, $post->post_type); } function get_previous_page_sort($sort, $post) { return "ORDER BY p.menu_order DESC, p.post_date DESC LIMIT 1"; } function get_next_page_sort($sort, $post) { return "ORDER BY p.menu_order ASC, p.post_date ASC LIMIT 1"; } // END ENQUEUE PARENT ACTION |
8行目のtc_show_post_navigationは、czr-front.php内部のページ送り作成処理から呼び出してもらうため。
下記の用に表示
投稿ページ:投稿時刻昇順(デフォルトのまま)
固定ページ:Order(menu_order)昇順