Custom Posts
Wir verwenden die Felder customPost und customPosts, um CPT-Daten abzurufen – sowohl für CPTs, die dem Schema zugeordnet sind (wie Post und Page), als auch für solche, die es nicht sind (wie ein CPT eines Plugins). Da die Ergebnisse Entitäten verschiedener Typen enthalten können, geben diese Felder den Typ CustomPostUnion zurück.

Custom-Post-Felder im Schema
Gato GraphQL unterscheidet klar, wann ein Custom Post ein „Custom Post" ist und kein direkter „Post".
Ein Kommentar kann beispielsweise zu einem Post hinzugefügt werden, aber auch zu einer Seite oder einem CPT. Deshalb hat der Typ Comment das Feld customPost: CustomPostUnion!, um die Entität abzurufen, zu der der Kommentar hinzugefügt wurde – anstelle des Feldes post: Post!.

Aus demselben Grund erhält das Feld customPosts das Argument customPostTypes statt postTypes.
CPTs, die dem Schema zugeordnet sind
Es gibt CPTs, die dem Schema zugeordnet wurden (wie Post und Page für die CPTs "post" und "page"). In diesem Fall wird die Query mit dem entsprechenden GraphQL-Typ für diesen CPT aufgelöst.
Beim Abrufen von Ergebnissen aus einem Union-Typ müssen wir die abzurufenden Felder über Fragments angeben. Diese können auf der Schnittstelle CustomPost, die von allen CPT-Typen implementiert wird, oder auf jedem einzelnen Typ wie Post oder Page ausgewertet werden.
In der folgenden Query rufen wir Custom Posts mit den CPTs "post" und "page" ab. Wir zeigen ihre Felder über 3 Fragments an, die prüfen, ob die Entität CustomPost implementiert oder vom Typ Post oder Page ist:
query {
customPosts(filter: { customPostTypes: ["post", "page"] }) {
...CustomPostProps
...PostProps
...PageProps
}
}
fragment CustomPostProps on CustomPost {
__typename
title
excerpt
url
dateStr(format: "d/m/Y")
}
fragment PostProps on Post {
tags {
id
name
}
}
fragment PageProps on Page {
author {
id
name
}
}CPTs, die nicht dem Schema zugeordnet sind
Wenn ein CPT noch nicht dem Schema zugeordnet wurde (wie "attachment", "revision" oder "nav_menu_item", oder ein CPT, der von einem Plugin installiert wurde), verwenden wir weiterhin die Felder customPost und customPosts und müssen den entsprechenden CPT-Namen im Feldargument filter.customPostTypes übergeben.
Da ihre Typen nicht im Schema existieren, werden ihre Daten über den Typ GenericCustomPost abgerufen, der alle gemeinsamen Eigenschaften von CPTs enthält (title, content, excerpt, date usw.).

