WordPress管理者検索:結果の拡張
公開: 2021-01-20Webサイトでコンテンツを見つけるのが難しい場合があります。 WordPress管理者として、あなたが探しているコンテンツを見つけるのは簡単です。 ありがたいことに、WordPressは、使用するほとんどの管理画面(投稿画面など)で検索機能を提供します。 この検索機能は優れていますが、それでもいくつかの点で制限があります。
たとえば、投稿管理画面で投稿を検索する場合、検索機能はデフォルトで、投稿タイトル、投稿の抜粋、投稿コンテンツで検索クエリテキストを検索し、それらの結果を返します。 しかし、カスタムフィールドに関連するキーワードで検索したい場合はどうでしょうか。 この情報は、イライラする可能性のある管理者投稿リストテーブルの検索結果には含まれていません。
前回の記事では、投稿タイプにカスタムフィールドを追加する方法を学びました。 検索結果にカスタムフィールドを含める方法も見てみましょう。
管理画面検索で検索クエリを拡張する
カスタムフィールドでの作業例では、投稿の1つに「source」というカスタムフィールドを作成し、URL値を挿入しました。
投稿リストテーブルに移動し、検索バーでこれらの「ソース」値の1つを使用すると、WordPressはデフォルトで検索時にカスタムフィールドを参照しないため、結果は得られません。
これを変更するには、WordPressが検索機能に提供する元のフックを拡張する必要があります。 拡張する必要のあるフックは、 get_posts
関数内の1779行目あたりのwp-includes/class-wp-query.php
ファイルに含まれているpre_get_posts
です。
WordPressクエリ
フロントビューまたは管理領域のいずれかでページにアクセスするたびに、一連のコードスクリプトが実行され、リクエストに対応するWP_Query
オブジェクトとそのプロパティが作成されます。
あらゆる場合にWP_Query
オブジェクトでどのような変更が発生するかを理解するために、クエリのプロパティ出力の一部の一時的なビューを作成してみましょう。
実行される前にクエリを表示するために、 pre_get_posts
アクションフックに印刷を追加します。 pre_get_posts
フィルターは、クエリ変数オブジェクトが作成された後、実際のクエリが実行される前に起動します。
アクティブなテーマのfunctions.php
ファイルに、次のコードを挿入します。
add_action( 'pre_get_posts', 'print_query' ); function print_query( ) { print_r ( $GLOBALS['wp_query']->query ); echo "<hr>"; print_r ( $GLOBALS['wp_query']->query_vars ); echo "<hr>"; }
これで、投稿管理画面にアクセスすると、 query
とquery_var
の出力が上部に出力されます。
コードをより簡単に表示するには、コードをコピーして無料のオンラインPHPビューティファイアに貼り付けることができます。
$GLOBALS['wp_query']->query
配列(最初の配列)は次のようになります。
Array ( [order] => [orderby] => [post_type] => post [posts_per_page] => 20 [post_status] => [perm] => )
たとえば、投稿管理画面で検索した場合、配列の出力は検索文字列を含めて変更されます。 たとえば、「wordpress.org」を検索すると、次のようになります。
Array ( [m] => 0 [cat] => 0 [s] => wordpress.org [paged] => 1 [order] => [orderby] => [post_type] => post [posts_per_page] => 20 [post_status] => [perm] => )
コードを組み立てる
上記の情報を念頭に置いて、必要な検索機能を実現するための正しいコードを挿入します。 これを行うには、アクティブなテーマのfunctions.php
に戻り、前の手順で少し前に挿入したコードを削除します。 次に、以下のコードを挿入します。
add_action( 'pre_get_posts', 'extend_admin_search' ); function extend_admin_search( $query ) { $post_type = 'post'; $custom_fields = array("source",); if( ! is_admin() ) return; if ( $query->query['post_type'] != $post_type ) return; $search_term = $query->query_vars['s']; $query->query_vars['s'] = ''; if ( $search_term != '' ) { $meta_query = array( 'relation' => 'OR' ); foreach( $custom_fields as $custom_field ) { array_push( $meta_query, array( 'key' => $custom_field, 'value' => $search_term, 'compare' => 'LIKE' )); } $query->set( 'meta_query', $meta_query ); }; }
次のステップは、 $post_type
変数と$custom_fields
変数を要件に適用される値に変更することです。 コードで何をしたか見てみましょう。
-
$post_type = 'post';
–ここでは、検索する投稿タイプを定義します。 -
$custom_fields = array("source",);
–ここでは、検索するカスタムフィールドを定義します。
pre_get_posts
フックを使用しているため、正しいページにいるときにカスタム検索拡張機能を適用することをコードで確認することが重要です。 WordPressに特定の条件下でコードを表示するように指示する場合は、いくつかの条件付きタグを使用します。
-
if ( ! is_admin() ) return;
条件は、管理領域にいない場合、コードが実行されないことを保証します。 -
if ( $query->query['post_type'] != $post_type )
は、$post_type
変数で定義した投稿タイプを処理するかどうかをチェックします。 私たちの場合、post
ます。 -
$search_term = $query->query_vars['s'];
ここで、検索文字列を変数に保持し、それを再び空に設定します$query->query_vars['s'] = '';
そうしないと、何も見つかりません。
これらの更新が行われているので、最後の検索を更新すると、正しい結果が得られます。 この例では、結果に「ソース」カスタムフィールドエントリ「https://dev」を含む「投稿1」の投稿が表示されます。 wordpress.org / reference / features / add_post_meta/'。
フロントビュー検索で検索クエリを拡張する
これで、管理者検索が「修正」され、フロントエンド検索機能の改善に進むことができるため、Webサイトユーザーもカスタムフィールドを検索できるようになりました。
以前の管理者検索でカスタムフィールドの結果が得られなかったのと同じように、フロントエンド検索でもカスタムフィールドの結果は返されません。
理想的には、ユーザーがこれらのフィールドを検索できるようにする必要があります。 この例では、投稿の1つにカスタムの「ソース」フィールドがあり、現在URL「https://dev.wordpress.org/reference/functions/add_post_meta/」が含まれています。 ユーザーが「wordpress.org」を検索すると、この投稿が結果に表示されます。 その方法を見つけましょう。
必要なコード
もう一度functions.phpファイルに移動し、前に貼り付けたコードをコピーします。 次に、これをそのコードのすぐ下に貼り付けます(したがって、 functions.php
にこのコードのコピーが2つあります)。次に、この2番目のコードのロットの関数の名前をextend_front_search
のような名前に変更します。 次のようになります。
add_action( 'pre_get_posts', 'extend_admin_search' ); function extend_admin_search( $query ) { $post_type = 'post'; $custom_fields = array("source",); if( ! is_admin() ) return; if ( $query->query['post_type'] != $post_type ) return; $search_term = $query->query_vars['s']; $query->query_vars['s'] = ''; if ( $search_term != '' ) { $meta_query = array( 'relation' => 'OR' ); foreach( $custom_fields as $custom_field ) { array_push( $meta_query, array( 'key' => $custom_field, 'value' => $search_term, 'compare' => 'LIKE' )); } $query->set( 'meta_query', $meta_query ); }; }
次に、 if ( $query->query['post_type'] != $post_type ) return;
を削除する必要があります。 調子。
add_action( 'pre_get_posts', 'extend_front_search' ); function extend_front_search( $query ) { $post_type = 'post'; $custom_fields = array("source",); if( is_admin() ) return; $search_term = $query->query_vars['s']; $query->query_vars['s'] = ''; if ( $search_term != '' ) { $meta_query = array( 'relation' => 'OR' ); foreach( $custom_fields as $custom_field ) { array_push( $meta_query, array( 'key' => $custom_field, 'value' => $search_term, 'compare' => 'LIKE' )); } $query->set( 'meta_query', $meta_query ); }; }
if( is_admin() ) return;
の条件を維持する必要があります。 コードがフロントエンドにのみ適用されるようにするためです。
代替戦略
WordPress検索を拡張してカスタムフィールドを含める別の方法は、SQLクエリを変更することです。
WP_Query
クラスは、 wp-includes/class-wp-query.php
ファイルの2897行目で説明されているように、それを細かく分割することでこれを支援します。
$clauses = (array) apply_filters_ref_array( 'posts_clauses_request', array( compact( $pieces ), &$this ) ); $where = isset( $clauses['where'] ) ? $clauses['where'] : ''; $groupby = isset( $clauses['groupby'] ) ? $clauses['groupby'] : ''; $join = isset( $clauses['join'] ) ? $clauses['join'] : ''; $orderby = isset( $clauses['orderby'] ) ? $clauses['orderby'] : ''; $distinct = isset( $clauses['distinct'] ) ? $clauses['distinct'] : ''; $fields = isset( $clauses['fields'] ) ? $clauses['fields'] : ''; $limits = isset( $clauses['limits'] ) ? $clauses['limits'] : '';
カスタムフィールドの記事で前述したように、すべてのカスタムフィールドデータはデータベースの「postmeta」テーブルに保存されます。これはデフォルトではWordPress検索に含まれていません。 したがって、最初のステップは、以下のコードを使用してこれら2つのテーブルを結合することです。
function join_meta_table( $join ) { global $wpdb; if ( is_search() ) { $join .=' LEFT JOIN '.$wpdb->postmeta. ' ON '. $wpdb->posts . '..post_id '; } return $join; } add_filter('posts_join', 'join_meta_table' );
もちろん、 posts_join
フックを使用して、クエリのJOIN句をフィルタリングしました。
次に、 posts_where
フックを使用して、ニーズに合わせてクエリのWHERE部分を変更します。
function modify_where_clause( $where ) { global $pagenow, $wpdb; if ( is_search() ) { $where = preg_replace( "/\(\s*".$wpdb->posts.".post_title\s+LIKE\s*(\'[^\']+\')\s*\)/", "(".$wpdb->posts.".post_title LIKE $1) OR (".$wpdb->postmeta.".meta_value LIKE $1)", $where ); } return $where; } add_filter( 'posts_where', 'modify_where_clause' );
最後になりましたが、重複を防ぐ必要があります。 これを実現するために、クエリのDISTINCT句をフィルタリングするposts_distinct
フックを使用します。
function prevent_duplicates( $where ) { global $wpdb; if ( is_search() ) { return "DISTINCT"; } return $where; } add_filter( 'posts_distinct', 'prevent_duplicates' );
次に、「wordpress.org」文字列を検索すると、フロントエンドで何が起こるかを見てみましょう。
予想通り、今回の結果は正しいです。 WordPress検索では、値が「https:// dev」の「source」フィールドが含まれているため、結果として「post1」が見つかりました。 wordpress.org / reference / features / add_post_meta /
WordPress検索結果のカスタム投稿タイプ
カスタム投稿タイプを検索可能にすることもできます(カスタム投稿タイプの作成方法がわからない場合は、こちらの記事を確認してください)。
'books'という名前のカスタム投稿タイプを作成し、この投稿タイプを検索結果に表示したいとします。 今回はSQLクエリを再作成する必要はありませんが、以下に示すように、 pre_get_posts
フックで投稿タイプを再定義するだけです。 コードは、 functions.php
ファイルにもう一度配置する必要があります。
function tg_include_custom_post_types_in_search_results( $query ) { if ( $query->is_main_query() && $query->is_search() && ! is_admin() ) { $query->set( 'post_type', array( 'post', 'books' ) ); } } add_action( 'pre_get_posts', 'tg_include_custom_post_types_in_search_results' );
ここで行ったことは、 post_type
フックへの引数として検索結果に含まれる目的の投稿タイプを追加することでした。
タイプを除外する場合は、配列から削除するだけです。
結論
WordPress Webサイトでの検索を改善することは、非常に役立ち、時間を大幅に節約できます。 エンドユーザーにとっては、カスタム投稿タイプとカスタムフィールドの両方を検索できることも重要です。 うまくいけば、上記の指示があなた自身のウェブサイトでこれを達成する方法への洞察をあなたに与えたでしょう。