web-dev-qa-db-fra.com

Afficher les messages liés à d'autres messages par un terme de taxonomie?

J'ai un type de message personnalisé pour les profils de musicien et une taxonomie pour leur emplacement (catégorisés de manière hiérarchique dans Pays puis Villes). Sur les pages de profil individuelles du musicien, je dois afficher une liste de musiciens dans la même ville (c'est-à-dire la taxonomie des enfants). Il serait également bon d'afficher les publications dans le même pays séparément (la taxonomie parente).

Le problème semble être de récupérer la taxonomie de manière dynamique, en séparant les taxonomies parent et enfant et de les utiliser dans une nouvelle boucle.

Je peux afficher une liste des taxonomies et supprimer les liens ...

$terms = get_the_term_list( $post->ID, 'locations', '', ', ', '' ) ;
echo strip_tags($terms);

... qui donne un résultat comme celui-ci: New York, USA

Et je peux facilement parcourir les publications avec une taxonomie fixe ...

<?php $my_query = new WP_Query( array( 'locations' => 'new-york', 'showposts' => 10 ) ); ?>
<?php while ($my_query->have_posts()) : $my_query->the_post(); ?>
<li><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a></li>
<?php endwhile; ?>

Mais j'ai du mal à combiner les deux: pour autant que je sache, "get_the_term_list" n'a pas la capacité de renvoyer une seule taxonomie et il ne semble pas qu'il existe d'équivalent taxonomique de "get_the_category".

Toute aide très appréciée !!!

2
George

Bonjour@ George:

Selon le nombre de musiciens que vous attendez dans votre base de données, vous pouvez choisir la route complète de l’API (ce qui est généralement préférable, chaque fois qu’elle est insérable) si vous allez en avoir un grand nombre (en milliers). ?) vous pouvez utiliser un code SQL personnalisé pour extraire exactement les enregistrements dont vous avez besoin.

Utiliser l'approche API WordPress

Les bases de l'approche API WordPress sont d'abord d'appeler wp_get_object_terms() avec $post->ID de votre musicien de profil et de votre taxonomie 'locations' qui retournera une liste de "terme" objets. (Malheureusement, vous n’avez besoin que d’un seul emplacement ou cette solution tombe en morceaux. Mais ignorer cela ...)

