[MU] Converte posts em páginas (e vice-versa)

📘 Aula: MU-Plugin “Simple Post Type Switcher” – Converta posts em páginas (e vice-versa) com um clique

Nesta aula, vamos construir um MU-Plugin extremamente leve e prático que adiciona a funcionalidade de alternar entre os tipos post e page diretamente na tela de edição e também na listagem (quick edit).

O código é limpo, não usa JavaScript pesado, não carrega CSS extra e funciona perfeitamente no ambiente Multisite. Ele é ideal para organizar conteúdo importado ou para ajustes pontuais na estrutura do site.


🎯 O que o plugin faz?

  • Adiciona um seletor de tipo dentro da metabox “Publicar”, ao lado do botão de atualização.
  • Permite converter um post em página ou uma página em post com apenas um clique.
  • Oferece também um link “Converter” diretamente na listagem de posts/páginas, eliminando a necessidade de abrir o editor.
  • Preserva metadados, comentários, taxonomias e dados do Elementor (a única coisa que muda é o tipo de post).

📁 Instalação

  1. Acesse o servidor via FTP ou File Manager.
  2. Navegue até a pasta /wp-content/mu-plugins/ (crie‑a se não existir).
  3. Crie um arquivo chamado simple-post-type-switcher.php.
  4. Cole o código abaixo e salve.
  5. Pronto! O plugin será carregado automaticamente em toda a rede – nenhuma ativação é necessária.

🧩 Código completo do MU-Plugin

