web-dev-qa-db-fra.com

Afficher les articles associés sur une seule page par taxonomie personnalisée dans un article personnalisé

J'essaie de construire un site Web de location de villas. Pour ce faire, j'ai créé deux types de publication personnalisés. L'une s'appelle "villa" et est utilisée pour afficher les villas à louer, l'autre est nommée "destinations" et indique les endroits où se trouvent ces villas.

J'ai utilisé le plugin CPT-onomies pour créer le type de message personnalisé "destinations", une taxonomie personnalisée pour mon type de message personnalisé "villa". Il existe deux types de messages personnalisés et l'un est utilisé comme taxonomie pour l'autre, pour montrer où se trouve cette villa. Sur chaque page concernant une seule villa.php, je souhaite afficher une villa associée à la fin du message (après la boucle), je souhaite que cette villa associée soit associée uniquement par destination (taxonomie personnalisée).

J'ai trouvé this article, j'ai suivi les instructions et il a en quelque sorte fait le tour pour moi; malheureusement, je ne peux pas comprendre deux choses: tous les messages liés. 2. Je ne sais pas comment exclure le message en cours de messages en rapport (des instructions expliquent comment y parvenir dans l'article que j'ai lié ci-dessus, mais cela ne fonctionne pas pour moi.)

J'ai ajouté ce code à functions.php

// Create a query for the custom taxonomy
    function related_posts_by_taxonomy( $post_id, $taxonomy, $args=array() ) {
        $query = new WP_Query();
        $terms = wp_get_object_terms( $post_id, $taxonomy );

        // Make sure we have terms from the current post
        if ( count( $terms ) ) {
            $post_ids = get_objects_in_term( $terms[0]->term_id, $taxonomy );
            $post = get_post( $post_id );
            $post_type = get_post_type( $post );

            // Only search for the custom taxonomy on whichever post_type
            // we AREN'T currently on
            // This refers to the custom post_types you created so
            // make sure they are spelled/capitalized correctly
            if ( strcasecmp($post_type, 'sites') == 0 ) {
                $type = 'sites';
            } else {
                $type = 'sites';
            }

            $args = wp_parse_args( $args, array(
                    'post_type' => $type,
                    'post__in' => $post_ids,
                    'taxonomy' => $taxonomy,
                    'term' => $terms[0]->slug,
                ) );
            $query = new WP_Query( $args );
        }

        // Return our results in query form
        return $query;
    }

Et ce code à single-villa.php

<?php $related =  related_posts_by_taxonomy( $post->ID, 'destinations' );
        while ( $related->have_posts() ): $related->the_post(); ?>

            <div class="inner">
                <a href="<?php get_permalink(); ?>"><?php the_post_thumbnail(); ?>  </a>
                <?php echo get_the_title(); ?>      

        </div>

        <?php endwhile; ?>

Je ne veux utiliser aucun plugin, je veux plutôt ajouter du code à mon thème pour le faire.

Merci à tous d'avance pour votre temps et vos réponses! Je voudrais m'excuser mais l'anglais n'est pas ma langue maternelle! Merci de votre compréhension.

3
BigDropGR

Je voudrais juste supprimer la fonction ci-dessus car il y a plusieurs bugs dans le code et n'est pas assez efficace. Je suis en fait surpris que cela fonctionne vraiment pour vous.

Votre meilleure solution ici serait d’écrire une nouvelle fonction complète. Voici le désir que nous voulons faire et comment nous allons accomplir cela

  • Obtenez l'objet de publication en cours sur la page de publication unique. $post n'est pas fiable, nous allons donc utiliser ici l'objet de requête principal que nous renverrons avec get_queried_object(). À partir de là, nous pouvons utiliser l'identifiant et le type de message pour obtenir d'autres informations connexes.

  • Obtenez les termes du post en cours affiché avec wp_get_post_term(). Nous allons définir le paramètre fields pour obtenir uniquement les identifiants de terme. Ce tableau d'identifiants de termes peut être utilisé dans notre tax_query

  • Ajoutez une validation pour valider la saisie de l'utilisateur et également la désinfecter

Mettons cela dans le code ( CAVEAT: tout cela n’a pas été testé et nécessite au moins PHP 5.4+ )

function get_related_posts( $taxonomy = '', $args = [] )
{
    /*
     * Before we do anything and waste unnecessary time and resources, first check if we are on a single post page
     * If not, bail early and return false
     */
    if ( !is_single() )
        return false;

    /*
     * Check if we have a valid taxonomy and also if the taxonomy exists to avoid bugs further down.
     * Return false if taxonomy is invalid or does not exist
     */
    if ( !$taxonomy ) 
        return false;

    $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
    if ( !taxonomy_exists( $taxonomy ) )
        return false;

    /*
     * We have made it to here, so we should start getting our stuff togther. 
     * Get the current post object to start of
     */
    $current_post = get_queried_object();

    /*
     * Get the post terms, just the ids
     */
    $terms = wp_get_post_terms( $current_post->ID, $taxonomy, ['fields' => 'ids'] );

    /*
     * Lets only continue if we actually have post terms and if we don't have an WP_Error object. If not, return false
     */
    if ( !$terms || is_wp_error( $terms ) )
        return false;

    /*
     * Set the default query arguments
     */
    $defaults = [
        'post_type' => $current_post->post_type,
        'post__not_in' => [$current_post->ID],
        'tax_query' => [
            [
                'taxonomy' => $taxonomy,
                'terms' => $terms,
                'include_children' => false
            ],
        ],
    ];

    /*
     * Validate and merge the defaults with the user passed arguments
     */
    if ( is_array( $args ) ) {
        $args = wp_parse_args( $args, $defaults );
    } else {
        $args = $defaults;
    }

    /*
     * Now we can query our related posts and return them
     */
    $q = get_posts( $args );

    return $q;
}

