Перевод страниц для многоязычного сайта WordPress (классический редактор)
Этот GraphQL-запрос помогает создать многоязычный сайт, где каждый сайт является переводом для определённого языка. Контент основан на классическом редакторе и лучше всего подходит для сети WordPress Multisite.
Этот запрос требует, чтобы в конечной точке были включены Вложенные мутации.
Запрос должен выполняться на основном сайте (с исходным контентом), на котором должен быть установлен пакет «Power Extensions». На всех остальных сайтах сети может быть установлен бесплатный плагин Gato GraphQL.
Для подключения к сайтам сети используется Application Password. Обязательно укажите переменные $username и $appPassword для пользователя с доступом ко всем сайтам.
Запрос получает язык главного сайта и внешнего сайта и сравнивает их:
- Если они одинаковы, просто реплицируются все страницы
- Если они различаются, реплицируются все страницы с переведённым контентом
(Таким образом, если главный сайт имеет язык en, а другой сайт в сети тоже имеет en, все страницы всё равно реплицируются.)
Затем он берёт страницы с основного сайта и (при необходимости) переводит их все сразу на язык целевого сайта, выполняя единственный вызов Google Translate API.
Наконец, он создаёт все эти страницы на внешнем сайте.
########################################################################
#
# Variables:
# - $username: The username to log into the external site
# - $appPassword: The application password to log into the external site
# - $externalSiteURL: The URL of the external site, where all pages will be (translated and) created
# - (Optional) $pageIDs: Restrict translating/creating the pages with given IDs
# - (Optional) $pageStatus: Fetch pages with given status
# - (Optional) $externalSiteGraphQLEndpointPath: Path to the GraphQL endpoint on the external site
#
# *********************************************************************
#
# === Description ===
#
# This Persisted GraphQL query helps create a Multilingual site
# where every site is the translation for some language. The content
# is based on the Classic editor, and it is most suitable with a
# WordPress multisite network.
#
# It must be executed on the master site, which must have the PRO plugin.
# All other sites in the network can have the free Gato GraphQL plugin.
#
# The query retrieves the language from the main site and from the external
# site, and compares them:
#
# - If they are the same, simply replicate all pages
# - If they are different, replicate all pages with translated content
#
# (This way, if the main site has "en" language, and another site in
# the network also has "en", all pages are still replicated.)
#
# Then it grabs all the pages from the master site, and (if required) it
# translates them all at once (in bulk) to the destination site's language,
# by executing a single call to the Google Translate API.
#
# Finally it creates all those pages in the external site.
#
########################################################################
query InitializeExternalSiteVariables
@configureWarningsOnExportingDuplicateVariable(enabled: false)
{
isGutenbergEditorEnabled
@export(as: "isGutenbergEditorEnabled")
emptyBool: _echo(value: false)
@export(as: "hasMasterPages")
@export(as: "executeTranslation")
@remove
}
query ExportData(
$username: String!
$appPassword: String!
$externalSiteURL: URL!
$externalSiteGraphQLEndpointPath: String! = "/graphql/internal/"
$pageIDs: [ID!]! = []
$pageStatus: [CustomPostStatusEnum!]! = [publish]
)
@depends(on: "InitializeExternalSiteVariables")
@skip(if: $isGutenbergEditorEnabled)
{
# Retrieve the language of the content
siteLanguage
@export(as: "fromLanguage")
# Generate the authorization header to connect to the external site
loginCredentials: _sprintf(
string: "%s:%s",
values: [$username, $appPassword]
)
@remove
base64EncodedLoginCredentials: _strBase64Encode(
string: $__loginCredentials
)
@remove
authorizationHeaderValue: _sprintf(
string: "Basic %s",
values: [$__base64EncodedLoginCredentials]
)
@remove
@export(as: "authorizationHeaderValue")
# Generate the external site's GraphQL endpoint to connect to
endpoint: _sprintf(
string: "%s%s",
values: [
$externalSiteURL,
$externalSiteGraphQLEndpointPath
]
)
@export(as: "endpoint")
masterPages: pages(filter: { ids: $pageIDs, status: $pageStatus }) {
id
emptyArray: _echo(value: [])
@export(
as: "rawTitle"
type: DICTIONARY
)
@export(
as: "rawContent"
type: DICTIONARY
)
@export(
as: "rawExcerpt"
type: DICTIONARY
)
@remove
}
hasMasterPages: _notEmpty(value: $__masterPages)
@export(as: "hasMasterPages")
}
query RetrieveAndExportExternalSiteLanguage
@depends(on: "ExportData")
@include(if: $hasMasterPages)
{
# Retrieve the language of the external site
externalHTTPRequest: _sendGraphQLHTTPRequest(input:{
endpoint: $endpoint,
query: """
{
me {
name
}
siteLanguage
}
""",
options: {
headers: [
{
name: "Authorization",
value: $authorizationHeaderValue
}
]
}
})
externalSiteLanguage: _objectProperty(
object: $__externalHTTPRequest,
by: {
path: "data.siteLanguage"
}
)
@export(as: "toLanguage")
# Indicate if connecting to the external site was successful
hasRetrievedExternalSiteLanguage: _notEmpty(
value: $__externalSiteLanguage
)
# Only translate the content if the master/destination sites languages are different
areFromToLanguagesDifferent: _notEquals(
value1: $fromLanguage
value2: $__externalSiteLanguage
)
# Flag to indicate if to translate the content
executeTranslation: _and(
values: [
$__hasRetrievedExternalSiteLanguage,
$__areFromToLanguagesDifferent,
]
)
@export(as: "executeTranslation")
}
query FetchData(
$pageIDs: [ID!]! = []
$pageStatus: [CustomPostStatusEnum!]! = [publish]
)
@depends(on: "RetrieveAndExportExternalSiteLanguage")
@include(if: $hasMasterPages)
{
fetchDataPages: pages(filter: { ids: $pageIDs, status: $pageStatus }) {
id
rawTitle
@export(
as: "rawTitle"
type: DICTIONARY
)
rawContent
@export(
as: "rawContent"
type: DICTIONARY
)
rawExcerpt
@export(
as: "rawExcerpt"
type: DICTIONARY
)
}
}
query AdaptData
@depends(on: "FetchData")
@include(if: $hasMasterPages)
{
adaptedToRawTitle: _echo(value: $rawTitle)
@underEachJSONObjectProperty(
passValueOnwardsAs: "value"
)
@applyField(
name: "_echo"
arguments: {
value: [$value]
}
setResultInResponse: true
)
@export(as: "adaptedToRawTitle")
adaptedFromTitle: _echo(value: $rawTitle)
@underEachJSONObjectProperty
@applyField(
name: "_echo"
arguments: {
value: [""]
}
setResultInResponse: true
)
@export(as: "adaptedFromTitle")
adaptedToRawContent: _echo(value: $rawContent)
@underEachJSONObjectProperty(
passValueOnwardsAs: "value"
)
@applyField(
name: "_echo"
arguments: {
value: [$value]
}
setResultInResponse: true
)
@export(as: "adaptedToRawContent")
adaptedFromRawContent: _echo(value: $rawContent)
@underEachJSONObjectProperty
@applyField(
name: "_echo"
arguments: {
value: [""]
}
setResultInResponse: true
)
@export(as: "adaptedFromRawContent")
adaptedToRawExcerpt: _echo(value: $rawExcerpt)
@underEachJSONObjectProperty(
passValueOnwardsAs: "value"
)
@applyField(
name: "_echo"
arguments: {
value: [$value]
}
setResultInResponse: true
)
@export(as: "adaptedToRawExcerpt")
adaptedFromRawExcerpt: _echo(value: $rawExcerpt)
@underEachJSONObjectProperty
@applyField(
name: "_echo"
arguments: {
value: [""]
}
setResultInResponse: true
)
@export(as: "adaptedFromRawExcerpt")
}
query TransformData
@depends(on: "AdaptData")
@include(if: $hasMasterPages)
{
transformations: _echo(value: {
metaRawTitle: {
from: $adaptedFromTitle,
to: $adaptedToRawTitle,
},
metaRawContent: {
from: $adaptedFromRawContent,
to: $adaptedToRawContent,
},
metaRawExcerpt: {
from: $adaptedFromRawExcerpt,
to: $adaptedToRawExcerpt,
}
})
@if(condition: $executeTranslation)
@underEachJSONObjectProperty
@underJSONObjectProperty(by: { key: "to" })
@underEachJSONObjectProperty
@underEachArrayItem
@strTranslate(
from: $fromLanguage,
to: $toLanguage
)
@export(as: "transformations")
}
query PrepareMetaReplacements
@depends(on: "TransformData")
@include(if: $hasMasterPages)
{
transformedMetaTitle: _echo(value: $rawTitle)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "pageID"
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_sprintf",
arguments: {
string: "metaRawTitle.to.%s",
values: [$pageID]
}
passOnwardsAs: "titlePath"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $transformations
by: { path: $titlePath }
}
passOnwardsAs: "transformedPostTitleAsArray"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $transformedPostTitleAsArray
position: 0
}
setResultInResponse: true
)
@export(
as: "transformedRawTitle"
)
transformedMetaRawContent: _echo(value: $rawContent)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "pageID"
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_sprintf",
arguments: {
string: "metaRawContent.to.%s",
values: [$pageID]
}
passOnwardsAs: "rawContentPath"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $transformations
by: { path: $rawContentPath }
}
passOnwardsAs: "transformedPostRawContentAsArray"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $transformedPostRawContentAsArray
position: 0
}
setResultInResponse: true
)
@export(
as: "transformedRawContent"
)
transformedMetaRawExcerpt: _echo(value: $rawExcerpt)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "pageID"
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_sprintf",
arguments: {
string: "metaRawExcerpt.to.%s",
values: [$pageID]
}
passOnwardsAs: "rawExcerptPath"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $transformations
by: { path: $rawExcerptPath }
}
passOnwardsAs: "transformedPostRawExcerptAsArray"
)
@applyField(
name: "_arrayItem",
arguments: {
array: $transformedPostRawExcerptAsArray
position: 0
}
setResultInResponse: true
)
@export(
as: "transformedRawExcerpt"
)
}
query ExportMutationInputs(
$pageIDs: [ID!]! = []
$pageStatus: [CustomPostStatusEnum!]! = [publish]
)
@depends(on: "PrepareMetaReplacements")
@include(if: $hasMasterPages)
{
exportPages: pages(filter: { ids: $pageIDs, status: $pageStatus }) {
id
transformedRawContent: _objectProperty(
object: $transformedRawContent,
by: {
key: $__id
}
)
transformedRawTitle: _objectProperty(
object: $transformedRawTitle,
by: {
key: $__id
}
)
transformedSlug: _echo(value: $__transformedRawTitle)
transformedRawExcerpt: _objectProperty(
object: $transformedRawExcerpt,
by: {
key: $__id
}
)
input: _echo(value: {
status: draft,
title: $__transformedRawTitle,
slug: $__transformedSlug,
excerpt: $__transformedRawExcerpt,
contentAs: {
html: $__transformedRawContent
}
})
@export(
as: "createPostMutationInputs"
type: LIST
)
}
}
mutation CreatePagesWithTranslationOnExternalSite
@depends(on: "ExportMutationInputs")
@include(if: $hasMasterPages)
{
createExternalSitePageHTTPRequests: _echo(value: $createPostMutationInputs)
@underEachArrayItem(
passValueOnwardsAs: "input"
)
@applyField(
name: "_sendGraphQLHTTPRequest"
arguments: {
input: {
endpoint: $endpoint,
query: """
mutation CreatePageFromMasterSite($input: JSONObject!) {
createPage(input: $input) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
page {
id
slug
title
content
status
url
excerpt
}
}
}
""",
variables: [
{
name: "input",
value: $input
}
],
options: {
headers: [
{
name: "Authorization",
value: $authorizationHeaderValue
}
]
}
}
},
setResultInResponse: true
)
}