Trabalhando com
Trabalhando comElementor

Elementor

Podemos editar os dados do Elementor de um post e atualizá-los conforme necessário, consultando, iterando, transformando e armazenando o meta JSON do Elementor para aquele post.

Consultar dados do Elementor

Há 2 campos para consultar os dados do Elementor:

  • elementorData retorna o JSON de todos os elementos no post do Elementor
  • elementorFlattenedDataItems também retorna o JSON, mas achatado em um array de nível único

Para transformar e atualizar dados do Elementor, usaremos elementorFlattenedDataItems, pois facilita a iteração dos elementos.

Consulte o campo elementorFlattenedDataItems, que retorna o JSON achatado de todos os elementos no post do Elementor.

query GetElementorData($customPostId: ID!) {
  customPost(by: { id: $customPostId }, status: any) {
    ...on ElementorMaybeEnabledForCustomPostType {
      elementorFlattenedDataItems
    }
  }
}

A resposta terá este formato:

{
  "data": {
    "post": {
      "elementorFlattenedDataItems": [
        {
          "id": "164e55c4",
          "elType": "container",
          "settings": {
            "layout": "full_width",
            "flex_gap": {
              "size": 0,
              "unit": "px",
              "column": "0",
              "row": "0",
              "isLinked": true
            },
            "min_height": {
              "unit": "vh",
              "size": 100,
              "sizes": []
            },
            "flex_align_items": "stretch",
            "content_position": "middle",
            "structure": "20",
            "margin": {
              "unit": "%",
              "top": "",
              "right": 0,
              "bottom": "",
              "left": 0,
              "isLinked": true
            },
            "padding": {
              "unit": "%",
              "top": "0",
              "right": "6",
              "bottom": "0",
              "left": "6",
              "isLinked": false
            },
            "margin_tablet": {
              "unit": "%",
              "top": "12",
              "right": 0,
              "bottom": "0",
              "left": 0,
              "isLinked": false
            },
            "margin_mobile": {
              "unit": "%",
              "top": "20",
              "right": 0,
              "bottom": "0",
              "left": 0,
              "isLinked": false
            },
            "padding_tablet": {
              "unit": "%",
              "top": "",
              "right": "",
              "bottom": "",
              "left": "",
              "isLinked": true
            },
            "z_index": 1,
            "_title": "Hero",
            "flex_direction": "row",
            "content_width": "full",
            "flex_direction_tablet": "column"
          },
          "isInner": false,
          "innerElementIds": [
            "600c1786",
            "5b451d4"
          ],
          "parentElementId": null
        },
        {
          "id": "600c1786",
          "elType": "container",
          "settings": {
            "_column_size": 50,
            "width": {
              "size": 50,
              "unit": "%"
            },
            "padding": {
              "unit": "%",
              "top": "0",
              "right": "12",
              "bottom": "0",
              "left": "0",
              "isLinked": false
            },
            "width_tablet": {
              "size": 100,
              "unit": "%"
            },
            "align_tablet": "center",
            "flex_gap": {
              "size": 20,
              "unit": "px",
              "column": "20",
              "row": "20",
              "isLinked": true
            },
            "padding_tablet": {
              "unit": "%",
              "top": "0",
              "right": "15",
              "bottom": "0",
              "left": "15",
              "isLinked": false
            },
            "padding_mobile": {
              "unit": "px",
              "top": "0",
              "right": "0",
              "bottom": "0",
              "left": "0",
              "isLinked": false
            },
            "content_width": "full",
            "flex_direction": "column",
            "flex_justify_content": "center",
            "flex_align_items": "flex-start",
            "flex_align_items_tablet": "center"
          },
          "isInner": true,
          "parentElementId": "164e55c4",
          "innerElementIds": [
            "db84e33",
            "7fe7b508",
            "314da60",
            "7b7e33ce",
            "7ff4508"
          ]
        },
        {
          "id": "db84e33",
          "elType": "widget",
          "settings": {
            "title": "Your health, <br><b>on your time<\/b>",
            "header_size": "h1",
            "title_color": "#0D3276",
            "typography_typography": "custom",
            "typography_font_family": "Poppins",
            "typography_font_size": {
              "unit": "px",
              "size": 76,
              "sizes": []
            },
            "typography_font_weight": "400",
            "typography_text_transform": "capitalize",
            "typography_font_style": "normal",
            "typography_text_decoration": "none",
            "typography_line_height": {
              "unit": "em",
              "size": 1,
              "sizes": []
            },
            "typography_letter_spacing": {
              "unit": "px",
              "size": 0,
              "sizes": []
            },
            "_z_index": 1,
            "align_tablet": "center",
            "typography_font_size_tablet": {
              "unit": "px",
              "size": 55,
              "sizes": []
            },
            "typography_font_size_mobile": {
              "unit": "px",
              "size": 40,
              "sizes": []
            }
          },
          "widgetType": "heading",
          "parentElementId": "600c1786",
          "innerElementIds": []
        }
      ]
    }
  }
}

