📘 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
- Acesse o servidor via FTP ou File Manager.
- Navegue até a pasta
/wp-content/mu-plugins/(crie‑a se não existir). - Crie um arquivo chamado
simple-post-type-switcher.php. - Cole o código abaixo e salve.
- 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)
- Abra qualquer post ou página para edição.
- Role para baixo até a metabox “Publicar” (geralmente na coluna da direita).
- Você verá uma nova linha chamada “Tipo de conteúdo:” com um seletor.
- Escolha Post ou Página (dependendo do que você deseja).
- Clique em “Atualizar” ou “Publicar”. O tipo será alterado instantaneamente.
🔹 Na listagem (quick edit)
- Vá para Posts → Todos os posts ou Páginas → Todas as páginas.
- Passe o mouse sobre o título do item que deseja converter.
- Abaixo das opções “Editar”, “Lixeira”, etc., aparecerá um novo link: “Converter para Página” ou “Converter para Post”.
- 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_typeno 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
noncee verificação de capacidadeedit_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! 🚀