[MU] Dashboard Custom Feed

Aula: Feed RSS Personalizado no Dashboard com MU-Plugin – Substituindo o Dashboard Custom Feed

Objetivo: Substituir o plugin dashboard-custom-feed por um MU-Plugin enxuto, que adiciona um widget personalizado ao painel administrativo do WordPress exibindo notícias ou atualizações a partir de um feed RSS, sem sobrecarga e com total controle sobre a exibição.

Contexto: Muitos sites utilizam o dashboard-custom-feed para criar um canal de comunicação com o cliente ou equipe diretamente no admin, ou para promover conteúdo relevante. No entanto, trata-se de um plugin desatualizado (não testado nas versões recentes do WordPress) que frequentemente depende de um plugin irmão (dashboard-custom-feed-admin) para criar o feed. Vamos consolidar essa funcionalidade em um único MU-Plugin simples, que lê qualquer feed RSS externo (ou interno) e o exibe no dashboard com formatação elegante.

Funcionalidades implementadas no nosso MU-Plugin

  • Adiciona um widget personalizado à tela inicial do painel administrativo.
  • Exibe itens de qualquer feed RSS (URL configurável diretamente no código).
  • Controla número de itens, exibição de resumo, data e autor.
  • Utiliza sistema de cache nativo do WordPress (fetch_feed), que armazena o feed por 12 horas para reduzir requisições externas.
  • Inclui tratamento de erro amigável caso o feed não esteja acessível.
  • Design responsivo e integrado ao estilo padrão do dashboard.

Código do MU-Plugin

Crie a pasta wp-content/mu-plugins/neodoor-dashboard-feed/ e dentro dela o arquivo neodoor-dashboard-feed.php com o conteúdo abaixo:

<?php
/**
 * Plugin Name:  Neodoor Dashboard Custom Feed
 * Description:  Adiciona um widget personalizado ao dashboard com feed RSS (notícias, atualizações).
 * Version:      1.0
 * Author:       Reinaldo (Neodoor.neo)
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

class Neodoor_Dashboard_Feed {

    private static $instance = null;

    // Configuração do feed – edite os valores conforme sua necessidade
    private $feed_url = 'https://wordpress.org/news/feed/'; // URL do feed RSS
    private $widget_title = 'Neodoor – Notícias e Atualizações'; // Título do widget
    private $items = 5;          // Número de itens a exibir
    private $show_summary = 1;   // Exibir resumo? 1 = sim, 0 = não
    private $show_author = 0;    // Exibir autor? 1 = sim, 0 = não
    private $show_date = 1;      // Exibir data? 1 = sim, 0 = não

    public static function get_instance() {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        add_action( 'wp_dashboard_setup', [ $this, 'add_dashboard_widget' ] );
    }

    /**
     * Registra o widget no dashboard
     */
    public function add_dashboard_widget() {
        wp_add_dashboard_widget(
            'neodoor_dashboard_feed_widget', // ID único do widget
            $this->widget_title,             // Título exibido
            [ $this, 'render_widget_output' ] // Função que exibe o conteúdo
        );
    }

    /**
     * Renderiza o conteúdo do widget: exibe o feed RSS
     */
    public function render_widget_output() {
        // Utiliza a função nativa fetch_feed (com cache de 12 horas)
        $rss = fetch_feed( $this->feed_url );

        if ( is_wp_error( $rss ) ) {
            // Exibe mensagem amigável em caso de erro (feed offline, URL inválida)
            echo '<div class="error"><p>Não foi possível carregar o feed de notícias. Verifique a URL ou tente novamente mais tarde.</p></div>';
            return;
        }

        // Limita o número de itens conforme configurado
        $max_items = $rss->get_item_quantity( $this->items );
        $rss_items = $rss->get_items( 0, $max_items );

        if ( empty( $rss_items ) ) {
            echo '<p>Nenhum item encontrado no feed.</p>';
            return;
        }

        // Abre o container com a classe padrão do WordPress para widgets RSS
        echo '<div class="rss-widget">';

        // Itera sobre os itens e exibe cada um
        foreach ( $rss_items as $item ) {
            $item_link = esc_url( $item->get_link() );
            $item_title = esc_html( $item->get_title() );
            $item_date = $item->get_date( 'U' );
            $item_author = $item->get_author();
            $author_name = $item_author ? esc_html( $item_author->get_name() ) : '';

            echo '<div class="rss-widget-item">';
            echo '<h4><a href="' . $item_link . '" target="_blank">' . $item_title . '</a></h4>';

            if ( $this->show_date && $item_date ) {
                echo '<p class="rss-date">' . date_i18n( get_option( 'date_format' ), $item_date ) . '</p>';
            }

            if ( $this->show_author && ! empty( $author_name ) ) {
                echo '<p class="rss-author">Por ' . $author_name . '</p>';
            }

            if ( $this->show_summary ) {
                $description = $item->get_description();
                if ( $description ) {
                    // Limita o resumo a 120 palavras (pode ajustar)
                    $excerpt = wp_trim_words( $description, 120, ' [...]' );
                    echo '<p class="rss-summary">' . esc_html( $excerpt ) . '</p>';
                }
            }

            echo '</div>';
        }

        echo '</div>';
    }
}

