Tutorial skema
Tutorial skemaPelajaran 13: Memodifikasi (dan menyimpan kembali) URL gambar dari semua blok Image dalam sebuah postingan

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.com menjadi cdn.mysite.com (agar mulai menyajikan aset-aset tersebut dari CDN)
  • Mengganti .jpg menjadi .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 rawContent postingan
  • 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 -->"
      }
    }
  }
}