Ensuite, vous récupérez l'ID terme du premier terme et le transmettez avec votre taxonomie 'locations' à get_objects_in_term() qui renvoie un tableau d'ID de publication auxquels les termes sont associés pour la taxonomie souhaitée. (Notez que ceci incluraTOUSposts qui ontANYterme associé à votre taxonomie 'locations', ce qui explique pourquoi cette approche n’est que bonne pour un plus petit nombre d'enregistrements.)

Ensuite, vous créez un objet WP_Query en lui passant une requête qui utilise post__in pour filtrer par la liste des ID de musicien que vous avez reçus ci-dessus, ainsi que par votre taxonomie 'locations' et son terme de ville spécifique capturé pour votre musicien profilé. Bien entendu, vous devez également vous rappeler de filtrer le musicien profilé à l'aide de l'argument 'post__not_in'.

Dans l'ensemble, j'ai regroupé cette logique dans une fonction appelée get_posts_related_by_taxonomy() dont vous pouvez voir le code source (j'ai laissé quelques détails de côté lorsque j'ai expliqué, mais j'espère qu'ils sont assez évidents):

function get_posts_related_by_taxonomy($post_id,$taxonomy,$args=array()) {
  $query = new WP_Query();
  $terms = wp_get_object_terms($post_id,$taxonomy);
  if (count($terms)) {
    // Assumes only one term for per post in this taxonomy
    $post_ids = get_objects_in_term($terms[0]->term_id,$taxonomy);
    $post = get_post($post_id);
    $args = wp_parse_args($args,array(
      'post_type' => $post->post_type, // The assumes the post types match
      'post__in' => $post_ids,
      'post__not_in' => $post->ID,
      'taxonomy' => $taxonomy,
      'term' => $terms[0]->slug,
    ));
    $query = new WP_Query($args);
  }
  return $query;
}

Maintenant, vous pouvez utiliser cette fonction dans votre propre boucle comme suit:

// This assumes that your musician profile record is in the $post variable
$musicians = get_posts_related_by_taxonomy($post->ID,'locations');?>
<ul>
<?php while ($musicians->have_posts()): $musicians->the_post(); ?>
  <li><?php the_id(); ?> -- <?php the_title(); ?></li>
<?php endwhile; ?>
</ul>

Utiliser l'approche Direct SQL

Comme je l'ai déjà dit, je préfère l'API WordPress lorsqu'elle est viable. Malheureusement, je pense que vous rencontrerez des problèmes de performances ou de mémoire si vous avez un nombre de musiciens assez important et si vous utilisez l'approche ci-dessus.

En tant qu'alternative performante et économe en mémoire, vous pouvez utiliser le SQL direct pour tout remplacer jusqu'à l'appel de get_objects_in_terms() inclus dans l'exemple précédent. La bonne nouvelle est que le code SQL est simple et qu'il est peu probable qu'il rencontre de futurs problèmes de compatibilité avec les nouvelles versions de WordPress, car le code SQL ne fait référence qu'aux clés primaires et étrangères et ne changera pas à moins de réorganiser complètement le système de taxonomie, ce qui, à mon avis, est peu probable.

À l’aide de SQL, j’ai créé une version différente de la fonction get_posts_related_by_taxonomy() que vous appellerez exactement de la même manière que la première version. Le code SQL reconnaît que la table wp_term_relationships doit simplement être reliée par son champ term_taxonomy_id commun qui relie tous les enregistrements de musicien pour un emplacement donné / (taxonomie) + ville / (terme) paire. Ensuite, nous le joignons à la table wp_term_taxonomy afin de pouvoir filtrer la taxonomie. Nous filtrons également par musicien profilé à une extrémité de la relation et nous filtrons pour nous assurer qu'aucun des musiciens liés n'est le musicien profilé à l'autre extrémité de la relation. la relation. Enfin, nous nous assurons que les types de publication de musiciens liés sont identiques à ceux de notre publication de musicien profilé afin que vous puissiez éviter une recherche supplémentaire. Dans ce cas, nous évitons d'appeler get_post().

Nos résultats SQL sont un tableau simple et agréable d’ID de publication que nous pouvons utiliser à nouveau avec l’argument post__in de WP_Query, mais cette fois-ci, nous n’avons pas besoin d’inclure les filtres post__not_in, taxonomy ou term$args et nous pouvons indiquer à post_type d’utiliser 'any' depuis. notre requête SQL a déjà traité tous ces problèmes.

Pour la deuxième version, voici le code dont vous avez besoin:

function get_posts_related_by_taxonomy($post_id,$taxonomy,$args=array()) {
  global $wpdb;
  $sql =<<<SQL
SELECT
  related.object_id
FROM
  {$wpdb->term_relationships} post
  INNER JOIN {$wpdb->term_taxonomy} link ON post.term_taxonomy_id = link.term_taxonomy_id
  INNER JOIN {$wpdb->term_relationships} related ON post.term_taxonomy_id = related.term_taxonomy_id
WHERE 1=1
  AND link.taxonomy='%s'
  AND post.object_id=%d
  AND post.object_id<>related.object_id
  AND post.post_type==related.post_type
SQL;
  $post_ids = $wpdb->get_col($wpdb->prepare($sql,$taxonomy,$post_id));
  $args = wp_parse_args($args,array(
    'post_type' => 'any',
    'post__in' => $post_ids,
  ));
  return new WP_Query($args);
}

Et encore une fois, vous utiliserez cette deuxième version de get_posts_related_by_taxonomy() exactement de la même manière que vous avez utilisé la première version.

J'espère que cela t'aides!

9
MikeSchinkel

Découvrez wp_get_object_terms() , c'est une fonction plus générale et ce que get_the_category() utilise en interne.

2
Rarst