このカスタムテーマでメインクエリとカスタムクエリがどのように機能するかについて疑問がありますか?


20

私はWordPressテーマ開発でかなり新しく、PHPにはあまり興味がありません(私はJavaとC#から来ました)、このカスタムテーマでは次の状況があります

ホームページで見ることができるように、最初に注目記事(特定のタグを使用して実装しました)を含むセクション(evidenzaのArticoliという名前)を表示し、その下に最新の投稿を含む別の領域(Ultimi Articoliという名前)があります注目の投稿ではありません。

それを行うには、このコードを使用します:

<section id="blog-posts">

<header class="header-sezione">
        <h2>Articoli in evidenza</h2>
</header>

<!--<?php query_posts('tag=featured');?>-->

<?php
    $featured = new WP_Query('tag=featured');

    if ($featured->have_posts()) : 
            while ($featured->have_posts()) : $featured->the_post();
            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
                 get_template_part('content', get_post_format());

             endwhile;
        wp_reset_postdata();
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>


<header class="header-sezione">
    <h2>Ultimi Articoli</h2>
</header>

<?php
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>

</section>

それはうまく機能しますが、このソリューションの品質とそれが正確にどのように機能するかについていくつかの疑問があります。

注目の投稿をすべて選択するには、次の行を使用しWP_Queryて、特定のタグを持つクエリを定義する新しいオブジェクトを作成しますfeatured

$featured = new WP_Query('tag=featured');

次に、そのhave_posts()メソッドを使用してこのクエリ結果を繰り返します。

だから、私が理解していることから、これはWordPressのメインクエリではなく、私が作成した新しいクエリです。私が理解していることから、この種の操作を実行したいときは、新しいクエリを作成し(完了した)、メインクエリを使用しない方が良いです。

本当ですか、それとも何か不足していますか?それが正しい場合、Wordpressのメインクエリを変更せずに新しいカスタムクエリを作成する方が良い理由を説明できますか

わかった。「注目」タグのないすべての投稿を表示します。これを行うには、このコードスニペットを使用しますが、これは逆にメインクエリを変更します。

    <?php
    // get the term using the slug and the tag taxonomy
    $term = get_term_by( 'slug', 'featured', 'post_tag' );
    // pass the term_id to tag__not_in
    query_posts( array( 'tag__not_in' => array ( $term->term_id )));
    ?>

    <?php
        if (have_posts()) :
            // Start the Loop.
            while (have_posts()) : the_post();
                get_template_part('content', get_post_format());

            endwhile;
        else :
            // If no content, include the "No posts found" template.
            get_template_part('content', 'none');

        endif;
        ?>

だから、これはかなり恐ろしいことだと思う。本当ですか?

更新:

同じ操作を行うために、functions.phpに追加したこの関数を見つけました(以下のすばらしい回答で)。

function exclude_featured_tag( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'tag__not_in', 'array(ID OF THE FEATURED TAG)' );
    }
}
add_action( 'pre_get_posts', 'exclude_featured_tag' );

この関数には、クエリ変数オブジェクトが作成された後、実際のクエリが実行される前に呼び出されるフックがあります。

だから、私が理解していることから、それは入力パラメータとしてクエリオブジェクトを受け取り、特定のタグ(私の場合はfeaturedタグ投稿)を除くすべての投稿を選択することによってそれを変更(実際にはフィルタリング)します

それでは、この機能で以前のクエリ(注目の投稿を表示するために使用されるクエリ)を使用して、テーマの注目されていない投稿のみを表示するにはどうすればよいですか?または、新しいクエリを作成する必要がありますか?

回答:


33

実際の質問は、基本的にカスタムクエリを実行するタイミングとメインクエリを使用するタイミングです。3つの部分に分けましょう

パート1

カスタムクエリを実行するタイミング(これは決定的なリストではありません)

  • カスタムコンテンツスライダーを作成するには

  • ページに注目コンテンツ領域を作成するには

  • 投稿を表示する必要がある場合のpage.phpテンプレート

  • 静的なフロントページにカスタムコンテンツが必要な場合

  • 関連する投稿、人気のある投稿、または情報の投稿を表示する

  • メインクエリの範囲外のその他のセカンダリまたは補足コンテンツ

