web-dev-qa-db-ja.com

すべてのカテゴリのすべての投稿に対するクエリをキャッシュするためにTransient APIを使用しますか?

これを使用して、すべてのカテゴリのすべての投稿を表示します。

$args_cat = array(
    // order by category name ascending
    'orderby' => 'name',
    'order' => 'ASC',
    // get only top level categories
    'parent' => 0
);
$categories = get_categories($args_cat);

// Full posts query
// if there are categories filled with posts
if (!empty ($categories) && !is_wp_error( $categories )) {

    foreach ($categories as $category) {

        // Query all posts by slug inside each category
        $args_category_posts = array(
            'post_type' => 'post',
            // The category slug and category name we get from the foreach over all categories
            'category_name' => $category->slug
        );

        $query = new WP_Query($args_category_posts);
        if ($query->have_posts()) {
            while ($query->have_posts()) {
                $query->the_post(); ?>
                <article class="<?php echo $category->slug ?>-article">
                    <h2 class="<?php echo $category->slug ?>-article-title">
                        <a href="<?php echo get_permalink() ?>"><?php echo get_the_title() ?></a>
                    </h2>
                    <p class="<?php echo $category->slug ?>-post-info">
                        <?php the_time('d. m. Y') ?>
                    </p>
                    <div <?php post_class() ?> >
                        <?php the_content(); ?>
                    </div>
                </article> <?php
            }
        } // end loop
    } // end foreach
wp_reset_postdata() ;
} // end if there are categories filled with posts

これ - これこれ そして これ /私は以下の正しいことをしているのか疑問に思います。

// Transient API all categories and all posts
$query_categories = get_transient('cached_categories');
if ( false === $query_categories){
    $args_cat = array(
        // order by category name ascending
        'orderby' => 'name',
        'order' => 'ASC',
        // get only top level categories
        'parent' => 0
    );
    // Instead of caching a WP Query I cache 'get_categories($args_cat)', OK to use it like this?
    $query_categories = get_categories($args_cat);
    set_transient('cached_categories', $query_categories, DAY_IN_SECONDS );
}

// Full posts query
// if there are categories filled with posts
if (!empty ($query_categories) && !is_wp_error( $query_categories )) {

    foreach ($query_categories as $category) {

        $query_category_posts = get_transient('cached_posts');
        if ( false === $query_category_posts ){

            // Query all posts by slug inside each category
            $args_category_posts = array(
                'post_type' => 'post',
                // The category slug and category name we get from the foreach over all categories
                'category_name' => $category->slug
            );

            // Here I cache the WP_Query, though this runs for all categories.
            // So am I storing multiple transients here?
            $query_category_posts = new WP_Query($args_category_posts);
            set_transient( 'cached_posts', $query_category_posts, DAY_IN_SECONDS );
        }

        if ($query_category_posts->have_posts()) {
            while ($query_category_posts->have_posts()) {
                $query_category_posts->the_post(); ?>
                <article class="<?php echo $category->slug ?>-article">
                    <h2 class="<?php echo $category->slug ?>-article-title">
                        <a href="<?php echo get_permalink() ?>"><?php echo get_the_title() ?></a>
                    </h2>
                    <p class="<?php echo $category->slug ?>-post-info">
                        <?php the_time('d. m. Y') ?>
                    </p>
                    <div <?php post_class() ?> >
                        <?php the_content(); ?>
                    </div>
                </article> <?php
            }
        } // end loop
    } // end foreach
wp_reset_postdata() ;
} // end if there are categories filled with posts

出力は問題ありません。すべてのカテゴリと投稿は正常に表示されますが、カテゴリと投稿は正しくキャッシュされますか?

コードでは、トランジェントを設定する2つの場所についてコメントしましたが、これがカテゴリ内のすべての投稿に対してget_categories()またはforeach内で使用できるかどうかはわかりません。

編集
トランジェントはget_categories()に対して機能します。 var_dumpの出力は、利用可能なカテゴリを保持しているWP_Termオブジェクトの配列を示しています。

