Tutorial del esquema
Tutorial del esquemaLección 9: Insertando/Eliminando un bloque (Gutenberg) en masa

Lección 9: Insertando/Eliminando un bloque (Gutenberg) en masa

Podemos actualizar entradas modificando el contenido HTML de sus bloques (Gutenberg).

Entre otros casos de uso, esto es útil para promocionar campañas (como cuando ofrecemos un descuento durante el Black Friday):

  • Antes de la campaña, creamos un bloque personalizado mycompany:black-friday-campaign-video con nuestra Call To Action, y ejecutamos una operación masiva para añadirlo a todas las entradas del sitio web
  • Después de la campaña, ejecutamos una operación masiva para eliminar el bloque de todas las entradas

Para que las consultas GraphQL en esta lección del tutorial funcionen, la Creando una configuración del esquema aplicada al endpoint necesita tener las Usar mutaciones anidadas habilitadas

Insertando un bloque en masa

Esta consulta GraphQL identifica el 3er bloque de párrafo en una entrada (buscando <!-- /wp:paragraph -->) y coloca el contenido HTML del bloque personalizado justo después:

mutation InjectBlock(
  $limit: Int! = 5,
  $offset: Int! = 0
) {
  posts: posts(
    pagination: { limit: $limit, offset: $offset }
    sort: { by: ID, order: ASC }
  ) {
    id
    rawContent
    adaptedRawContent: _strRegexReplace(
      in: $__rawContent,
      searchRegex: "#(<!-- /wp:paragraph -->[\\s\\S]+<!-- /wp:paragraph -->[\\s\\S]+<!-- /wp:paragraph -->)#U",
      replaceWith: "$1<!-- mycompany:black-friday-campaign-video -->\n<figure class=\"wp-block-video\"><video controls src=\"https://mysite.com/videos/BlackFriday2023.mp4\"></video></figure>\n<!-- /mycompany:black-friday-campaign-video -->",
      limit: 1
    )
    update(input: {
      contentAs: { html: $__adaptedRawContent },
    }) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
      post {
        id
        rawContent
      }
    }
  }
}

Insertando el bloque con más opciones

Esta consulta GraphQL, similar a la anterior, genera la regex dinámicamente, permitiéndonos pasar el tipo de bloque a buscar, y después de cuántos de esos bloques colocar el bloque personalizado:

query CreateRegex(
  $searchBlockType: String! = "wp:paragraph"
  $injectAfterBlockCount: Int!
  $injectBlockMarkup: String!
) {
  endingBlockMarkup: _sprintf(
    string: "<!-- /%s -->",
    values: [$searchBlockType]
  )
    @remove
  endingBlockMarkupArray: _arrayPad(
    array: [],
    length: $injectAfterBlockCount,
    value: $__endingBlockMarkup
  )
    @remove
  regexString: _arrayJoin(
    array: $__endingBlockMarkupArray,
    separator: "[\\s\\S]+"
  )
    @remove
  regex: _sprintf(
    string: "#(%s)#U",
    values: [$__regexString]
  )
    @export(as: "regex")
    @remove
  replaceWith: _sprintf(
    string: "$1%s",
    values: [$injectBlockMarkup]
  )
    @export(as: "replaceWith")
    @remove
}
 
mutation InjectBlock(
  $limit: Int! = 5,
  $offset: Int! = 0
  $times: Int! = 1
)
  @depends(on: "CreateRegex")
{
  posts: posts(
    pagination: { limit: $limit, offset: $offset }
    sort: { by: ID, order: ASC }
  ) {
    id
    rawContent
    adaptedRawContent: _strRegexReplace(
      in: $__rawContent,
      searchRegex: $regex,
      replaceWith: $replaceWith,
      limit: $times
    )
    update(input: {
      contentAs: { html: $__adaptedRawContent },
    }) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
      post {
        id
        rawContent
      }
    }
  }
}

Proporcionamos el diccionario de variables así:

{
  "injectBlockMarkup": "<!-- mycompany:black-friday-campaign-video -->\n<figure class=\"wp-block-video\"><video controls src=\"https://mysite.com/videos/BlackFriday2023.mp4\"></video></figure>\n<!-- /mycompany:black-friday-campaign-video -->",
  "injectAfterBlockCount": 3
}
  • Durante el desarrollo/testing de la consulta GraphQL, imprime los patrones regex en la respuesta colocando # antes de las directivas @remove (para comentarlas):
{
  field
    # @remove   <= Adding "#" before will disable the directive
}

Eliminando un bloque en masa

Esta consulta GraphQL busca todas las entradas que contienen el bloque personalizado, y lo elimina de su fuente HTML:

mutation RemoveBlock {
  posts(filter: { search: "\"<!-- /mycompany:black-friday-campaign-video -->\"" } ) {
    id
    rawContent
    adaptedRawContent: _strRegexReplace(
      in: $__rawContent,
      searchRegex: "#(<!-- mycompany:black-friday-campaign-video -->[\\s\\S]+<!-- /mycompany:black-friday-campaign-video -->)#",
      replaceWith: ""
    )
    update(input: {
      contentAs: { html: $__adaptedRawContent },
    }) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
      post {
        id
        rawContent
      }
    }
  }
}

Eliminando un bloque con más opciones

Esta consulta GraphQL, similar a la anterior, genera la regex dinámicamente, permitiéndonos pasar el tipo de bloque a eliminar:

query CreateVars(
  $removeBlockType: String!
) {
  regex: _sprintf(
    string: "#(<!-- %1$s -->[\\s\\S]+<!-- /%1$s -->)#",
    values: [$removeBlockType]
  )
    @export(as: "regex")
    @remove
 
  search: _sprintf(
    string: "\"<!-- /%1$s -->\"",
    values: [$removeBlockType]
  )
    @export(as: "search")
    @remove
}
 
mutation RemoveBlock
  @depends(on: "CreateVars")
{
  posts(filter: { search: $search } ) {
    id
    rawContent
    adaptedRawContent: _strRegexReplace(
      in: $__rawContent,
      searchRegex: $regex,
      replaceWith: ""
    )
    update(input: {
      contentAs: { html: $__adaptedRawContent },
    }) {
      status
      errors {
        __typename
        ...on ErrorPayload {
          message
        }
      }
      post {
        id
        rawContent
      }
    }
  }
}

Proporcionamos el diccionario de variables así:

{
  "removeBlockType": "mycompany:black-friday-campaign-video"
}