Maintenant que nous avons une meilleure fonction en place, nous pouvons l’utiliser dans nos parties de page de publication unique ou de modèle de contenu en fonction de votre cas d’utilisation exact. Comme vous l'avez peut-être remarqué, notre nouvelle fonction get_related_posts() a deux paramètres, le premier qui accepte une seule valeur de taxonomie et le second un tableau d'arguments. Ces arguments seront les arguments passés à notre requête afin que vous puissiez passer tout tableau valide d'arguments acceptables à WP_Query et get_posts ici.

Exemple:

Vous avez besoin d'un message pour être renvoyé. Vous pouvez donc essayer les solutions suivantes: ( Veuillez noter que vous n'utilisez pas le paramètre type de message ni aucun des paramètres de type taxonomie ici, vous pourriez obtenir une sortie inattendue )

if ( function_exists( 'get_related_posts' ) ) {
    $related_posts = get_related_posts( 'my_taxonomy_name', ['posts_per_page' => 1] );
    if ( $related_posts ) {
        foreach ( $related_posts as $post ) {
            setup_postdata( $post ); 
            // Use your template tags and html mark up as normal like
            the_title();
            the_content();
            // etc etc
        }
        wp_reset_postdata();
    }
}

MODIFIER

D'après les commentaires, il semble que votre version de PHP soit antérieure à la version 5.4, ce qui ne prend pas en charge la nouvelle syntaxe de tableau abrégé ([]). Vous obtenez donc le redoutable WSOD. Pour que cela fonctionne, vous devez changer la nouvelle syntaxe de tableau en ancienne syntaxe (array()).

Vous pouvez essayer ce qui suit:

function get_related_posts( $taxonomy = '', $args = array() )
{
    /*
     * Before we do anything and waste unnecessary time and resources, first check if we are on a single post page
     * If not, bail early and return false
     */
    if ( !is_single() )
        return false;

    /*
     * Check if we have a valid taxonomy and also if the taxonomy exists to avoid bugs further down.
     * Return false if taxonomy is invalid or does not exist
     */
    if ( !$taxonomy ) 
        return false;

    $taxonomy = filter_var( $taxonomy, FILTER_SANITIZE_STRING );
    if ( !taxonomy_exists( $taxonomy ) )
        return false;

    /*
     * We have made it to here, so we should start getting our stuff togther. 
     * Get the current post object to start of
     */
    $current_post = get_queried_object();

    /*
     * Get the post terms, just the ids
     */
    $terms = wp_get_post_terms( $current_post->ID, $taxonomy, array( 'fields' => 'ids') );

    /*
     * Lets only continue if we actually have post terms and if we don't have an WP_Error object. If not, return false
     */
    if ( !$terms || is_wp_error( $terms ) )
        return false;

    /*
     * Set the default query arguments
     */
    $defaults = array(
        'post_type' => $current_post->post_type,
        'post__not_in' => array( $current_post->ID),
        'tax_query' => array(
            array(
                'taxonomy' => $taxonomy,
                'terms' => $terms,
                'include_children' => false
            ),
        ),
    );

    /*
     * Validate and merge the defaults with the user passed arguments
     */
    if ( is_array( $args ) ) {
        $args = wp_parse_args( $args, $defaults );
    } else {
        $args = $defaults;
    }

    /*
     * Now we can query our related posts and return them
     */
    $q = get_posts( $args );

    return $q;
}

Et puis pour utiliser le code dans les modèles, changez pour

if ( function_exists( 'get_related_posts' ) ) {
    $related_posts = get_related_posts( 'my_taxonomy_name', array( 'posts_per_page' => 1) );
    if ( $related_posts ) {
        foreach ( $related_posts as $post ) {
            setup_postdata( $post ); 
            // Use your template tags and html mark up as normal like
            the_title();
            the_content();
            // etc etc
        }
        wp_reset_postdata();
    }
}
6
Pieter Goosen

Donc, pour atteindre vos deux problèmes, tout ce que nous avons à faire est de modifier le tableau $ args utilisé pour la requête. Comme il s'agit d'une requête, nous pouvons utiliser n'importe lequel des paramètres que Wordpress nous a gentiment fournis ici: WP_Query .

Comme celui-ci: post__not_in (array) - use post ids. Specify post NOT to retrieve.

Et celui-ci: posts_per_page (int) - number of post to show per page

Ajoutons maintenant ces 2 paramètres au tableau $ args.

$args = wp_parse_args( $args, array(
    'post_type' => $type,
    'post__in' => $post_ids,
    'taxonomy' => $taxonomy,
    'term' => $terms[0]->slug,
    'post__not_in' => $post_id, // $post_id has already been provided for us.
    'posts_per_page' => 1,
) );

Et ça devrait être ça. Cela affichera probablement aussi le dernier post de la taxonomie, de sorte que vous aurez probablement la même "villa" apparaître beaucoup. Mais vous pouvez définir le paramètre orderby pour résoudre ce problème.

0
ngearing