0
172

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 20 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
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!