Cómo emular el comportamiento de permalinks en páginas estáticas
Estoy trabajando en un sitio WordPress que muestra resultados de una API de Eventos en una página específica.
La página está en /whats-on.
Quiero proporcionar enlaces en la página con formato como misitio.com/whats-on/nombre-del-evento que enlacen a otra página mostrando los detalles del evento. Si simplemente agrego los enlaces, WordPress intentará encontrar un post con el nombre 'nombre-del-evento' y mostrará un error 404.
¿Hay alguna manera de evitar este comportamiento? ¿Cómo podría agregar reescrituras desde un plugin?
CÓDIGO ACTUALIZADO:
class SpektrixPlugin {
public function activate() {
global $wp_rewrite;
flush_rewrite_rules();
add_action('init',array($this, 'properties_add_rewrite_rules'));
add_filter('query_vars', array($this, 'properties_add_query_vars'));
}
public function properties_add_query_vars( $vars) {
$vars[] = "event"; // nombre de la variable como aparece en la URL
return $vars;
}
public function properties_add_rewrite_rules() {
//Cambia your_page_id con el ID de la página whats-on
add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?p=8&event='.$matches[1] , 'top' );
}
public function spektrix_list_events() {
$api = new SpektrixApiClient();
return $api->getAllEvents();
}
}
$SpektrixEvents= new SpektrixPlugin();
register_activation_hook( __file__, array($SpektrixEvents, 'activate') );

Necesitas agregar reglas de reescritura y los query_vars para adaptarlos a tus necesidades.
Por ejemplo. En tu archivo functions.php o de plugin:
// Registrar nuevas variables para usar en las reglas de reescritura
add_filter('query_vars', 'properties_add_query_vars');
function properties_add_query_vars( $vars) {
$vars[] = "my_action"; // nombre de la variable como aparece en la URL
return $vars;
}
// Agregar la nueva regla de reescritura a las existentes
add_action('init','properties_add_rewrite_rules');
function properties_add_rewrite_rules() {
//Cambia your_page_id con el ID de la página whats-on
add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?page_id=your_page_id&my_action='.$matches[1] , 'top' );
}
Y luego en la plantilla para la página whats-on (crea un archivo de plantilla page-whats-on.php, ver esto):
global $wp_query;
if(isset($wp_query->query_vars('my_action')) && $wp_query->query_vars('my_action') == 'some_action'){
//Haz lo que necesites
}
No olvides vaciar las reglas de reescritura antes de probar tus nuevas reglas. Puedes hacerlo yendo a ajustes->enlaces permanentes y haciendo clic en el botón Guardar.
EDITAR
En tu pregunta actualizada tienes algunos problemas en tu código.
- Había un error en mi código, donde la variable de consulta para la página es
page_id
y escribí solop
. Lo siento por eso. - Las reglas de reescritura y las variables de consulta personalizadas deben agregarse en el gancho de acción init, solo flush_rewrite_rules(); debe ejecutarse solo en el gancho de activación por razones de rendimiento (yo mismo hice una pregunta relacionada).
He probado este código y funciona:
class SpektrixPlugin {
public function __construct(){
add_filter('query_vars', array($this, 'add_query_vars'));
add_action('init', array($this, 'add_rewrite_rules'));
}
public function activate() {
flush_rewrite_rules();
}
public function deactivate() {
flush_rewrite_rules();
}
public function add_query_vars($vars) {
$vars[] = "event"; // nombre de la variable como aparece en la URL
return $vars;
}
public function add_rewrite_rules() {
//Cambia your_page_id con el ID de la página whats-on
add_rewrite_rule( 'whats-on/(.+)/?$' , 'index.php?page_id=8&event=$matches[1]' , 'top' );
}
public function spektrix_list_events() {
//$api = new SpektrixApiClient();
//return $api->getAllEvents();
return 'Test';
}
}
$SpektrixEvents = new SpektrixPlugin();
register_activation_hook( __file__, array($SpektrixEvents, 'activate') );
register_deactivation_hook( __file__, array($SpektrixEvents, 'deactivate') );
Ahora necesitas verificar cuando la variable de consulta event
esté presente. En tu caso, creo que, como dije antes, la mejor manera de hacer esta verificación es en la plantilla de la página. Puedes crear una plantilla específica para tu página con ID 8. Solo crea un archivo page-8.php y colócalo en la carpeta de tu tema (también puedes ponerlo en una carpeta de plugin pero esto requiere trabajo adicional). En page-8.php puedes hacer algo como esto:
<?php
get_header();
global $wp_query;
if($wp_query->get('event') == 'event'){
echo $SpektrixEvents->spektrix_list_events();
}
get_footer();
?>
Ahora si vas a yoursite.com/whats-on/event/ obtendrás "Test" impreso.

Gracias. ¿Lo anterior está destinado a ir en el functions.php de un tema? ¿Cómo haría esto en un plugin? Tampoco estoy seguro de por qué necesitaría wp_query. No estoy consultando la base de datos.

El primer fragmento de código va en functions.php o en un archivo de plugin. El segundo fragmento de código debe ir preferiblemente en un archivo de plantilla específico para tu página /whats-on. He usado $wp_query para verificar si la variable de consulta personalizada está configurada y obtener su valor, no para consultar la base de datos. Después de la verificación puedes consultar directamente la base de datos o lo que quieras hacer. Ten en cuenta que estas recomendaciones son porque has pedido reescribir a la página específica /whats-on.

He actualizado la pregunta con algo de código. Todavía obtengo un 404 cuando voy a mysite.com/whats-on/nombre-del-evento. ¿Puedes detectar algo que haya hecho mal? Llevo muchas horas despierto :-/. He actualizado las reglas de reescritura

Gracias de nuevo. He avanzado un poco más. Sin embargo, esos flushes de reescritura no parecen funcionar y tengo que guardar manualmente en los ajustes de enlaces permanentes.

Sí, me acabo de dar cuenta de eso, pero una vez que los ajustes de enlaces permanentes se han actualizado manualmente, funciona, ¿verdad?
