web-dev-qa-db-fra.com

Utilisez l'API transitoire pour mettre en cache les requêtes pour toutes les publications dans toutes les catégories?

J'utilise cela pour afficher tous les messages dans toutes les catégories.

$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

Après avoir lu ceci , ceci , ceci et ceci je me demande si je fais la bonne chose ci-dessous.

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

La sortie est correcte, toutes les catégories et les publications s'affichent correctement, mais les catégories et les publications sont-elles correctement mises en cache maintenant?

Dans le code, j'ai commenté les deux endroits où j'ai défini le transitoire, mais je ne sais pas si cela peut être utilisé avec get_categories() ou dans la foreach pour tous les articles de la catégorie.

Modifier
Le transitoire fonctionne pour get_categories(). La sortie var_dump me montre un tableau des objets WP_Term contenant les catégories disponibles.

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

Modifier
Le transitoire à l'intérieur de la foreach n'obtient que la première catégorie et ses messages et le répète pour le nombre de catégories. D'autres catégories que la première ne sont pas présentes, probablement parce que le même transitoire est appelé pour le nombre de catégories et que, après le premier tour de foreach, il est plein et que, par conséquent, la boucle affiche uniquement les messages de la première catégorie.

Maintenant, comment puis-je créer un nouveau transitoire qui conserve les messages par catégorie à chaque cycle de la foreach pour le nombre de catégories?

Totalement nouveau pour l'API transitoire et essayer de l'utiliser à bon escient. En essayant d’ajuster le code et de s’en tenir aux meilleures pratiques, si c’est une mauvaise utilisation avec des erreurs cachées ou inexistantes car cela ne fonctionne pas, veuillez me le faire savoir. Un peu de conseils ou si j’ai bien saisi le "chemin" pour utiliser les transitoires serait très apprécié.

Solution
Per cette réponse Je devais donner au transitoire créé pour chaque catégorie le nom de la catégorie (slug). Sinon, seule la première catégorie est stockée dans le transitoire et une fois remplie pour le deuxième cycle, elle ne sera pas modifiée. Par conséquent, seuls les messages de la première catégorie étaient affichés.

Utiliser uniquement $category pour la variable transitoire ne fonctionnait pas, car $category était un objet et une chaîne était nécessaire. Je l'ai donc modifiée en $category->slug et maintenant, cela fonctionne.

Cela a été fait aux deux endroits, obtenant et réglant le transitoire. Je vous remercie!

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

Vous sauvegardez chaque objet de requête pour chaque catégorie sur le même transitoire. Comme cela se produit rapidement et que le délai est d'un jour, vous obtenez toujours l'objet de requête pour la première catégorie. Attribuez à votre nom de variable une variable avec la catégorie, par exemple comme ça:

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

Bien sûr, vous devez ensuite obtenir le transitoire avec le nom de la variable.

3
Nicolai