メインクエリをいつ使用するか。

プライマリコンテンツを表示するには

  • ホームページと、バックエンドでブログページとして設定されているページ

  • archive.php、category.php、author.php、taxonomy.php、tag.php、date.phpなどのテンプレートを含むすべてのアーカイブページ

  • 更新:カスタムコンテンツを実際のページと静的なフロントページに表示します(実際のページと静的なフロントページでpre_get_posts使用するを参照

パート2

すべての注目の投稿を選択するには、次の行を使用して、特定のタグが注目されているクエリを定義する新しいWP_Queryオブジェクトを作成します。

だから、私が理解していることから、これはWordPresのメインクエリではなく、私が作成した新しいクエリです。私が理解していることから、新しいクエリを作成し(完了したように)、この種の操作を実行するときにメインクエリを使用しない方が良い

正しい。これは、メインクエリの範囲外になります。これは、メインクエリでは作成できないセカンダリまたは補足コンテンツです。あなたは常にべきでいずれかを使用しWP_Queryたりget_posts、カスタムクエリを作成します。

query_postsカスタムクエリやその他のクエリを作成するために使用しないでください。私の強調。

注:この関数は、プラグインまたはテーマで使用するためのものではありません。後で説明するように、メインクエリを変更するためのより良い、よりパフォーマンスの高いオプションがあります。query_posts()は、ページのメインクエリをクエリの新しいインスタンスに置き換えることにより、ページのメインクエリを変更する非常に単純で問題の多い方法です。これは非効率的で(SQLクエリを再実行します)、状況によっては完全に失敗します(特に投稿のページネーションを処理する場合は特にそうです)。

進む

わかりました。次に、注目のタグを持たないすべての投稿を表示します。これを行うには、メインクエリを反対に変更する次のコードスニペットを使用します。

query_posts( array( 'tag__not_in' => array ( $term->term_id )));

だから、これはかなり恐ろしいことだと思います。本当ですか?

それはすべて間違っており、あなたの声明は残念ながら真実です。前に言ったように、絶対に使用しないでくださいquery_posts。それはパフォーマンスに悪い完全に新しいクエリを実行し、ほとんどの場合、ページネーションが正しく機能するためのメインクエリの不可欠な部分であるページネーションを中断します。

これが主要なコンテンツなので、デフォルトループでメインクエリを使用する必要があります。これは次のようになります。これで十分です。

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
?>

この部分を完全に取り除き、削除し、燃やして忘れることができます

<?
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

OK、それを実行すると、メインクエリとデフォルトループを使用して、機能タグからの投稿がホームページに表示されることがわかります。

このタグをホームページから削除する正しい方法はpre_get_postsです。これは、メインクエリとプライマリコンテンツループを変更するために常に使用する必要あるフックを変更する適切な方法です。

したがって、のコードpre_get_postsは正確であり、これが使用すべき関数です。一つだけpre_get_posts、バックエンドも変更するため、管理ページにいないことを常に確認してください。だから、これはホームページから注目のfunctions.phpタグ付けれた投稿を削除するために使用する適切なコードです

add_action( 'pre_get_posts', 'exclude_featured_tag' );
function exclude_featured_tag( $query ) 
{
    if (    !is_admin() 
         && $query->is_home() 
         && $query->is_main_query() 
    ) {
        $query->set( 'tag__not_in', [ID OF THE FEATURED TAG] );
    }
}

パート3

今後役立つ参考資料


どういたしまして。便利だとうれしく思います。エンジョウ:-)
ピーター・グーセン

うわー、かなり答えです!しかし、重要な情報が1つ欠けています。メインの投稿ページ以外に WPに「これは投稿ページです」と伝える方法はありますか。カテゴリ10,11,12の投稿のリストと、カテゴリ13,14,15の別のリストが必要だとしましょう。pre_get_postsを使用してメインクエリにカテゴリを挿入する方法はわかりますが、WPに適切なページネーションを持つ投稿のリストとしてレンダリングするように指示するにはどうすればよいですか?ここであなたの広範な答えに従う必要があります本当にwordpress.stackexchange.com/a/215027/74134それはページだから?確かにWordPressはサイト内で複数のブログリストをネイティブに許可していますか?
マークベリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.