web-dev-qa-db-fra.com

Obtenir toutes les catégories et les publications dans ces catégories

Je recherche une solution qui me permet d'imprimer les éléments suivants:

Cat 1        Cat 2        Cat 3
 Post 1       Post 1       Post 1
 Post 2       Post 2       Post 2
 Post 3                    Post 3
                           Post 4

MODIFIER

Je cherche quelque chose qui ne nécessitera que one requête de base de données! Donc, si vous avez une foreach dans votre code suivie d'un new WP_Query, alors ce n'est pas ce que je recherche (je prévois de le mettre sur la page d'accueil de mon site Web).

7
Ben

EDIT REVISIT NO 2

Je n'ai jamais touché le API transitoire , jusqu'à ce jour où j'ai vu @MikeSchinkel répondre dans cet article . Cela m'a inspiré à revisiter ce post une fois de plus. Après quelques essais, je suis arrivé avec ce qui suit:

  • Le temps d'exécution est passé d'environ 0,07 seconde à environ 0,002 seconde.

  • Le temps de requête dans la base de données a été réduit de moitié

  • Avec le transitoire, seulement 2 requêtes de base de données sont exécutées

Comment fonctionne le code (je vais juste discuter des modifications par rapport au code original à partir deREVISIT):

ÉTAPE 1

Nous devons enregistrer la valeur de $q dans un transitoire, c’est la valeur qui contient la liste des catégories avec les titres des publications.

ÉTAPE 2

Nous devons d’abord vérifier si un transitoire existe et, s’il n’en existe pas, créer le transitoire. Si le transitoire existe, récupérez ses informations

ÉTAPE 3

Cette information est maintenant transmise via une boucle foreach pour imprimer la liste avec les noms de catégories et les titres d'articles.

ÉTAPE 4

Dans l'état actuel des choses, le transitoire sera mis à jour toutes les douze heures. Cela peut être réglé pour répondre à vos besoins. Cependant, le transitoire devra être supprimé et recréé chaque fois que le statut d'une publication change. Cela peut être du brouillon à la publication, un nouveau message en cours de publication ou un message en cours de destruction. Pour ce faire, vous devez utiliser delete_transient qui sera relié au transition_post_status qui sera déclenché à chaque changement de statut d'une publication.

Voici le code complet:

Dans votre functions.php

add_action( 'transition_post_status', 'publish_new_post', 10, 3 );

function publish_new_post() {
   delete_transient( 'category_list' );
}

Dans votre modèle où vous devez afficher votre liste

<?php
if ( false === ( $q = get_transient( 'category_list' ) ) ) {

    $args = array( 
        'posts_per_page' => -1
    );

    $query = new WP_Query($args); 

    $q = array();

    while ( $query->have_posts() ) { 

        $query->the_post(); 

        $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';

        $categories = get_the_category();

        foreach ( $categories as $key=>$category ) {

            $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

        }

        $q[$b][] = $a; // Create an array with the category names and post titles
    }


    /* Restore original Post Data */
    wp_reset_postdata();

set_transient( 'category_list', $q, 12 * HOUR_IN_SECONDS );
}

foreach ($q as $key=>$values) {
        echo $key;

        echo '<ul>';
            foreach ($values as $value){
                echo '<li>' . $value . '</li>';
            }
        echo '</ul>';
    }


?>

REVISITE

J'ai récemment proposé une solution très légère beaucoup plus rapide que les autres solutions possibles proposées. Sur mon site de test, le temps de génération total n’est que d’environ 0,07 seconde et seulement 6 requêtes de base de données selon Query Monitor , tandis que les autres méthodes me donnent un temps de génération d’environ 0,35 seconde et 50 requêtes de base de données supplémentaires.

Voici un aperçu de ma méthode

ÉTAPE 1

Vous devez d’abord créer une requête personnalisée avec WP_Query pour récupérer tous les articles publiés.

$args = array( 
        'posts_per_page' => -1
    );

    $query = new WP_Query($args);   
    $q = array();

    while ( $query->have_posts() ) { 

    }

    /* Restore original Post Data */
    wp_reset_postdata();

Étape 2

En utilisant get_the_category , récupérez une liste de toutes les catégories auxquelles un article appartient.

$categories = get_the_category();

        foreach ( $categories as $key=>$category ) {

            $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

        }

ÉTAPE 3

Attribuer des variables au titre et aux catégories de l'article

$a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';

et

$b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

ÉTAPE 4

Combinez ces deux variables pour former un tableau multidimensionnel

$q[$b][] = $a;

Pour voir ce qui se passe dans le tableau, faites simplement un var_dump

?><pre><?php var_dump($q); ?></pre><?php

ÉTAPE 5

À l'aide de boucles foreach, créez votre liste de diffusion triée par catégorie.

foreach ($q as $key=>$values) {
    echo $key;

    echo '<ul>';
        foreach ($values as $value){
            echo '<li>' . $value . '</li>';
        }
    echo '</ul>';
}

TOUS ENSEMBLE MAINTENANT!

Voici le code complet

<?php

    $args = array( 
        'posts_per_page' => -1
    );

    $query = new WP_Query($args);   
    $q = array();

    while ( $query->have_posts() ) { 

        $query->the_post(); 

        $a = '<a href="'. get_permalink() .'">' . get_the_title() .'</a>';

        $categories = get_the_category();

        foreach ( $categories as $key=>$category ) {

            $b = '<a href="' . get_category_link( $category ) . '">' . $category->name . '</a>';    

        }

        $q[$b][] = $a; // Create an array with the category names and post titles
    }

    /* Restore original Post Data */
    wp_reset_postdata();

    foreach ($q as $key=>$values) {
        echo $key;

        echo '<ul>';
            foreach ($values as $value){
                echo '<li>' . $value . '</li>';
            }
        echo '</ul>';
    }

?>
14
Pieter Goosen

Je voulais juste ajouter ma solution qui dérive de cette question j'avais. Cela met en cache la requête pour les catégories et met également en cache les articles, y compris le contenu de l'article, dans chaque catégorie. La première fois que le cache est rempli, il y a des requêtes de base de données normales. Cependant, une fois remplies, les catégories et les publications mises en cache sont servies.

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

essayez maintenant ce code

$cat_ids=array();
foreach (get_categories() as $cat)
{
    array_Push($cat_ids, $cat->cat_ID);
}
$the_query = new WP_Query(array('post_type'=>'post', array('category__and' => $cat_ids) ) );
if( $the_query->have_posts() ): 
    while ( $the_query->have_posts() ) : $the_query->the_post(); 
        echo the_title();
    endwhile;
endif; 
wp_reset_query();
0
nikhil gadhiya