A lo largo de este artículo te invito a crear tu propio framework. Sí, sí, ya se que no hay que reinventar la rueda, que existen framework a patadas y todo eso. La idea es que aprendes a usar Twig como motor de plantillas para ayudarte a manejar un sitio web relativamente estático sin tener que estar duplicando contenido. Va a ser algo muy sencillo, sin conexión a bases de datos, autenticación de usuarios, etc. Vamos, lo mínimo que se despacha en frameworks
Si estás empezando con PHP, y sobre todo, si no conoces Composer, antes de seguir leyendo te recomiendo seguir el tutorial "Automatiza la creación de tus proyectos con Composer" en este mismo blog.
En este artículo te propongo un esquema propio, he intentado seguir los estándares actuales, pero, si algo te gusta más de otra manera eres libre de modificarlo. Incluso, si cambias algunas cosas, y ves que algo falla eso también va a ser una oportunidad de aprendizaje. Así que, ya sabes, te doy un guión pero te invito a saltártelo cuando quieras, si no te sientes muy seguro, hazlo una primera vez al pie de la letra y luego lo haces improvisando, intentando seguir los pasos de memoria, cambiando los nombres de variables o carpetas por otros que te gusten más, etc.
Si has hecho el tutorial de Composer, citado antes, puedes utilizar el mismo proyecto que creaste allí. También puedes crear el proyecto desde cero, ahora te explico como.
Comenzando con tu pequeño framekenstein
Ve a la carpeta donde tienes tus proyectos web y crea un nuevo directorio con el nombre framekenstein (tu pequeño monstruo), también puedes llamarlo framky cariñosamente.
A continuación ve a la línea de comandos, sitúate en la carpeta del proyecto, teclea composer init y a tirar millas. Cuando te pregunte por las dependencias añade twig/twig.
Y por último ejecuta composer install para bajarte las dependencias que has declarado y generar los ficheros composer.lock y /vendor/autoload.php.
Perfecto, repasa la estructura de carpetas y archivos para ver que lo tienes todo en orden; la mía está así:
1
2
3
4
5
6
7
8 .
├── composer.json
├── composer.lock
└── vendor
├── autoload.php
├── composer
├── symfony
└── twig
Te invito a curiosear un poco por cada carpeta, para ver que tienes hasta ahora, cuando termines crea estas carpetas adicionales en la raiz del proyecto:
- public: donde vivirán nuestros ficheros públicos y nuestro controlador principal, ahora te explico esto último
- views: (por "vistas") donde vivirán tu código html (en forma de plantillas twig)
- cache/twig: para la caché (carpeta donde se almacenan los ficheros "precocinados") de Twig
Utilizando la librería de plantillas Twig
Si quieres generar páginas web desde tu nuevo framework te recomiendo utilizar algún lenguaje de plantillas. Esto facilitará enormemente tu vida y hará de ti una persona más feliz.
Cuando no utilizas plantillas tienes que hacer cosas como estas para generar html:
Con Twig quedaría así:
¡Ja, ja, puede que a primera vista te parezca casi peor! Pero si te fijas bien las variables se imprimen de forma más directa, evitas la tentación de insertar código php entre el código html y además tienes herencia de plantillas, escape de variables, construcciones lógicas sencillas, etc. Ya verás, cuando te acostumbres a usarlo no podrás vivir si él.
Para empezar crea un fichero index.php dentro de la carpeta public. Haz un require del fichero vendor/autoload.php que ha creado Composer y añade un par de líneas para configurar Twig.
Primero le indicas la carpeta donde Twig debe buscar las plantillas o vistas (normalmente se le llama views o templates) y la carpeta donde almacenar la caché de las vistas (normalmente cache/twig)
Asi quedaría el fichero public/index.php:
1
2
3
4 <?php
require_once '../vendor/autoload.php';
$loader = new Twig_Loader_Filesystem('../views');
$twig = new Twig_Environment($loader, array('cache' => '../cache/twig', 'debug' => true));
Con esto ya tendrías Twig "precargado" para empezar a utilizarlo como lenguaje de plantillas. Y ahora, a sacarle partido.
Primera prueba con Twig
Para empezar vas a hacer algo muy simple: mostrar ¡por fin! algo en tu navegador.
Para ello en tú index.php añade esta línea al final:
1 print("<p>Hola, soy Framy!</p>");
Activa desde consola el servidor web que viene integrado con php utilizando la orden:
1 php -S localhost:8000 -t public
Ahora ve a tu navegador web y teclea http://localhost:8000. Debería aparecer una página con la frase: Hola, soy Framky! Si algo no ha ido bien repasa de nuevo las instrucciones anteriores.
Ahora vas a hacer lo mismo, pero utilizando el motor de Twig.
Crea un fichero dentro de la carpeta views con el nombre saludo.html.twig y este contenido:
1 <p>Hola, soy Framky!</p>
En index.php elimina o comenta la línea del print y añade lo siguiente:
1
2
3 // print("<p>Hola, soy Framky!</p>");
$html = $twig->render('saludo.html.twig');
print($html);
La variable $twig es un objeto de la clase Twig_Environment, lo declaraste así un poco más arriba. Aquí lo que hace es llamar al método render() que a su vez carga la vista que le has indicado, buscando en la carpeta views (que también le indicaste más arriba).
NOTA: para seguir este tutorial no es necesario que conozcas la programación orientada a objetos (OOP por sus siglas en inglés). Si no tienes ni idea del tema, piensa que una clase es como una super función que tiene métodos (que son funciones definidas dentro de la clase) y propiedades (que son variables de la clase). Para utilizar una clase normalmente hay que crear un objeto de esa clase, ese objeto se almacena en una variable que ya podemos utilizar. Has creado dos objetos de distintas clases hace un rato cuando te dije que teclearas el código:
1
2 $loader = new Twig_Loader_Filesystem('../views');
$twig = new Twig_Environment($loader, array('cache' => '../cache/twig', 'debug' => true));$loader contiene ahora un objeto de la clase Twig_Loader_Filesystem y $twig contiene un objeto de la clase Twig_Environment
El método render() te devuelve la plantilla de twig procesada (en esta caso no ha tenido mucho trabajo), lo que devuelve no es más que código html que luego has mostrado en el navegador con la orden print.
Toda esta complejidad puede parecerte innecesaria, pero fíjate que ya has conseguido algo que es bastante importante en una aplicación: separar la lógica de tu aplicación (index.php) del contenido que vas a mostrar: el código HTML.
Existe otra función de Twig, la función display() que te ahorra un paso en el código de arriba:
1
2
3 // $html = $twig->render('saludo.html.twig');
// print($html);
$twig->display('saludo.html.twig');
Prueba de nuevo a recargar el navegador y verás que imprime lo mismo. No obstante, al menos de momento, prefiero que sigas usando el print para que siempre tengas claro que lo único que hace twig es generar código html.
Un enrutado muy básico
Bueno, con una sola página el framework quedaría demasiado pequeño. Así que ahora verás como habilitar un mecanismo muy básico para cargar distintas páginas, para ello se le pasa al controlador principal el nombre de la página que quieres cargar y él se encargará de llamarla. Vamos a pasar la página utilizando la URL con el parámetro p.
1
2
3
4
5
6
7
8
9
10 <?php
// public/index.php
require_once '../vendor/autoload.php';
$twig_loader = new Twig_Loader_Filesystem('../views');
$twig = new Twig_Environment($twig_loader, array('cache' => '../cache/twig',));
$pagina = $_GET['p'] . '.html.twig';
$html = $twig->render($pagina);
print($html);
Con el método $_GET puedes capturar los parámetros que vienen en la URL, en este caso "p". Ahora puedes crear más plantillas en el directorio views y llamarlas desde la barra de direcciones del navegador.
http://localhost:8080/index.php?p=despedida
En este caso tendrías que crear una plantilla denominada despedida.html.twig
Usar el método $_GET no es muy seguro así que vas a sustituirlo por una función más moderna, filter_input, que además permite filtrar entradas indeseadas. Con filter_has_var te aseguras previamente que se haya pasado el parámetro p con la URL.
1
2
3
4
5
6
7
8 if (filter_has_var(INPUT_GET, 'p')){
$pagina = filter_input(INPUT_GET, 'p', FILTER_SANITIZE_URL);
} else {
$pagina = 'inicio';
}
$pagina .= '.html.twig';
$html = $twig->render($pagina);
print($html);
Añade una página de inicio (inicio.html.twig) por si alguien se olvida de rellenar la variable p en la URL y para que sirva de página por defecto. Su contenido podría ser algo así de momento:
Herencia de plantillas
Te habrás fijado que hasta ahora las páginas webs que has creado estaban bastante incompletas. ¡Ni siquiera tenían la etiqueta html!
Esto es posible porque los navegadores se lo tragan casi todo, pero no es nada correcto, así que vas a solucionarlo en las plantillas que has creado hasta ahora.
1
2
3
4
5
6
7
8
9
10
11
12
Uff, vaya lata ¿no? ¿Imaginas esto en una web con cien páginas? Y todavía le faltan las hojas de estilo, los ficheros de JavaScript, la estructura de la página: cabecera, menú, pié, etc. Sería super engorroso de crear y no digamos ya de mantener.
Como ya habrás imaginado nadie hace esto así, en este caso lo vas a solucionar con Twig gracias a su capacidad de heredar plantillas.
Todos estos ficheros, con algunas pequeñas mejoras los tienes en GitHub.
El fichero layout
Vas a crear un nuevo fichero, dentro de la carpeta views, con el nombre layout.html.twig. Lo he llamado así porque es lo más habitual, pero puedes darle el nombre que prefieras.
Ahora vas a hacer que tus plantillas hereden de esta, para ello modifica el archivo inicio.html.twig
Recarga de nuevo tu web. ¡Por fin estás viendo twig en acción!
¡Cuidado!
Puede que al actualizar algunas páginas la caché de Twig te siga mostrando el contenido anterior. Borra todas las carpetas que se encuentran debajo del directorio /cache/twig si te pasa esto. Aunque no debería ocurrir si en el controlador principal pusiste ‘debug’ => true al llamar al objeto Twig.
La primera etiqueta que hemos usado, extends, en el fichero inicio.html.twig es la encargada de llamar a la plantilla principal que hemos definido como layout.html.twig. De esta manera inicio "hereda" la estructura de layout . Pero observa que hemos definido unas etiquetas block y endblock en ambas plantillas. Estas etiquetas vienen a decir que se sustituya el bloque contenido de la plantilla principal por el de la plantilla hija. Puedes crear tantos bloques como necesites dando a cada uno nombres distintos
Y ahora puedes modificar la página saludo.html.twig de la misma manera
Te invito a hacer lo mismo con la página despedida.html.twig
Y por último añade una pequeña hoja de estilo y un pequeño logo a tu framekenstein para que quede más bonito. Para ello modifica de nuevo el fichero layout.htm.twig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 <!doctype html>
<html lang="es">
<head>
<meta charset="utf-8">
<title>Framekenstein</title>
<link rel="stylesheet" href="css/frame.css">
</head>
<body>
<header class="header">
<div class="logo"><img src="img/logo_framekenstein_mini.png" alt="logo elephpant"></div>
<h1><a href="/index.php">Framekenstein</a></h1>
</header>
<main class="main">
<div class="main-content">
{% block contenido %}
{% endblock %}
</div>
</main>
<footer class="footer">
Made with Framekenstein · Más tutoriales en <a href="http://galatar.com">Galatar</a>
</footer>
</body>
</html>
El contenido de la hoja de estilo frame.css sería este:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 /* /public/css/frame.css */
/* Mini reset */
body {
margin: 0;
padding: 0;
}
p {
margin: 0 0 10px 0;
}
/* fin reset */
body {
font-family: "Open Sans", sans-serif;
}
.header, .footer {
background: #def4ba;
padding: 10px;
}
.header a {
text-decoration: none;
color: #7ca53a;
}
.logo {
float:right;
}
.main-content{
padding: 10px;
}
Te tiene que quedar con el aspecto de la siguiente imagen
Todo el código de esta segunda versión también lo tienes en GitHub
Resumiendo
Aunque de una manera un poco primitiva, sin objetos, con un enrutador muy básico y sin llegar a utilizar ni un 1% de la potencia de Twig he intentado darte una idea de lo útil que es utilizar Twig para que todas las páginas de tu web puedan tener una plantilla común.
A este pequeño armazón que has montado se le pueden seguir añadiendo todas las páginas que te hagan falta, agregarle un menú de navegación, etc.
Si te decides por algo un poco mejor estructurado te recomiendo dar un vistazo a la librería Easy-Twig. Está disponible para instalar desde Composer: composer create-project demontpx/easy-twig
Aunque la mejor opción para trabajar con Twig es usarlo en su propio elemento, combinando otros potentes paquetes del framework Symfony. Pero de eso hablaremos pronto en este blog.
En cualquier caso espero poder publicar en breve otro tutorial de Twig con una estructura más acorde con las buenas prácticas usadas en la actualidad en PHP.
Deja una respuesta