Translating additional Gutenberg blocks
Gato AI Translations for Polylang can translate block-based posts.
The plugin ships with support for WordPress core blocks, and provides the ability for users to support additional blocks.
Supporting additional blocks
You can translate custom blocks from your application, or block from 3rd-party plugins.
Please read guide Extending Page Builder elements to translate first.
The documentation below is a continuation of that process, applied to Gutenberg blocks.
For instance, let's say we are using the Kadence's testimonials block:

When executing the translation, that block will remain in its original language:

By the end of this guide, all properties in the block will be translated:

To add support for translating a block, follow the steps below.
Identify the block properties to translate
The plugin translates blocks by extracting all the properties inside a block, translating those, and then injecting the translated properties back into the block.
In order to extract the properties from a block, the plugin needs to know:
- Which properties are translatable
- How to retrieve them from within the block
- How to replace the property with its translation
Execute the Translate custom posts GraphQL query, and browse all the blocks and their properties in the GraphQL response, under key blockFlattenedDataItems
.
Explore that entry to identify the block properties that must be translated.
In our case, we find the "kadence/testimonial"
block, containing properties title
, content
and occupation
(all under attributes
) that need to be translated.

We must also identify how those strings are stored in the block HTML, printed under the first rawContent
entry:

In our case, the block HTML is:
<!-- wp:kadence/testimonial {\"uniqueID\":\"1021_4fe748-f5\",\"url\":\"https://gatomultilingual.local/wp-content/uploads/2025/01/Luciano_Pavarotti_2004.jpg\",\"id\":184,\"subtype\":\"jpeg\",\"title\":\"Here is my secret\",\"content\":\"My voice needs to be strong and clear. That's why I drink green tea every morning. Stay away from fried food!\",\"name\":\"Luciano Pavarotti\",\"occupation\":\"Opera singer\",\"sizes\":{\"thumbnail\":{\"height\":150,\"width\":150,\"url\":\"https://gatomultilingual.local/wp-content/uploads/2025/01/Luciano_Pavarotti_2004-150x150.jpg\",\"orientation\":\"landscape\"},\"medium\":{\"height\":300,\"width\":210,\"url\":\"https://gatomultilingual.local/wp-content/uploads/2025/01/Luciano_Pavarotti_2004-210x300.jpg\",\"orientation\":\"portrait\"},\"full\":{\"url\":\"https://gatomultilingual.local/wp-content/uploads/2025/01/Luciano_Pavarotti_2004.jpg\",\"height\":629,\"width\":440,\"orientation\":\"portrait\"}}} /-->
The query will execute a regular expression (regex) search and replace on that HTML, to replace a string with its translation.
Later on, from this HTML, we will identify how to reach each property that needs to be translated (title, content and occupation) and create the corresponding regex.
Adapt the Gato GraphQL query
We can conveniently check which of the already-supported core
blocks has a similar structure, and copy/paste/adapt that code for our block.
In our case, "kadence/testimonial"
has a similar structure to "core/paragraph"
(which contains the content
property to translate), then we can copy and adapt its code.
The logic to translate a block is spread across 7 sections in the GraphQL query. They are marked with a GraphQL comment Insert code for custom blocks (g-{1-7})
, like this one:
###############################################
##### Insert code for custom blocks (g-1)
###############################################
Search for them, copy the logic from the already-supported block ("core/paragraph"
) in that section, and adapt it accordingly for your block ("kadence/testimonial"
) by renaming variables, adapting the name of the property, and identifying the regex to replace the value of property in the block HTML.
The 7 sections for "core/paragraph"
are:
Section 1 (defines a set of dynamic variables):
@export(
as: "originCoreParagraphContentItems"
type: DICTIONARY
)
@export(
as: "originCoreParagraphContentReplacementsFrom"
type: DICTIONARY
)
@export(
as: "originCoreParagraphContentReplacementsTo"
type: DICTIONARY
)
Section 2 (extracts a property from within the block, and exports it under a dynamic variable):
originCoreParagraph: blockFlattenedDataItems(
filterBy: { include: "core/paragraph" }
)
@underEachArrayItem
@underJSONObjectProperty(
by: { path: "attributes.content" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "originCoreParagraphContentItems"
type: DICTIONARY
)
Section 3 (defines another set of dynamic variables):
@export(
as: "coreParagraphContentItems"
type: DICTIONARY
)
@export(
as: "coreParagraphContentReplacementsFrom"
type: DICTIONARY
)
@export(
as: "coreParagraphContentReplacementsTo"
type: DICTIONARY
)
Section 4 (extracts the strings to translate for a property and assigns them to a dynamic variable, and prepares storing the translations in another dynamic variable):
originCoreParagraphContentItems: _objectProperty(
object: $originCoreParagraphContentItems
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
coreParagraphContentItems: _echo(value: $__originCoreParagraphContentItems)
@export(
as: "coreParagraphContentItems"
type: DICTIONARY
)
@remove
originCoreParagraphContentReplacementsFrom: _objectProperty(
object: $originCoreParagraphContentReplacementsFrom
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
coreParagraphContentReplacementsFrom: _echo(value: $__originCoreParagraphContentReplacementsFrom)
@export(
as: "coreParagraphContentReplacementsFrom"
type: DICTIONARY
)
@remove
originCoreParagraphContentReplacementsTo: _objectProperty(
object: $originCoreParagraphContentReplacementsTo
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
coreParagraphContentReplacementsTo: _echo(value: $__originCoreParagraphContentReplacementsTo)
@export(
as: "coreParagraphContentReplacementsTo"
type: DICTIONARY
)
@remove
Section 5 (defines a set of replacements to perform):
coreParagraphContent: {
from: $coreParagraphContentItems,
to: $coreParagraphContentItems,
},
Section 6 (defines the regex that will match the property value within the block's HTML):
@underJSONObjectProperty(
by: { key: "coreParagraphContent" }
affectDirectivesUnderPos: [1, 6]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 4],
)
@underEachJSONObjectProperty
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:paragraph .*?-->\\n?<p ?.*?>)%s(</p>\\n?<!-- /wp:paragraph -->)#",
values: [$value]
},
setResultInResponse: true
)
@export(
as: "coreParagraphContentReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "coreParagraphContentReplacementsTo",
)
Section 7 (performs the regex search and replace, replacing the property value inside the block's HTML with its translation):
@underEachJSONObjectProperty(
passKeyOnwardsAs: "customPostID"
affectDirectivesUnderPos: [1, 2]
)
@applyField(
name: "_propertyExistsInJSONObject"
arguments: {
object: $coreParagraphContentReplacementsFrom
by: { key: $customPostID }
}
passOnwardsAs: "hasPostID"
)
@if(
condition: $hasPostID
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_objectProperty",
arguments: {
object: $coreParagraphContentReplacementsFrom,
by: {
key: $customPostID
}
},
passOnwardsAs: "postCoreParagraphContentReplacementsFrom"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $coreParagraphContentReplacementsTo,
by: {
key: $customPostID
}
},
passOnwardsAs: "postCoreParagraphContentReplacementsTo"
)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: $postCoreParagraphContentReplacementsFrom,
replaceWith: $postCoreParagraphContentReplacementsTo
)
Let's adapt them for "kadence/testimonial"
. Notice that, with the exception of Section 6 (more details below), all sections are pretty much a copy/paste and adapt:
Section 1:
@export(
as: "originKadenceTestimonialTitleItems"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialTitleReplacementsFrom"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialTitleReplacementsTo"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialContentItems"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialContentReplacementsFrom"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialContentReplacementsTo"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialOccupationItems"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialOccupationReplacementsFrom"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialOccupationReplacementsTo"
type: DICTIONARY
)
Section 2:
originKadenceTestimonial: blockFlattenedDataItems(
filterBy: { include: "kadence/testimonial" }
)
@underEachArrayItem
@underJSONObjectProperty(
by: { path: "attributes.title" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "originKadenceTestimonialTitleItems"
type: DICTIONARY
)
@underEachArrayItem
@underJSONObjectProperty(
by: { path: "attributes.content" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "originKadenceTestimonialContentItems"
type: DICTIONARY
)
@underEachArrayItem
@underJSONObjectProperty(
by: { path: "attributes.occupation" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "originKadenceTestimonialOccupationItems"
type: DICTIONARY
)
Section 3:
@export(
as: "kadenceTestimonialTitleItems"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialTitleReplacementsFrom"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialTitleReplacementsTo"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialContentItems"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialContentReplacementsFrom"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialContentReplacementsTo"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialOccupationItems"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialOccupationReplacementsFrom"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialOccupationReplacementsTo"
type: DICTIONARY
)
Section 4:
originKadenceTestimonialTitleItems: _objectProperty(
object: $originKadenceTestimonialTitleItems
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialTitleItems: _echo(value: $__originKadenceTestimonialTitleItems)
@export(
as: "kadenceTestimonialTitleItems"
type: DICTIONARY
)
@remove
originKadenceTestimonialTitleReplacementsFrom: _objectProperty(
object: $originKadenceTestimonialTitleReplacementsFrom
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialTitleReplacementsFrom: _echo(value: $__originKadenceTestimonialTitleReplacementsFrom)
@export(
as: "kadenceTestimonialTitleReplacementsFrom"
type: DICTIONARY
)
@remove
originKadenceTestimonialTitleReplacementsTo: _objectProperty(
object: $originKadenceTestimonialTitleReplacementsTo
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialTitleReplacementsTo: _echo(value: $__originKadenceTestimonialTitleReplacementsTo)
@export(
as: "kadenceTestimonialTitleReplacementsTo"
type: DICTIONARY
)
@remove
originKadenceTestimonialContentItems: _objectProperty(
object: $originKadenceTestimonialContentItems
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialContentItems: _echo(value: $__originKadenceTestimonialContentItems)
@export(
as: "kadenceTestimonialContentItems"
type: DICTIONARY
)
@remove
originKadenceTestimonialContentReplacementsFrom: _objectProperty(
object: $originKadenceTestimonialContentReplacementsFrom
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialContentReplacementsFrom: _echo(value: $__originKadenceTestimonialContentReplacementsFrom)
@export(
as: "kadenceTestimonialContentReplacementsFrom"
type: DICTIONARY
)
@remove
originKadenceTestimonialContentReplacementsTo: _objectProperty(
object: $originKadenceTestimonialContentReplacementsTo
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialContentReplacementsTo: _echo(value: $__originKadenceTestimonialContentReplacementsTo)
@export(
as: "kadenceTestimonialContentReplacementsTo"
type: DICTIONARY
)
@remove
originKadenceTestimonialOccupationItems: _objectProperty(
object: $originKadenceTestimonialOccupationItems
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialOccupationItems: _echo(value: $__originKadenceTestimonialOccupationItems)
@export(
as: "kadenceTestimonialOccupationItems"
type: DICTIONARY
)
@remove
originKadenceTestimonialOccupationReplacementsFrom: _objectProperty(
object: $originKadenceTestimonialOccupationReplacementsFrom
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialOccupationReplacementsFrom: _echo(value: $__originKadenceTestimonialOccupationReplacementsFrom)
@export(
as: "kadenceTestimonialOccupationReplacementsFrom"
type: DICTIONARY
)
@remove
originKadenceTestimonialOccupationReplacementsTo: _objectProperty(
object: $originKadenceTestimonialOccupationReplacementsTo
by: { key: $__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialOccupationReplacementsTo: _echo(value: $__originKadenceTestimonialOccupationReplacementsTo)
@export(
as: "kadenceTestimonialOccupationReplacementsTo"
type: DICTIONARY
)
@remove
Section 5:
kadenceTestimonialTitle: {
from: $kadenceTestimonialTitleItems,
to: $kadenceTestimonialTitleItems,
},
kadenceTestimonialContent: {
from: $kadenceTestimonialContentItems,
to: $kadenceTestimonialContentItems,
},
kadenceTestimonialOccupation: {
from: $kadenceTestimonialOccupationItems,
to: $kadenceTestimonialOccupationItems,
},
Section 6:
Analyzing the HTML for the "kadence/testimonial"
block, we must identify how to reach each property that needs to be translated (title, content and occupation):
<!-- wp:kadence/testimonial {[...],\"title\":\"Here is my secret\",\"content\":\"My voice needs to be strong and clear. That's why I drink green tea every morning. Stay away from fried food!\",[...],\"occupation\":\"Opera singer\",[...]} /-->
Then we create the corresponding regex for each property. The regex must match everything that comes before and after the string to translate, like this:
#(match everything before)%s(match everything after)#
In our case, we obtain:
- title:
#(<!-- wp:kadence/testimonial .*?\"title\":\")%s(\".*? /-->)#
- content:
#(<!-- wp:kadence/testimonial .*?\"content\":\")%s(\".*? /-->)#
- occupation:
#(<!-- wp:kadence/testimonial .*?\"occupation\":\")%s(\".*? /-->)#
Finally, we inject the regex on the code below:
@underJSONObjectProperty(
by: { key: "kadenceTestimonialTitle" }
affectDirectivesUnderPos: [1, 6]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 4],
)
@underEachJSONObjectProperty
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:kadence/testimonial .*?\"title\":\")%s(\".*? /-->)#",
values: [$value]
},
setResultInResponse: true
)
@export(
as: "kadenceTestimonialTitleReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "kadenceTestimonialTitleReplacementsTo",
)
@underJSONObjectProperty(
by: { key: "kadenceTestimonialContent" }
affectDirectivesUnderPos: [1, 6]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 4],
)
@underEachJSONObjectProperty
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:kadence/testimonial .*?\"content\":\")%s(\".*? /-->)#",
values: [$value]
},
setResultInResponse: true
)
@export(
as: "kadenceTestimonialContentReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "kadenceTestimonialContentReplacementsTo",
)
@underJSONObjectProperty(
by: { key: "kadenceTestimonialOccupation" }
affectDirectivesUnderPos: [1, 6]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 4],
)
@underEachJSONObjectProperty
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:kadence/testimonial .*?\"occupation\":\")%s(\".*? /-->)#",
values: [$value]
},
setResultInResponse: true
)
@export(
as: "kadenceTestimonialOccupationReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "kadenceTestimonialOccupationReplacementsTo",
)
Section 7:
@underEachJSONObjectProperty(
passKeyOnwardsAs: "customPostID"
affectDirectivesUnderPos: [1, 2]
)
@applyField(
name: "_propertyExistsInJSONObject"
arguments: {
object: $kadenceTestimonialTitleReplacementsFrom
by: { key: $customPostID }
}
passOnwardsAs: "hasPostID"
)
@if(
condition: $hasPostID
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_objectProperty",
arguments: {
object: $kadenceTestimonialTitleReplacementsFrom,
by: {
key: $customPostID
}
},
passOnwardsAs: "postKadenceTestimonialTitleReplacementsFrom"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $kadenceTestimonialTitleReplacementsTo,
by: {
key: $customPostID
}
},
passOnwardsAs: "postKadenceTestimonialTitleReplacementsTo"
)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: $postKadenceTestimonialTitleReplacementsFrom,
replaceWith: $postKadenceTestimonialTitleReplacementsTo
)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "customPostID"
affectDirectivesUnderPos: [1, 2]
)
@applyField(
name: "_propertyExistsInJSONObject"
arguments: {
object: $kadenceTestimonialContentReplacementsFrom
by: { key: $customPostID }
}
passOnwardsAs: "hasPostID"
)
@if(
condition: $hasPostID
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_objectProperty",
arguments: {
object: $kadenceTestimonialContentReplacementsFrom,
by: {
key: $customPostID
}
},
passOnwardsAs: "postKadenceTestimonialContentReplacementsFrom"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $kadenceTestimonialContentReplacementsTo,
by: {
key: $customPostID
}
},
passOnwardsAs: "postKadenceTestimonialContentReplacementsTo"
)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: $postKadenceTestimonialContentReplacementsFrom,
replaceWith: $postKadenceTestimonialContentReplacementsTo
)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "customPostID"
affectDirectivesUnderPos: [1, 2]
)
@applyField(
name: "_propertyExistsInJSONObject"
arguments: {
object: $kadenceTestimonialOccupationReplacementsFrom
by: { key: $customPostID }
}
passOnwardsAs: "hasPostID"
)
@if(
condition: $hasPostID
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_objectProperty",
arguments: {
object: $kadenceTestimonialOccupationReplacementsFrom,
by: {
key: $customPostID
}
},
passOnwardsAs: "postKadenceTestimonialOccupationReplacementsFrom"
)
@applyField(
name: "_objectProperty",
arguments: {
object: $kadenceTestimonialOccupationReplacementsTo,
by: {
key: $customPostID
}
},
passOnwardsAs: "postKadenceTestimonialOccupationReplacementsTo"
)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: $postKadenceTestimonialOccupationReplacementsFrom,
replaceWith: $postKadenceTestimonialOccupationReplacementsTo
)
Working on some code editor, copy the GraphQL query into a new file (you can format it as GraphQL to have syntax highlighting), add the 7 sections for the new block, and copy the adapted query back into the GraphiQL client.
Then execute the query, and check if the translated post has the block properties translated (by editing the translated post in the WordPress editor and refreshing the page).
Repeat until it all works, and then persist the query via a hook in PHP code.
Persist the GraphQL query via hooks in PHP code
When using the gatompl:persisted_query
hook, the placeholders in the GraphQL query to inject the custom logic are:
##### Insert code for custom blocks (g-1)
##### Insert code for custom blocks (g-2)
- ...
##### Insert code for custom blocks (g-7)
Example - Persisting the query for the testimonial block
For the "kadence/testimonial"
block, using the gatompl:persisted_query
hook, the PHP logic is this one (notice that inside <<<GRAPHQL
, GraphQL variables must be escaped: \$
):
add_filter(
'gatompl:persisted_query',
function (string $persistedQuery, string $persistedQueryFile): string {
if (str_ends_with($persistedQueryFile, '/translate-customposts-for-polylang.gql')) {
return str_replace(
[
'##### Insert code for custom blocks (g-1)',
'##### Insert code for custom blocks (g-2)',
'##### Insert code for custom blocks (g-3)',
'##### Insert code for custom blocks (g-4)',
'##### Insert code for custom blocks (g-5)',
'##### Insert code for custom blocks (g-6)',
'##### Insert code for custom blocks (g-7)',
],
[
<<<GRAPHQL
##### Insert code for custom blocks (g-1)
@export(
as: "originKadenceTestimonialTitleItems"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialTitleReplacementsFrom"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialTitleReplacementsTo"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialContentItems"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialContentReplacementsFrom"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialContentReplacementsTo"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialOccupationItems"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialOccupationReplacementsFrom"
type: DICTIONARY
)
@export(
as: "originKadenceTestimonialOccupationReplacementsTo"
type: DICTIONARY
)
GRAPHQL,
<<<GRAPHQL
##### Insert code for custom blocks (g-2)
originKadenceTestimonial: blockFlattenedDataItems(
filterBy: { include: "kadence/testimonial" }
)
@underEachArrayItem
@underJSONObjectProperty(
by: { path: "attributes.title" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "originKadenceTestimonialTitleItems"
type: DICTIONARY
)
@underEachArrayItem
@underJSONObjectProperty(
by: { path: "attributes.content" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "originKadenceTestimonialContentItems"
type: DICTIONARY
)
@underEachArrayItem
@underJSONObjectProperty(
by: { path: "attributes.occupation" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "originKadenceTestimonialOccupationItems"
type: DICTIONARY
)
GRAPHQL,
<<<GRAPHQL
##### Insert code for custom blocks (g-3)
@export(
as: "kadenceTestimonialTitleItems"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialTitleReplacementsFrom"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialTitleReplacementsTo"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialContentItems"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialContentReplacementsFrom"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialContentReplacementsTo"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialOccupationItems"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialOccupationReplacementsFrom"
type: DICTIONARY
)
@export(
as: "kadenceTestimonialOccupationReplacementsTo"
type: DICTIONARY
)
GRAPHQL,
<<<GRAPHQL
##### Insert code for custom blocks (g-4)
originKadenceTestimonialTitleItems: _objectProperty(
object: \$originKadenceTestimonialTitleItems
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialTitleItems: _echo(value: \$__originKadenceTestimonialTitleItems)
@export(
as: "kadenceTestimonialTitleItems"
type: DICTIONARY
)
@remove
originKadenceTestimonialTitleReplacementsFrom: _objectProperty(
object: \$originKadenceTestimonialTitleReplacementsFrom
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialTitleReplacementsFrom: _echo(value: \$__originKadenceTestimonialTitleReplacementsFrom)
@export(
as: "kadenceTestimonialTitleReplacementsFrom"
type: DICTIONARY
)
@remove
originKadenceTestimonialTitleReplacementsTo: _objectProperty(
object: \$originKadenceTestimonialTitleReplacementsTo
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialTitleReplacementsTo: _echo(value: \$__originKadenceTestimonialTitleReplacementsTo)
@export(
as: "kadenceTestimonialTitleReplacementsTo"
type: DICTIONARY
)
@remove
originKadenceTestimonialContentItems: _objectProperty(
object: \$originKadenceTestimonialContentItems
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialContentItems: _echo(value: \$__originKadenceTestimonialContentItems)
@export(
as: "kadenceTestimonialContentItems"
type: DICTIONARY
)
@remove
originKadenceTestimonialContentReplacementsFrom: _objectProperty(
object: \$originKadenceTestimonialContentReplacementsFrom
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialContentReplacementsFrom: _echo(value: \$__originKadenceTestimonialContentReplacementsFrom)
@export(
as: "kadenceTestimonialContentReplacementsFrom"
type: DICTIONARY
)
@remove
originKadenceTestimonialContentReplacementsTo: _objectProperty(
object: \$originKadenceTestimonialContentReplacementsTo
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialContentReplacementsTo: _echo(value: \$__originKadenceTestimonialContentReplacementsTo)
@export(
as: "kadenceTestimonialContentReplacementsTo"
type: DICTIONARY
)
@remove
originKadenceTestimonialOccupationItems: _objectProperty(
object: \$originKadenceTestimonialOccupationItems
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialOccupationItems: _echo(value: \$__originKadenceTestimonialOccupationItems)
@export(
as: "kadenceTestimonialOccupationItems"
type: DICTIONARY
)
@remove
originKadenceTestimonialOccupationReplacementsFrom: _objectProperty(
object: \$originKadenceTestimonialOccupationReplacementsFrom
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialOccupationReplacementsFrom: _echo(value: \$__originKadenceTestimonialOccupationReplacementsFrom)
@export(
as: "kadenceTestimonialOccupationReplacementsFrom"
type: DICTIONARY
)
@remove
originKadenceTestimonialOccupationReplacementsTo: _objectProperty(
object: \$originKadenceTestimonialOccupationReplacementsTo
by: { key: \$__originCustomPostId }
failIfNonExistingKeyOrPath: false
valueWhenNonExistingKeyOrPath: []
)
kadenceTestimonialOccupationReplacementsTo: _echo(value: \$__originKadenceTestimonialOccupationReplacementsTo)
@export(
as: "kadenceTestimonialOccupationReplacementsTo"
type: DICTIONARY
)
@remove
GRAPHQL,
<<<GRAPHQL
##### Insert code for custom blocks (g-5)
kadenceTestimonialTitle: {
from: \$kadenceTestimonialTitleItems,
to: \$kadenceTestimonialTitleItems,
},
kadenceTestimonialContent: {
from: \$kadenceTestimonialContentItems,
to: \$kadenceTestimonialContentItems,
},
kadenceTestimonialOccupation: {
from: \$kadenceTestimonialOccupationItems,
to: \$kadenceTestimonialOccupationItems,
},
GRAPHQL,
<<<GRAPHQL
##### Insert code for custom blocks (g-6)
@underJSONObjectProperty(
by: { key: "kadenceTestimonialTitle" }
affectDirectivesUnderPos: [1, 6]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 4],
)
@underEachJSONObjectProperty
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:kadence/testimonial .*?\"title\":\")%s(\".*? /-->)#",
values: [\$value]
},
setResultInResponse: true
)
@export(
as: "kadenceTestimonialTitleReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "kadenceTestimonialTitleReplacementsTo",
)
@underJSONObjectProperty(
by: { key: "kadenceTestimonialContent" }
affectDirectivesUnderPos: [1, 6]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 4],
)
@underEachJSONObjectProperty
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:kadence/testimonial .*?\"content\":\")%s(\".*? /-->)#",
values: [\$value]
},
setResultInResponse: true
)
@export(
as: "kadenceTestimonialContentReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "kadenceTestimonialContentReplacementsTo",
)
@underJSONObjectProperty(
by: { key: "kadenceTestimonialOccupation" }
affectDirectivesUnderPos: [1, 6]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 4],
)
@underEachJSONObjectProperty
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:kadence/testimonial .*?\"occupation\":\")%s(\".*? /-->)#",
values: [\$value]
},
setResultInResponse: true
)
@export(
as: "kadenceTestimonialOccupationReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "kadenceTestimonialOccupationReplacementsTo",
)
GRAPHQL,
<<<GRAPHQL
##### Insert code for custom blocks (g-7)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "customPostID"
affectDirectivesUnderPos: [1, 2]
)
@applyField(
name: "_propertyExistsInJSONObject"
arguments: {
object: \$kadenceTestimonialTitleReplacementsFrom
by: { key: \$customPostID }
}
passOnwardsAs: "hasPostID"
)
@if(
condition: \$hasPostID
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_objectProperty",
arguments: {
object: \$kadenceTestimonialTitleReplacementsFrom,
by: {
key: \$customPostID
}
},
passOnwardsAs: "postKadenceTestimonialTitleReplacementsFrom"
)
@applyField(
name: "_objectProperty",
arguments: {
object: \$kadenceTestimonialTitleReplacementsTo,
by: {
key: \$customPostID
}
},
passOnwardsAs: "postKadenceTestimonialTitleReplacementsTo"
)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: \$postKadenceTestimonialTitleReplacementsFrom,
replaceWith: \$postKadenceTestimonialTitleReplacementsTo
)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "customPostID"
affectDirectivesUnderPos: [1, 2]
)
@applyField(
name: "_propertyExistsInJSONObject"
arguments: {
object: \$kadenceTestimonialContentReplacementsFrom
by: { key: \$customPostID }
}
passOnwardsAs: "hasPostID"
)
@if(
condition: \$hasPostID
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_objectProperty",
arguments: {
object: \$kadenceTestimonialContentReplacementsFrom,
by: {
key: \$customPostID
}
},
passOnwardsAs: "postKadenceTestimonialContentReplacementsFrom"
)
@applyField(
name: "_objectProperty",
arguments: {
object: \$kadenceTestimonialContentReplacementsTo,
by: {
key: \$customPostID
}
},
passOnwardsAs: "postKadenceTestimonialContentReplacementsTo"
)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: \$postKadenceTestimonialContentReplacementsFrom,
replaceWith: \$postKadenceTestimonialContentReplacementsTo
)
@underEachJSONObjectProperty(
passKeyOnwardsAs: "customPostID"
affectDirectivesUnderPos: [1, 2]
)
@applyField(
name: "_propertyExistsInJSONObject"
arguments: {
object: \$kadenceTestimonialOccupationReplacementsFrom
by: { key: \$customPostID }
}
passOnwardsAs: "hasPostID"
)
@if(
condition: \$hasPostID
affectDirectivesUnderPos: [1, 2, 3]
)
@applyField(
name: "_objectProperty",
arguments: {
object: \$kadenceTestimonialOccupationReplacementsFrom,
by: {
key: \$customPostID
}
},
passOnwardsAs: "postKadenceTestimonialOccupationReplacementsFrom"
)
@applyField(
name: "_objectProperty",
arguments: {
object: \$kadenceTestimonialOccupationReplacementsTo,
by: {
key: \$customPostID
}
},
passOnwardsAs: "postKadenceTestimonialOccupationReplacementsTo"
)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: \$postKadenceTestimonialOccupationReplacementsFrom,
replaceWith: \$postKadenceTestimonialOccupationReplacementsTo
)
GRAPHQL,
],
$persistedQuery
);
}
return $persistedQuery;
},
10,
2
);