web-dev-qa-db-fra.com

Obtenir la description de la taxe basée sur la variable

J'essaie d'afficher une description de taxonomie en fonction de la taxonomie définie pour la page (définie avec une variable)

En l'état, je ne vois que la première description, quelle que soit la variable de catégorie définie.

Voici comment je l'ai mis en place:

J'ai créé un type de message personnalisé appelé "produit" et mis en place une taxonomie appelée "type_produit".

    //Register product post type
    add_action('init', 'product_register');
    function product_register() {
        $labels = array(
            'name' => ('Products'),
            'singular_name' => ('Product'),
            'add_new' => ('Add New'),
            'add_new_item' => ('Add New Product'),
            'edit_item' => ('Edit Product'),
            'new_item' => ('New Product'),
            'view_item' => ('View Product'),
            'search_items' => ('Search'),
            'not_found' => ('Nothing found'),
            'not_found_in_trash' => ('Nothing found in Trash'),
            'parent_item_colon' => ''
            );
        $args = array(
            'labels' => $labels,
            'menu_icon' => 'dashicons-tag',
            'public' => true,
            'has_archive' => true,
            'supports' => array('title', 'revisions', 'editor','thumbnail'),
            'capability_type' => 'post',
            'rewrite' => array("slug" => "product"), // Permalinks format
            );
        register_taxonomy('product_type', array('product'), array(
            'hierarchical' => true,
            'label' => 'Product Type',
            'singular_label' => 'Type',
            'show_ui' => true,
            'show_admin_column' => true,
            'query_var' => true,
            'rewrite' => true)
        );
        register_post_type( 'product' , $args );
    }

Dans la partie finale de wordpress, j'ai chargé cela de quelques termes et ajouté des descriptions.

Admin category list with values archive-products.php fonctionne comme une page d'arrivée, mais accepte les informations d'une variable appelée $ type pour filtrer le contenu.

    if (isset($_GET['type']) || !empty($_GET['type']) ) {
        $filtered = true;
        $type = $_GET['type'];
    }

Avec ces informations, je peux configurer une requête WP_Query pour les éléments contenant ce terme de taxonomie.

    if ($filtered == true) {
        $type = explode(' ', $_GET['type']);
        $taxonomy = array(
            array(
                'taxonomy' => 'product_type',
                'field'    => 'slug',
                'terms'    => $type
                )
            );
    $args = array(
        'post_type' => 'product',
        'posts_per_page' => -1,
        'order' => 'DEC',
        'orderby' => 'title',
        'offset' => '0',
        'tax_query' => $taxonomy
        );
    $the_query = new WP_Query($args);
    if($the_query->have_posts()):
        $terms = get_the_terms( $post->ID, 'product_type' );
    if($terms) {
        foreach( $terms as $term ) {
    echo $term->description; //always shows first term description, but should display description based on $type
    }
    }
    while($the_query->have_posts()):$the_query->the_post();
    the_title();
    the_content();
    endwhile;
    else: //nothing to show here
    endif;} else {
    // non-filtered page design
    }

La requête fonctionne très bien mais, comme je l’ai mentionné plus tôt, elle ne fait que tirer la première description de la taxonomie.

C'est la partie qui est destinée à gérer cela:

    $terms = get_the_terms( $post->ID, 'product_type' );
    if($terms) {
        foreach( $terms as $term ) {
    echo $term->description;
    }
    }

J'avais deviné que cela devait figurer dans la requête pour trouver la description correcte, mais cela ne semble pas faire la différence.

J'ai aussi essayé ceci:

    $term = get_term_by( $post->ID, $type, 'product_type' );
    echo $term->description;

mais cela ne retourne rien.

Je suis à court d'idées. Je n'ai rien trouvé via Google ou en effectuant une recherche sur ce site.

Tout conseil est apprécié, merci d'avance.

2
mdcrtv

