Pelajaran 13: Memodifikasi (dan menyimpan kembali) URL gambar dari semua blok Image dalam sebuah postingan
Pada pelajaran tutorial sebelumnya, kita mempelajari bahwa kita dapat mengiterasi struktur dalam blok (Gutenberg) pada konten postingan, dan mengekstrak item yang diinginkan.
Mari kita jelajahi sekarang cara mentransformasi item-item tersebut, dan menyimpannya kembali ke dalam postingan.
Query dalam pelajaran tutorial ini memodifikasi URL gambar dalam blok core/image pada sebuah postingan:
- Mengganti
mysite.commenjadicdn.mysite.com(agar mulai menyajikan aset-aset tersebut dari CDN) - Mengganti
.jpgmenjadi.avif
GraphQL query untuk mentransformasi (dan menyimpan kembali) URL gambar dari semua blok core/image dalam sebuah postingan
Mutasi updatePost menerima konten HTML postingan. Kemudian, kita harus:
- Mengambil
rawContentpostingan - Menerapkan transformasi pada kode HTML tersebut, mengganti URL asli dengan URL yang telah dikonversi
- Menyimpan konten yang telah disesuaikan
GraphQL query di bawah ini mengeksekusi transformasi pada kode HTML melalui direktif @strRegexReplaceMultiple, dengan setiap pola regex yang dihasilkan secara dinamis berdasarkan konten HTML dalam blok (dalam hal ini, menargetkan elemen src dalam kode HTML blok core/image). Karena pola regex yang dihasilkan bisa mengandung karakter khusus regex (seperti ., +, (, dll), dan penggantiannya bisa mengandung variabel penggantian regex (seperti $1), semuanya harus di-escape.
query InitializeEmptyVariables {
emptyArray: _echo(value: [])
@export(as: "coreImageURLItems")
@export(as: "coreImageURLReplacementsFrom")
@export(as: "coreImageURLReplacementsTo")
@remove
}
# Extract all the image URLs from the `core/image` blocks, and export them under `$coreImageURLItems`
query FetchData($postID: ID!)
@configureWarningsOnExportingDuplicateVariable(enabled: false)
@depends(on: "InitializeEmptyVariables")
{
post(by: { id: $postID } ) {
rawContent
@export(as: "rawContent")
coreImage: blockFlattenedDataItems(
filterBy: { include: "core/image" }
)
@underEachArrayItem
@underJSONObjectProperty(
by: { key: "attributes" }
)
@underJSONObjectProperty(
by: { key: "url" }
failIfNonExistingKeyOrPath: false
)
@export(
as: "coreImageURLItems"
)
}
}
# Convert the URLs and place the results under `$transformations`
query TransformData
@depends(on: "FetchData")
{
transformations: _echo(value: {
coreImageURL: {
from: $coreImageURLItems,
to: $coreImageURLItems,
},
})
@underEachJSONObjectProperty
@underJSONObjectProperty(by: { key: "to" })
@underEachArrayItem
@strRegexReplace(
searchRegex: "#^https?://mysite.com/(.*)\\.jpg$#",
replaceWith: "https://cdn.mysite.com/$1.avif"
)
@export(as: "transformations")
}
# Escape the regex patterns and their replacements
query EscapeRegexStrings
@depends(on: "TransformData")
{
escapedRegexStrings: _echo(value: $transformations)
@underEachJSONObjectProperty
@underJSONObjectProperty(by: { key: "from" })
@underEachArrayItem
@strQuoteRegex
@underEachJSONObjectProperty
@underJSONObjectProperty(
by: { key: "to" }
affectDirectivesUnderPos: [1, 3],
)
@underEachArrayItem
@strRegexReplace(
searchRegex: "#\\$(\\d+)#",
replaceWith: "\\\\\\$1"
)
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "$1%s$2",
values: [$value]
},
setResultInResponse: true
)
@export(as: "escapedRegexTransformations")
}
# Generate the regex patterns, and assign them to `$coreImageURLReplacementsFrom`
query CreateRegexReplacements
@depends(on: "EscapeRegexStrings")
{
regexReplacements: _echo(value: $escapedRegexTransformations)
@underJSONObjectProperty(
by: { key: "coreImageURL" }
affectDirectivesUnderPos: [1, 5]
)
@underJSONObjectProperty(
by: { key: "from" }
affectDirectivesUnderPos: [1, 3],
)
@underEachArrayItem(
passValueOnwardsAs: "value"
)
@applyField(
name: "_sprintf",
arguments: {
string: "#(<!-- wp:image .*?-->\\n?.*<img .*?src=\\\")%s(\\\".*>.*\\n?<!-- /wp:image -->)#",
values: [$value]
},
setResultInResponse: true
)
@export(
as: "coreImageURLReplacementsFrom",
)
@underJSONObjectProperty(
by: { key: "to" }
)
@export(
as: "coreImageURLReplacementsTo",
)
}
# Execute the regex search and replace, export the results under `$transformedRawContent`
query ExecuteRegexReplacements
@depends(on: "CreateRegexReplacements")
{
transformedRawContent: _echo(value: $rawContent)
@strRegexReplaceMultiple(
limit: 1,
searchRegex: $coreImageURLReplacementsFrom,
replaceWith: $coreImageURLReplacementsTo
)
@export(as: "transformedRawContent")
}
# Execute the mutation to update the post
mutation ModifyAndUpdatePost($postID: ID!)
@depends(on: "ExecuteRegexReplacements")
{
updatePost(input: {
id: $postID,
contentAs: {
html: $transformedRawContent
}
}) {
status
errors {
__typename
...on ErrorPayload {
message
}
}
post {
id
title
rawContent
}
}
}Responsnya adalah:
{
"data": {
"post": {
"rawContent": "<!-- wp:paragraph -->\n<p>This is a paragraph block.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">Image Block (Standard)</h2>\n<!-- /wp:heading -->\n\n<!-- wp:image {\"sizeSlug\":\"large\"} -->\n<figure class=\"wp-block-image size-large\"><img src=\"http://mysite.com/fs_img/mysite/2008/themes_photo.jpg\" alt=\"\"/></figure>\n<!-- /wp:image -->\n\n<!-- wp:image {\"sizeSlug\":\"large\"} -->\n<figure class=\"wp-block-image size-large\"><img src=\"http://mysite.com/fs_img/mysite/2007/email_photo.jpg\" alt=\"\"/></figure>\n<!-- /wp:image -->",
"coreImage": [
{
"name": "core/image",
"attributes": {
"sizeSlug": "large",
"url": "http://mysite.com/fs_img/mysite/2008/themes_photo.jpg",
"alt": ""
}
},
{
"name": "core/image",
"attributes": {
"sizeSlug": "large",
"url": "http://mysite.com/fs_img/mysite/2007/email_photo.jpg",
"alt": ""
}
}
]
},
"transformations": {
"coreImageURL": {
"from": [
"http://mysite.com/fs_img/mysite/2008/themes_photo.jpg",
"http://mysite.com/fs_img/mysite/2007/email_photo.jpg"
],
"to": [
"https://cdn.mysite.com/fs_img/mysite/2008/themes_photo.avif",
"https://cdn.mysite.com/fs_img/mysite/2007/email_photo.avif"
]
}
},
"escapedRegexStrings": {
"coreImageURL": {
"from": [
"http://mysite\\.com/fs_img/mysite/2008/themes_photo\\.jpg",
"http://mysite\\.com/fs_img/mysite/2007/email_photo\\.jpg"
],
"to": [
"$1https://cdn.mysite.com/fs_img/mysite/2008/themes_photo.avif$2",
"$1https://cdn.mysite.com/fs_img/mysite/2007/email_photo.avif$2"
]
}
},
"regexReplacements": {
"coreImageURL": {
"from": [
"#(<!-- wp:image .*?-->\\n?.*<img .*?src=\\\")http://mysite\\.com/fs_img/mysite/2008/themes_photo\\.jpg(\\\".*>.*\\n?<!-- /wp:image -->)#",
"#(<!-- wp:image .*?-->\\n?.*<img .*?src=\\\")http://mysite\\.com/fs_img/mysite/2007/email_photo\\.jpg(\\\".*>.*\\n?<!-- /wp:image -->)#"
],
"to": [
"$1https://cdn.mysite.com/fs_img/mysite/2008/themes_photo.avif$2",
"$1https://cdn.mysite.com/fs_img/mysite/2007/email_photo.avif$2"
]
}
},
"transformedRawContent": "<!-- wp:paragraph -->\n<p>This is a paragraph block.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">Image Block (Standard)</h2>\n<!-- /wp:heading -->\n\n<!-- wp:image {\"sizeSlug\":\"large\"} -->\n<figure class=\"wp-block-image size-large\"><img src=\"https://cdn.mysite.com/fs_img/mysite/2008/themes_photo.avif\" alt=\"\"/></figure>\n<!-- /wp:image -->\n\n<!-- wp:image {\"sizeSlug\":\"large\"} -->\n<figure class=\"wp-block-image size-large\"><img src=\"https://cdn.mysite.com/fs_img/mysite/2007/email_photo.avif\" alt=\"\"/></figure>\n<!-- /wp:image -->",
"updatePost": {
"status": "SUCCESS",
"errors": null,
"post": {
"id": 13,
"title": "Released v0.6, check it out",
"rawContent": "<!-- wp:paragraph -->\n<p>This is a paragraph block.</p>\n<!-- /wp:paragraph -->\n\n<!-- wp:heading -->\n<h2 class=\"wp-block-heading\">Image Block (Standard)</h2>\n<!-- /wp:heading -->\n\n<!-- wp:image {\"sizeSlug\":\"large\"} -->\n<figure class=\"wp-block-image size-large\"><img src=\"https://cdn.mysite.com/fs_img/mysite/2008/themes_photo.avif\" alt=\"\"/></figure>\n<!-- /wp:image -->\n\n<!-- wp:image {\"sizeSlug\":\"large\"} -->\n<figure class=\"wp-block-image size-large\"><img src=\"https://cdn.mysite.com/fs_img/mysite/2007/email_photo.avif\" alt=\"\"/></figure>\n<!-- /wp:image -->"
}
}
}
}