web-dev-qa-db-ja.com

$ query-> query_var ['post_type']はページに設定されていません

検索ページで投稿タイプでフィルタリングできることについての@kaiserからの この 応答からの削除、すべて自動的にアドインできるようにしたい利用可能なパブリック投稿タイプの。それで、@ kaiserの助けを借りて、私は思いつきました:

function sw_custom_post_type_includes($query) {
    $args = array(
        'public'   => true
    ); 
    $output = 'names'; // names or objects, note names is the default
    $operator = 'and'; // 'and' or 'or'
    $post_types = get_post_types( $args, $output, $operator ); 
    if ( !is_search() && !in_array( get_post_type(), $post_types ) )
        return;

    $query->set( 'post_type', $post_types );
    return $query;
}
add_filter('pre_get_posts', 'sw_custom_post_type_includes');

最初はうまくいったようですが、問題に遭遇しました - > &post_type=pageを使おうとしたとき以外は>投稿タイプによって正しくフィルタリングされたものすべてが正しくありません。 post_typeに対して未定義のインデックスエラーが発生していました。なぜこれがうまくいかなかったのかわからなかった。そこで、私はprint_r($query->query_vars)を使って、すべてが正しく引き込まれているかどうかを確認することにしました。低くて注意 - ページを除くすべての投稿タイプで、その変数が設定されていました。

私はこれについて別の開発者と相談し、彼らは問題を検証しました。これは私が回避策として使用したものです:

function sw_custom_post_type_includes($query) {
    if(isset($_GET['post_type']) && ((!isset($query->query_vars['post_type'])) || (isset($query->query_vars['post_type']) && $query->query_vars['post_type'] != 'nav_menu_item'))) {
        $query->set('post_type', urldecode($_GET['post_type']));
    }
}
add_action('pre_get_posts', 'sw_custom_post_type_includes');

これは正直に言って数時間私を困惑させている何かのための奇妙な回避策のようです。これを入力した人は誰でもバーチャルハイファイブで報われます。

1
Zach

前回の回答で混乱を避けるために、pre_get_postsはフィルタではないので、何も返す必要はありません。

私が見るあなたの唯一の問題はifです:

if ( !is_search() && !in_array( get_post_type(), $post_types ) )
    return;

基本的にget_post_type()はpre_get_postsの間はfalseを返します。グローバル$ postはまだ設定されていないからです(通常はループを開始すると設定されます)。

すべての公開投稿タイプが必要なときとそうでないときがよくわかりません。すべてのパブリック投稿タイプをすべて含むようにすべての検索を設定するだけの場合は、本当にis_search()をチェックするだけで済みます。また、変更するクエリがメインのクエリであり、プラグインやテーマファイルが作成しているカスタムクエリではないことを確認することもできます。コードは次のようになります。

function range_search_all_public_post_types( $q ) {
    if ( is_search() && is_main_query() )
        $q->set( 'post_type', get_post_types( array( 'public' => true ) ) );
}
add_action( 'pre_get_posts', 'range_search_all_public_post_types' );

それでおしまい。これにより、すべての公開投稿タイプが検索対象として照会されます。

あなたがホームページと検索にすべての一般的な投稿タイプを望むならば、これを使ってください:

function range_search_all_public_post_types( $q ) {
    if ( ( is_search() || is_home() ) && is_main_query() )
        $q->set( 'post_type', get_post_types( array( 'public' => true ) ) );
}
add_action( 'pre_get_posts', 'range_search_all_public_post_types' );

更新:

あなたが抱えている問題は、publicly_queryableがfalseに設定されているpost_typeに特有のものです。 publicly_queryableでなくても、基本的にすべてのパブリック型が機能することを望みます。これを行うには、このコードを使用します。

function range_search_all_public_post_types( $q ) {
    if ( is_search() && is_main_query() && '' == $q->get( 'post_type' ) && ! empty( $_GET['post_type'] ) && post_type_exists( $_GET['post_type'] ) && get_post_type_object( $_GET['post_type'] )->public )
        $q->set( 'post_type', $_GET['post_type'] );
}
add_action( 'pre_get_posts', 'range_search_all_public_post_types' );

基本的に、post_typeがURLに含まれているがQP_Queryには含まれていない場合、それはpublicly_queryableではないことが原因と考えられます。その場合は修正します。これがチェックされるものです:

  • これは検索ページですか?
  • これが主な質問ですか?
  • クエリにpost_typeが指定されていませんか?
  • URLにpost_typeが指定されていますか?
  • URL指定のpost_typeは存在しますか?
  • URLで指定されたpost_typeはパブリックですか?

これらすべてが当てはまる場合は、post_typeをURL内のものに設定します。

2

私が質問に答えたとき、これはフォローアップであり、ここで質問に多くコメントした後、あなたはどこかであなたがページの結果を取得するのを妨げている別のフィルタまたは条件を持っていることは確かです。これがあなたの問題であるという99%の可能性。あなたは空のVanillaインストールから始めて、それが機能していることを証明するためにこのフィルタ以外何も実行しないようにしてください。次に、何が起こっているのかがわかるまで、カスタムのものをすべて削除/コメントアウトしたり、プラグインを無効にしたりします。

0
kaiser

あなたが書いた

if ( !is_search() && !in_array( get_post_type(), $post_types ) )
    return;

page$post_types配列にない場合は空のreturn;があります

実際には、なぜこのセキュリティを追加するのかわかりませんが、この関数はpre_get_postsフィルタのおかげで実際に必要なときにのみ呼び出されます。

あなただけのリターンを変更する必要があります:

function sw_custom_post_type_includes($query) {
    $args = array(
        'public'   => true
    ); 
    $output = 'names'; // names or objects, note names is the default
    $operator = 'and'; // 'and' or 'or'
    $post_types = get_post_types( $args, $output, $operator ); 
    if ( !is_search() && !in_array( get_post_type(), $post_types ) )
        return $query;  //#### keep it unchanged instead of removing everything ####

    $query->set( 'post_type', $post_types );
    return $query;
}
add_filter('pre_get_posts', 'sw_custom_post_type_includes');

考えただけで試していません

0
Christian