0
61

SHARE

Comunicação entre Blocos com Block Context API no WordPress

Comunicação entre Blocos com Block Context API no WordPress

Aprenda como usar o Block Context API no Gutenberg para permitir a comunicação entre blocos pai e filho no editor do WordPress
Este post é a parte 13 de 20 da Série WordPress Extremo: Gutenberg + React + Blocos Customizados

Fala, Dev WordPress! 👋

Aqui é o Asllan Maciel — e hoje a conversa é sobre uma das ferramentas mais poderosas (e menos exploradas) do desenvolvimento com Gutenberg: a Block Context API.

Se você já precisou criar um bloco pai que influencia o comportamento de blocos filhos, já percebeu que passar valores pode virar um emaranhado. A boa notícia? O Block Context resolve isso de forma elegante.


📦 O que é o Block Context?

É como o Context API do React, mas dentro do Gutenberg: um bloco pai fornece dados para seus filhos sem precisar passar explicitamente por atributos ou props.


🧠 Quando Usar?

Use o contexto de bloco quando:

  • Um bloco filho precisa acessar um valor definido no bloco pai;
  • Você quer reduzir repetição de props ou atributos;
  • Precisa padronizar valores compartilhados, como temas de cores, configurações de layout ou visibilidade.

💡 Exemplo Prático: context-box + context-label

Vamos criar dois blocos:

  • wp24h/context-box: Define uma cor de fundo.
  • wp24h/context-label: Lê e exibe essa cor via contexto.

🗂️ Estrutura de Pastas

blocks/
└── context-box/
    ├── block.json
    ├── index.js
    ├── edit.js
    ├── save.js
    ├── style.css
    └── context-label/
        ├── block.json
        ├── index.js
        ├── edit.js
        ├── save.js
        └── style.css

🔧 1. Bloco Pai: context-box

block.json

{
  "apiVersion": 2,
  "name": "wp24h/context-box",
  "title": "Context Box",
  "category": "layout",
  "icon": "screenoptions",
  "attributes": {
    "backgroundColor": {
      "type": "string",
      "default": "#d9f7be"
    }
  },
  "providesContext": {
    "wp24h/bgColor": "backgroundColor"
  },
  "supports": {
    "html": false
  },
  "editorScript": "file:../../dist/context-box.js"
}

index.js

import './style.css';
import edit from './edit';
import save from './save';

import { registerBlockType } from '@wordpress/blocks';

import metadata from './block.json';

registerBlockType(metadata.name, {
  ...metadata,
  edit,
  save,
});

edit.js

import { useBlockProps, InspectorControls, InnerBlocks } from '@wordpress/block-editor';
import { PanelBody, ColorPalette } from '@wordpress/components';

export default function Edit({ attributes, setAttributes }) {
  const { backgroundColor } = attributes;

  const setColor = (color) => setAttributes({ backgroundColor: color });

  return (
    <>
      <InspectorControls>
        <PanelBody title="Cor de Fundo">
          <ColorPalette
            value={backgroundColor}
            onChange={setColor}
          />
        </PanelBody>
      </InspectorControls>
      <div {...useBlockProps({ style: { backgroundColor, padding: '20px' } })}>
        <InnerBlocks allowedBlocks={['wp24h/context-label']} />
      </div>
    </>
  );
}

save.js

import { useBlockProps, InnerBlocks } from '@wordpress/block-editor';

export default function save({ attributes }) {
  return (
    <div {...useBlockProps.save({ style: { backgroundColor: attributes.backgroundColor, padding: '20px' } })}>
      <InnerBlocks.Content />
    </div>
  );
}

style.css

.wp-block-wp24h-context-label {
  font-size: 14px;
  color: #333;
}

🧩 2. Bloco Filho: context-label

block.json

{
  "apiVersion": 2,
  "name": "wp24h/context-label",
  "title": "Context Label",
  "category": "layout",
  "icon": "admin-customizer",
  "usesContext": ["wp24h/bgColor"],
  "editorScript": "file:../../../dist/context-label.js"
}

index.js

import './style.css';
import edit from './edit';
import save from './save';

import { registerBlockType } from '@wordpress/blocks';

import metadata from './block.json';

registerBlockType(metadata.name, {
  ...metadata,
  edit,
  save,
});

edit.js

import { useBlockProps } from '@wordpress/block-editor';

export default function Edit({ context }) {
  const bgColor = context['wp24h/bgColor'];

  return (
    <div {...useBlockProps()} style={{ border: '2px dashed #666', padding: '10px', margin: '10px 0' }}>
      <p>Cor herdada: <strong>{bgColor}</strong></p>
    </div>
  );
}

save.js

import { useBlockProps } from '@wordpress/block-editor';

export default function save() {
  return <div {...useBlockProps()}>Bloco filho</div>;
}

style.css

