web-dev-qa-db-ja.com

ホームページ上の3つの異なる投稿タイプ

更新:答えてくれてありがとう、しかしこのコードを実装した後はテーマ/サイトを壊してしまいます。きっと私だけど、これが私のfunctions.phpファイルだ:

// Custom posts for homepage
function get_featured_one() { /* returns post #1 */ }
function get_featured_two() { /* returns posts #2 and #3 */ }

add_action( 'pre_get_posts', function( $query ) {
    if ( ! $query->is_main_query() || is_admin() )
        return;

    if ( is_front_page() ) {
        $featured_one = get_featured_one();
        $featured_two = get_featured_two();

        $exclude = array_merge( wp_list_pluck( $featured_one->posts , 'ID' ), wp_list_plugk( $featured_two->posts, 'ID' ) );
        $query->set( 'post__not_in', $exclude );
    }
});

function get_featured_one() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'posts_per_page' => 1,
    ) );
}

function get_featured_two() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'tag' => 'featured',
        'posts_per_page' => 2,
    ) );
}

これは最新の投稿を含む私のヘッダファイルです:

<section class="header-latest-post">    
    <?php if ( is_front_page() && ! is_paged() ) :
        $latest = get_featured_one();
        while ( $latest->have_post() ) : $latest->the_post();
            get_template_part('content',get_post_format());
        endwhile;
    endif; ?>
</section>
<!-- End latest post -->

そして、これはホームページ上の2つの最新の投稿と標準ループのためのコードです:

<!-- Start two featured posts -->
<section class="two-feat-posts">
    <?php if ( is_front_page() && ! is_paged() ) :
    $latest = get_featured_two();
    while ( $latest->have_post() ) : $latest->the_post();
        get_template_part('content',get_post_format());
    endwhile;
    endif; ?>
</section>
<!-- End two featured posts -->

<h4 class="main-title">Previous episodes</h4>

<!-- Start standard loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <?php get_template_part('content',get_post_format()); ?>
<?php endwhile; endif; ?>
<!-- End standard loop -->

これ以上の助けは非常に高く評価されるでしょう:)


私はテーマをコーディングしていて、私は半分解決しましたが壁にぶつかったピクルスに出くわしました。

本質的に私が達成しようとしているのはこれです:

  1. ホームページのヘッダ領域に表示される最新の投稿(投稿1)
  2. 2つの注目記事(投稿2と3)それぞれ50%幅
  3. それから10のリストの残りのポスト(ポスト4から13)

私はメインのループで10個の投稿を表示しています。これは最新の投稿を相殺するものです(最新のものはサイトの上部にあります)。

<?php

        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        $args = array (
            'post_type' => 'post',
            'posts_per_page' => '10',
            'paged' => $paged
        );

        $mainLoop = new WP_Query( $args );

        if( $mainLoop->have_posts() ) :

        while( $mainLoop->have_posts() ) : $mainLoop->the_post(); ?>

    <?php get_template_part( 'content', get_post_format() ); ?>

    <?php endwhile;

        the_posts_pagination( array(
            'mid_size'  => 2,
            'prev_text' => __( 'Previous', 'textdomain' ),
            'next_text' => __( 'Next', 'textdomain' ),
        ) );

        wp_reset_postdata();

        else : get_template_part( 'content', 'none' );

        endif;

    ?>

これがヘッダの最新投稿のコードです。

<?php
            $args = array (
                'post_type' => 'post',
                'posts_per_page' => '1'
            );

            $latestPost = new WP_Query( $args );

            if( $latestPost->have_posts() ):

            while( $latestPost->have_posts() ): $latestPost->the_post();

                 get_template_part('content',get_post_format());

             endwhile;

            endif;

            wp_reset_postdata();
        ?>

私が遭遇した問題はページネーションでした。すべてのページで同じ投稿を表示していたので、I はcodex. からこの修正を実装しました。ヘッダーも1つオフセットされており、最新の投稿は表示されていません。

私はまだ2つのおすすめ投稿をまだコーディングしていないので、それらについてもアドバイスを使用できます(1ページに3つのカスタムループがあっても大丈夫ですか?)。

ありがとう。

3
Garry Aylott

メインのクエリでフロントページとページ付きページに異なる量の投稿を表示していないので、オフセットをいじる必要はありません。あなたが必要としているのはあなたがpre_get_postsアクションを使ってできるあなたがあなたのクエリからすでに示した3つの投稿を除外することです:

function get_featured_one() { /* returns your post #1 */ }
function get_featured_two() { /* returns your posts #2 and #3 */ }

add_action( 'pre_get_posts', function( $query ) {
    if ( ! $query->is_main_query() || is_admin() )
        return;

    if ( is_front_page() ) {
        $featured_one = get_featured_one();
        $featured_two = get_featured_two();

        $exclude = array_merge( wp_list_pluck( $featured_one->posts , 'ID' ), wp_list_plugk( $featured_two->posts, 'ID' ) );
        $query->set( 'post__not_in', $exclude );
    }
});

WordPressはテンプレートファイルに到達するずっと前から既にそのクエリを実行しているので、テンプレートファイル内で$mainLoopを削除するだけなので、再度実行する必要はありません。あなたの必要なのはあなたの最新の投稿をあなたのヘッダーに表示することです:

<?php if ( is_front_page() && ! is_paged() ) : ?>
    <?php $latest = get_featured_one(); ?>
    <?php while ( $latest->have_post() ) : $latest->the_post(); ?>
        <!-- Output stuff here. -->
    <?php endwhile; ?>
<?php endif; ?>

あなたの2つの50/50投稿のアーカイブ/フロントページ/インデックステンプレートはget_featured_two()と同じです。その後、(実際の)メインループが他のすべての処理を行います。だからこれはあなたの注文です:

  • $latest->have_posts()
  • $featured->have_posts()
  • have_posts()

ページ付きページの場合は、おそらく$featuredの出力を除外したいでしょうが、それでもフロントページに表示しているので、それらの投稿はメインのクエリから除外します。また、それらをメインクエリに含めると、メインクエリによって返される投稿の総数(ページ付きページ)が変わり、ページネーションが壊れます。

両方のget_featured_*関数はWP_Queryオブジェクトを返さなければなりません:

function get_featured_one() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'posts_per_page' => 1,
    ) );
}

function get_featured_two() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'tag' => 'featured',
        'posts_per_page' => 2,
    ) );
}

パフォーマンスを向上させるためにおそらく静的キャッシングを使用することもできますが、それらを1回のリクエストで複数回呼び出すとまったく同じ出力になるはずであることが確実な場合に限ります(つまりswitch_to_blog()コンテキストでは使用しません)。

投稿は注目と最新の両方の可能性があるため、_one()から返される投稿を_two()から除外することもおそらく賢明です。

私のSemicolonテーマでは、 もう少し複雑な でも似たようなことをしました。おすすめの投稿が一番上に貼り付けられているかどうかに関係なく、投稿の数を同じにする必要があるため、オフセットマジックが必要になります。しかし、アイデアは非常に似ています。

それが役立つことを願っています。

1
kovshenin