Vous avez beaucoup de problèmes ici:

  • Vous ne devriez pas utiliser les variables $_GET sans les désinfecter. Ne faites jamais confiance aux entrées d'utilisateur et aux paramètres d'URL. Ils pourraient contenir du code malveillant pouvant nuire à votre site. Pour désinfecter et valider une variable $_GET, utilisez la fonction php filter_input

    $filtered = filter_input( INPUT_GET, 'type', FILTER_SANITIZE_STRING )
    
  • Utilisez la requête principale et utilisez pre_get_posts pour filtrer la requête principale en conséquence. Il n'est pas nécessaire d'utiliser une requête personnalisée, car il s'agit d'une page d'archive.

  • Vous essayez de vous tromper sur la description actuelle du terme, vous devriez utiliser get_term_by pour obtenir le terme objet qui contiendra les informations dont vous avez besoin

  • Cela peut ne pas être lié, mais pourquoi n’utilisez-vous pas une page taxonomy.php qui gérera tout ce qui précède comme il se doit. Vous avez juste besoin de vider vos permaliens et tout devrait fonctionner comme il se doit. Mais c’est quelque chose que vous devez examiner à votre rythme

Permet de trier d'abord la page d'archive. J'ai commenté le code afin de le rendre facile à comprendre. Je ne sais pas combien de termes vous passerez, mais de votre code j'en ai pris plus que 1. Sinon, veuillez voir le code et ajuster en conséquence

$filtered = filter_input( INPUT_GET, 'type', FILTER_SANITIZE_STRING );
if ( $filtered  ) {
    /**
     * I don't know if you will be passing more than one term. From your code it seems so
     */
    $types = explode( ' ', $filtered ); 
    foreach ( $types as $type ) {

        /**
         * Get the term object. 
         *
         * I have used the slug here as it seems that you are passing the slug. Adjust as necessary
         *
         * @see get_term_by()
         */
        $term = get_term_by( 'slug', $type, 'product_type' );
        // Make sure that $term has a valid value before outputting anything
        if ( !empty( $term ) || !is_wp_error( $term ) )
            echo $term->description; // Show term description
    }
    /* Replace code above with the following if you are passing just one term
    $term = get_term_by( 'slug', $filtered, 'product_type' ); 
    if ( !empty( $term ) || !is_wp_error( $term ) )
        echo $term->description; // Show term description
    */
    if ( have_posts() ) {
        while( have_posts() ) {
            the_post();

            the_title();
            the_content();
        }
    }

} else {

    // non-filtered page design
    // I don't know what will be displayed here, so I'm keeping the loop and this separate

}

Cela devrait trier la page d'archive. Par défaut, ce qui suit est passé par défaut, nous ne les transmettrons donc pas dans notre action.

  • type de poste

  • décalage.

Alors, regardons notre action. J'ai de nouveau commenté le code pour le rendre facile à suivre. Veuillez noter que ce qui suit nécessite au moins PHP 5.4+ en raison de la syntaxe de tableau courte ([]) utilisée. Pour les versions plus anciennes, revenir à l'ancienne syntaxe de tableau (array())

add_action( 'pre_get_posts', function ( $q ) 
{
    $filtered = filter_input( INPUT_GET, 'type', FILTER_SANITIZE_STRING );
    if (    !is_admin() // Only target the front end
         && $q->is_main_query() // Only target the main query
         && $q->is_post_type_archive( 'product' ) // Only target product archive page
         && $filtered // If we have a $_GET['type'] variable
    ) {
        if ( isset( $q->get( 'tax_query' ) ) ) //Get current tax query
            $tax_query = []; // Set current tax_query to an empty array

        // Set our new tax_query
        $tax_query = [
            [
                'taxonomy'         => 'product_type',
                'field'            => 'slug'
                'terms'            => explode( ' ', $filtered ),
                'include_children' => false
            ]
        ];
        $q->set( 'tax_query', $tax_query ); // Set new tax_query
        $q->set( 'posts_per_page', -1 ); // Get all posts
        $q->set( 'order', 'DESC' ); // Descending sort order
        $q->set( 'orderby', 'title' ); // Sort by title
    }
});

J'espère que c'est ce dont vous avez besoin

1
Pieter Goosen