Tutorial dello schema
Tutorial dello schemaLezione 13: Modificare (e salvare nuovamente) gli URL delle immagini da tutti i blocchi Image in un post

Lezione 13: Modificare (e salvare nuovamente) gli URL delle immagini da tutti i blocchi Image in un post

Nella lezione precedente del tutorial, abbiamo appreso che è possibile iterare la struttura interna dei blocchi (Gutenberg) nel contenuto del post ed estrarre gli elementi desiderati.

Esploriamo ora come trasformare quegli elementi e salvarli nuovamente nel post.

La query in questa lezione del tutorial modifica l'URL delle immagini nei blocchi core/image di un post:

  • Sostituendo mysite.com con cdn.mysite.com (per iniziare a servire quelle risorse da un CDN)
  • Sostituendo .jpg con .avif

Query GraphQL per trasformare (e salvare nuovamente) gli URL delle immagini da tutti i blocchi core/image in un post

La mutation updatePost riceve il contenuto HTML del post. Quindi, dobbiamo:

  • Recuperare il rawContent del post
  • Applicare trasformazioni a quel codice HTML, sostituendo gli URL originali con gli URL convertiti
  • Salvare il contenuto adattato

La query GraphQL seguente esegue le trasformazioni nel codice HTML tramite la direttiva @strRegexReplaceMultiple, con ogni pattern regex generato dinamicamente in base al contenuto HTML interno dei blocchi (in questo caso, punta all'elemento src nel codice HTML del blocco core/image). Poiché i pattern regex generati potrebbero contenere qualsiasi carattere speciale di regex (come ., +, (, ecc.) e le sostituzioni potrebbero contenere una variabile di sostituzione regex (come $1), questi devono essere sottoposti a 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
    }    
  }
}

La risposta è:

{
  "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 -->"
      }
    }
  }
}