it-swarm.dev

Zobrazování příspěvků souvisejících s jinými příspěvky podle termínu taxonomie?

Mám vlastní typ příspěvku pro profily hudebníků a taxonomii pro jejich umístění (hierarchicky rozděleny do zemí a poté do měst). Na jednotlivých stránkách profilu hudebníka musím zobrazit seznam hudebníků ve stejném městě (tj. Taxonomii dítěte). Také by bylo dobré oddělené zobrazení příspěvků ve stejné zemi (nadřazená taxonomie).

Zdá se, že problémem je dynamické načítání taxonomie, oddělení rodičovských a dětských taxonomií a jejich použití v nové smyčce.

Můžu zobrazit seznam taxonomií a odškrtnout odkazy ...

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

... který vrací výsledek jako tento: New York, USA

A mohu snadno projít příspěvky pomocí pevné hodnoty taxonomie ...

<?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; ?>

Mám však problémy s kombinací těchto dvou: pokud mohu říci 'get_the_term_list', nemá schopnost vrátit pouze jednu taxonomii a nezdá se, že by to bylo ekvivalentem taxonomie 'get_the_category'.

Nějaká pomoc velmi ocenil !!!

2
George

Ahoj @ George :

V závislosti na tom, kolik hudebníků očekáváte, že budou ve vaší databázi, můžete buď jít na úplnou trasu API (což je obecně preferováno, kdykoli je to možné) , pokud budete mít velké číslo z nich (tisíce?), můžete jít s některými vlastní SQL vytáhnout přesně záznamy, které potřebujete.

Použití API aplikace WordPress

Základy přístupu WordPress API jsou první volání wp_get_object_terms() s $post->ID vašeho hudebníka ve vašem profilu a vaše 'locations' taxonomie, která vrátí seznam "termínů" objektů. (Bohužel potřebujete, aby se jednalo pouze o jedno místo, nebo se toto řešení rozpadne. Ale ignorování ...)

Dále si vezměte termín ID prvního termínu a předejte jej spolu s vaší 'locations' taxonomií get_objects_in_term(), která vrací pole ID účtů, které mají výrazy spojené s požadovanou taxonomií. (Toto bude zahrnovat VŠECHNY příspěvky, které mají LIBOVOLNÝ výraz spojený s vaší taxonomií 'locations', proto je tento přístup vhodný pouze pro menší počet záznamů.)

Potom vytvoříte objekt WP_Query, který mu předá dotaz, který používá post__in k filtrování podle seznamu hudebníků ID, která jste obdrželi výše, stejně jako vaše 'locations' taxonomie a její konkrétní termín města zachycený pro vašeho profilovaného hudebníka. Samozřejmě musíte také pamatovat na filtrování profilovaného hudebníka pomocí argumentu 'post__not_in'.

Celkově jsem zabalil tuto logiku do funkce nazvané get_posts_related_by_taxonomy(), jejíž zdrojový kód můžete vidět zde (když jsem vysvětlil, ale doufejme, že jsou rozumně zřejmé, zanechal jsem pár detailů):

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;
}

Nyní můžete tuto funkci použít v vlastní smyčce takto:

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

Použití přímého přístupu SQL

Jak jsem již řekl, dávám přednost WordPress API, když je životaschopný. Bohužel si myslím, že narazíte na problémy s výkonem nebo pamětí, pokud máte i poměrně velký počet hudebníků a použijete výše uvedený přístup.

Jako alternativní výkonný a paměťově efektivní alternativu můžete použít přímý SQL k nahrazení všeho až do volání get_objects_in_terms() v předchozím příkladu. Dobrou zprávou je, že SQL je přímočarý a je nepravděpodobné, že by narazil na budoucí problémy s kompatibilitou s novými verzemi WordPressu, protože SQL používal pouze odkazy na primární a cizí klíče a to se nezmění, pokud zcela nezmění systém taxonomie, což je podle mého názoru nepravděpodobné.

Pomocí SQL jsem vytvořil jinou verzi funkce get_posts_related_by_taxonomy(), kterou budete nazývat přesně stejnou jako první verze. SQL rozpoznává, že tabulka wp_term_relationships musí být spojena dohromady pomocí svého společného pole term_taxonomy_id, které bude odkazovat na všechny záznamy hudebníků daného umístění/ (taxonomie) + město/ (termín) pár. Pak se připojíme k tabulce wp_term_taxonomy, takže můžeme filtrovat na taxonomii a také filtrujeme podle profilovaného hudebníka na jednom konci vztahu a filtrujeme, abychom se ujistili, že žádný z příbuzných hudebníků není profilovaným hudebníkem na druhém konci. vztah. Nakonec se ujistíme, že související typy hudebníků se shodují s typem příspěvku našeho profilovaného hudebníka, takže se můžete vyhnout ještě dalšímu vyhledávání, v tomto případě se vyhneme volání get_post().

Naše výsledky z SQL jsou pěkné jednoduché pole ID účtů, které můžeme znovu použít s argumentem post__inWP_Query, ale tentokrát nemusíme zahrnout post__not_in, taxonomy nebo term filtr $args a my můžeme říci post_type použít 'any' protože náš SQL dotaz již zpracoval všechny tyto.

Pro druhou verzi je zde kód, který potřebujete:

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);
}

A znovu, budete používat tuto druhou verzi get_posts_related_by_taxonomy() přesně stejným způsobem, jakým jste použili první verzi.

Snad to pomůže!

9
MikeSchinkel

Podívejte se wp_get_object_terms() , je to obecnější funkce a co get_the_category() používá interně.

2
Rarst