0
4

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 14 de 15 da Série WordPress Extremo

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 Dinâmico com Renderização no ServidorBloco de Posts com Filtro por Múltiplas Categorias >>

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 Criar um Bloco WordPress com Filtro por Múltiplas Categorias

Bloco de Posts com Filtro por Múltiplas Categorias

Como Criar um Bloco Dinâmico no WordPress com Renderização PHP

Bloco Dinâmico com Renderização no Servidor

Conectando Blocos Gutenberg à REST API

Conectando Blocos com a REST API do WordPress

Componentes Reutilizáveis e Campos Compostos no Gutenberg

Componentes Reutilizáveis e Atributos Compostos em Blocos Gutenberg

Adicionando Imagem Ícone e Classe CSS Personalizada em Bloco Gutenberg

Ícones, Imagens e Classes Personalizadas no Gutenberg

Atributos Visuais e Estilo Dinâmico com Gutenberg

Cor, Alinhamento e Estilo Dinâmico com Gutenberg + React

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!