0
39

SHARE

Como Filtrar Posts por Categoria em um Bloco Gutenberg

Filtrando Posts por Categoria no Editor do Bloco

Aprenda a criar um bloco personalizado em WordPress que exibe os últimos posts com filtro por categoria. Ideal para projetos dinâmicos com Gutenberg
Este post é a parte 2 de 16 da Série WordPress Extremo: Gutenberg + React + Blocos Customizados

Hoje vamos aprimorar o bloco wp24h/posts, adicionando um controle no editor para que o usuário possa selecionar categorias específicas dos posts que serão listados. Isso exige:

  • Consultar as categorias via REST API
  • Usar o componente SelectControl no painel lateral do editor
  • Passar essa informação como atributo
  • Usar esse atributo no render_callback para exibir os posts filtrados

🧱 Estrutura esperada do bloco após esse dia:

blocks/
└── posts/
    ├── block.json
    ├── index.js
    ├── edit.js
    ├── save.js
    └── components/
        └── PostList.js
inc/
└── render/
    └── render-posts.php

🧩 Código do bloco atualizado:

block.json

{
  "apiVersion": 2,
  "name": "wp24h/posts",
  "title": "Lista de Posts WP24H",
  "category": "widgets",
  "icon": "list-view",
  "description": "Um bloco que exibe os últimos posts via REST API.",
  "attributes": {
    "quantidade": { "type": "number", "default": 3 },
    "categoria": { "type": "number", "default": 0 }
  },
  "supports": { "html": false }
}

edit.js

import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, RangeControl, SelectControl } from '@wordpress/components';
import { useState, useEffect } from '@wordpress/element';
import apiFetch from '@wordpress/api-fetch';
import PostList from './components/PostList';

export default function Edit({ attributes, setAttributes }) {
  const { quantidade = 3, categoria = 0 } = attributes;
  const [posts, setPosts] = useState([]);
  const [categorias, setCategorias] = useState([]);

  // Busca categorias (uma vez só)
  useEffect(() => {
    apiFetch({ path: '/wp/v2/categories' })
      .then((data) => setCategorias([{ id: 0, name: 'Todas' }, ...data]))
      .catch((err) => {
        console.error('Erro ao carregar categorias:', err);
        setCategorias([{ id: 0, name: 'Todas' }]);
      });
  }, []);

  // Busca posts sempre que quantidade ou categoria mudar
  useEffect(() => {
    const path = categoria === 0
      ? `/wp/v2/posts?per_page=${quantidade}`
      : `/wp/v2/posts?per_page=${quantidade}&categories=${categoria}`;

    apiFetch({ path })
      .then((data) => setPosts(data))
      .catch((err) => {
        console.error('Erro ao carregar posts:', err);
        setPosts([]);
      });
  }, [quantidade, categoria]);

  return (
    <>
      <InspectorControls>
        <PanelBody title="Configurações">
          <RangeControl
            label="Quantidade de posts"
            min={1}
            max={10}
            value={quantidade}
            onChange={(val) => setAttributes({ quantidade: val })}
          />
          <SelectControl
            label="Categoria"
            value={categoria}
            options={categorias.map((cat) => ({
              label: cat.name,
              value: cat.id
            }))}
            onChange={(val) => setAttributes({ categoria: parseInt(val) })}
          />
        </PanelBody>
      </InspectorControls>

      <div {...useBlockProps()}>
        <PostList posts={posts} />
      </div>
    </>
  );
}

render-posts.php

function wp24h_render_block_posts($attributes) {
    $qtd = isset($attributes['quantidade']) ? intval($attributes['quantidade']) : 3;
    $cat = isset($attributes['categoria']) ? intval($attributes['categoria']) : 0;

    $args = [
        'post_type' => 'post',
        'posts_per_page' => $qtd,
    ];

    if ($cat > 0) {
        $args['cat'] = $cat;
    }

    $query = new WP_Query($args);

    if (!$query->have_posts()) {
        return '<p>Sem posts recentes no momento.</p>';
    }

    ob_start();
    echo '<ul class="wp24h-post-list-frontend">';
    while ($query->have_posts()) {
        $query->the_post();
        echo '<li><a href="' . get_permalink() . '">' . get_the_title() . '</a></li>';
    }
    echo '</ul>';
    wp_reset_postdata();

    return ob_get_clean();
}

Navegação<< Bloco de Posts com Filtro por Múltiplas CategoriasBloco Dinâmico com Renderização no Servidor >>

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
Como Carregar Scripts e Estilos no WordPress Apenas Quando Necessário

Scripts e Estilos Condicionais: Carregando apenas quando necessário

Internacionalização de Blocos Gutenberg (i18n)

Internationalização de Blocos Gutenberg (i18n)

Como Criar Blocos Condicionais no Gutenberg com Atributos

Como Criar Blocos Condicionais no Gutenberg com Atributos

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

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

Blocos Reutilizáveis com InnerBlocks no Gutenberg

Blocos Reutilizáveis com InnerBlocks no Gutenberg

Como Salvar Dados Personalizados no WordPress Usando Blocos Gutenberg e REST API

Salvando Dados Personalizados no Backend via REST API

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!