Your SlideShare is downloading. ×
これからのpre_get_postsの話をしよう
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

これからのpre_get_postsの話をしよう

24,759

Published on

第24回WordBench神戸で話した資料です。

第24回WordBench神戸で話した資料です。

Published in: Technology
0 Comments
34 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
24,759
On Slideshare
0
From Embeds
0
Number of Embeds
14
Actions
Shares
0
Downloads
28
Comments
0
Likes
34
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. これからの by @HissyNC / WordBench Kobe Group pre_get_posts: What's the Right Way to Use? pre_get_posts の話をしよう 1
  • 2. query_posts非推奨? 『query_postsを捨てよ、pre_get_postsを 使おう』というブログ記事を公開したとこ ろ、はてブなどでバズる。「いつの間にこ んなことになっていたんだよ…」「非推奨 だなんて!いますぐ直さなきゃ!」「急に 言われても困る」「query_posts使いまく ってたぜマジかよ…」「初心者にこの説明 はキツイでしょ」等々の意見が噴出。 2
  • 3. pre_get_postsとは何か? 結局、Codexのquery_postsのページに非 推奨の文字が入ったのは一時的なもので、 その後表現が修正され、「query_postsの 代わりにpre_get_postsフィルターを使う ことを強く推奨する」となった。ではなぜ 数多のWordPress本でも紹介されている query_postsが推奨されないのだろうか。 pre_get_postsフィルターとは何なのか。 3
  • 4. まず テンプレート とは何か 4
  • 5. データベースから 目的のデータを 取得して 表示するためのもの 5
  • 6. ではない 6
  • 7. テンプレートとは 表示するデータを 整形する ためのもの 7
  • 8. データを取得する 目的には 本来使わない 8
  • 9. どんなデータを 取得するかを 決定するのは 9
  • 10. URL 10
  • 11. ?p=1 ?cat=1 ?cat=1&post_type=book&paged=2 クエリー・ストリングという $query_string 11
  • 12. URLで どのデータを取得 するかが決まる どんな処理を行う かが決まる 12
  • 13. ほかのCMS でも同じ 13
  • 14. URLがページの 内容を表している = インターネットの 基本的な概念 14
  • 15. ここで疑問 15
  • 16. Webページには たくさんのデータ が表示されており 各ページで共通の ものもある 16
  • 17. たとえば サイドバーに 新着記事を5件表示 URLとは関係なく どのページにもある 17
  • 18. 記事の下に 関連記事を5件表示 URLとは間接的に関係 があるが 直接示しているもの ではない 18
  • 19. これらを サブクエリー と呼ぶ 19
  • 20. ?p=1 ?cat=1 ?cat=1&post_type=book&paged=2 クエリー・ストリングと直接対応し ているデータのことを 20
  • 21. メインクエリー と呼ぶ 21
  • 22. メインクエリー と サブクエリー 違いを理解しよう 22
  • 23. トップページの内容と してニュースカテゴリ ーの記事を表示する メインクエリー or サブクエリー? 23
  • 24. トップページの内容と してニュースカテゴリ ーの記事を表示する メインクエリー or サブクエリー? 24
  • 25. WordPressでは、フロントページ は新着投稿か、固定ページか、 2択です。CMSとしてはそれだ け?と違和感がありますが、そう いう設計ですので、本来特定のカ テゴリーの記事をトップページで 表示するのはWordPressではでき ません。get_postsを使うか、ウ ィジェットを使いましょう 25
  • 26. query_posts の 迷宮 26
  • 27. query_postsとは 本来 メインクエリーを 改変するためのもの 27
  • 28. http://example.com/?cat=1 28
  • 29. http://example.com/?cat=1 カテゴリーID が 1 28
  • 30. http://example.com/?cat=1 have_posts() = 投稿が存在する? カテゴリーID が 1 28
  • 31. http://example.com/?cat=1 have_posts() = 投稿が存在する? カテゴリーID が 1 the_post() = テンプレートタグを有効化 28
  • 32. http://example.com/?cat=1 have_posts() = 投稿が存在する? カテゴリーID が 1 the_post() = テンプレートタグを有効化 <a href= <?php the_permalink(); ?> > <h2> <?php the_title(); ?></a> </h2> 28
  • 33. http://example.com/?cat=1 have_posts() = 投稿が存在する? カテゴリーID が 1 the_post() = テンプレートタグを有効化 <a href= <?php the_permalink(); ?> > <h2> <?php the_title(); ?></a> </h2> ↓次の投稿へ have_posts() = 投稿が存在する? 28
  • 34. カテゴリーを指定している が、それ以外は? 表示件数(10件?) 並び順(投稿日が新しい順) 投稿タイプ(投稿) デフォルト設定がある 29
  • 35. メインクエリーには デフォルト設定 がある 30
  • 36. メインクエリーの デフォルト設定を 変更したい = query_posts 31
  • 37. 32
  • 38. ?cat=1 32
  • 39. ?cat=1 デフォルト設定 32
  • 40. ?cat=1 デフォルト設定 クエリーストリングの生成 32
  • 41. ?cat=1 条件分岐タグの設定 デフォルト設定 クエリーストリングの生成 32
  • 42. ?cat=1 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 クエリーストリングの生成 32
  • 43. ?cat=1 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み クエリーストリングの生成 32
  • 44. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 <a href= <?php the_permalink(); ?> > <h2> 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み クエリーストリングの生成 32
  • 45. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み クエリーストリングの生成 32
  • 46. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 クエリーストリングの生成 32
  • 47. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 クエリーストリングの生成 32
  • 48. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 クエリーストリングの生成 32
  • 49. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 クエリーストリングの生成 クエリーストリングの再生成 32
  • 50. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 クエリーストリングの生成 クエリーストリングの再生成 条件分岐タグの再設定 32
  • 51. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 クエリーストリングの生成 クエリーストリングの再生成 条件分岐タグの再設定 データベースから投稿を再取得 32
  • 52. ?cat=1 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 条件分岐タグの設定 デフォルト設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 クエリーストリングの生成 クエリーストリングの再生成 条件分岐タグの再設定 データベースから投稿を再取得 query_posts以前のアレコレが消えてしまった! 32
  • 53. 大丈夫! 戻す手段が あります 33
  • 54. wp_reset_query() query_posts 発動前の状態に戻す 34
  • 55. query_posts 何が問題なのか? 35
  • 56. ページ送りが効かない (頻出) 原因 = $query_string と結合していない global $query_string; query_posts( $query_string . '&order=ASC' ); 36
  • 57. 条件分岐タグの設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 query_posts()以前の条件で テンプレートが選ばれてしまう =意図せず404になる 37
  • 58. 条件分岐タグの設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 条件分岐タグの再設定 2回DBから投稿データを取得 =非効率、表示遅速の原因 38
  • 59. 条件分岐タグの設定 データベースから投稿を取得 使用するテンプレートの読み込み query_posts() = 投稿の再取得 条件分岐タグの再設定 条件分岐タグが上書きされる =混乱のもと 39
  • 60. 条件分岐タグの上書き と、query_posts()を サブクエリーの取得に 使ってしまう間違いが 重なるとカオス 40
  • 61. header.php footer.php category.php is_category() = true sidebar.phpで query_posts()を使用 wp_reset_query() 書き忘れ is_category() = false テンプレートファイルをま たいで影響が出る 41
  • 62. まとめ 42
  • 63. query_postsは 便利だが、影響範囲が 大きすぎる 43
  • 64. 条件分岐の上書きは 初心者には分かりにくい 44
  • 65. これからの 推奨される 方法 45
  • 66. メインクエリー の改変 = pre_get_posts 46
  • 67. サブクエリー の作成 = get_posts 47
  • 68. サブクエリー の作成 = get_posts 条件分岐タグが書き換わらない 47
  • 69. 用途によって 使いわけよう 48
  • 70. メインクエリー の改変 = pre_get_posts 49
  • 71. function 関数( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( クエリーの改変を適用する条件 ) { $query->set( パラメーター , 値 ); return; } } add_action( 'pre_get_posts', '関数名' ); pre_get_posts基本文法 50
  • 72. function 関数( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( クエリーの改変を適用する条件 ) { $query->set( パラメーター , 値 ); return; } } add_action( 'pre_get_posts', '関数名' ); pre_get_posts基本文法 管理画面とメインクエリー以外 には適用しない 51
  • 73. function 関数( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( クエリーの改変を適用する条件 ) { $query->set( パラメーター , 値 ); return; } } add_action( 'pre_get_posts', '関数名' ); pre_get_posts基本文法 表示条件を変更したい ページを絞り込む 52
  • 74. function 関数( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( クエリーの改変を適用する条件 ) { $query->set( パラメーター , 値 ); return; } } add_action( 'pre_get_posts', '関数名' ); pre_get_posts基本文法 メインクエリーの パラメーターを設定 53
  • 75. function 関数( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( クエリーの改変を適用する条件 ) { $query->set( パラメーター , 値 ); return; } } add_action( 'pre_get_posts', '関数名' ); pre_get_posts基本文法 関数の名前は 自由につけて良い 54
  • 76. function 関数( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( クエリーの改変を適用する条件 ) { 処理 return; } } add_action( 'pre_get_posts', '関数名' ); pre_get_posts基本文法 【最重要】 テーマのfunctions.phpに記載する query_postsの様に 各テンプレートには書かない 55
  • 77. ?cat=1 デフォルト設定 条件分岐タグの設定 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 <a href= <?php the_permalink(); ?> > <h2> データベースから投稿を取得 使用するテンプレートの読み込み クエリーストリングの生成 56
  • 78. ?cat=1 デフォルト設定 条件分岐タグの設定 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 データベースから投稿を取得 使用するテンプレートの読み込み クエリーストリングの生成 56
  • 79. ?cat=1 デフォルト設定 条件分岐タグの設定 have_posts() = 投稿が存在する? the_post() = テンプレートタグを有効化 データベースから投稿を取得 使用するテンプレートの読み込み クエリーストリングの生成 pre_get_posts フィルター = クエリーストリングに無い条件の追加 56
  • 80. function exclude_category_at_home( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( $query->is_home() ) { $query->set( 'cat', '-1,-1347' ); return; } } add_action( 'pre_get_posts', 'exclude_category_at_home' ); メインページから特定のカテゴリーを除外する 57
  • 81. function exclude_category_at_home( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( $query->is_home() ) { $query->set( 'cat', '-1,-1347' ); return; } } add_action( 'pre_get_posts', 'exclude_category_at_home' ); メインページから特定のカテゴリーを除外する メインページのみに制限 注意:is_home() ではなく $query->is_home() 58
  • 82. function exclude_category_at_home( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( $query->is_home() ) { $query->set( 'cat', '-1,-1347' ); return; } } add_action( 'pre_get_posts', 'exclude_category_at_home' ); メインページから特定のカテゴリーを除外する $query->set( パラメーター , 値 ); 使えるパラメーターはCodexの 関数リファレンス/WP_Queryを参照 59
  • 83. function search_exclude_cat_1( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( $query->is_search() ) { $query->set( 'category__not_in', array(1) ); return; } } add_action( 'pre_get_posts', 'search_exclude_cat_1' ); 検索結果から特定のカテゴリーを除外する 60
  • 84. function search_exclude_cat_1( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( $query->is_search() ) { $query->set( 'category__not_in', array(1) ); return; } } add_action( 'pre_get_posts', 'search_exclude_cat_1' ); 検索結果から特定のカテゴリーを除外する 検索結果で IDが1のカテゴリーを除外 配列で指定することもできる 61
  • 85. function search_only_post( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( $query->is_search() ) { $query->set( 'post_type', 'post' ); return; } } add_action( 'pre_get_posts', 'search_only_post' ); 検索結果から固定ページを除外(投稿のみ) 62
  • 86. function search_only_post( $query ) { if ( is_admin() ¦¦ ! $query->is_main_query() ) return; if ( $query->is_search() ) { $query->set( 'post_type', 'post' ); return; } } add_action( 'pre_get_posts', 'search_only_post' ); 検索結果から固定ページを除外(投稿のみ) 検索結果のみに制限 Codexのサンプルは$query->is_search プロパティを見るより関数で書こう $query->is_search() → ○ 63
  • 87. function set_post_per_page( $query ) { if ( is_admin() || ! $query->is_main_query() ) return; if ( $query->is_home() ) { $query->set( 'posts_per_page', 1 ); return; } if ( $query->is_post_type_archive( 'movie' ) ) { $query->set( 'posts_per_page', 50 ); return; } } add_action( 'pre_get_posts', 'set_post_per_page'); 条件にしたがって表示件数を変更 64
  • 88. function set_post_per_page( $query ) { if ( is_admin() || ! $query->is_main_query() ) return; if ( $query->is_home() ) { $query->set( 'posts_per_page', 1 ); return; } if ( $query->is_post_type_archive( 'movie' ) ) { $query->set( 'posts_per_page', 50 ); return; } } add_action( 'pre_get_posts', 'set_post_per_page'); 条件にしたがって表示件数を変更 メインページでは 1件表示 65
  • 89. function set_post_per_page( $query ) { if ( is_admin() || ! $query->is_main_query() ) return; if ( $query->is_home() ) { $query->set( 'posts_per_page', 1 ); return; } if ( $query->is_post_type_archive( 'movie' ) ) { $query->set( 'posts_per_page', 50 ); return; } } add_action( 'pre_get_posts', 'set_post_per_page'); 条件にしたがって表示件数を変更 movie 投稿タイプのアーカイブでは 50件表示 66
  • 90. 注意点 あくまでパラメーターの追加 固定ページをアーカイブに等 根本的に変更するのは厳しい = サブクエリーを使う 67
  • 91. 注意点 一部の条件分岐は pre_get_postsのタイミ ングでは動作しない 例:is_front_page() 68
  • 92. サブクエリー の作成 = get_posts 69
  • 93. global $post; $args = array( 'posts_per_page' => 5, 'cat' => 1 ); $myposts = get_posts( $args ); foreach( $myposts as $post ) { setup_postdata($post); ?> <h1><?php the_title(); ?></h1> <?php } wp_reset_postdata(); get_posts記述例 70
  • 94. global $post; $args = array( 'posts_per_page' => 5, 'cat' => 1 ); $myposts = get_posts( $args ); foreach( $myposts as $post ) { setup_postdata($post); ?> <h1><?php the_title(); ?></h1> <?php } wp_reset_postdata(); get_posts記述例 テンプレートタグのセットアップ テンプレートタグのリセット 71
  • 95. Codexで get_posts のサンプルの書き方 が微妙にまちまち Codexの改善に期待 72
  • 96. $args = array( 'posts_per_page' => 5, 'offset' => 0, 'cat' => 0, 'orderby' => 'post_date', 'order' => 'DESC', 'post_type' => 'post', 'post_status' => 'publish', 'suppress_filters' => true, 'ignore_sticky_posts' => true, 'no_found_rows' => true ); WP_Query記述例 $the_query = new WP_Query( $args ); if ( $the_query->have_posts() ) { while ( $the_query->have_posts() ) { $the_query->the_post(); ?> <h1><?php the_title(); ?></h1> <?php } } wp_reset_postdata(); 上級者向けかも 73
  • 97. まとめ 74
  • 98. メインクエリーの変更は pre_get_posts サブクエリーの作成は get_posts (or WP_Query) 使い分ける 75
  • 99. Thanks! 質問は公式フォーラム または Twitter: @HissyNC まで 76

×