web-dev-qa-db-ja.com

カスタムクエリで1つの投稿フォームからの投稿を表示し、メインクエリで除外する

最初にpost-format-aside(すべて現在のタグに割り当てられている)で4つの投稿を表示し、次に特定のタグの「本物の」アーカイブ(post-format-asideを除く)を表示しようとしています。今のところ私はメインのクエリから投稿形式を除いて関数を使っています:

add_action('pre_get_posts', 'keyl_get_emp_posts');
function keyl_get_emp_posts($query) {
if (is_tag()) {
if ($query->is_main_query())
 $taxq = array(
    'tag' => $current_tag,
    array(
        'taxonomy' => 'post_format',
        'field' => 'slug',
        'terms' => array(
            'post-format-aside'
          ),
        'operator' => 'NOT IN'
    )
);

    $query->set('tax_query',$taxq);
}

}

私はpost-format-asideだけでカスタムクエリを表示しようとしているより

<div class="row">
<?php $current_tag = single_tag_title("", false);
$args = array(
    'posts_per_page' => 4,
    'tag' => $current_tag,
    'post_type' => array('post', 'renvoeringsdamm'),
    'tax_query' => array(
        array(
            'taxonomy' => 'post_format',
            'field' => 'slug',
            'terms' => array( 'post-format-aside' )
        )
    )
);
$query = new WP_Query( $args );
if ( $query->have_posts() ) {
  while ( $query->have_posts() ) {
    $query->the_post(); ?>
    <div class="col-sm-3 col-xs-6">
        <?php get_template_part( 'content', get_post_format() ); ?>
    </div>
    <?php
  }
      wp_reset_postdata();
} ?>
</div>

しかし、post-format-aside専用の特別なクエリは、すべてのタイプのポストフォーマットからの投稿を表示することです...それで、私の質問は、本当に、これまでのところ何が悪いのか、です。.

1
HannesH

あなたのtax_queryが失敗しているのではないかと思いますが、実際にはあなたのtagパラメータは失敗しています。 single_tag_title() スラッグではなく、タグのnameを返します。

すべてのタグおよびカテゴリのクエリは、tax_queryクラスに渡されてからSQLクエリの相対文字列を構築する前に、WP_QueryクラスのWP_Tax_Queryに変換されます。検証前および渡された用語の用語IDを取得する前に、用語名とスラッグがサニタイズされます。 (念のため、tax_query内で用語名とnameパラメータを使用しない理由をお読みください。私の答えを確認してください ここ

さて、スラッグshouldは常に小文字で、ハイフンで区切られた複数の単語です。スラッグとして名前を渡しています。用語名が用語slug列で何も一致しないため(slug列を調べるようにtax_queryに指示したため)、WP_Tax_Queryはその用語が無効で存在しないことを受け入れ、そのため単に空にして空を返します。文字列これが大きな欠陥が出てくるところです(私の考えではこれは修正されるべきバグです)。 WP_Tax_Queryは空のSQL結合文字列をWP_Queryに送り返します。WP_Queryはこれをtax_queryが存在しなかったかのように誤って読み取り、結合句なしでSQLを構築して実行します。これは予想外にもall件の投稿を返しますが、私の意見ではまったく投稿を返しません。これはあなたが見ているものです

そのため、解決策を見て、コードを整理して信頼性を高めましょう。

まず、あなたのpre_get_postアクション

  • フロントエンドのみを対象とするチェックを追加します。それ以外の場合はバックエンドクエリも影響を受けます。

  • is_tag()を現在のインスタンスに設定します

  • タグページで現在のtax_queryを取得し、投稿フォーマットセクションを追加してそれを新しいtax_queryとして渡すように変更します。

あなたのコードを次のように調整することができます。(私はクロージャーを使っていますが、あなたの質問のように古いスタイルに戻すことができます;-)

add_action('pre_get_posts', function ($q) 
{
    if (    !is_admin() // Only targets front end queries
         && $q->is_main_query() // Only targets the main query
         && $q->is_tag() // Only targets tag archive pages  
    ) {
        // Gets the current tax_query
        $tax_query_obj = $q->tax_query->queries;
        // Add the post format query part to the current tax_query
        $tax_query_obj[] = [
            'taxonomy' => 'post_format',
            'field' => 'slug',
            'terms' => ['post-format-aside'],
            'operator' => 'NOT IN'
        ];
        //Build a proper tax query
        $tax_query = [
            'relation' => 'AND',
            $tax_query_obj
        ];
        // Set the modified tax_query
        $q->set( 'tax_query', $tax_query );

        // Set any additional parameters here except tag parameters
    }
}, PHP_INT_MAX );

カスタムクエリの場合は、get_queried_object_id()を使用し、それをポストフォーマットのtax_queryで使用することで、現在表示されているタグIDを取得できます。引数に次のことを試すことができます。(新しい短い配列構文のため、PHP 5.4以降が必要です([]

$args = [
    'tax_query' => [
        [
            'taxonomy' => 'post_tag', // Default tag taxonomy
            'terms' => get_queried_object_id(), // Gets current tag archive tag ID
        ],
        [
            'taxonomy' => 'post_format',
            'field' => 'slug',
            'terms' => 'post-format-aside'
        ],
    ],
    // Rest of your arguments excluding tag parameter
];
1
Pieter Goosen