<?php
/**
 * Plugin Name: Simple Post Type Switcher (Post ↔ Page)
 * Description: Adiciona um seletor para converter posts em páginas (e vice-versa) na tela de edição.
 * Version: 1.0
 * Author: Reinaldo (Neodoor)
 *
 * Este MU‑Plugin NÃO usa jQuery, NÃO carrega CSS extra e NÃO polui o banco de dados.
 * Funciona com o Editor Clássico e com o Gutenberg.
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit; // Bloqueia acesso direto.
}

// ==================================================
// 1. Adiciona o seletor de tipo de post na metabox "Publicar"
// ==================================================
add_action( 'post_submitbox_misc_actions', 'neodoor_pt_switcher_submitbox' );

function neodoor_pt_switcher_submitbox() {
    global $post;

    // Apenas para posts que já existem (evita exibir na criação).
    if ( $post->post_status == 'auto-draft' ) {
        return;
    }

    // Tipos de post permitidos: apenas 'post' e 'page'.
    $allowed_types = array( 'post', 'page' );
    if ( ! in_array( $post->post_type, $allowed_types ) ) {
        return;
    }

    // Define o rótulo oposto para exibir no seletor.
    $new_type = ( $post->post_type === 'post' ) ? 'page' : 'post';
    $label    = ( $new_type === 'page' ) ? 'Página' : 'Post';

    // Gera o HTML do seletor.
    ?>
    <div class="misc-pub-section misc-pub-post-type-switcher">
        <label for="neodoor_pt_switch">Tipo de conteúdo:</label>
        <select name="neodoor_pt_switch" id="neodoor_pt_switch">
            <option value="<?php echo esc_attr( $post->post_type ); ?>" selected="selected">
                <?php echo esc_html( ucfirst( $post->post_type ) ); ?>
            </option>
            <option value="<?php echo esc_attr( $new_type ); ?>">
                <?php echo esc_html( $label ); ?>
            </option>
        </select>
        <?php wp_nonce_field( 'neodoor_pt_switch_action', 'neodoor_pt_switch_nonce' ); ?>
    </div>
    <?php
}

// ==================================================
// 2. Salva a alteração do tipo de post quando o post é atualizado
// ==================================================
add_action( 'save_post', 'neodoor_pt_switcher_save', 10, 2 );

function neodoor_pt_switcher_save( $post_id, $post ) {
    // Impede execução em autosave, revisão ou quando não há nonce.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
        return;
    }
    if ( wp_is_post_revision( $post_id ) ) {
        return;
    }
    if ( ! isset( $_POST['neodoor_pt_switch_nonce'] ) ||
         ! wp_verify_nonce( $_POST['neodoor_pt_switch_nonce'], 'neodoor_pt_switch_action' ) ) {
        return;
    }

    // Verifica se o usuário tem permissão.
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        return;
    }

    // Captura o novo tipo de post selecionado.
    $new_type = isset( $_POST['neodoor_pt_switch'] ) ? sanitize_text_field( $_POST['neodoor_pt_switch'] ) : '';
    if ( empty( $new_type ) ) {
        return;
    }

    // Permite apenas os tipos 'post' e 'page'.
    if ( ! in_array( $new_type, array( 'post', 'page' ) ) ) {
        return;
    }

    // Se o tipo não mudou, não faz nada.
    if ( $new_type === $post->post_type ) {
        return;
    }

    // Atualiza o tipo de post diretamente no banco.
    global $wpdb;
    $wpdb->update(
        $wpdb->posts,
        array( 'post_type' => $new_type ),
        array( 'ID' => $post_id ),
        array( '%s' ),
        array( '%d' )
    );

    // Limpa o cache do post para evitar inconsistências.
    clean_post_cache( $post_id );
}

// ==================================================
// 3. Adiciona o link "Converter" na listagem (Quick Edit)
//    (Opcional – extremamente leve, sem jQuery)
// ==================================================
add_filter( 'post_row_actions', 'neodoor_pt_switcher_quick_link', 10, 2 );
add_filter( 'page_row_actions', 'neodoor_pt_switcher_quick_link', 10, 2 );

function neodoor_pt_switcher_quick_link( $actions, $post ) {
    // Apenas para 'post' e 'page'.
    if ( ! in_array( $post->post_type, array( 'post', 'page' ) ) ) {
        return $actions;
    }

    // Monta a URL de conversão (usa o próprio admin-post.php).
    $url = add_query_arg(
        array(
            'action'   => 'neodoor_pt_quick_switch',
            'post_id'  => $post->ID,
            'new_type' => ( $post->post_type === 'post' ) ? 'page' : 'post',
            '_wpnonce' => wp_create_nonce( 'neodoor_pt_quick_switch_' . $post->ID ),
        ),
        admin_url( 'admin-post.php' )
    );

    $actions['neodoor_pt_switch'] = sprintf(
        '<a href="%s" style="color: #0073aa;">Converter para %s</a>',
        esc_url( $url ),
        ( $post->post_type === 'post' ) ? 'Página' : 'Post'
    );

    return $actions;
}

// ==================================================
// 4. Processa a conversão via link rápido (admin-post.php)
// ==================================================
add_action( 'admin_post_neodoor_pt_quick_switch', 'neodoor_pt_quick_switch_handler' );

function neodoor_pt_quick_switch_handler() {
    // Verifica o nonce.
    if ( empty( $_GET['_wpnonce'] ) || empty( $_GET['post_id'] ) || empty( $_GET['new_type'] ) ) {
        wp_die( 'Requisição inválida.' );
    }

    $post_id = intval( $_GET['post_id'] );
    if ( ! wp_verify_nonce( $_GET['_wpnonce'], 'neodoor_pt_quick_switch_' . $post_id ) ) {
        wp_die( 'Falha de segurança. Tente novamente.' );
    }

    // Verifica permissão.
    if ( ! current_user_can( 'edit_post', $post_id ) ) {
        wp_die( 'Você não tem permissão para editar este conteúdo.' );
    }

    $new_type = sanitize_text_field( $_GET['new_type'] );
    if ( ! in_array( $new_type, array( 'post', 'page' ) ) ) {
        wp_die( 'Tipo de post inválido.' );
    }

    // Atualiza o tipo de post.
    global $wpdb;
    $wpdb->update(
        $wpdb->posts,
        array( 'post_type' => $new_type ),
        array( 'ID' => $post_id ),
        array( '%s' ),
        array( '%d' )
    );

    clean_post_cache( $post_id );

    // Redireciona de volta para a tela de listagem.
    $referer = wp_get_referer();
    if ( ! $referer ) {
        $referer = admin_url( 'edit.php' );
    }
    wp_safe_redirect( $referer );
    exit;
}

📌 Como usar

🔹 Na tela de edição (post ou página)

  1. Abra qualquer post ou página para edição.
  2. Role para baixo até a metabox “Publicar” (geralmente na coluna da direita).
  3. Você verá uma nova linha chamada “Tipo de conteúdo:” com um seletor.
  4. Escolha Post ou Página (dependendo do que você deseja).
  5. Clique em “Atualizar” ou “Publicar”. O tipo será alterado instantaneamente.

🔹 Na listagem (quick edit)

  1. Vá para Posts → Todos os posts ou Páginas → Todas as páginas.
  2. Passe o mouse sobre o título do item que deseja converter.
  3. Abaixo das opções “Editar”, “Lixeira”, etc., aparecerá um novo link: “Converter para Página” ou “Converter para Post”.
  4. Clique no link. O item será convertido e você será redirecionado de volta para a listagem.

🧹 Boas práticas e recomendações

  • Preservação de dados: O plugin altera apenas a coluna post_type no banco de dados. Todos os metadados, taxonomias e configurações do Elementor permanecem intactos.
  • ⚠️ Cuidado com URLs: Converta apenas itens recentes ou que não tenham sido amplamente indexados. A URL original deixará de existir – use redirecionamentos 301 se necessário.
  • 🔒 Segurança: O código utiliza nonce e verificação de capacidade edit_post, garantindo que apenas usuários autorizados possam realizar a conversão.

✅ Conclusão

Este MU-Plugin é o exemplo perfeito do que pregamos: simples, funcional e sem firulas. Ele resolve uma necessidade real (reorganização de conteúdo) sem a complexidade dos plugins comerciais e sem propagandas. Ideal para seu caderno de estudos e para uso em qualquer site da rede.

Arquivo final: /wp-content/mu-plugins/simple-post-type-switcher.php

Agora você tem uma ferramenta poderosa e minimalista para gerenciar seus tipos de post. Basta instalar e começar a usar! 🚀

Média: 2.9 (48 votos)