Working with 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.
Custom Post fields in the schema
Gato GraphQL makes a clear distinction of when a custom post is a "custom post", and not directly a "post".
For instance, a comment can be added to a post, but also to a page and to a CPT, hence type Comment
has field customPost: CustomPostUnion!
to retrieve the entity where the comment was added, instead of field post: Post!
.
That's also why field customPosts
receives argument customPostTypes
instead of postTypes
.
CPTs mapped to the schema
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.
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
:
CPTs not mapped to the schema
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).
In the query below, we fetch custom posts for a variety of CPTs:
Allowing access to Custom Post Types
CPTs must be explicitly allowed to be queryable, as explained in guide Allowing access to Custom Post Types.
Querying custom posts
The GraphQL types for CPTs which have been mapped to the schema (such as "post"
=> Post
and "page"
=> Page
) are incorporated directly into CustomPostUnion
.
For any CPT that has not been modeled in the schema (such as "attachment"
, "revision"
or "nav_menu_item"
, or any CPT installed by any plugin), their data will be accessed via the GenericCustomPost
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:
This query retrieves entries from multiple CPTS:
Because all Custom Posts implement interface CustomPost
, we can retrieve data from CustomPostUnion
using a fragment reference or an inline fragment:
If we know that the comment was added to a post, we can also query fields specific to the Post
:
Filtering CPTs by a custom taxonomy
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 tags
and categories
in the filter
input.
In the query below, we fetch custom posts filtering by category:
Fetching custom CPT data
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.
We can additionally create field Root.products: [Product!]
, and use it directly:
Mutating custom CPT data
Concerning CPTs which do not require any additional fields over those from the Post
type, you can use both createCustomPost
and updateCustomPost
mutations without any fear or restraint.
For instance, a MyPortfolio
CPT that uses the standard fields title
and content
, and has no extra fields, can be fully managed via these mutations.
This query creates an entry for the "my-portfolio"
CPT:
This query updates the title and content for that same CPT:
Custom post types that are provided by 3rd-party plugins may need to be created (and possibly updated too) by the corresponding plugin only.
This is because they may have their custom data (either in wp_postmeta
or in a proprietary table) that needs to be added too, and that Gato GraphQL is unaware of.
To manage these CPTs appropriately, a corresponding integration between that plugin and Gato GraphQL must be created, to provide the mapping for all the fields for the CPT.
For instance, we can use field Root.updateCustomPost
to translate and update the title and content of an WooCommerce product (i.e. from the Product CPT). However, we cannot create an WooCommerce product; for that, we must use the corresponding "WooCommerce for Gato GraphQL" extension.