Neodoor_Dashboard_Feed::get_instance();

Instruções de instalação

  1. Certifique-se de que o autoloader loader.php esteja presente em /wp-content/mu-plugins/ (conforme aula anterior).
  2. Crie a pasta neodoor-dashboard-feed dentro de /wp-content/mu-plugins/.
  3. Dentro dela, crie o arquivo neodoor-dashboard-feed.php e cole o código acima.
  4. Desative e remova o plugin dashboard-custom-feed da lista de plugins (bem como qualquer plugin complementar como dashboard-custom-feed-admin).

Configuração do feed

Para personalizar o feed e a aparência do widget, edite as propriedades privadas no início da classe:

private $feed_url = 'https://wordpress.org/news/feed/';   // URL do feed RSS
private $widget_title = 'Neodoor – Notícias e Atualizações'; // Título do widget
private $items = 5;          // Número de itens a exibir
private $show_summary = 1;   // Exibir resumo? 1 = sim, 0 = não
private $show_author = 0;    // Exibir autor? 1 = sim, 0 = não
private $show_date = 1;      // Exibir data? 1 = sim, 0 = não

Por exemplo, para exibir os últimos 3 posts do seu próprio site (cujo feed geralmente está em https://seudominio.com/feed/), basta alterar as configurações acima.

Cache e performance

O WordPress utiliza a função fetch_feed(), que armazena o feed em cache por padrão durante 12 horas, evitando requisições repetitivas ao servidor de origem e melhorando a performance do dashboard[reference:0]. Para alterar esse intervalo (por exemplo, para forçar atualização a cada hora), você pode adicionar o seguinte filtro em um MU-Plugin separado ou no próprio arquivo:

add_filter( 'wp_feed_cache_transient_lifetime', function( $seconds ) {
    return 3600; // 1 hora em segundos
} );

Tratamento de erros e fallback

Se o feed estiver indisponível (servidor fora do ar, URL incorreta), o widget exibe uma mensagem amigável em vez de quebrar o layout do dashboard. O mesmo ocorre se o feed estiver vazio ou se houver qualquer outro erro.

Teste

  1. Após criar o MU-Plugin, acesse o dashboard administrativo do WordPress (Painel → Início).
  2. Você verá um novo widget, geralmente posicionado na coluna da esquerda ou direita, com o título configurado (padrão: “Neodoor – Notícias e Atualizações”).
  3. O widget deve listar os últimos 5 posts do feed do WordPress.org, com título, data e resumo (conforme sua configuração).
  4. Teste a alteração da URL do feed para o feed RSS de outro site (ex: seu próprio site).
  5. Para simular um erro, altere temporariamente a URL do feed para um endereço inválido – o widget exibirá a mensagem de erro.

Possíveis melhorias e variações

  • Suporte a múltiplos feeds: Para exibir feeds de várias fontes, adapte o código para iterar sobre um array de URLs, chamando fetch_feed() para cada uma e mesclando os itens.
  • Link “Ver mais” ao final: Adicione um link para o site de origem do feed.
  • Permitir que o usuário configure a URL via tela de opções: Em vez de fixar no código, crie uma página de configurações usando a API de Opções do WordPress.
  • Ícone ou imagem destacada: Se o feed incluir imagens, você pode exibi-las usando expressões regulares ou bibliotecas de parsing.

Comparação com o plugin original

Nosso MU-Plugin substitui as principais funções do dashboard-custom-feed, com as seguintes vantagens:

  • Sem dependências externas: Não requer um plugin separado para criar/gerenciar o feed.
  • Leve e transparente: O código é curto e visível, sem sobrecarga de CSS/JS desnecessários.
  • Atualizado: Funciona perfeitamente nas versões mais recentes do WordPress (6.x).
  • Controle total: Você decide exatamente o que exibir e como formatar.

Observações finais

  • Feed deve estar ativo: O site de origem do feed precisa ter o RSS habilitado; caso contrário, o widget não conseguirá recuperar os dados[reference:1].
  • Cache inicial: Ao instalar ou alterar a URL do feed, o WordPress pode demorar até 12 horas para exibir os novos itens (a menos que você limpe o cache de transients). Para forçar a atualização imediata, utilize um plugin de limpeza de cache ou execute o seguinte comando WP-CLI: wp transient delete --all.
  • Segurança: As funções esc_url(), esc_html() e wp_trim_words() garantem que o conteúdo exibido seja seguro, prevenindo injeção de código malicioso através do feed.
  • Personalização CSS: Você pode adicionar estilos personalizados para o widget usando o gancho admin_head ou editando o arquivo admin.css do tema, caso queira alterar cores, fontes ou espaçamentos.

Registro no caderno

Data:

Funcionalidade: Feed RSS personalizado no painel administrativo

Plugins substituídos: dashboard-custom-feed (e dashboard-custom-feed-admin, se instalado)

Tempo de implementação: ~10 minutos (configuração e testes)

Observação: O feed padrão aponta para wordpress.org/news; lembre-se de alterar para a URL desejada antes de colocar em produção.

Média: 3.2 (24 votos)