Tiempo de lectura: 4 min
Entrega 3: Los Shortcodes de Frontend (Formulario y Calendario Interactivo)
Valencia, 25/10/2026, G.B.
En las entregas anteriores vimos cómo levantar los cimientos del plugin en la base de datos y cómo estructurar el panel de administración en el backend. En este tercer bloque me centro en la parte visible para el usuario: los shortcodes que dan vida a la agenda en el frontend de la web.
Para conseguirlo, divido la funcionalidad en dos shortcodes independientes pero complementarios: indaga_agenda (entre corchetes) para gestionar el alta, edición y listado de citas, y calendario_agenda (entre corchetes) para renderizar el calendario mensual interactivo.
1. El Shortcode de Gestión y Formulario (indaga_agenda) (entre corchetes)
Este shortcode permite desplegar un formulario de alta y edición de eventos, acompañado de una tabla con los registros actuales de la instancia. Todo ello protegido mediante comprobaciones de sesión de usuario, validación de nonces y funciones de saneamiento de datos.
public function renderizar_shortcode_agenda( $atts ) {
global $wpdb;
$tabla = $wpdb->prefix . 'indaga_agenda';
$atts = shortcode_atts( array( 'id' => 'default' ), $atts, 'indaga_agenda' );
$grupo_id = sanitize_text_field( $atts['id'] );
$user_id = get_current_user_id();
$mensaje = '';
// Procesamiento del formulario de guardado / edición
if ( isset( $_POST['indaga_agenda_frontend_nonce'] ) && wp_verify_nonce( $_POST['indaga_agenda_frontend_nonce'], 'guardar_evento_frontend' ) ) {
if ( !is_user_logged_in() ) {
return '<p style="color:red;">Debes iniciar sesión para gestionar la agenda.</p>';
}
$evento_id = isset( $_POST['evento_id'] ) ? absint( $_POST['evento_id'] ) : 0;
$titulo = sanitize_text_field( $_POST['titulo'] );
$descripcion = sanitize_textarea_field( $_POST['descripcion'] );
$fecha_inicio = sanitize_text_field( $_POST['fecha_inicio'] );
$fecha_fin = sanitize_text_field( $_POST['fecha_fin'] );
$categoria = sanitize_text_field( $_POST['categoria'] );
if ( !empty( $titulo ) && !empty( $fecha_inicio ) ) {
$datos = array(
'user_id' => $user_id,
'grupo_id' => $grupo_id,
'titulo' => $titulo,
'descripcion' => $descripcion,
'fecha_inicio' => $fecha_inicio,
'fecha_fin' => !empty( $fecha_fin ) ? $fecha_fin : $fecha_inicio,
'categoria' => $categoria
);
if ( $evento_id > 0 ) {
$wpdb->update( $tabla, $datos, array( 'id' => $evento_id ), array( '%d', '%s', '%s', '%s', '%s', '%s', '%s' ), array( '%d' ) );
$mensaje = '<div style="background:#d4edda; color:#155724; padding:10px; margin-bottom:15px; border-radius:4px;">¡Evento actualizado con éxito!</div>';
} else {
$wpdb->insert( $tabla, $datos, array( '%d', '%s', '%s', '%s', '%s', '%s', '%s' ) );
$mensaje = '<div style="background:#d4edda; color:#155724; padding:10px; margin-bottom:15px; border-radius:4px;">¡Evento creado con éxito!</div>';
}
}
}
// ... (código de renderizado de la vista y formulario)
}
Puntos clave del formulario:
- Soporte multinstancia por atributo: A través del parámetro
id="nombre_instancia"(por defectodefault), delimito los registros que pertenecen a esa agenda concreta. - Doble funcionalidad (Alta / Edición): Si el sistema detecta un parámetro
editar_iden la URL, carga automáticamente los datos del evento en los inputs para modificarlos sin duplicar registros.
2. El calendario interactivo (calendario_agenda) (entre corchetes)
Para mostrar los eventos en una vista de calendario mensual limpia y visual, transformo los registros de la base de datos a un array de JavaScript y construyo una cuadrícula dinámica.
public function renderizar_shortcode_calendario( $atts ) {
global $wpdb;
$tabla = $wpdb->prefix . 'indaga_agenda';
$atts = shortcode_atts( array( 'id' => 'default' ), $atts, 'calendario_agenda' );
$grupo_id = sanitize_text_field( $atts['id'] );
$eventos = $wpdb->get_results( $wpdb->prepare( "SELECT * FROM $tabla WHERE grupo_id = %s ORDER BY fecha_inicio ASC", $grupo_id ) );
$eventos_js = array();
foreach ( $eventos as $ev ) {
$eventos_js[] = array(
'id' => $ev->id,
'titulo' => $ev->titulo,
'descripcion' => $ev->descripcion,
'categoria' => $ev->categoria,
'fecha_inicio' => $ev->fecha_inicio,
'fecha_fin' => $ev->fecha_fin
);
}
// ... (retorno del HTML y script de renderizado)
}
Características del motor visual en JavaScript:
- Navegación fluida por meses: Botones de avance y retroceso (
cambiarMes()) que recalculan los días de la semana y sitúan correctamente el primer día del mes. - Fichas modales emergentes: Al hacer clic sobre cualquier evento listado dentro de una casilla del calendario, se despliega una ventana flotante con los detalles completos (horarios, categoría y descripción).
- Conexión directa con el alta: El botón superior «+ Añadir Evento» o hacer clic directamente sobre cualquier día del calendario desplaza la vista automáticamente hacia el formulario y precarga la fecha seleccionada.
Con esta tercera entrega queda completamente documentada la arquitectura del plugin Agenda Indaga (v1.3.0): desde los cimientos en la base de datos, pasando por el panel de administración multinstancia, hasta la interacción visual en el frontend.

