web-dev-qa-db-ja.com

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

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

あなたがホームページで見ることができるように私は最初に 特集記事 (私は特定のタグを使ってそれを実装しました)を含むセクション(証拠では 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>

<?
// 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>

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

すべての 特集記事 を選択するには、この行を使用して、特定のタグfeaturedを持つクエリを定義する新しいWP_Queryオブジェクトを作成します。

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

それから、have_posts()メソッドを使ってこのクエリ結果を繰り返します。

だから、私が理解したことから、これはWordPressのメインクエリーではありませんが、私が作成した新しいクエリーです。私が理解していることから、私はこのような操作を実行したい時にメインのクエリを使用しないで(新しいように)新しいクエリを作成する方が良いです。

それは本当ですか、それとも何かが足りないのですか。もしそれが本当なら、Wordpressのメインクエリーを変更しないほうが良いのはなぜ新しいカスタムクエリーを作成するのが良いのか私に説明できますか?

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

    <?
    // 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タグの投稿)

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

19
AndreaNobili

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

パート1

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

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

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

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

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

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

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

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

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

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

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

  • UPDATE:真のページと静的なフロントページにカスタムコンテンツを表示(を参照 真のページでpre_get_postsを使用するおよび静的フロントページ

パート2

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

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

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

NEVER USEquery_posts カスタムクエリまたはその他のクエリを作成します。私の強調。

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

進む

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

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

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

それはすべて間違っており、あなたの声明は残念ながら真実です。前述したように、NEVER use 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 を使用することです。これは、メインクエリを変更する適切な方法と、プライマリコンテンツループに変更を加えるために使用する必要があるalwaysのフックです。

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

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] );
    }
}

パート

今後役立つ参考資料

32
Pieter Goosen