In der folgenden Query rufen wir Custom Posts für eine Vielzahl von CPTs ab:
query {
customPosts(
filter:{
customPostTypes: [
"page",
"nav_menu_item",
"wp_block",
"wp_global_styles"
]
}
) {
... on CustomPost {
id
title
customPostType
status
}
__typename
}
}Zugriff auf Custom Post Types erlauben
CPTs müssen explizit als abfragbar freigegeben werden, wie in der Anleitung Zugriff auf Custom Post Types erlauben erklärt.
Custom Posts abfragen
Die GraphQL-Typen für CPTs, die dem Schema zugeordnet wurden (wie "post" => Post und "page" => Page), werden direkt in CustomPostUnion eingebunden.
Für jeden CPT, der nicht im Schema modelliert wurde (wie "attachment", "revision" oder "nav_menu_item", oder ein CPT, der von einem Plugin installiert wurde), wird auf seine Daten über den Typ GenericCustomPost zugegriffen.
Wir geben die abzurufenden CPTs über das Feldargument filter.customPostTypes an, das eine Liste von Strings mit den CPT-Namen wie in WordPress definiert (wie "post", "page" usw.) entgegennimmt. Zum Beispiel:
query {
customPosts(
filter: { customPostTypes: ["some-custom-cpt"] }
) {
... on CustomPost {
id
title
}
}
}Diese Query ruft Einträge aus mehreren CPTs ab:
query {
customPosts(
filter: {
customPostTypes: [
"post",
"page",
"attachment",
"nav_menu_item",
"custom_css",
"revision"
],
status: [
publish,
inherit,
auto_draft
]
}
) {
id
title
content
status
customPostType
__typename
}
}Da alle Custom Posts die Schnittstelle CustomPost implementieren, können wir Daten aus CustomPostUnion über eine Fragment-Referenz oder ein Inline-Fragment abrufen:
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
}
}
}Wenn wir wissen, dass der Kommentar zu einem Post hinzugefügt wurde, können wir auch Felder abfragen, die spezifisch für den Post sind:
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
...on Post {
categoryNames
}
}
}
}CPTs nach einer benutzerdefinierten Taxonomie filtern
Ein Custom Post Type kann benutzerdefinierte Taxonomien (Tags und Kategorien) haben, die ihm zugeordnet sind. Zum Beispiel kann ein CPT "product" die Kategorie-Taxonomie "product-cat" und die Tag-Taxonomie "product-tag" zugeordnet haben.
Wir können Ergebnisse nach diesen zugeordneten Taxonomien filtern, über die Eingaben tags und categories im filter-Input.
In der folgenden Query rufen wir Custom Posts mit einem Kategorie-Filter ab:
query {
customPosts(
filter: {
categories: {
includeBy: {
ids: [26, 28]
}
taxonomy: "product-cat"
}
}
) {
... on CustomPost {
id
title
}
... on GenericCustomPost {
categories(taxonomy: "product-cat") {
id
}
}
}
}Benutzerdefinierte CPT-Daten abrufen
Mit GenericCustomPost können wir nur die Felder anfordern, die allen CPTs gemeinsam sind; das Abrufen benutzerdefinierter Daten aus einem CPT wird nicht unterstützt (wie das Abrufen der Preisdaten für einen benutzerdefinierten CPT "product").
Um benutzerdefinierte CPT-Daten abzurufen, müssen wir stattdessen die entsprechenden Resolver in PHP-Code erstellen, um den CPT dem Schema zuzuordnen:
- Einen Typ
Producterstellen - Ein Feld
pricedaran anhängen
Nun wird der Typ CustomPostUnion (zurückgegeben von Root.customPosts) alle Einträge dieses CPTs zu einem Product-Typ auflösen.
query {
customPosts(
filter: {
customPostTypes: "product"
}
) {
__typename
...on CustomPost { # interface implemented by all CPT types
id
title
customPostType
status
}
...on Product { # custom CPT type
price # custom field
}
}
}Wir können zusätzlich das Feld Root.products: [Product!] erstellen und es direkt verwenden:
query {
products {
__typename # Product
id
title
status
price # custom field
}
}Benutzerdefinierte CPT-Daten mutieren
Bei CPTs, die keine zusätzlichen Felder über die des Typs Post hinaus benötigen, kannst du sowohl die Mutations createCustomPost als auch updateCustomPost ohne Bedenken oder Einschränkungen verwenden.
Ein MyPortfolio-CPT, der die Standardfelder title und content verwendet und keine zusätzlichen Felder hat, kann beispielsweise vollständig über diese Mutations verwaltet werden.
Diese Query erstellt einen Eintrag für den CPT "my-portfolio":
mutation {
createCustomPost(
input: {
customPostType: "my-portfolio"
title: "My photograph"
contentAs: { html: "This is my photo, check it out." }
}
) {
status
errors {
__typename
...on ErrorPayload {
message
}
...on GenericErrorPayload {
code
}
}
customPost {
__typename
...on CustomPost {
id
title
content
}
}
}
}Diese Query aktualisiert den Titel und den Inhalt für denselben CPT:
mutation {
updateCustomPost(input: {
id: 1
customPostType: "my-portfolio"
title: "Updated title"
contentAs: { html: "Updated content" }
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
customPost {
__typename
...on CustomPost {
id
title
content
}
}
}
}Custom Post Types, die von Drittanbieter-Plugins bereitgestellt werden, müssen möglicherweise nur vom entsprechenden Plugin erstellt (und möglicherweise auch aktualisiert) werden.
Das liegt daran, dass sie möglicherweise eigene benutzerdefinierte Daten haben (entweder in wp_postmeta oder in einer proprietären Tabelle), die ebenfalls hinzugefügt werden müssen und von denen Gato GraphQL keine Kenntnis hat.
Um diese CPTs ordnungsgemäß zu verwalten, muss eine entsprechende Integration zwischen diesem Plugin und Gato GraphQL erstellt werden, die das Mapping aller Felder des CPTs bereitstellt.
Wir können beispielsweise das Feld Root.updateCustomPost verwenden, um den Titel und den Inhalt eines WooCommerce-Produkts (d. h. des Product-CPTs) zu übersetzen und zu aktualisieren. Wir können jedoch kein WooCommerce-Produkt erstellen; dafür müssen wir die entsprechende Erweiterung „WooCommerce for Gato GraphQL" verwenden.