web-dev-qa-db-ja.com

'pre_get_posts'を使用してアーカイブとフィードから分類法を含めたり除外したりする

私がやろうとしているのは?

私のブログはeditionと呼ばれるカスタム分類法を使い、us-canada(6)、eu(7)そしてindia(8)のような用語 - term slug(ID)を使います。

特定の「エディション」に割り当てられていないことを確認したい すべての用語の下に表示される(つまり、投稿がアメリカ、ヨーロッパ、またはインドに割り当てられていない場合、アーカイブに表示される)これらすべての用語のページ).

私が試したことはありますか?

これは、私が正確に何をしようとしているのか、そして何が間違っているのかを理解してもらうための用語の1つに関連するサンプルコードです。

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive($query) {

    if ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) {
        $query->set( 'post_type', array( 'post' ) );

        $query->set( 'tax_query',
            array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => array( 1, 2, 4, 5 )
                ),
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );
    }

    return $query;
}

何が問題なのですか 上記のコードは動作しません(他の人が試したことがあります: code-1code-2 )、それは何も変わりません。デバッグエラーもありません。

それで、私は何が間違っていたのでしょうか?

_ also _ 、変更がこれらの用語のフィードにも適用されることを確認するために、前述のコードの関連する行を次のように置き換えました。

function better_editions_archive($query) {

    if ( ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) || ( $query->is_feed() && $query->is_tax( 'edition', 6 ) ) ) {

しかし、それは用語のフィードバックを用語のアーカイブにリダイレクトし始めます。つまり、example.com/edition/usa/feed/は関数が配置された状態でexample.com/edition/usa/にリダイレクトします。

繰り返しになりますが、私は何をしなければならないのかわかりません。

更新:何が私のために働いたの? (しかし...)

add_filter( 'pre_get_posts', 'better_editions_archive' );

function better_editions_archive( $query ) {
    if ( $query->is_tax( 'edition', 6 ) && $query->is_main_query() ) {

        $args = array(
            'post_type' => 'post',

            'tax_query' => array(
                'relation' => 'AND',
                array(
                    'taxonomy' => 'category',
                    'field' => 'id',
                    'terms' => array( 1, 2, 4, 5 )
                ),
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );

        $query->query_vars = $args;
    }

    return $query;
}

それはうまくいきます、しかし問題は、私が知識のあるWordPress開発者とのチャットについての詳細な議論であり、彼が私にこれを言ったことです(あなたはここで 完全な会話をたどることができます

そして、この配列をquery_varsとして代入します。今query_varsはかなりラージオブジェクトです。そして、あなたは基本的にそこにあるデータを上書きしてあなたのカスタムデータを追加するだけです。これは、デフォルトごとに追加されたものすべてを「設定解除」することを意味します。

彼はこの解決策を使用しないように忠告し、その代わりに$query->set();メソッドを使用します。

しかし、あなたがはるかに上に見ることができるように、私はもう片方を働かせることができなかった。だから私は誰かが私が間違っていることを私に言うことができるかどうか見るために、より技術的ではない話で、ここにいます。

5
its_me

もう一度撮ります。

以下はメインクエリを修正して、 Editionカスタム分類法の用語なし に属するすべての投稿をループに含めるようにします。

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive( $query ) {

    if ( $query->is_tax( 'edition' ) && $query->is_main_query() ) {
        $terms = get_terms( 'edition', array( 'fields' => 'ids' ) );
        $query->set( 'post_type', array( 'post' ) );
        $query->set( 'tax_query', array(
            'relation' => 'OR',
            array(
                'taxonomy' => 'edition',
                'field' => 'id',
                'terms' => $terms,
                'operator' => 'NOT IN'
            )
        ) );
    }

    return $query;
}
14
vancoder

自己メモ: @ vancoderの答えは基本的にこれより良い(そして自動化された)バージョンです:

add_filter('pre_get_posts','better_editions_archive');

function better_editions_archive($query) {

    if ( $query->is_tax( 'edition') && $query->is_main_query() ) {

        $query->set( 'post_type', array( 'post' ) );

        $query->set( 'tax_query',
            array(
                array(
                    'taxonomy' => 'edition',
                    'field' => 'id',
                    'terms' => array( 6, 7, 8 ),
                    'operator' => 'NOT IN'
                )
            )
        );

    }

    return $query;
}

(コードの意味) カスタム分類法 'edition'に属する任意の用語のアーカイブである場合は、次のようになります。

  1. このコードは、「アーカイブページ」という用語のデフォルトの機能を台無しにしません。つまり、カスタム分類法「edition」の用語に割り当てられた投稿は、(通常通り)関連用語のアーカイブに表示されます。

  2. ただし、投稿が特定のカスタム分類の用語のいずれにも割り当てられていない場合('terms' => array( 6, 7, 8 )および'operator' => 'NOT IN'を参照)、カスタム分類のすべての用語のアーカイブページにそのような投稿を表示します。

  3. このコードは、上記の用語のフィードにも影響を与えるため、フィードはアーカイブページのコンテンツを反映しています。これは、私が必要としているものです。フィードに影響を与えたくない場合、つまり変更をアーカイブページにのみ適用したい場合は、IFを次のように置き換えます。

    if ( $query->is_tax( 'edition') && $query->is_main_query() && ! $query->is_feed() ) {
    
1
its_me