He creado un plugin completo que te permitirá crear Custom Post Types desde el panel de administración, con sus propias categorías y páginas automáticas.. Aquí te explico cómo usarlo:
📦 Instalación:
- Crea una carpeta llamada
custom-post-type-creator
en/wp-content/plugins/
- Guarda el código en un archivo llamado
custom-post-type-creator.php
dentro de esa carpeta, https://gist.github.com/ximosa/85ec824c2a9d57cf4981638978bdb0bb
- Activa el plugin desde el panel de WordPress (Plugins → Plugins instalados)
✨ Características principales:
- Crear Post Types personalizados desde el admin con un formulario simple
- Categorías automáticas para cada Post Type creado
- URLs automáticas (ej:
tudominio.com/portafolio
) - Plantilla visual incluida para mostrar los posts en grid
- Gestión completa desde el panel de administración
🚀 Cómo usar:
- Ve a CPT Creator en el menú lateral del admin
- Rellena el formulario:
- Slug:
portafolio
(minúsculas, sin espacios) - Nombre Plural:
Portafolios
- Nombre Singular:
Portafolio
- Icono:
dashicons-portfolio
(opcional)
- Slug:
- Haz clic en Crear Post Type
- ¡Importante! Ve a Ajustes → Enlaces permanentes y haz clic en "Guardar" para actualizar las URLs
- Aparecerá un nuevo menú "Portafolios" en tu admin
- Crea tus posts y categorías desde ahí
- Visita
tudominio.com/portafolio
para ver todos los posts publicados
El plugin incluye una tabla donde verás:
- La URL donde se mostrarán los posts
- Enlaces directos para administrar posts y categorías
- Opción para eliminar Post Types
Puedes crear todos los Post Types que necesites, sin límite.
Cada vez que uses el formulario, se creará un nuevo Post Type completamente independiente:
Ejemplos de lo que podrías crear:
- Portafolio →
tudominio.com/portafolio
- Productos →
tudominio.com/productos
- Servicios →
tudominio.com/servicios
- Testimonios →
tudominio.com/testimonios
- Equipo →
tudominio.com/equipo
- Eventos →
tudominio.com/eventos
Cada uno tendrá:
- ✅ Su propio menú en el admin
- ✅ Sus propias categorías independientes
- ✅ Su propia URL de archivo
- ✅ Su propia gestión de posts
En la tabla del plugin verás todos listados:
Slug | Nombre | URL
------------|-------------|-------------------------
portafolio | Portafolios | tudominio.com/portafolio
productos | Productos | tudominio.com/productos
servicios | Servicios | tudominio.com/servicios
Y cada uno con sus botones para:
- Administrar (crear/editar posts)
- Ver Categorías (crear categorías propias)
- Eliminar (si ya no lo necesitas)
Todos quedan guardados en la base de datos y se cargan automáticamente cada vez que WordPress inicia.
Te voy a explicar cómo modificar el código para añadir campos personalizados. Te daré un ejemplo práctico y luego te enseño cómo replicarlo para otros campos.
📚 Conceptos básicos:
En WordPress, los campos personalizados se llaman "meta fields" y se guardan con funciones como add_meta_box()
y update_post_meta()
.
🎯 Ejemplo práctico: Añadir campo "Precio" a un Post Type
Te voy a mostrar el código que debes añadir y dónde exactamente colocarlo:
Guía: Cómo Añadir Campos Personalizados al Plugin
📍 PASO 1: Ubicar dónde añadir el código
Abre tu archivo custom-post-type-creator.php
y busca esta línea (está cerca del inicio):
add_action('template_redirect', array($this, 'custom_post_type_template'));
Justo debajo de esa línea, añade estos nuevos hooks:
add_action('add_meta_boxes', array($this, 'add_custom_meta_boxes'));
add_action('save_post', array($this, 'save_custom_meta_boxes'));
📍 PASO 2: Añadir las funciones al final del archivo
Busca el final de la clase (antes del último }
y antes de new Custom_Post_Type_Creator();
).
Ahí añade estas dos funciones:
Función 1: Crear el Meta Box (el formulario en el admin)
// Añadir Meta Boxes personalizados
public function add_custom_meta_boxes() {
global $wpdb;
// Obtener todos los Post Types creados
$custom_post_types = $wpdb->get_results("SELECT * FROM {$this->table_name}");
foreach ($custom_post_types as $cpt) {
// Añadir meta box para cada Post Type
add_meta_box(
$cpt->post_type_slug . '_custom_fields', // ID único
'Campos Personalizados', // Título del box
array($this, 'render_meta_box'), // Función que dibuja el formulario
$cpt->post_type_slug, // En qué Post Type aparece
'normal', // Posición (normal, side, advanced)
'high' // Prioridad
);
}
}
// Dibujar el formulario del Meta Box
public function render_meta_box($post) {
// Nonce para seguridad
wp_nonce_field('save_custom_fields', 'custom_fields_nonce');
// Obtener valores guardados
$precio = get_post_meta($post->ID, '_precio', true);
$ubicacion = get_post_meta($post->ID, '_ubicacion', true);
$fecha_evento = get_post_meta($post->ID, '_fecha_evento', true);
$destacado = get_post_meta($post->ID, '_destacado', true);
?>
<table class="form-table">
<tr>
<th><label for="precio">Precio</label></th>
<td>
<input type="text"
id="precio"
name="precio"
value="<?php echo esc_attr($precio); ?>"
class="regular-text">
<p class="description">Ejemplo: $99.00</p>
</td>
</tr>
<tr>
<th><label for="ubicacion">Ubicación</label></th>
<td>
<input type="text"
id="ubicacion"
name="ubicacion"
value="<?php echo esc_attr($ubicacion); ?>"
class="regular-text">
<p class="description">Ciudad, País</p>
</td>
</tr>
<tr>
<th><label for="fecha_evento">Fecha del Evento</label></th>
<td>
<input type="date"
id="fecha_evento"
name="fecha_evento"
value="<?php echo esc_attr($fecha_evento); ?>">
</td>
</tr>
<tr>
<th><label for="destacado">¿Destacado?</label></th>
<td>
<input type="checkbox"
id="destacado"
name="destacado"
value="1"
<?php checked($destacado, '1'); ?>>
<label for="destacado">Marcar como destacado</label>
</td>
</tr>
</table>
<?php
}
Función 2: Guardar los valores
// Guardar los valores de los campos personalizados
public function save_custom_meta_boxes($post_id) {
// Verificar nonce
if (!isset($_POST['custom_fields_nonce']) ||
!wp_verify_nonce($_POST['custom_fields_nonce'], 'save_custom_fields')) {
return;
}
// Verificar autoguardado
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// Verificar permisos
if (!current_user_can('edit_post', $post_id)) {
return;
}
// Guardar cada campo
if (isset($_POST['precio'])) {
update_post_meta($post_id, '_precio', sanitize_text_field($_POST['precio']));
}
if (isset($_POST['ubicacion'])) {
update_post_meta($post_id, '_ubicacion', sanitize_text_field($_POST['ubicacion']));
}
if (isset($_POST['fecha_evento'])) {
update_post_meta($post_id, '_fecha_evento', sanitize_text_field($_POST['fecha_evento']));
}
// Checkbox (si no está marcado, no viene en $_POST)
$destacado = isset($_POST['destacado']) ? '1' : '0';
update_post_meta($post_id, '_destacado', $destacado);
}
📍 PASO 3: Mostrar los campos en el frontend
Busca esta parte en la función custom_post_type_template()
:
<div class="cpt-excerpt" style="color: #666; margin-bottom: 15px;">
<?php the_excerpt(); ?>
</div>
Justo debajo, añade:
<?php
// Mostrar campos personalizados
$precio = get_post_meta(get_the_ID(), '_precio', true);
$ubicacion = get_post_meta(get_the_ID(), '_ubicacion', true);
$fecha_evento = get_post_meta(get_the_ID(), '_fecha_evento', true);
$destacado = get_post_meta(get_the_ID(), '_destacado', true);
?>
<?php if ($destacado == '1'): ?>
<span style="background: #ff6b6b; color: white; padding: 4px 10px; border-radius: 3px; font-size: 0.85em; font-weight: bold; margin-bottom: 10px; display: inline-block;">
⭐ DESTACADO
</span>
<?php endif; ?>
<div class="cpt-custom-fields" style="margin-bottom: 15px; font-size: 0.95em;">
<?php if ($precio): ?>
<p style="margin: 5px 0;"><strong>💰 Precio:</strong> <?php echo esc_html($precio); ?></p>
<?php endif; ?>
<?php if ($ubicacion): ?>
<p style="margin: 5px 0;"><strong>📍 Ubicación:</strong> <?php echo esc_html($ubicacion); ?></p>
<?php endif; ?>
<?php if ($fecha_evento): ?>
<p style="margin: 5px 0;"><strong>📅 Fecha:</strong> <?php echo date('d/m/Y', strtotime($fecha_evento)); ?></p>
<?php endif; ?>
</div>
🎨 TIPOS DE CAMPOS QUE PUEDES AÑADIR
Campo de Texto
<input type="text" name="nombre_campo" value="<?php echo esc_attr($valor); ?>">
Área de Texto (Textarea)
<textarea name="descripcion" rows="5" class="large-text"><?php echo esc_textarea($valor); ?></textarea>
Select (Lista desplegable)
<select name="estado">
<option value="activo" <?php selected($valor, 'activo'); ?>>Activo</option>
<option value="inactivo" <?php selected($valor, 'inactivo'); ?>>Inactivo</option>
</select>
Checkbox
<input type="checkbox" name="visible" value="1" <?php checked($valor, '1'); ?>>
Campo de Número
<input type="number" name="cantidad" value="<?php echo esc_attr($valor); ?>" min="0" step="1">
Campo de URL
<input type="url" name="sitio_web" value="<?php echo esc_url($valor); ?>" class="regular-text">
Campo de Email
<input type="email" name="correo" value="<?php echo esc_attr($valor); ?>" class="regular-text">
Campo de Fecha
<input type="date" name="fecha" value="<?php echo esc_attr($valor); ?>">
Campo de Color
<input type="color" name="color_fondo" value="<?php echo esc_attr($valor); ?>">
🔄 PLANTILLA PARA AÑADIR UN NUEVO CAMPO
Cada vez que quieras añadir un campo nuevo, sigue estos pasos:
1️⃣ Añadir en render_meta_box()
:
<tr>
<th><label for="NOMBRE_CAMPO">Etiqueta del Campo</label></th>
<td>
<input type="text"
id="NOMBRE_CAMPO"
name="NOMBRE_CAMPO"
value="<?php echo esc_attr(get_post_meta($post->ID, '_NOMBRE_CAMPO', true)); ?>"
class="regular-text">
<p class="description">Descripción de ayuda</p>
</td>
</tr>
2️⃣ Añadir en save_custom_meta_boxes()
:
if (isset($_POST['NOMBRE_CAMPO'])) {
update_post_meta($post_id, '_NOMBRE_CAMPO', sanitize_text_field($_POST['NOMBRE_CAMPO']));
}
3️⃣ Mostrar en el frontend:
<?php
$nombre_campo = get_post_meta(get_the_ID(), '_NOMBRE_CAMPO', true);
if ($nombre_campo):
?>
<p><strong>Etiqueta:</strong> <?php echo esc_html($nombre_campo); ?></p>
<?php endif; ?>
⚠️ IMPORTANTE: Funciones de sanitización
Según el tipo de dato, usa la función correcta:
- Texto general:
sanitize_text_field()
- Textarea:
sanitize_textarea_field()
- Email:
sanitize_email()
- URL:
esc_url_raw()
- Número:
intval()
ofloatval()
- HTML:
wp_kses_post()
(permite HTML seguro)
📦 EJEMPLO COMPLETO: Añadir campo "Galería de Imágenes"
Si quieres un campo más avanzado como una galería:
// En render_meta_box()
$galeria = get_post_meta($post->ID, '_galeria', true);
?>
<tr>
<th><label>Galería de Imágenes</label></th>
<td>
<input type="hidden" id="galeria" name="galeria" value="<?php echo esc_attr($galeria); ?>">
<button type="button" class="button" id="upload_galeria">Subir Imágenes</button>
<div id="galeria_preview"></div>
<script>
jQuery(document).ready(function($){
$('#upload_galeria').click(function(e) {
e.preventDefault();
var image = wp.media({
title: 'Seleccionar Imágenes',
multiple: true
}).open()
.on('select', function(e){
var uploaded_images = image.state().get('selection');
var ids = [];
uploaded_images.each(function(img) {
ids.push(img.id);
});
$('#galeria').val(ids.join(','));
});
});
});
</script>
</td>
</tr>
✅ RESUMEN RÁPIDO
- Añade los hooks al inicio de
__construct()
- Copia las dos funciones al final de la clase
- Personaliza los campos que necesites
- Muestra los valores en el frontend
- Guarda el archivo y recarga WordPress
¿Necesitas ayuda con algún campo específico? 😊
No hay comentarios:
Publicar un comentario