Demo Gato GraphQL + Meta Box

Đồng bộ hóa bài viết giữa 2 trang web, bao gồm metadata Meta Box (và cả Slim SEO)

Đồng bộ hóa bài viết và dữ liệu Meta Box (cũng như Slim SEO) từ một trang WordPress sang trang khác, sử dụng Gato GraphQL cho WordPress

Leonardo Losoviz
Leonardo Losoviz -
Logo
Image
Target Image
Target Image

Chúng ta có thể đồng bộ hóa một bài viết từ trang WordPress này sang trang WordPress khác, bao gồm cả metadata được quản lý qua Meta Box, hoặc được thêm bởi Slim SEO (hay các plugin khác).

Trong demo này, chúng ta sẽ dùng GraphQL để:

  1. Lấy một bài viết cùng toàn bộ metadata của nó từ trang nguồn
  2. Tạo bài viết mới hoặc cập nhật bài viết hiện có trên trang đích, và sao chép dữ liệu cùng metadata của bài viết từ trang nguồn

Query này yêu cầu:

  • Gato GraphQL + các extension PRO trên trang nguồn
  • Plugin Gato GraphQL miễn phí trên trang đích
  • Nested Mutations được bật trên endpoint của trang đích

Chúng ta cần cung cấp các biến sau:

  • postType: Custom post type của bài viết cần đồng bộ hóa giữa các trang
  • postSlug: Slug của bài viết cần đồng bộ hóa giữa các trang
  • downstreamServerGraphQLEndpointURL: URL endpoint GraphQL của trang WordPress đích
  • username: Tên người dùng của application password để xác thực trên trang đích
  • appPassword: Mật khẩu của application password để xác thực trên trang đích
  • update: Có cập nhật bài viết hiện có (true) hay tạo mới (false) không

Khi cập nhật bài viết, định danh chung giữa trang upstream và trang downstream là slug của bài viết.

Query GraphQL phải được thực thi trên trang nguồn.

Dưới đây là query GraphQL:

query CheckHasCustomPost($postSlug: String!, $postType: String! = post)
{
  customPost(by: { slug: $postSlug }, status: any, customPostTypes: [$postType])
    @fail(
      message: "There is no post in the upstream site with the provided slug"
      data: {
        slug: $postSlug
      }
    )
  {
    rawTitle
      @export(as: "postTitle")
    rawContent
      @export(as: "postContent")
    rawExcerpt
      @export(as: "postExcerpt")
 
    metaKeys(filter: { exclude: [
      "_thumbnail_id",
      "_edit_last",
    ] })
    meta(keys: $__metaKeys) 
      @export(as: "postMeta")
  }
 
  isMissingPostInUpstream: _isNull(value: $__customPost)
    @export(as: "isMissingPostInUpstream")
}
 
query ExportCreateCustomPostOnTargetSiteGraphQLQuery(
  $update: Boolean! = false
)
  @depends(on: "CheckHasCustomPost")
  @skip(if: $isMissingPostInUpstream)
  @skip(if: $update)
{
  query: _echo(value: """
 
mutation CreateCustomPost(
  $postType: String! = post
  $postSlug: String!
  $postTitle: String!
  $postExcerpt: String!
  $postContent: String!
  $postMeta: NullableListValueJSONObject!
) {
  createCustomPost(input: {
    customPostType: $postType
    title: $postTitle,
    excerpt: $postExcerpt,
    slug: $postSlug,
    contentAs: { html: $postContent },
    status: draft,
    meta: $postMeta,
  }) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    customPost {
      __typename
      ...on CustomPost {
        customPostType
        title
        excerpt
        slug
        content
        status
      }
    }
  }
}
 
    """
  )
    @export(as: "query")
    @remove
}
 
query ExportUpdateCustomPostOnTargetSiteGraphQLQuery(
  $update: Boolean! = false
)
  @depends(on: "CheckHasCustomPost")
  @skip(if: $isMissingPostInUpstream)
  @include(if: $update)
{
  query: _echo(value: """
 
mutation UpdateCustomPost(
  $postType: String! = post
  $postSlug: String!
  $postTitle: String!
  $postContent: String!
  $postExcerpt: String!
  $postMeta: NullableListValueJSONObject!
) {
  customPost(by: { slug: $postSlug }, status: any, customPostTypes: [$postType]) {
    update(input: {
      title: $postTitle,
      excerpt: $postExcerpt,
      contentAs: { html: $postContent },
      meta: $postMeta,
    }) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
      customPost {
        __typename
        ...on CustomPost {
          customPostType
          title
          excerpt
          slug
          content
          status
        }
      }
    }
  }
}
 
    """
  )
    @export(as: "query")
    @remove
}
 
query CreateOrUpdateCustomPostOnTargetSite(
  $downstreamServerGraphQLEndpointURL: String!
  $postSlug: String!
  $username: String!
  $appPassword: String!
  $postType: String! = post
)
  @depends(on: [
    "ExportCreateCustomPostOnTargetSiteGraphQLQuery",
    "ExportUpdateCustomPostOnTargetSiteGraphQLQuery",
  ])
  @skip(if: $isMissingPostInUpstream)
{
  loginCredentials: _sprintf(
    string: "%s:%s",
    values: [$username, $appPassword]
  )
    @remove
 
  base64EncodedLoginCredentials: _strBase64Encode(
    string: $__loginCredentials
  )
    @remove
 
  loginCredentialsHeaderValue: _sprintf(
    string: "Basic %s",
    values: [$__base64EncodedLoginCredentials]
  )
    @remove
 
  _sendGraphQLHTTPRequest(
    input: {
      endpoint: $downstreamServerGraphQLEndpointURL,
      query: $query,
      variables: [
        {
          name: "postSlug",
          value: $postSlug
        },
        {
          name: "postTitle",
          value: $postTitle
        },
        {
          name: "postContent",
          value: $postContent
        },
        {
          name: "postExcerpt",
          value: $postExcerpt
        },
        {
          name: "postMeta",
          value: $postMeta
        },
        {
          name: "postType",
          value: $postType
        }
      ],
      options: {
        headers: [
          {
            name: "Authorization",
            value: $__loginCredentialsHeaderValue
          }
        ]
      }
    }
  )
}

Các biến sẽ có dạng như sau:

{
  "postType": "post",
  "postSlug": "hello-world",
  "downstreamServerGraphQLEndpointURL": "https://target-site.com/graphql",
  "update": false,
  "username": "admin",
  "appPassword": "{ application password, eg: cNEp BVPy QVxF eVqH lggt BTb4 }"
}

Đăng ký nhận bản tin của chúng tôi

Cập nhật tất cả những điều mới từ Gato GraphQL.