Alle WordPress Tags von Beiträgen einer bestimmten Kategorie auslesen

Donnerstag, der 30. Oktober 2008. Veröffentlicht von René.

Robert Griffin verwendet das WordPress Plugin SensitiveTagCloud von mir, und hat mich gefragt wie es möglich ist eine Liste aller Tags zu bekommen die an Beiträgen einer bestimmten Kategorie verwendet wurden. Ich kann dazu zwei Lösungen anbieten:

Die WordPress-Lösung zum Weiterbasteln und für verschiedenste Bedingungen

Bei der SensitiveTagCloud funktioniert das für jede Art von Archiv-Seiten (Author-, Kategorie-, Tag-, …Archiv) so: Es werden alle Beiträge ausgelesen und dann die Tags dieser Beiträge gesammelt. Um die Beiträge einer Kategorie anzuzeigen führt WordPress eine auf die maximale Anzahl anzuzeigenden Beiträge pro Seite limitierte Query aus. Diese Query wiederholt die SensitiveTagCloud einfach, jedoch ohne das Limit, um eine komplette Liste aller Beiträge dieser Kategorie zu bekommen. Für das Auslesen der Tags eines Beitrags genügt es übrigens die Spalte ID statt alle Spalten (inkl. z.B. dem Inhalt des Posts) abzufragen (SensitiveTagCloud Option “Activate Performance Hacks”).
Los gehts: Um eine Liste aller Beiträge in z.B. einer bestimmten Kategorie zu bekommen, kann man einfach die WordPress-Funktion get_posts(…) verwenden. Dann müssen nur noch die Tags dieser Beiträge mit wp_get_post_tags(…) ausgelesen und gesammelt werden.

// get all posts of category 1
$posts = get_posts( 'category=1' );
// get tags of the posts
$tags = array();
foreach( $posts as $post ) {  // go through posts
  $posttags = wp_get_post_tags( $post->ID ); // get tags of the post
  // add new tag objects to the tags array (array_merge does not work for objects)
  foreach( $posttags as $posttag ) {
    if( !array_key_exists($posttag->slug,$tags) )
      $tags[ $posttag->slug ] = $posttag;
  }
}
// for example print out the tags
foreach( $tags as $tag ) { // go through tags
  echo $tag->name.'('.$tag->slug.')'.',';
}

Da alle Beiträge der Kategorie komplett ausgelesen und die Tags jeweils in einzelnen Querys abgefragt werden, ist dieser Weg nicht gerade ressourcenschonend, was bei größeren Datenmengen zu Problemen führen kann.

English Text: WordPress solution for easy modifications: The SensitiveTagCloud-Plugin works like this for each archive type (category, author, …): For listing all posts of a category, WordPress runs a query with a limit to the maximum number of posts per page. This query is repeated by the SensitiveTagCloud, but without the limit, to get all posts in the category. Than the SensitiveTagCloud simply collects all tags of the posts. Btw: To get the tags of a post, the ID of the post is enough, you don’t need the content (SensitiveTagCloud Option “Activate Performance Hacks” confines the query to the id instead of selecting *). Let’s have a look at the code above: To get all posts within a specific category the simple WordPress funktion get_posts(…) is used. Than the tags of each post can be retrieved by wp_get_post_tags(…).

Die vermutlich performanteste Lösung: Eine Datenbank-Abfrage die in nur einer einzlenen Query genau die benötigten Informationen ausliest

Hier der Code dazu für WordPress:

function get_tags_of_category( $categoryid ) {
  global $wpdb;
 
  // only integers are allowed
  $categoryid = (integer)$categoryid;
 
  // create query
  $query = 
    "SELECT DISTINCT ".
      "t.name, t.slug ".
    "FROM ".
      "$wpdb->posts as p, ".
      "$wpdb->term_relationships as trc, $wpdb->term_taxonomy as ttc, ".
      "$wpdb->term_relationships as trt, $wpdb->term_taxonomy as ttt, $wpdb->terms as t ".
    "WHERE ".
        "p.ID=trc.object_id AND trc.term_taxonomy_id=ttc.term_taxonomy_id AND ttc.taxonomy='category' AND ttc.term_id=$categoryid ".
      "AND ".
        "trt.object_id=p.ID AND trt.term_taxonomy_id=ttt.term_taxonomy_id AND ttt.taxonomy='post_tag' AND t.term_id=ttt.term_id";
 
  // run query and return result
  return $wpdb->get_results( $query );
}
 
// example usage: output tags of category 1
$tags = get_tags_of_category( 1 );
foreach( $tags as $tag ) { // go through tags
  echo $tag->name.'('.$tag->slug.')'.',';
}

Die Query wird dann je nach Tabellen-Präfix für die Kategorie mit der ID 1 zum Beispiel so aussehen:

SELECT DISTINCT 
  t.name, t.slug 
FROM 
  posts AS p, 
  term_relationships AS trc, term_taxonomy AS ttc, 
  term_relationships AS trt, term_taxonomy AS ttt, terms AS t 
WHERE 
    p.ID=trc.object_id AND trc.term_taxonomy_id=ttc.term_taxonomy_id AND ttc.taxonomy='category' AND ttc.term_id=1
  AND 
    trt.object_id=p.ID AND trt.term_taxonomy_id=ttt.term_taxonomy_id AND ttt.taxonomy='post_tag' AND t.term_id=ttt.term_id

Es werden alle Tags abgefragt die an den Beiträgen hängen, welche sich in der Kategorie 1 befinden. Die Verknüpfung zwischen Beiträgen (Tabelle “posts”) und Kategorien oder Tags in der Tabelle “term_taxonomy” wird über die Tabelle “term_relationships” hergestellt. Die Namen und Slugs der Tags (und Kategorien) befinden sich in der Tabelle “terms”.

English Text: The probably most performant way: A single database query that selects exactly the information we need. Above the WordPress code for this solution and the query that would be executed when get_tags_of_category(…) is called for the category with id 1 for example (can differ if table prefix is set).


Weiterlesen


Kategorien: WordPress


Kommentare

Die Kommentare dieser Seite können über folgendes Feed verfolgt werden: Kommentar-Feed dieser Seite