Bekerja dengan
Bekerja denganCustom Posts

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.

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!.

Tipe Comment

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).

Generic Custom Post

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 price padanya

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.