WordPress-Termergebnisse abrufen, die sich auf eine andere Taxonomie beziehen

Avatar of Christian Nolen
Christian Nolen am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Der folgende Beitrag ist ein Gastbeitrag von Christian Nolen. Christian beschreibt eine Situation, in der Daten intelligent und vernünftig organisiert werden, aber dennoch etwas knifflig abzufragen sind. Er beschreibt eine Lösung, die nicht zu sehr ins Detail geht, um sie richtig zu machen.

Wenn Sie jemals WordPress-Entwicklung betrieben haben, mussten Sie wahrscheinlich bereits benutzerdefinierte Beitragstypen erstellen und Taxonomien registrieren. Die Arbeit mit Taxonomien ist unkompliziert, wenn die Beziehung eins-zu-eins ist, d. h. "Gib mir alle Taxonomie-Terme, benutze get_terms(), oder gib mir alle mit dem aktuellen Beitrag verknüpften Terme, benutze get_the_terms()."

Aber was tun Sie, wenn die zurückgegebenen Ergebnisse sich auf eine andere Taxonomie beziehen sollen? Keine der üblichen Funktionen hilft. Bevor ich auf die Lösung eingehe, werfen wir einen genaueren Blick auf das Problem. Der Anwendungsfall ist eine **Portfolio-Website**, die eine Vielzahl von Dienstleistungen in mehreren Märkten anbietet. Unsere Einrichtung ist wie folgt:

  • Benutzerdefinierter Beitragstyp: Portfolio
  • Taxonomie: Dienstleistungen
  • Terme: Entwicklung, Illustration, Fotografie, Printdesign, Webdesign
  • Taxonomie: Märkte
  • Terme: Bürgerlich, Unternehmen, Bildung, Gesundheit, gemeinnützig

Diese Website erfordert die Verwendung einer Taxonomie-Vorlage für **Dienstleistungen** und **Märkte**. Wenn ein Besucher auf einer dieser Taxonomie-Seiten landet, wird ein Tabellenlayout angezeigt, das Portfolio-Elemente für zugehörige Märkte (bei Ansicht einer Dienstleistung) oder zugehörige Dienstleistungen (bei Ansicht eines Marktes) zeigt.

Screenshot of tab layout with the first tab empty

Auf dem obigen Screenshot zeige ich eine Fotografie-Dienstleistungsseite. Ich habe get_terms('market') verwendet, um die gültigen Märkte abzurufen (zu einer $markets Variable zugewiesen). Ich iteriere durch jeden Markt, um meinen Tab zu erstellen, und verwende dann WP_Query, um alle entsprechenden Portfolio-Elemente abzurufen. Der Parameter tax_query wird verwendet, um die Ergebnisse auf den aktuellen Markt und die aktuelle Dienstleistung einzugrenzen (in diesem Fall definiert durch get_query_var('term')).

Das erste, was uns auffällt, ist ein peinlich leerer "Bürgerlich"-Tab, der die Tatsache hervorhebt, dass in diesem Markt keine Dienstleistungen erbracht wurden. Außerdem ist es der erste Tab, den ein Besucher beim Aufrufen dieser Seite sieht.

Die Lösung

Ich habe erhebliche Zeit mit der Recherche einer Lösung verbracht. Die einzige Lösung, die ich fand, beinhaltete das Abfragen der Datenbank mit wpdb. Ja, das war eine Lösung, aber sie fühlte sich nicht richtig an. Ich wusste, dass es einen eingebauten Weg geben musste, diesen Anwendungsfall zu behandeln.

Nachdem ich tiefer in das WordPress Codex eingetaucht war, entdeckte ich wp_get_object_terms(). Die Beschreibung der Funktion lautet wie folgt:

Ruft die mit den gegebenen Objekten in den bereitgestellten Taxonomien verknüpften Terme ab.

Das bereitgestellte Beispiel ähnelt stark einem, das Sie für get_the_terms() finden würden. Der Schlüssel ist, dass der Objektparameter ein Array sein kann.

Das Objekt, das wir an wp_get_object_terms() übergeben möchten, ist ein Array von Beitrags-IDs. Der effizienteste Weg, den ich mir vorstellen konnte, dieses Array zu erstellen, war die Verwendung von get_posts() mit dem Parameter fields auf "ids" gesetzt. Sie könnten WP_Query verwenden, aber ich habe mich für get_posts() entschieden, weil

  1. get_posts() gibt ein Array anstelle eines Objekts zurück
  2. Ich werde meinen anfänglichen get_posts()-Aufruf niemals mit WP_Query verwechseln, der innerhalb des tabellarischen Inhalts verwendet wird.
$service_slug = get_query_var('term');	
$service_post_IDs = get_posts(array(
  'post_type' => 'portfolio',
  'posts_per_page' => -1,
  'tax_query' => array(
    array(
      'taxonomy' => 'service',
      'field' => 'slug',
      'terms' => $service_slug
    )
  ),
  'fields' => 'ids'
));

Das obige ist, wie wir die richtige Teilmenge von Beitrags-IDs erhalten. Wie bereits erwähnt, rufe ich den aktuellen Dienstleistungs-Slug ab, indem ich get_query_var('term') verwende und ihn der Variablen $service_slug zuweise. Dies wird in tax_query verwendet, um sicherzustellen, dass wir nur Beitrags-IDs erhalten, die dem aktuellen Taxonomie-Term zugewiesen sind. Durch Setzen des Parameters fields auf ids ist das Ergebnis ein indizierter Array von Beitrags-IDs.

Jetzt, da ich das Array von Beitrags-IDs habe, kann ich get_terms() durch Folgendes ersetzen:

$markets = wp_get_object_terms($service_post_IDs, 'market');

Wenn ich die Seite aktualisiere, ist der "Bürgerlich"-Tab verschwunden und wir haben einen Tab mit den richtigen Inhalten.

Screenshot of how the corrected tab layout - without empty tab Civic

Ich könnte hier aufhören. Aber jetzt stören mich die Argumente, die innerhalb von WP_Query verwendet werden.

$args = array(
  'post_type' => 'portfolio',
  'posts_per_page' => -1,
  'tax_query' => array(
    'relation' => 'AND',
    array(
      'taxonomy' => 'market',
      'field'    => 'slug',
      'terms'    => $m->slug,
    ),
    array(
      'taxonomy' => 'service',
      'field'    => 'slug',
      'terms'    => $service_slug,
    ),
  )
);

Ja, das obige funktioniert einwandfrei. Aber ich habe das Gefühl, dass ich meine Bemühungen in Bezug auf meine tax_query dupliziere. Was wir tun können, ist, die tax_query umzugestalten, um nur den aktuellen Markt einzuschließen und den Parameter post__in mit dem Array der Dienstleistungs-Beitrags-IDs zu nutzen.

$args = array(
  'post_type' => 'portfolio',
  'posts_per_page' => -1,
  'tax_query' => array(
    array(
      'taxonomy' => 'market',
      'field'    => 'slug',
      'terms'    => $m->slug,
    )
  ),
  'post__in' => $service_post_IDs
);

Das Ergebnis im Frontend ist dasselbe, aber jetzt sind die Abfrageargumente schlanker und leichter zu lesen. Am wichtigsten ist, dass Sie jetzt eine Vorlage haben, die Ihren Besuchern gültige Informationen anzeigt.