¿Te gustaría extender las funcionalidades de WordPress más allá de entradas y páginas? Los Custom Post Types (CPT) son una herramienta poderosa que permite transformar tu sitio web en cualquier tipo de aplicación o plataforma personalizada: desde directorios hasta portafolios, catálogos, cursos, paquetes de servicios y más.
En esta guía completa aprenderás:
Qué son los CPT y por qué son importantes.
Cuándo y para qué deberías usarlos.
Cómo crearlos (con plugins o manualmente con código).
Posibles errores comunes y cómo solucionarlos.
Consejos y mejores prácticas.
Ejemplos prácticos.
¿Qué son los Custom Post Types (CPT) en WordPress?
Un Custom Post Type (CPT) es un tipo de contenido personalizado que puedes registrar en WordPress para mostrar información que no encaja dentro del formato tradicional de entradas o páginas.
Por ejemplo:
Un sitio de bienes raíces podría usar un CPT llamado «Propiedades».
Un restaurante podría crear un CPT llamado «Menú».
Una agencia de viajes podría usar un CPT llamado «Paquetes».
WordPress, por defecto, incluye tipos de contenido como:
post
(entradas de blog)page
(páginas)attachment
(archivos multimedia)
Los CPT permiten ampliar esa funcionalidad sin modificar el núcleo de WordPress.
¿Cuándo usar un Custom Post Type?
Usa un CPT cuando:
Necesitas un tipo de contenido con su propia interfaz de administración.
Quieres organizar contenidos que no son entradas ni páginas.
Requieres campos personalizados, taxonomías o funcionalidades específicas.
Beneficios:
Organización clara y escalable.
Separación lógica de contenidos.
Mejor experiencia de usuario en la administración.
Facilita SEO al tener URL limpias y estructuradas.
Desventajas (si no se usan correctamente):
Complejidad en la estructura si se abusa.
Requiere conocimientos técnicos si se hace con código.
Posibles conflictos con plugins o temas mal desarrollados.
¿Cómo crear un CPT en WordPress?
Tienes dos formas principales:
1. Usar un plugin (fácil y rápido)
Plugins como:
Permiten crear CPTs sin tocar código. Solo debes:
Instalar el plugin.
Acceder a su interfaz.
Crear el nuevo tipo de contenido.
Definir etiquetas, capacidades y características.
2. Usar código PHP (control total y profesional)
Si prefieres tener el control absoluto del comportamiento de tu CPT o estás desarrollando un tema/plugin personalizado, puedes registrar tu Custom Post Type manualmente desde el archivo functions.php
o en un plugin personalizado.
A continuación, te mostramos un ejemplo completo de cómo registrar un CPT llamado «Package»:
if ( ! function_exists('custom_post_type_Package') ) {
// Register Custom Post Type
function custom_post_type_Package() {
$labels = array(
'name' => _x( 'Packages', 'Post Type General Name', 'text_domain' ),
'singular_name' => _x( 'Package', 'Post Type Singular Name', 'text_domain' ),
'menu_name' => __( 'Packages', 'text_domain' ),
'name_admin_bar' => __( 'Packages', 'text_domain' ),
'archives' => __( 'Archives', 'text_domain' ),
'attributes' => __( 'Atributes', 'text_domain' ),
'parent_item_colon' => __( 'Parent:', 'text_domain' ),
'all_items' => __( 'All Packages', 'text_domain' ),
'add_new_item' => __( 'Add new Package', 'text_domain' ),
'add_new' => __( 'Add new', 'text_domain' ),
'new_item' => __( 'New Package', 'text_domain' ),
'edit_item' => __( 'Edit Package', 'text_domain' ),
'update_item' => __( 'Update Package', 'text_domain' ),
'view_item' => __( 'View Package', 'text_domain' ),
'view_items' => __( 'View Packages', 'text_domain' ),
'search_items' => __( 'Search Package', 'text_domain' ),
'not_found' => __( 'Not found', 'text_domain' ),
'not_found_in_trash' => __( 'Not found in trash', 'text_domain' ),
'featured_image' => __( 'Featured image', 'text_domain' ),
'set_featured_image' => __( 'Select featured image', 'text_domain' ),
'remove_featured_image' => __( 'Delete featured image', 'text_domain' ),
'use_featured_image' => __( 'Use as featured image', 'text_domain' ),
'insert_into_item' => __( 'Insert', 'text_domain' ),
'uploaded_to_this_item' => __( 'Upload', 'text_domain' ),
'items_list' => __( 'List', 'text_domain' ),
'items_list_navigation' => __( 'Navigation list', 'text_domain' ),
'filter_items_list' => __( 'Filterr', 'text_domain' ),
);
$args = array(
'label' => __( 'Package', 'text_domain' ),
'description' => __( 'CPT Packages', 'text_domain' ),
'labels' => $labels,
'supports' => array( 'title', 'editor', 'author', 'excerpt', 'thumbnail', 'revisions', ),
/*'taxonomies' => array( 'category', 'post_tag' ),*/
'menu_icon' => 'dashicons-admin-home',
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'page',
'show_in_rest' => true,
);
register_post_type( 'Package', $args );
register_taxonomy(
"package-category",
array("package"),
array(
"hierarchical" => true,
"label" => "Categories",
"singular_label" => "Category",
"rewrite" => array(
'slug' => 'package-category',
'with_front'=> false
)
)
);
}
add_action( 'init', 'custom_post_type_Package', 0 );
}
Explicación del código línea por línea:
if ( ! function_exists('custom_post_type_Package') )
: Asegura que la función no se declare más de una vez.function custom_post_type_Package() { … }
: Declara la función encargada de registrar el CPT.$labels
: Define todos los textos que aparecerán en el admin de WordPress para este CPT. Esto incluye el nombre en singular, plural, textos para botones, menú, etc.$args
: Contiene la configuración del CPT:'label'
y'description'
: Nombre y descripción general.'supports'
: Funcionalidades habilitadas (editor, imagen destacada, autor, etc.).'menu_icon'
: Ícono que se mostrará en el panel lateral (en este caso, una casa).'public'
,'show_ui'
,'has_archive'
: Controlan la visibilidad del CPT en el sitio y en el admin.'show_in_rest' => true
: Habilita soporte para el editor de bloques (Gutenberg) y API REST.
register_post_type( 'Package', $args )
: Registra el Custom Post Type con los argumentos definidos.register_taxonomy(...)
: Registra una taxonomía personalizada llamadapackage-category
asociada al CPTpackage
, que se comporta como una categoría jerárquica.
Importante: Aunque el register_post_type
usa 'Package'
con mayúscula, internamente se recomienda en producción usarlo en minúsculas ('package'
) para evitar conflictos con las URLs. Asegúrate también de visitar Ajustes > Enlaces permanentes > Guardar cambios después de registrar un nuevo CPT, para evitar errores 404.
Errores comunes al crear CPT y cómo solucionarlos
Error | Solución |
---|---|
El CPT no aparece en el admin | Asegúrate de que show_ui y show_in_menu estén en true . |
No aparece en el front-end | Revisa que public y has_archive estén activados. |
No aparece en el editor de bloques | Activa show_in_rest . |
Problemas con URLs | Vuelve a guardar los enlaces permanentes en Ajustes > Enlaces Permanentes. |
Mejores prácticas al usar CPT
Usa nombres en minúsculas y sin espacios:
portafolio
,servicio
,proyecto
.Registra taxonomías personalizadas para categorizar tu contenido.
Usa
show_in_rest
para habilitar soporte Gutenberg y la API REST.Si usas código, colócalo en el archivo
functions.php
del tema hijo o mejor aún, crea un plugin personalizado.Limpia los rewrites cada vez que registres un nuevo CPT (
flush_rewrite_rules()
solo una vez).
Ejemplo práctico: Sitio de Agencia de Viajes
CPT: Packages
Taxonomía: Países o Tipo de viaje (aventura, cultural, lujo)
Campos personalizados:
Precio
Fecha de salida
Duración
Imagen destacada
Ventajas:
Gestión ordenada
Fácil navegación para usuarios
SEO mejorado por URLs personalizadas como:
digitalsolutionsnetwork.com/package/aventura-machu-picchu
Los Custom Post Types en WordPress son herramientas fundamentales para construir sitios web avanzados, organizados y escalables. Ya sea que los crees con plugins o manualmente, aprender a usarlos correctamente te abre las puertas al desarrollo web profesional.
Si estás buscando personalizar tu sitio WordPress o desarrollar una solución a medida, en Digital Solutions Network podemos ayudarte. Contáctanos y da el siguiente paso hacia un sitio web optimizado y funcional.