$query_categories = get_categories($args_cat);
var_dump($query_categories);
set_transient('cached_categories', $query_categories, DAY_IN_SECONDS );

編集
foreachの中の一時的なものは、最初のカテゴリーとその投稿を取得し、それをカテゴリーの数だけ繰り返すことです。最初のカテゴリ以外のカテゴリは存在しません。これはおそらく、同じトランジェントがカテゴリの数に対して呼び出され、foreachの最初のラウンド以降はいっぱいになり、したがってループが最初のカテゴリの投稿のみを表示するためです。

カテゴリ数のforeachの各サイクルでカテゴリごとの投稿を保持する新しい一時的なものを作るにはどうすればいいですか?

Transient APIはまったく新しく、それをうまく利用しようとしています。コードを調整してベストプラクティスを維持しようとしているが、これがうまくいかないために潜んでいるエラーやすべてを使用していないエラーがすべて悪い使い方である場合は、教えてください。ちょっとしたガイダンスや、トランジェントを使う方法を理解したことがあれば、大いに評価されるでしょう。

解決策
[/。]あたり この答え /各カテゴリに対して作成されたトランジェントにカテゴリ名(スラグ)を付けなければなりませんでした。それ以外の場合は、最初のカテゴリのみがトランジェントに格納され、2番目のサイクルでいっぱいになると変更されません。したがって、最初のカテゴリの投稿のみが表示されていました。

$categoryはオブジェクトであり、文字列が必要であるため、一時変数に$categoryを使用しただけでは機能しませんでした。そのため、$category->slugに変更しても機能します。

これは、トランジェントの取得と設定の両方で行われました。ありがとうございました!

// Transients API all categories and all posts
$query_categories = get_transient('cached_categories');
if ( false === $query_categories){
    $args_cat = array(
        // order by category name ascending
        'orderby' => 'name',
        'order' => 'ASC',
        // get only top level categories
        'parent' => 0
    );
    // Instead of caching a WP Query I cache 'get_categories()'.
    $query_categories = get_categories($args_cat);
    // var_dump($query_categories);
    set_transient('cached_categories', $query_categories, DAY_IN_SECONDS );
}

// Full posts query
// if there are categories filled with posts
if (!empty ($query_categories) && !is_wp_error( $query_categories )) {

    foreach ($query_categories as $category) {

        // var_dump($category);
        $query_category_posts = get_transient('cached_posts_' . $category->slug );
        if ( false === $query_category_posts ){

            // Query all posts by slug inside each category
            $args_category_posts = array(
                'post_type' => 'post',
                // The category slug and category name we get from the foreach over all categories
                'category_name' => $category->slug
            );

            // Here I cache the WP_Query, though this runs for all categories.
            // Because of that the '$category->slug' is used to serve a string and not an object.
            $query_category_posts = new WP_Query($args_category_posts);         
            set_transient( 'cached_posts_' . $category->slug , $query_category_posts, DAY_IN_SECONDS );
        }

        if ($query_category_posts->have_posts()) {
            while ($query_category_posts->have_posts()) {
                $query_category_posts->the_post(); ?>
                <article class="<?php echo $category->slug ?>-article">
                    <h2 class="<?php echo $category->slug ?>-article-title">
                        <a href="<?php echo get_permalink() ?>"><?php echo get_the_title() ?></a>
                    </h2>
                    <p class="<?php echo $category->slug ?>-post-info">
                        <?php the_time('d. m. Y') ?>
                    </p>
                    <div <?php post_class() ?> >
                        <?php the_content(); ?>
                    </div>
                </article> <?php
            }
        } // end loop
    } // end foreach
wp_reset_postdata() ;
} // end if there are categories filled with posts
2
lowtechsun

各カテゴリのすべてのクエリオブジェクトを同じトランジェントに保存します。これは速く行われ、時間枠は1日であるため、常に最初のカテゴリのクエリオブジェクトが返されます。カテゴリを使用して一時的な名前を可変にします。このような:

$query_category_posts = get_transient('cached_posts_' . $category );

もちろん、その場合は変数名を使って一時変数を取得する必要があります。

3
Nicolai