doneresearchMichael UnoPosted on December 9, 2019 (Last Edited on December 11, 2019) by Michael Uno カスタム投稿タイプでどうすれば Sticky posts の機能を導入できるか模索中 Sticky posts はカスタム投稿タイプには非対応とのこと https://core.trac.wordpress.org/ticket/12702
is_sticky() に apply_filters( 'is_sticky', $is_sticky, $post_id ); とあるので、タグやカスタムフィードでスティッキーだよという情報をどこかに保存して、そのフィルターでテーマ側に知らせればスティッキーの機能自体は使える。 Elaborate
ん、class-wp-query.php に以下のラインがある // Put sticky posts at the top of the posts array $sticky_posts = get_option( 'sticky_posts' ); if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) { 12345 // Put sticky posts at the top of the posts array $sticky_posts = get_option( 'sticky_posts' ); if ( $this->is_home && $page <= 1 && is_array( $sticky_posts ) && ! empty( $sticky_posts ) && ! $q['ignore_sticky_posts'] ) { てことは option_sticky_posts フィルター使って、Sticky 該当するタームの関連付けポストを探してって手もあるが。DB クエリが増える。 となると、その Sticky タームが入った時点で sticky_posts をアップデートするとか。 Elaborate
なんで if ( $this->is_home ってホーム以外はスティッキーしないようにしてるんだ。別の場所でできるようにすると、クエリ数が増えて遅くなるからかな。 $this->is_home の値をいじると副作用ありそうなのでやめとくとなると、クエリの結果を編集するか。それかテーマ側でガンっとハードコードしてしまうか。 Elaborate
うーん。ちょっと無理っぽいね。別途 WP_Query でポストを取得したとしてもそれをテーマで表示させようとすると、the_post() とか the_content() とか、get_the_ID() は wp_list_comments() 内で呼ばれてるし、イタレート中のアイテムを内部から参照するような関数がいたるところで呼ばれてて、これ弄るのはちょっと副作用が出てきそう。 setup_postdata() や wp_reset_postdata() の中覗いたら、割りかし処理が重い。 Elaborate
アーカイブのループの為のメインクエリ結果に、スティッキーのクエリ結果をインジェクトしてもいけるみたい (https://tareq.co/2013/01/sticky-posts-in-custom-post-type-archives/) Elaborate
https://michaeluno.sakura.ne.jp/technotes/wordpress-%e3%81%ae%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%a0%e6%8a%95%e7%a8%bf%e3%82%bf%e3%82%a4%e3%83%97%e3%81%a7%e3%82%b9%e3%83%86%e3%82%a3%e3%83%83%e3%82%ad%e3%83%bc%e6%8a%95%e7%a8%bf%e3%82%92%e5%8f%af/ にまとめた。 Elaborate
これはクエリオブジェクトをグローバルでリファレンスしてたのが問題。the_posts フィルターのコールバックの2つ目のパラメーターから WP_Query オブジェクトにアクセスできる。そこから対象の投稿タイプをチェックすればOKできた。 Elaborate
is_sticky()
にapply_filters( 'is_sticky', $is_sticky, $post_id );
とあるので、タグやカスタムフィードでスティッキーだよという情報をどこかに保存して、そのフィルターでテーマ側に知らせればスティッキーの機能自体は使える。ちなみにこのフィルターは WordPress 5.3 よりサポート
ただ、Twenty Seventeen の場合、アーカイブ表示でホーム以外はスティックさせないようになっている
ん、
class-wp-query.php
に以下のラインがあるてことは
option_sticky_posts
フィルター使って、Sticky 該当するタームの関連付けポストを探してって手もあるが。DB クエリが増える。となると、その Sticky タームが入った時点で
sticky_posts
をアップデートするとか。なんで
if ( $this->is_home
ってホーム以外はスティッキーしないようにしてるんだ。別の場所でできるようにすると、クエリ数が増えて遅くなるからかな。$this->is_home
の値をいじると副作用ありそうなのでやめとくとなると、クエリの結果を編集するか。それかテーマ側でガンっとハードコードしてしまうか。うーん。ちょっと無理っぽいね。別途
WP_Query
でポストを取得したとしてもそれをテーマで表示させようとすると、the_post()
とかthe_content()
とか、get_the_ID()
はwp_list_comments()
内で呼ばれてるし、イタレート中のアイテムを内部から参照するような関数がいたるところで呼ばれてて、これ弄るのはちょっと副作用が出てきそう。setup_postdata()
やwp_reset_postdata()
の中覗いたら、割りかし処理が重い。これも、最初の設計なんだよなー
アーカイブのループの為のメインクエリ結果に、スティッキーのクエリ結果をインジェクトしてもいけるみたい (https://tareq.co/2013/01/sticky-posts-in-custom-post-type-archives/)
OKできた
ページド表示の場合、スティックさせないようにした。
この一連の方法について記事にまとめようか。もう少し時間置いて使ってみて、不具合がでてこないか様子見よう。
https://michaeluno.sakura.ne.jp/technotes/wordpress-%e3%81%ae%e3%82%ab%e3%82%b9%e3%82%bf%e3%83%a0%e6%8a%95%e7%a8%bf%e3%82%bf%e3%82%a4%e3%83%97%e3%81%a7%e3%82%b9%e3%83%86%e3%82%a3%e3%83%83%e3%82%ad%e3%83%bc%e6%8a%95%e7%a8%bf%e3%82%92%e5%8f%af/ にまとめた。
アーカイブビューの Recent Posts Widget にノートカスタム投稿タイプのスティッキーが入ってきてしまっている。
これはクエリオブジェクトをグローバルでリファレンスしてたのが問題。
the_posts
フィルターのコールバックの2つ目のパラメーターからWP_Query
オブジェクトにアクセスできる。そこから対象の投稿タイプをチェックすればOKできた。