Custom Posts
We gebruiken de velden customPost en customPosts om CPT-data op te halen, zowel voor CPT's die gekoppeld zijn aan het schema (zoals Post en Page) als voor die dat niet zijn (zoals een CPT van een plugin). Omdat de resultaten entiteiten van verschillende types kunnen bevatten, retourneren deze velden het type CustomPostUnion.

Custom Post-velden in het schema
Gato GraphQL maakt een duidelijk onderscheid tussen wanneer een custom post een "custom post" is, en niet direct een "post".
Een reactie kan bijvoorbeeld worden toegevoegd aan een post, maar ook aan een pagina en aan een CPT; daarom heeft type Comment het veld customPost: CustomPostUnion! om de entiteit op te halen waaraan de reactie is toegevoegd, in plaats van het veld post: Post!.

Dat is ook de reden waarom het veld customPosts het argument customPostTypes accepteert in plaats van postTypes.
CPT's gekoppeld aan het schema
Er zijn CPT's die aan het schema zijn gekoppeld (zoals Post en Page voor de CPT's "post" en "page"). In dit geval wordt de query opgelost met het bijbehorende GraphQL-type voor die CPT.
Wanneer je resultaten ophaalt uit een union-type, moet je de op te halen velden opgeven via fragmenten. Deze kunnen worden geëvalueerd op interface CustomPost, die door alle CPT-types wordt geïmplementeerd, of op elk afzonderlijk type, zoals Post of Page.
In de onderstaande query halen we custom posts op met CPT's "post" en "page". We geven hun velden weer via 3 fragmenten, die controleren of de entiteit CustomPost implementeert, of van type Post of Page is:
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
}
}CPT's niet gekoppeld aan het schema
Wanneer een CPT nog niet aan het schema is gekoppeld (zoals "attachment", "revision" of "nav_menu_item", of een CPT die door een plugin is geĆÆnstalleerd), gebruiken we nog steeds de velden customPost en customPosts, en moeten we de bijbehorende CPT-naam opgeven via het veldargument filter.customPostTypes.
Omdat hun types niet in het schema bestaan, worden hun gegevens opgehaald via type GenericCustomPost, dat alle gemeenschappelijke eigenschappen van CPT's bevat (title, content, excerpt, date, enz.).

In de onderstaande query halen we custom posts op voor een verscheidenheid aan CPT's:
query {
customPosts(
filter:{
customPostTypes: [
"page",
"nav_menu_item",
"wp_block",
"wp_global_styles"
]
}
) {
... on CustomPost {
id
title
customPostType
status
}
__typename
}
}Toegang verlenen tot Custom Post Types
CPT's moeten expliciet worden toegestaan om opvraagbaar te zijn, zoals uitgelegd in de gids Toegang verlenen tot Custom Post Types.
Custom posts opvragen
De GraphQL-types voor CPT's die aan het schema zijn gekoppeld (zoals "post" => Post en "page" => Page) worden direct opgenomen in CustomPostUnion.
Voor elke CPT die niet in het schema is gemodelleerd (zoals "attachment", "revision" of "nav_menu_item", of een CPT geĆÆnstalleerd door een plugin), worden de gegevens benaderd via het type GenericCustomPost.
We geven de op te halen CPT's aan via het veldargument filter.customPostTypes, dat een lijst van strings accepteert met de CPT-namen zoals gedefinieerd in WordPress (zoals "post", "page", enz.). Bijvoorbeeld:
query {
customPosts(
filter: { customPostTypes: ["some-custom-cpt"] }
) {
... on CustomPost {
id
title
}
}
}Deze query haalt gegevens op uit meerdere CPT's:
query {
customPosts(
filter: {
customPostTypes: [
"post",
"page",
"attachment",
"nav_menu_item",
"custom_css",
"revision"
],
status: [
publish,
inherit,
auto_draft
]
}
) {
id
title
content
status
customPostType
__typename
}
}Omdat alle Custom Posts de interface CustomPost implementeren, kunnen we gegevens ophalen uit CustomPostUnion via een fragmentverwijzing of een inline fragment:
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
}
}
}Als we weten dat de reactie aan een post is toegevoegd, kunnen we ook velden opvragen die specifiek zijn voor Post:
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
...on Post {
categoryNames
}
}
}
}CPT's filteren op een aangepaste taxonomie
Een custom post type kan aangepaste taxonomieƫn (tags en categorieƫn) aan zich gekoppeld hebben. Een CPT "product" kan bijvoorbeeld de categorietaxonomie "product-cat" en de tagtaxonomie "product-tag" hebben.
We kunnen resultaten filteren op deze gekoppelde taxonomieƫn via de inputs tags en categories in de filter-input.
In de onderstaande query halen we custom posts op gefilterd op categorie:
query {
customPosts(
filter: {
categories: {
includeBy: {
ids: [26, 28]
}
taxonomy: "product-cat"
}
}
) {
... on CustomPost {
id
title
}
... on GenericCustomPost {
categories(taxonomy: "product-cat") {
id
}
}
}
}Aangepaste CPT-data ophalen
Met GenericCustomPost kunnen we alleen die velden opvragen die gemeenschappelijk zijn voor alle CPT's; het ophalen van aangepaste data uit een CPT wordt niet ondersteund (zoals het ophalen van prijsdata van een aangepaste CPT "product").
Om aangepaste CPT-data op te halen, moeten we in plaats daarvan de bijbehorende resolvers in PHP-code aanmaken om de CPT aan het schema te koppelen:
- Maak een type
Productaan - Voeg er een veld
priceaan toe
Nu zal het type CustomPostUnion (geretourneerd door Root.customPosts) alle items van deze CPT omzetten naar een 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
}
}
}We kunnen bovendien het veld Root.products: [Product!] aanmaken en dit direct gebruiken:
query {
products {
__typename # Product
id
title
status
price # custom field
}
}Aangepaste CPT-data muteren
Voor CPT's die geen extra velden nodig hebben bovenop die van het type Post, kun je zowel de mutaties createCustomPost als updateCustomPost zonder enige zorg of beperking gebruiken.
Een CPT MyPortfolio die de standaardvelden title en content gebruikt en geen extra velden heeft, kan bijvoorbeeld volledig worden beheerd via deze mutaties.
Deze query maakt een item aan voor de 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
}
}
}
}Deze query werkt de titel en inhoud van diezelfde CPT bij:
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 worden geleverd door externe plugins moeten mogelijk worden aangemaakt (en eventueel ook bijgewerkt) door alleen de bijbehorende plugin.
Dit komt omdat ze mogelijk eigen data hebben (in wp_postmeta of in een eigen tabel) die ook moet worden toegevoegd, en waarvan Gato GraphQL niet op de hoogte is.
Om deze CPT's goed te beheren, moet een bijbehorende integratie tussen die plugin en Gato GraphQL worden aangemaakt, die de koppeling voor alle velden van de CPT biedt.
We kunnen bijvoorbeeld het veld Root.updateCustomPost gebruiken om de titel en inhoud van een WooCommerce-product te vertalen en bij te werken (d.w.z. van de Product CPT). We kunnen echter geen WooCommerce-product aanmaken; daarvoor moeten we de bijbehorende extensie "WooCommerce for Gato GraphQL" gebruiken.