Custom Posts
Nous utilisons les champs customPost et customPosts pour récupérer les données de CPT, aussi bien pour les CPTs mappés au schéma (comme Post et Page) que pour ceux qui ne le sont pas (comme un CPT d'un plugin). Comme les résultats peuvent inclure des entités de types différents, ces champs retournent le type CustomPostUnion.

Champs de Custom Post dans le schéma
Gato GraphQL fait une distinction claire entre le moment où un custom post est un « custom post » et non directement un « post ».
Par exemple, un commentaire peut être ajouté à un post, mais aussi à une page et à un CPT ; c'est pourquoi le type Comment dispose du champ customPost: CustomPostUnion! pour récupérer l'entité où le commentaire a été ajouté, plutôt que du champ post: Post!.

C'est aussi pour cette raison que le champ customPosts reçoit l'argument customPostTypes plutôt que postTypes.
CPTs mappés au schéma
Il existe des CPTs qui ont été mappés au schéma (comme Post et Page pour représenter les CPTs "post" et "page"). Dans ce cas, la requête sera résolue en utilisant le type GraphQL correspondant pour ce CPT.
Lors de la récupération de résultats depuis un type union, nous devons spécifier les champs à récupérer via des fragments. Ceux-ci peuvent être évalués sur l'interface CustomPost, qui est implémentée par tous les types de CPT, ou sur chaque type individuel, comme Post ou Page.
Dans la requête ci-dessous, nous récupérons des custom posts avec les CPTs "post" et "page". Nous affichons leurs champs via 3 fragments, qui évaluent si l'entité implémente CustomPost, ou est de type Post ou Page :
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 non mappés au schéma
Lorsqu'un CPT n'a pas encore été mappé au schéma (comme "attachment", "revision" ou "nav_menu_item", ou tout CPT installé par un plugin), nous utilisons toujours les champs customPost et customPosts, et nous devons passer le nom du CPT correspondant sous l'argument de champ filter.customPostTypes.
Comme leurs types n'existent pas dans le schéma, leurs données seront récupérées via le type GenericCustomPost, qui contient toutes les propriétés communes aux CPTs (title, content, excerpt, date, etc.).

Dans la requête ci-dessous, nous récupérons des custom posts pour une variété de CPTs :
query {
customPosts(
filter:{
customPostTypes: [
"page",
"nav_menu_item",
"wp_block",
"wp_global_styles"
]
}
) {
... on CustomPost {
id
title
customPostType
status
}
__typename
}
}Autoriser l'accès aux Custom Post Types
Les CPTs doivent être explicitement autorisés à être interrogeables, comme expliqué dans le guide Autoriser l'accès aux Custom Post Types.
Interroger des custom posts
Les types GraphQL pour les CPTs qui ont été mappés au schéma (comme "post" => Post et "page" => Page) sont intégrés directement dans CustomPostUnion.
Pour tout CPT qui n'a pas été modélisé dans le schéma (comme "attachment", "revision" ou "nav_menu_item", ou tout CPT installé par un plugin), ses données seront accessibles via le type GenericCustomPost.
Nous indiquons les CPTs à récupérer via l'argument de champ filter.customPostTypes, qui reçoit une liste de chaînes, avec les noms de CPT tels qu'ils sont définis dans WordPress (comme "post", "page", etc.). Par exemple :
query {
customPosts(
filter: { customPostTypes: ["some-custom-cpt"] }
) {
... on CustomPost {
id
title
}
}
}Cette requête récupère des entrées de plusieurs CPTs :
query {
customPosts(
filter: {
customPostTypes: [
"post",
"page",
"attachment",
"nav_menu_item",
"custom_css",
"revision"
],
status: [
publish,
inherit,
auto_draft
]
}
) {
id
title
content
status
customPostType
__typename
}
}Comme tous les Custom Posts implémentent l'interface CustomPost, nous pouvons récupérer des données de CustomPostUnion en utilisant une référence à un fragment ou un fragment inline :
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
}
}
}Si nous savons que le commentaire a été ajouté à un post, nous pouvons également interroger les champs spécifiques au Post :
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
...on Post {
categoryNames
}
}
}
}Filtrer les CPTs par une taxonomie personnalisée
Un custom post type peut avoir des taxonomies personnalisées (étiquettes et catégories) qui lui sont associées. Par exemple, un CPT "product" peut avoir associée la taxonomie de catégorie "product-cat" et la taxonomie d'étiquette "product-tag".
Nous pouvons filtrer les résultats par ces taxonomies associées, via les entrées tags et categories dans l'entrée filter.
Dans la requête ci-dessous, nous récupérons des custom posts en filtrant par catégorie :
query {
customPosts(
filter: {
categories: {
includeBy: {
ids: [26, 28]
}
taxonomy: "product-cat"
}
}
) {
... on CustomPost {
id
title
}
... on GenericCustomPost {
categories(taxonomy: "product-cat") {
id
}
}
}
}Récupérer des données personnalisées de CPT
En utilisant GenericCustomPost, nous ne pouvons demander que les champs communs à tous les CPTs ; la récupération de données personnalisées d'un CPT n'est pas prise en charge (comme la récupération des données de prix pour un CPT personnalisé "product").
Pour récupérer des données personnalisées de CPT, nous devons à la place créer les resolvers correspondants, en code PHP, pour mapper le CPT au schéma :
- Créer un type
Product - Lui attacher un champ
price
Désormais, le type CustomPostUnion (retourné par Root.customPosts) résoudra toutes les entrées de ce CPT vers un type Product.
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
}
}
}Nous pouvons également créer le champ Root.products: [Product!], et l'utiliser directement :
query {
products {
__typename # Product
id
title
status
price # custom field
}
}Muter des données personnalisées de CPT
Concernant les CPTs qui ne nécessitent pas de champs supplémentaires par rapport à ceux du type Post, vous pouvez utiliser aussi bien les mutations createCustomPost que updateCustomPost sans crainte ni restriction.
Par exemple, un CPT MyPortfolio qui utilise les champs standard title et content, et n'a pas de champs supplémentaires, peut être entièrement géré via ces mutations.
Cette requête crée une entrée pour le 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
}
}
}
}Cette requête met à jour le titre et le contenu pour ce même 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
}
}
}
}Les custom post types fournis par des plugins tiers peuvent avoir besoin d'être créés (et éventuellement mis à jour aussi) uniquement par le plugin correspondant.
Cela est dû au fait qu'ils peuvent avoir leurs données personnalisées (soit dans wp_postmeta soit dans une table propriétaire) qui doivent également être ajoutées, et dont Gato GraphQL n'a pas connaissance.
Pour gérer ces CPTs de manière appropriée, une intégration correspondante entre ce plugin et Gato GraphQL doit être créée, afin de fournir le mapping de tous les champs du CPT.
Par exemple, nous pouvons utiliser le champ Root.updateCustomPost pour traduire et mettre à jour le titre et le contenu d'un produit WooCommerce (c'est-à-dire du CPT Product). En revanche, nous ne pouvons pas créer un produit WooCommerce ; pour cela, nous devons utiliser l'extension « WooCommerce for Gato GraphQL » correspondante.