Pulsa ESC para cerrar

Curso WordpressCurso Wordpress

Tipos de contenido personalizados sin plugins: crea una sección «Recursos» con register_post_type

WordPress trae dos tipos de contenido principales: entradas y páginas. Pero muchos sitios necesitan otros: productos, eventos, cursos, recetas, proyectos de un portafolio. Meterlos como entradas en una categoría funciona a medias: se mezclan con el blog, comparten plantilla y se desordenan.

La solución son los tipos de contenido personalizados (Custom Post Types o CPT). WooCommerce los usa para los productos y bbPress para los foros y debates. Hoy creamos el nuestro: una sección de Recursos (herramientas, plantillas y descargas recomendadas), con su propio menú en el panel y su propia dirección: tudominio.cl/recursos/.

Antes de empezar

  • Trabaja en un sitio de pruebas.
  • Pondremos el código en un plugin propio, no en el functions.php del tema. ¿Por qué? Si algún día cambias de tema, tus recursos no deben desaparecer. El contenido es del sitio, no del diseño.

Paso 1. Crea el plugin

En wp-content/plugins, crea la carpeta cwp-recursos y dentro el archivo cwp-recursos.php:

<?php
/**
 * Plugin Name: CWP Recursos
 * Description: Tipo de contenido "Recursos" para el sitio.
 * Version:     1.0.0
 * License:     GPL-2.0-or-later
 */

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

Paso 2. Registra el tipo de contenido

Agrega debajo:

add_action( 'init', 'cwp_recursos_registrar' );

function cwp_recursos_registrar() {
	$etiquetas = array(
		'name'               => 'Recursos',
		'singular_name'      => 'Recurso',
		'add_new'            => 'Añadir nuevo',
		'add_new_item'       => 'Añadir nuevo recurso',
		'edit_item'          => 'Editar recurso',
		'new_item'           => 'Nuevo recurso',
		'view_item'          => 'Ver recurso',
		'search_items'       => 'Buscar recursos',
		'not_found'          => 'No se encontraron recursos',
		'not_found_in_trash' => 'No hay recursos en la papelera',
		'all_items'          => 'Todos los recursos',
		'menu_name'          => 'Recursos',
	);

	register_post_type(
		'cwp_recurso',
		array(
			'labels'       => $etiquetas,
			'public'       => true,
			'has_archive'  => 'recursos',
			'rewrite'      => array( 'slug' => 'recursos', 'with_front' => false ),
			'menu_icon'    => 'dashicons-portfolio',
			'menu_position' => 5,
			'supports'     => array( 'title', 'editor', 'excerpt', 'thumbnail', 'revisions' ),
			'show_in_rest' => true,
		)
	);
}

Activa el plugin. En el panel aparece un menú nuevo, Recursos, con su propio icono, justo debajo de Entradas.

Qué significa cada opción

  • 'cwp_recurso': el nombre interno. Máximo 20 caracteres, minúsculas y guiones bajos. Lleva prefijo para no chocar con otro plugin. No lo cambies después: los recursos ya creados quedarían «huérfanos».
  • labels: los textos que se ven en el panel. Sin ellos, WordPress mostraría «Entradas» en todas partes.
  • public: visible en el sitio y en el panel.
  • has_archive: crea una página que lista todos los recursos, en /recursos/.
  • rewrite: la dirección de cada recurso será /recursos/nombre-del-recurso/.
  • menu_icon: un icono de la colección Dashicons de WordPress (búscalos en developer.wordpress.org/resource/dashicons).
  • supports: qué cajas tiene el editor: título, contenido, extracto, imagen destacada, revisiones.
  • show_in_rest: imprescindible para usar el editor de bloques. Sin esto, el CPT se edita con el editor clásico.

Paso 3. Actualiza los enlaces permanentes

Crea un recurso de prueba y ábrelo. Si ves un error 404, es normal: WordPress todavía no conoce las direcciones nuevas. Ve a Ajustes → Enlaces permanentes y pulsa Guardar cambios sin cambiar nada. Ahora sí funciona.

Para que eso pase solo al activar el plugin, agrega:

register_activation_hook( __FILE__, 'cwp_recursos_activar' );

function cwp_recursos_activar() {
	cwp_recursos_registrar();
	flush_rewrite_rules();
}

register_deactivation_hook( __FILE__, 'flush_rewrite_rules' );

flush_rewrite_rules() es una operación pesada. Úsala solo al activar o desactivar, nunca dentro de init, o pondrás lento todo el sitio.

Paso 4. ¿Cómo se ven en el sitio?

WordPress elige la plantilla del tema siguiendo una jerarquía. Para nuestros recursos:

  • Un recurso individual: busca single-cwp_recurso.php; si no existe, usa single.php.
  • El listado /recursos/: busca archive-cwp_recurso.php; si no existe, usa archive.php.

Así que, sin hacer nada, tus recursos se verán como las entradas del tema. Si quieres un diseño distinto, crea esas plantillas en tu tema hijo, copiando single.php como punto de partida. En un tema de bloques, se crean desde Apariencia → Editor → Plantillas.

Paso 5. Muestra los últimos recursos en cualquier lugar

Con un tipo de contenido propio, puedes consultar solo esos contenidos. Este shortcode lista los 5 más recientes:

add_shortcode( 'ultimos_recursos', 'cwp_recursos_lista' );

function cwp_recursos_lista() {
	$consulta = new WP_Query(
		array(
			'post_type'      => 'cwp_recurso',
			'posts_per_page' => 5,
			'no_found_rows'  => true,
		)
	);

	if ( ! $consulta->have_posts() ) {
		return '';
	}

	$html = '<ul class="cwp-recursos">';
	while ( $consulta->have_posts() ) {
		$consulta->the_post();
		$html .= sprintf(
			'<li><a href="%s">%s</a></li>',
			esc_url( get_permalink() ),
			esc_html( get_the_title() )
		);
	}
	wp_reset_postdata();

	return $html . '</ul>';
}
  • no_found_rows le ahorra a la base de datos contar el total, porque no necesitamos paginación.
  • wp_reset_postdata() es obligatorio después de un bucle propio: devuelve a WordPress a la entrada que estaba mostrando. Sin él, la página puede mostrar datos cruzados.

¿Y con un plugin como CPT UI?

Plugins como Custom Post Type UI hacen esto con un formulario, sin código. Son una buena opción. Hacerlo a mano tiene ventajas: entiendes lo que pasa, no dependes de otro plugin y el código queda versionado junto a tu proyecto.

En la próxima entrada de Estructuras Avanzadas le agregamos a los recursos una taxonomía propia (nivel: principiante, intermedio, avanzado), y luego campos personalizados.

¿Qué tipo de contenido necesita tu sitio? Cuéntanos en el foro qué quieres organizar y te ayudamos a decidir si conviene un CPT, una categoría o una página.