Também podemos filtrar elementos por nome via o parâmetro filterBy (que aceita include e exclude).

Executando esta query:

query GetElementorData($customPostId: ID!) {
  customPost(by: { id: $customPostId }, status: any) {
    ...on ElementorMaybeEnabledForCustomPostType {
      elementorFlattenedDataItems(filterBy: { include: ["heading"] })
    }
  }
}

...será produzida esta resposta:

{
  "data": {
    "post": {
      "elementorFlattenedDataItems": [
        {
          "id": "db84e33",
          "elType": "widget",
          "settings": {
            "title": "Your health, <br><b>on your time<\/b>",
            "header_size": "h1",
            "title_color": "#0D3276",
            "typography_typography": "custom",
            "typography_font_family": "Poppins",
            "typography_font_size": {
              "unit": "px",
              "size": 76,
              "sizes": []
            },
            "typography_font_weight": "400",
            "typography_text_transform": "capitalize",
            "typography_font_style": "normal",
            "typography_text_decoration": "none",
            "typography_line_height": {
              "unit": "em",
              "size": 1,
              "sizes": []
            },
            "typography_letter_spacing": {
              "unit": "px",
              "size": 0,
              "sizes": []
            },
            "_z_index": 1,
            "align_tablet": "center",
            "typography_font_size_tablet": {
              "unit": "px",
              "size": 55,
              "sizes": []
            },
            "typography_font_size_mobile": {
              "unit": "px",
              "size": 40,
              "sizes": []
            }
          },
          "widgetType": "heading",
          "parentElementId": "600c1786",
          "innerElementIds": []
        }
      ]
    }
  }
}

Modificar e armazenar dados do Elementor

Itere os elementos no JSON produzido por elementorFlattenedDataItems, modifique-os conforme necessário e armazene o JSON modificado de volta no meta do post, por meio da mutation elementorMergeCustomPostElementDataItem.

Nesta query, filtramos os elementos por nome e exportamos os headings modificados (sob a variável dinâmica $modifiedElementorHeadings) e também seus IDs (sob a variável dinâmica $modifiedElementorHeadingIDs):

query GetAndModifyElementorData($customPostId: ID!) {
  customPost(by: { id: $customPostId }, status: any) {
    ...on ElementorMaybeEnabledForCustomPostType {
      elementorFlattenedDataItems(filterBy: {include: ["heading"]})
        @underEachArrayItem(affectDirectivesUnderPos: [1, 3])
          @underJSONObjectProperty(by: { key: "id" })
            @export(as: "modifiedElementorHeadingIDs")
          @underJSONObjectProperty(
            by: { path: "settings.title" }
            failIfNonExistingKeyOrPath: false
            affectDirectivesUnderPos: [1, 2]
          )
            @strUpperCase
            @export(as: "modifiedElementorHeadings")
    }
  }
}

Em seguida, use a mutation elementorMergeCustomPostElementDataItem para mesclar essas entradas no JSON meta do post.

Para isso, você deve primeiro gerar o input a ser injetado na mutation, como um array com o ID e as configurações de cada elemento modificado:

query GenerateElementorMergeDataItemInputs
  @depends(on: "GetAndModifyElementorData")
{
  elementorMergeDataItemInputs: _echo(value: $modifiedElementorHeadingIDs)
    @underEachArrayItem(
      passIndexOnwardsAs: "index",
      passValueOnwardsAs: "id"
      affectDirectivesUnderPos: [1, 2]
    )
      @applyField(
        name: "_arrayItem",
        arguments: {
          array: $modifiedElementorHeadings,
          position: $index
        },
        passOnwardsAs: "heading"
      )
      @applyField(
        name: "_echo",
        arguments: {
          value: {
            id: $id,
            settings: {
              title: $heading
            }
          }
        }
        setResultInResponse: true
      )
    @export(as: "elementorMergeDataItemInputs")
}
 
mutation StoreElementorData($customPostId: ID!)
  @depends(on: "GenerateElementorMergeDataItemInputs")
{
  elementorMergeCustomPostElementDataItem(input: {
    customPostID: $customPostId
    elements: $elementorMergeDataItemInputs
  }) {
    status
    errors {
      __typename
      ...on ErrorPayload {
        message
      }
    }
    customPost {
      __typename
      ...on CustomPost {
        id
        elementorFlattenedDataItems
      }
    }
  }
}