Custom Posts
Kita menggunakan field customPost dan customPosts untuk mengambil data CPT, baik untuk CPT yang telah dipetakan ke skema (seperti Post dan Page) maupun yang belum (seperti CPT dari suatu plugin). Karena hasilnya dapat mencakup entitas dari berbagai tipe, field-field ini mengembalikan tipe CustomPostUnion.

Field Custom Post dalam skema
Gato GraphQL membuat perbedaan yang jelas antara kapan suatu custom post adalah "custom post", dan bukan langsung sebuah "post".
Misalnya, komentar dapat ditambahkan ke sebuah post, tetapi juga ke halaman dan ke CPT, sehingga tipe Comment memiliki field customPost: CustomPostUnion! untuk mengambil entitas tempat komentar ditambahkan, alih-alih field post: Post!.

Itulah juga mengapa field customPosts menerima argumen customPostTypes alih-alih postTypes.
CPT yang dipetakan ke skema
Ada CPT yang telah dipetakan ke skema (seperti Post dan Page untuk merepresentasikan CPT "post" dan "page"). Dalam kasus ini, query akan diselesaikan menggunakan tipe GraphQL yang sesuai untuk CPT tersebut.
Saat mengambil hasil dari union type, kita perlu menentukan field yang akan diambil melalui fragment. Fragment-fragment ini dapat dievaluasi pada interface CustomPost, yang diimplementasikan oleh semua tipe CPT, atau pada setiap tipe individual, seperti Post atau Page.
Dalam query di bawah ini, kita mengambil custom posts dengan CPT "post" dan "page". Kita menampilkan field-field mereka melalui 3 fragment, yang mengevaluasi apakah entitas mengimplementasikan CustomPost, atau bertipe Post atau 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
}
}CPT yang tidak dipetakan ke skema
Ketika sebuah CPT belum dipetakan ke skema (seperti "attachment", "revision" atau "nav_menu_item", atau CPT apa pun yang diinstal oleh suatu plugin), kita tetap menggunakan field customPost dan customPosts, dan kita harus meneruskan nama CPT yang sesuai di bawah argumen field filter.customPostTypes.
Karena tipe-tipenya tidak ada dalam skema, datanya akan diambil melalui tipe GenericCustomPost, yang berisi semua properti umum untuk CPT (title, content, excerpt, date, dll).

Dalam query di bawah ini, kita mengambil custom posts untuk berbagai CPT:
query {
customPosts(
filter:{
customPostTypes: [
"page",
"nav_menu_item",
"wp_block",
"wp_global_styles"
]
}
) {
... on CustomPost {
id
title
customPostType
status
}
__typename
}
}Mengizinkan akses ke Custom Post Types
CPT harus secara eksplisit diizinkan agar dapat di-query, sebagaimana dijelaskan dalam panduan Allowing access to Custom Post Types.
Melakukan query custom posts
Tipe GraphQL untuk CPT yang telah dipetakan ke skema (seperti "post" => Post dan "page" => Page) dimasukkan langsung ke dalam CustomPostUnion.
Untuk CPT apa pun yang belum dimodelkan dalam skema (seperti "attachment", "revision" atau "nav_menu_item", atau CPT apa pun yang diinstal oleh suatu plugin), datanya akan diakses melalui tipe GenericCustomPost.
Kita menentukan CPT yang akan diambil melalui argumen field filter.customPostTypes, yang menerima daftar string, dengan nama CPT sebagaimana didefinisikan di WordPress (seperti "post", "page", dll). Contohnya:
query {
customPosts(
filter: { customPostTypes: ["some-custom-cpt"] }
) {
... on CustomPost {
id
title
}
}
}Query ini mengambil entri dari beberapa CPT:
query {
customPosts(
filter: {
customPostTypes: [
"post",
"page",
"attachment",
"nav_menu_item",
"custom_css",
"revision"
],
status: [
publish,
inherit,
auto_draft
]
}
) {
id
title
content
status
customPostType
__typename
}
}Karena semua Custom Post mengimplementasikan interface CustomPost, kita dapat mengambil data dari CustomPostUnion menggunakan referensi fragment atau inline fragment:
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
}
}
}Jika kita mengetahui bahwa komentar ditambahkan ke sebuah post, kita juga dapat melakukan query field yang spesifik untuk Post:
query {
comments {
id
date
content
customPost {
__typename
...on CustomPost {
id
title
url
}
...on Post {
categoryNames
}
}
}
}Memfilter CPT berdasarkan taksonomi kustom
Sebuah custom post type dapat memiliki taksonomi kustom (tag dan kategori) yang terkait dengannya. Misalnya, CPT "product" mungkin memiliki taksonomi kategori "product-cat" dan taksonomi tag "product-tag" yang terkait.
Kita dapat memfilter hasil berdasarkan taksonomi yang terkait ini, melalui input tags dan categories dalam input filter.
Dalam query di bawah ini, kita mengambil custom posts dengan memfilter berdasarkan kategori:
query {
customPosts(
filter: {
categories: {
includeBy: {
ids: [26, 28]
}
taxonomy: "product-cat"
}
}
) {
... on CustomPost {
id
title
}
... on GenericCustomPost {
categories(taxonomy: "product-cat") {
id
}
}
}
}Mengambil data CPT kustom
Menggunakan GenericCustomPost, kita hanya dapat meminta field-field yang umum untuk semua CPT; mengambil data kustom dari suatu CPT tidak didukung (seperti mengambil data harga untuk CPT kustom "product").
Untuk mengambil data CPT kustom, kita perlu membuat resolver yang sesuai, dalam kode PHP, untuk memetakan CPT ke skema:
- Membuat tipe
Product - Melampirkan field
pricepadanya
Sekarang, tipe CustomPostUnion (dikembalikan oleh Root.customPosts) akan me-resolve semua entri dari CPT ini ke tipe 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
}
}
}Kita juga dapat membuat field Root.products: [Product!], dan menggunakannya secara langsung:
query {
products {
__typename # Product
id
title
status
price # custom field
}
}Melakukan mutasi data CPT kustom
Mengenai CPT yang tidak memerlukan field tambahan selain yang ada pada tipe Post, kamu dapat menggunakan mutasi createCustomPost dan updateCustomPost tanpa rasa takut atau kekhawatiran.
Misalnya, CPT MyPortfolio yang menggunakan field standar title dan content, dan tidak memiliki field tambahan, dapat dikelola sepenuhnya melalui mutasi-mutasi ini.
Query ini membuat entri untuk 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
}
}
}
}Query ini memperbarui judul dan konten untuk CPT yang sama:
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 type yang disediakan oleh plugin pihak ketiga mungkin perlu dibuat (dan kemungkinan juga diperbarui) hanya oleh plugin yang bersangkutan.
Ini karena mereka mungkin memiliki data kustom mereka sendiri (baik di wp_postmeta maupun di tabel proprietary) yang perlu ditambahkan juga, dan yang tidak diketahui oleh Gato GraphQL.
Untuk mengelola CPT ini dengan tepat, integrasi yang sesuai antara plugin tersebut dan Gato GraphQL harus dibuat, untuk menyediakan pemetaan bagi semua field CPT.
Misalnya, kita dapat menggunakan field Root.updateCustomPost untuk menerjemahkan dan memperbarui judul serta konten produk WooCommerce (yaitu dari CPT Product). Namun, kita tidak dapat membuat produk WooCommerce; untuk itu, kita harus menggunakan ekstensi "WooCommerce for Gato GraphQL" yang sesuai.