Custom Posts

We use fields customPost and customPosts to fetch CPT data, both for CPTs that are mapped to the schema (such as Post and Page) or not (such as a CPT from some plugin). Because the results can include entities from different types, these fields return the CustomPostUnion type.

We indicate the CPTs to retrieve via field argument filter.customPostTypes, which receives a list of strings, with the CPT names as defined in WordPress (such as "post", "page", etc). For instance:

{
customPosts(
filter: { customPostTypes: ["some-custom-cpt"] }
) {
... on CustomPost {
id
title
}
}
}

Querying CPTs mapped to the schema permalink

There are CPTs which have been mapped to the schema (such as Post and Page to represent CPTs "post" and "page"). In this case, the query will be resolved using the corresponding GraphQL type for that CPT.

Custom Post Union
Custom Post Union

When fetching results from a union type, we need to specify the fields to retrieve through fragments. These can be evaluated on interface CustomPost, which is implemented by all CPT types, or on each individual type, such as Post or Page.

In the query below, we fetch custom posts with CPTs "post" and "page". We display their fields through 3 fragments, which evaluate if the entity implements CustomPost, or is of type Post or Page:

Querying CPTs not mapped to the schema permalink

When a CPT has not been mapped to the schema yet (such as "attachment", "revision" or "nav_menu_item", or any CPT installed by any plugin), we still use fields customPost and customPosts, and we must pass the corresponding CPT name under the filter.customPostTypes field arg.

Because their types do not exist in the schema, their data will be retrieved via type GenericCustomPost, which contains all the common properties to CPTs (title, content, excerpt, date, etc).

Generic Custom Post
Generic Custom Post

In the query below, we fetch custom posts for a variety of CPTs:

Allowing access to unmapped CPT types permalink

The CPTs accessible via the GenericCustomPost type must be explicitly configured in the plugin Settings page, as explained in guide Adding a custom post type to the schema.

Filtering CPTs by a custom taxonomy permalink

A custom post type can have custom taxonomies (tags and categories) associated to them. For instance, a CPT "product" may have associated the category taxonomy "product-cat" and the tag taxonomy "product-tag".

We can filter results by these associated taxonomies, via inputs tagTaxonomy and categoryTaxonomy in the filter input.

In the query below, we fetch custom posts filtering by category:

{
customPosts(
filter: {
categoryIDs: [26, 28],
categoryTaxonomy: "product-cat"
}
) {
... on CustomPost {
id
title
}
... on GenericCustomPost {
categories(taxonomy: "product-cat") {
id
}
}
}
}

Fetching custom CPT data permalink

Using GenericCustomPost, we can only request those fields which are common to all CPTs; fetching custom data from some CPT is not supported (such as fetching the price data for a custom CPT "product").

To fetch custom CPT data, instead, we need to create the corresponding resolvers, in PHP code, to map the CPT to the schema:

  • Create a type Product
  • Attach a price field to it

Now, the CustomPostUnion type (returned by Root.customPosts) will resolve all entries from this CPT to a Product type.

{
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 can additionally create field Root.products: [Product!], and use it directly:

{
products {
__typename # Product
id
title
status
price # custom field
}
}