El tipo de ruta con expresiones regulares (Regex) es útil si tenemos URLs que se pueden comparar contra una expresión regular.
Por ejemplo, asumiendo que queremos crear un sistema simple de documentación para nuestro sitio web. La documentación consistiría en páginas "estáticas" que se hacen corresponder con URLs del tipo /doc/<page_name>.html.
Con el termino "página estática" nos referimos a una página que contiene principalmente código HTML estático más varios fragmentos de código PHP en linea. Para cada página simple no necesitamos crear acciones separadas en el controlador. Todas las páginas "estáticas" se pueden servir con una sola de acción en el controlador.
Vamos a implementar la ruta que servirá las páginas "estáticas" del sitio. Como
las páginas "estáticas" son simples, generalmente no necesitamos agregar un método
de acción por página en el controlador. Todas las páginas serán manejadas por una
sola acción: IndexController::docAction()
.
Primero, agregamos la ruta Regex llamada "doc" en el archivo module.config.php:
'doc' => [
'type' => Regex::class,
'options' => [
'regex' => '/doc(?<page>\/[a-zA-Z0-9_\-]+)\.html',
'defaults' => [
'controller' => Controller\IndexController::class,
'action' => 'doc',
],
'spec'=>'/doc/%page%.html'
],
],
La línea 2 define el tipo de ruta como Regex. En la línea 4 tenemos le expresión
regular /doc(?<page>\/[a-zA-Z0-9_\-]+)\.html
. Estas coincidirán con URLs como
"/doc/contents.html", "/doc/introduction.html", etc. La expresión contiene una
captura 6 llamada "page" que será regresada por la ruta encontrada
junto con los parámetros por defecto .
La linea 9 contiene la opción spec
que es usada por la ruta para generar URLs
(hablaremos sobre la generación de URLs por la ruta luego en este capítulo).
6) Con las expresiones regulares de PHP PCRE es posible nombrar un sub-patrón
usando la sintaxis (?P<name>pattern)
. Este sub-patrón se indexará
en el arreglo de comparación por su nombre.
No olvidemos agregar la siguiente línea al comienzo del archivo
module.config.php
:
user Zend\Router\Http\Regex;
Luego, agregamos la siguiente acción a la clase IndexController
:
public function docAction()
{
$pageTemplate = 'application/index/doc'.
$this->params()->fromRoute('page', 'documentation.phtml');
$filePath = __DIR__.'/../../view/'.$pageTemplate.'.phtml';
if(!file_exists($filePath) || !is_readable($filePath)) {
$this->getResponse()->setStatusCode(404);
return;
}
$viewModel = new ViewModel([
'page'=>$pageTemplate
]);
$viewModel->setTemplate($pageTemplate);
return $viewModel;
}
En las líneas 3-4 de arriba recuperamos el parámetro page
de la ruta (¿recuerdas
la captura llamada "page" de nuestra expresión regular?) y la guardamos en la variable
$pageTemplate
. Usaremos la variable $pageTemplate
para determinar el nombre del
plantilla de la vista que se pasará al view resolver. Luego, en las líneas 6-10 revisamos
si el archivo existe y si no regresamos el código de estado 404 "Not Found" que
forzará que ZF3 muestre la página de error. En la línea 12 creamos el contenedor
de la variable ViewModel
y en la línea 15 colocamos el nombre del plantilla de la
vista que se mostrará.
Para ver el sistema de documentación en acción creamos un par de plantillas "estáticas":
la página para la Tabla de Contenidos (contents.phtml
) y la página de Introducción
(introduction.phtml
). Creamos la subcarpeta doc debajo de la carpeta
view/application/index del modulo Application
y colocamos la plantilla de vista
contents.phtml ahí:
<h1>Table of Contents</h1>
<ul>
<li>
<a href="<?= $this->url('doc', ['page'=>'introduction']); ?>">
Introduction
</a>
</li>
</ul>
En las líneas de arriba escribimos el código HTML para la cabecera de la página
de la "Tabla de Contenidos" y una lista que contiene un solo elemento llamado "Introduction"
apuntando a la página "estática" Introduction. El enlace URL se genera con el
ayudante de vista Url
(para más detalles obre el ayudante Url
podemos ver
las siguientes secciones de este capítulo).
Luego agregamos la página introduction.phtml dentro de la misma carpeta doc:
<h1>Introduction</h1>
<p>Some introductory materials.</p>
En las líneas de arriba definimos las etiquetas HTML para una página de Introducción simple.
Ahora, si abrimos la URL "http://localhost/doc/contents.html" en nuestro navegador, podremos ver un sistema bueno y simple de documentación que podemos extender y usar en nuestro sitio web (figura 5.8):
Haciendo click en el enlace Introduction iremos a la página estática "Introduction". Además, podemos agregar otras páginas al directorio doc haciendo que estén automáticamente disponibles para los usuarios del sitio web a través de nuestra ruta Regex.
Una de las desventajas de este sistema de documentación es que no funciona bien si anidamos páginas colocándolas en subcarpetas debajo de la carpeta doc. La razón de esta limitación recae en la manera en que la ruta Regex construye URLs. No podemos construir rutas que contienen caracteres barra, como esta es un carácter "inseguro" la URL se codificará automáticamente. Sortearemos este problema con el tipo de ruta custom que crearemos al final de este capítulo.