.wp-block-wp24h-context-label {
  font-size: 14px;
  color: #333;
}

⚙️ 3. Webpack

No webpack.config.js:

entry: {
  'context-box': path.resolve(__dirname, 'blocks/context-box/index.js'),
  'context-label': path.resolve(__dirname, 'blocks/context-box/context-label/index.js'),
  // outros blocos...
},

⚙️ 4. Init

Temos agora que registrar nossos novos blocos, mas para isso, vamos precisar mexer um pouco no método register_blocks() para que:

🧼 Evite registros duplicados e mensagens de erro.
🔍 Varra todos os diretórios de blocos (incluindo blocos filhos);
🚫 Ignore blocos que já foram registrados manualmente (ex: wp24h/posts);
✅ Use block.json como fonte de verdade;
⚙️ Leia automaticamente os scripts gerados no dist/ (ex: dist/context-box.js e .asset.php);

public function register_blocks()
{
    $base_path   = __DIR__ . '/../../blocks/';
    $dist_url    = plugins_url('dist/', dirname(__DIR__, 2));
    $dist_path   = __DIR__ . '/../../dist/';
    $excluir     = ['wp24h/posts']; // blocos com render_callback registrados manualmente

    $iterator = new \RecursiveIteratorIterator(
        new \RecursiveDirectoryIterator($base_path),
        \RecursiveIteratorIterator::SELF_FIRST
    );

    foreach ($iterator as $file) {
        if ($file->getFilename() !== 'block.json') {
            continue;
        }

        $block_dir  = $file->getPath();
        $block_json = json_decode(file_get_contents($file->getRealPath()), true);

        // Verifica se o nome está definido e não é um dos blocos a serem ignorados
        if (!isset($block_json['name'])) {
            continue;
        }

        $block_name = $block_json['name'];

        if (in_array($block_name, $excluir, true)) {
            continue;
        }

        // Extrai o slug final (ex: 'context-box' de 'wp24h/context-box')
        $slug = explode('/', $block_name)[1] ?? null;

        if (!$slug) {
            continue;
        }

        $asset_file = "{$dist_path}{$slug}.asset.php";
        $script_url = "{$dist_url}{$slug}.js";

        if (!file_exists($asset_file)) {
            continue;
        }

        $asset = include $asset_file;

        wp_register_script(
            "wp24h-{$slug}",
            $script_url,
            $asset['dependencies'],
            $asset['version']
        );

        register_block_type($block_dir, [
            'editor_script' => "wp24h-{$slug}"
        ]);
    }
}

✅ Resultado Final

  • O bloco context-box define uma cor de fundo.
  • O bloco context-label, posicionado dentro dele, lê essa cor via contexto e a exibe.
  • Nenhuma prop foi passada diretamente — tudo via contexto, limpo e reutilizável.

Navegação<< Blocos Reutilizáveis com InnerBlocks no GutenbergComo Criar Blocos Condicionais no Gutenberg com Atributos >>

Não perca mais nenhuma atualização aqui!

Ative as Notificações!

Clique aqui e, em seguida, clique em Permitir na caixa que aparecerá na parte superior da janela, próximo à barra de endereços.

Torne-se um Assinante e Eleve seu Conhecimento do WordPress!

Acesso Exclusivo, Suporte Especializado e Muito Mais.

Se você está aproveitando nosso conteúdo gratuito, vai adorar os benefícios exclusivos que oferecemos aos nossos assinantes! Ao se tornar um assinante do WP24Horas, você terá acesso a:

Não perca a oportunidade de maximizar seu potencial no WordPress. Clique no botão abaixo para se tornar um assinante e leve suas habilidades ao próximo nível!

Não perca mais nenhuma atualização aqui!

Tabela de Conteúdo
PUBLICIDADE
Últimos Posts
Listagem e Detalhes de Posts WordPress com API REST no Next.js

Listagem de Posts e Roteamento Dinâmico no Next.js

Frontend com Next.js - Setup e Integração Inicial com WordPress

Frontend com Next.js: Setup e Integração Inicial

Configurando o WordPress como Backend Headless

Configurando o WordPress como Backend Headless

REST API do WordPress

REST API do WordPress: Visão Geral

Introdução ao WordPress Headless

Introdução ao WordPress Headless

Como Distribuir Seus Blocos Gutenberg em Plugins ou no GitHub

Distribuindo Seus Blocos: Plugins, Repositório e GitHub

Você precisa estar logado para ver esta informação.

Torne-se um Assinante e Eleve seu Conhecimento do WordPress!

Acesso Exclusivo, Suporte Especializado e Muito Mais.

Se você está aproveitando nosso conteúdo gratuito, vai adorar os benefícios exclusivos que oferecemos aos nossos assinantes! 

Não perca a oportunidade de maximizar seu potencial no WordPress. Clique no botão abaixo para se tornar um assinante e leve suas habilidades ao próximo nível!