• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
これからのpre_get_postsの話をしよう
 

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

on

  • 15,973 views

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

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

Statistics

Views

Total Views
15,973
Views on SlideShare
6,190
Embed Views
9,783

Actions

Likes
30
Downloads
22
Comments
0

11 Embeds 9,783

http://notnil-creative.com 9597
https://twitter.com 111
http://cloud.feedly.com 34
http://monoxa.net 31
http://webcache.googleusercontent.com 3
http://wordbench.org 2
http://reader.aol.com 1
http://cache.yahoofs.jp 1
http://www.feedspot.com 1
https://www.chatwork.com 1
https://www.google.co.jp 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution-ShareAlike LicenseCC Attribution-ShareAlike License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

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

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