Lavorare con
Lavorare conCustom Posts

Custom Posts

Utilizziamo i campi customPost e customPosts per recuperare i dati dei CPT, sia per i CPT mappati allo schema (come Post e Page) che per quelli che non lo sono (come un CPT di qualche plugin). Poiché i risultati possono includere entità di tipi diversi, questi campi restituiscono il tipo CustomPostUnion.

Tipo CustomPostUnion

Campi Custom Post nello schema

Gato GraphQL fa una chiara distinzione tra quando un custom post è un "custom post" e non direttamente un "post".

Per esempio, un commento può essere aggiunto a un post, ma anche a una pagina e a un CPT; per questo motivo il tipo Comment ha il campo customPost: CustomPostUnion! per recuperare l'entità in cui è stato aggiunto il commento, invece del campo post: Post!.

Tipo Comment

È anche per questa ragione che il campo customPosts riceve l'argomento customPostTypes invece di postTypes.

CPT mappati allo schema

Esistono CPT che sono stati mappati allo schema (come Post e Page per rappresentare i CPT "post" e "page"). In questo caso, la query verrà risolta utilizzando il tipo GraphQL corrispondente per quel CPT.

Quando si recuperano risultati da un tipo union, è necessario specificare i campi da recuperare tramite fragment. Questi possono essere valutati sull'interfaccia CustomPost, che è implementata da tutti i tipi di CPT, oppure su ciascun tipo individuale, come Post o Page.

Nella query seguente, recuperiamo custom post con i CPT "post" e "page". Visualizziamo i loro campi tramite 3 fragment, che valutano se l'entità implementa CustomPost, o è di tipo Post o 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 non mappati allo schema

Quando un CPT non è ancora stato mappato allo schema (come "attachment", "revision" o "nav_menu_item", o qualsiasi CPT installato da un plugin), utilizziamo comunque i campi customPost e customPosts, e dobbiamo passare il nome del CPT corrispondente nell'argomento di campo filter.customPostTypes.

Poiché i loro tipi non esistono nello schema, i loro dati verranno recuperati tramite il tipo GenericCustomPost, che contiene tutte le proprietà comuni ai CPT (title, content, excerpt, date, ecc.).

Custom Post Generico

Nella query seguente, recuperiamo custom post per una varietà di CPT:

query {
  customPosts(
    filter:{
      customPostTypes: [
        "page",
        "nav_menu_item",
        "wp_block",
        "wp_global_styles"
      ]
    }
  ) {
    ... on CustomPost {
      id
      title
      customPostType
      status
    }
    __typename
  }
}

Consentire l'accesso ai Custom Post Type

I CPT devono essere esplicitamente autorizzati a essere interrogabili, come spiegato nella guida Consentire l'accesso ai Custom Post Type.

Interrogare i custom post

I tipi GraphQL per i CPT che sono stati mappati allo schema (come "post" => Post e "page" => Page) sono incorporati direttamente in CustomPostUnion.

Per qualsiasi CPT che non è stato modellato nello schema (come "attachment", "revision" o "nav_menu_item", o qualsiasi CPT installato da un plugin), i suoi dati saranno accessibili tramite il tipo GenericCustomPost.

Indichiamo i CPT da recuperare tramite l'argomento di campo filter.customPostTypes, che riceve un elenco di stringhe, con i nomi dei CPT come definiti in WordPress (come "post", "page", ecc.). Per esempio:

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

Questa query recupera voci da più 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
  }
}

Poiché tutti i Custom Post implementano l'interfaccia CustomPost, possiamo recuperare dati da CustomPostUnion usando un riferimento a un fragment o un fragment inline:

query {
  comments {
    id
    date
    content
    customPost {
      __typename
      ...on CustomPost {
        id
        title
        url
      }
    }
  }
}

Se sappiamo che il commento è stato aggiunto a un post, possiamo anche interrogare i campi specifici del Post:

query {
  comments {
    id
    date
    content
    customPost {
      __typename
      ...on CustomPost {
        id
        title
        url
      }
      ...on Post {
        categoryNames
      }
    }
  }
}

Filtrare i CPT per una tassonomia personalizzata

Un custom post type può avere tassonomie personalizzate (tag e categorie) associate. Per esempio, un CPT "product" può avere associata la tassonomia di categoria "product-cat" e la tassonomia di tag "product-tag".

Possiamo filtrare i risultati per queste tassonomie associate, tramite gli input tags e categories nell'input filter.

Nella query seguente, recuperiamo custom post filtrando per categoria:

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

Recuperare dati personalizzati di CPT

Usando GenericCustomPost, possiamo richiedere solo i campi comuni a tutti i CPT; il recupero di dati personalizzati da un CPT non è supportato (come il recupero dei dati del prezzo per un CPT personalizzato "product").

Per recuperare dati personalizzati di CPT, dobbiamo invece creare i resolver corrispondenti, in codice PHP, per mappare il CPT allo schema:

  • Creare un tipo Product
  • Collegargli un campo price

Ora, il tipo CustomPostUnion (restituito da Root.customPosts) risolverà tutte le voci di questo CPT a un tipo 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
    }
  }
}

Possiamo inoltre creare il campo Root.products: [Product!], e usarlo direttamente:

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

Mutare dati personalizzati di CPT

Per quanto riguarda i CPT che non richiedono campi aggiuntivi rispetto a quelli del tipo Post, è possibile utilizzare sia le mutation createCustomPost che updateCustomPost senza alcun timore o limitazione.

Per esempio, un CPT MyPortfolio che utilizza i campi standard title e content, e non ha campi aggiuntivi, può essere gestito interamente tramite queste mutation.

Questa query crea una voce per il 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
      }
    }
  }
}

Questa query aggiorna il titolo e il contenuto per lo stesso CPT:

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
      }
    }
  }
}

I custom post type forniti da plugin di terze parti potrebbero dover essere creati (e possibilmente aggiornati) solo dal plugin corrispondente.

Questo perché potrebbero avere i loro dati personalizzati (in wp_postmeta o in una tabella proprietaria) che devono essere aggiunti anch'essi, e di cui Gato GraphQL non è a conoscenza.

Per gestire questi CPT in modo appropriato, è necessario creare un'integrazione corrispondente tra quel plugin e Gato GraphQL, che fornisca il mapping di tutti i campi del CPT.

Per esempio, possiamo usare il campo Root.updateCustomPost per tradurre e aggiornare il titolo e il contenuto di un prodotto WooCommerce (ovvero del CPT Product). Non possiamo però creare un prodotto WooCommerce; per questo dobbiamo usare l'estensione "WooCommerce for Gato GraphQL" corrispondente.