Includes y subdirectorios en PHP

Es posible que si estamos desarrollando una plantilla HTML para portarla a formato PHP, nos sean muy útiles las funciones de include o require.

Estas funciones nos ayudan a agregar contenido de otros ficheros para simplificar el código y no tengamos que estar repitiendo el mismo código una y otra vez en todas las páginas del sitio.

Es muy útil para apartados como las cabeceras, los asides y los pies de página. Elementos del sitio que son exactamente iguales en todas las páginas por donde vamos navegando.

Existe una diferencia clave entre la función include o require.

  • Include: En el caso de no encontrar la ruta del archivo que se agrega, solo nos avisa con un warning y sigue ejecutando el código que le quede por completar.
  • Require: Al igual que include, cuando no encuentra el archivo llamado, esta función lo hace es mostrar un error y detiene el resto de la ejecución del código.

Lo que quiere decir que una función require es más estricta a include.

Estructura de archivos

Si nuestro plan es el de ahorrar líneas de código para que las plantillas desempeñen su función debemos partir de una buena estructura de archivos.

En esta captura se aprecia que nuestro proyecto raíz cuenta con unos archivos clave: cabecera.php, pie.php e index.php. A parte una serie de subdirectorios que corresponden a otras páginas y los componentes de estilos, fuentes y scripts.

Siguiendo la estructura HTML de cualquier página, la parte de la cabecera contendrá todas las etiquetas de identificación del sitio, títulos, descripciones, rutas a estilos y además en este caso, hasta el menú de navegación para toda la web.

Mientras que el pie tendrá la etiqueta footer, los cierres de etiquetas para el body del documento, las rutas a scripts y el cierre de html.

Dos firmes candidatos de código repetido que hemos separado en ficheros diferentes para que los cambios que realicemos en ellos, puedan ser apreciados en todas las páginas.

Llamadas en archivos de páginas

Una vez tenemos segmentado el código en cada parte, es hora de introducirlo antes y después de nuestro código de contenido.

Primero incluimos la cabecera, seguido del cuerpo del contenido que queramos dar a la página en concreto y terminando con el cierre añadiendo el archivo del pie:

Ayudándonos de PHP podemos insertar el contenido de la cabecera y el pie con una línea de código, en este caso nos estamos ayudando de la función require().

Pero, ¿qué pasa con los archivos que están en subdirectorios?. Como en el ejemplo de Blog. Esta página no está en la raíz y si llamara de igual manera que hemos hecho en el home a los archivos de cabecera y pie, nos saltaría un error de que no los encuentra.

Es tan sencillo como añadir ‘../’ antes del nombre del archivo como se ve en la captura de arriba. Lo que le estamos diciendo a PHP es que se dirija al directorio padre para que vaya a buscar los mismos archivos de cabecera y pie que están en la raíz.

Nota: Por cada bajada de subdirectorio tenemos que agregar un ‘../’ a la ruta para lleguemos a la raíz del proyecto.

¡No funcionan los estilos ni los scripts!

Aunque hayamos conseguido enganchar los archivos de cabecera y pie, y no me está lanzando ningún error la función require(), ¿por qué no se me está cogiendo los estilos y scripts que tenía funcionando en la página del Home?

Es porque tenemos configuradas las rutas para que funcione en ficheros de la raíz del proyecto y no hemos tenido en cuenta los que se encuentran por debajo del padre.

¿Cómo se soluciona este problema?

Bueno, pues lo primero que debemos configurar es un pequeño truco que funciona muy bien. Vamos a pensar en el orden de ejecución de PHP para los elementos y resulta muy sencillo buscarle solución a este problema.

  • Configurar una variable llamada $raiz. Esta variable la vamos a declarar en cada una de las páginas de contenido como el home o el blog. Y lo que va a contener es la ruta hasta el padre. Es decir, que si vamos a configurar la ruta al padre en el archivo home la variable será: $raiz = ‘./’; Porque ya estamos en el padre, pero si estamos en blog, donde tenemos que movernos un directorio arriba será: $raiz = ‘../’;

  • Seguir conservando la rutas relativas en las funciones require. Es muy importante que, como hemos explicando anteriormente, las rutas a los archivos de cabecera y pie sigan conservando las rutas relativas porque es la manera de que no nos lancen errores.
  • Modificar las rutas en los archivos de plantilla como cabecera y pie. Con la ayuda de echo vamos a imprimir la ruta a la raíz seguida del directorio donde se encuentra nuestro recurso. El único inconveniente de esto es que tenemos que modificar todos los enlaces a los recursos para que funcione. Por ejemplo en la cabecera sería así:

Y para el archivo del pie.php

Ahora sí, que se nos muestra todo el contenido afectándole los estilos y scripts que tienen en nuestra raíz de proyecto.

La explicación es bien sencilla. Al declarar la variable raíz en cada una de las páginas les estamos enviando por PHP la ruta a la que se debe dirigir todo enlace que componen la cabecera o el pie. Así que cuando nos encontramos en el directorio padre, raíz se va a apuntar a sí misma. Y si nos encontramos en un subdirectorio, raíz va a recorrer hacia atrás hasta llegar al padre.

 

I am the monster in your head.

Anuncios

Laravel 14: CRUD. Eliminar registros

Ponemos final a esta parte del manual de #Laravel donde hemos explicado los argumentos básicos para realizar un CRUD, o lo que viene siendo lo mismo: lectura, inserción, actualización y eliminación de datos en una BD.

El último procedimiento que nos faltaba es la eliminación de registros. Anteriormente, expuse una tabla en la que recogíamos el ID de la línea a actualizar y era enviada por la URL. Pues del mismo modo vamos a proceder para que al pulsar el botón de borrado, éste recoga el ID a eliminar y lo maneje.

Entonces bien, ahora nuestra tabla cuenta con los dos botones (actualizar y eliminación) pero con rutas distintas. Sin embargo, la última parte de la URL observamos que sigue siendo la { $vuelo->id }:

Ahora, observemos cual sería la ruta que manejará tanto la URL como la función que debe llamar en el controlador:

Como no vamos a recurrir a los datos recogidos de un formulario; sino que ya sabemos el ID, enviamos a una URL llamada /borra/{id} que lo que hará, será llamar a la función borra dentro de nuestro controlador.

Ya en nuestro controlador, tenemos la función pública borra que requiere de la $id que va a borrar. Vale, en este caso conocemos la ID y podemos valernos solamente del método destroy(requiere una primary key). Pero en el caso de que queramos eliminar un registro por medio de otro campo, utilizaríamos la función delete(); bajo previa búsqueda del registro con find().

Y con esto ya habríamos terminado nuestra aplicación. Para que no quede duda, dejo por aquí el enlace al repositorio del proyecto para que se quede registrado todo el código y sea de utilidad.

 

I am the monster in your head.

Laravel 13: CRUD. Actualizar datos

Una vez sabemos insertar y leer los datos para mostrarlos por pantalla vamos a proceder a lo que sería un poco más complicado: recoger los datos para cambiarlos y actualizarlos.

Debemos tener claro los procedimientos y diferenciar lo que sería recoger el dato que queremos variar para que el cambio solo surta efecto en él y no en otro diferente.

He implementado un sistema de formularios y vistas con Bootstrap para que sea más vistoso pero yo me voy a basar en la funcionalidad.

En la vista principal que llamé index he añadido un par de columnas más para una vez mostrar los vuelos de un aeropuerto podamos editarlo enviando el id que corresponde a cada línea.

Prestemos atención a cada una de las columnas de la tabla. Ayudándonos de Blade podemos mostrar el resultado de cada uno de los vuelos y el campo de la BD. Sin embargo, en la penúltima columna vamos a colocar un enlace/botón que haga la función de edición. Una manera de editar cada vuelo por el ID correspondiente es enviando por el enlace el propio ID.

De ahí que el enlace sea /edit/{{ $vuelo->id }}, porque básicamente, le estamos diciendo que cuando vaya al formulario de edición se lleve consigo el ID que corresponde al vuelo en su conjunto.

Echemos un vistazo a las rutas un segundo:

Como he dicho antes, el primer paso es recoger, en este caso, el vuelo que vamos a editar por medio de su ID. Por eso la primera ruta va a funcionar con el método GET y la ruta que va a llamar es exactamente la que hemos puesto en el enlace de la vista.

Cuidado cómo enviamos el ID del vuelo. Blade va a entender que lo recoges para guardarlo en una variable llamada “id” y que no lo quieres mostrar por pantalla. Por eso se usan las llaves simples.

Y ¿quién maneja esto?, una función llamada preEdit($id). Veámosla:

Como en la ruta le hemos enviado el ID del vuelo recogido vamos a crear un objeto que podamos manejar con Eloquent. La query necesaria para que tengamos el objeto del vuelo que corresponda con el ID se hace por medio del método where donde le decimos que el campo “id”, debe ser la variable que recibe por URL.

Una vez obtenido lo mandamos como un array a la vista del formulario que lo va a cargar (los datos editables).

El formulario de la edición sería el siguiente:

Es muy parecido al formulario que hicimos de la inserción, solo que tiene una serie de cambios muy destacables.

Ahora la acción del método va a enviar a una URL de confirmación con la ID del vuelo escogido anteriormente.

No olvidarnos de que en todo formulario debemos usar el campo de CSRF para que no haya inyecciones maliciosas.

Y en las etiquetas input mostramos los datos que corresponden al vuelo que vamos a modificar, permitiéndonos así, ver qué había antes de realizar los cambios.

Ahora el Controlador ejecutará la siguiente función:

Una función que recibe el objeto Request para la obtención de los inputs del formulario y el ID del vuelo.

Guardamos en variables mediante el objeto Request los valores registrados en los inputs del formulario anterior.

Creamos un objeto del Vuelo usando el método find() pasándole la ID de la función.

Registramos los nuevos nombres en los campos y guardamos. Volviendo a enviar una vista al usuario, que dice que ha sido modificado el elemento correctamente.

 

I am the monster in your head.

 

Laravel 12: CRUD. Lectura de datos

Continuamos ahora con la prueba para verificar que los datos que hemos conseguido insertar en la base de datos podamos verlos en nuestro navegador por medio de las consultas Eloquent. Si en el anterior CRUD de inserción de datos no aplicamos la metodología MVC aquí sí vamos a aplicarla, más que nada por comodidad a la hora recoger las consultas.

Vamos a empezar a crear un modelo Student. Recordamos que los modelos siempre van a ser en singular por convenio aunque la tabla que tengamos en nuestra BD sea students.

php artisan make:model Student

Dentro del directorio App\ nos vamos a encontrar ahora un archivo del modelo Student.php con una clase del mismo nombre. Vamos a ponerle una variable protected que haga referencia a la tabla de estudiantes.

Ahora creamos el controlador, que en este caso lo llamaremos StudViewController

php artisan make:controller StudViewController

Lo primero es añadir el espacio de nombres para usar el modelo Student. Es importante para no tener que depender del uso de la clase “DB” famosa.

A continuación, creamos una función llamada index() donde manejaremos con Eloquent lo que queremos obtener de la tabla estudiantes. En este caso, vamos a recoger todos los valores y lo vamos a devolver a una vista:

El siguiente paso obviamente, es crear la vista. Una vista de la que nos valdremos de Blade para recorrer el array que nos envía el controlador:

Para terminar, vamos a orden en nuestra ruta. Llamamos por medio del método get() el nombre de la vista seguido del método que está contenido en nuestro controlador:

Probamos que todo funciona a la perfección:

 

I’m the monster in your head.

Laravel 11: CRUD. Insertar registros

Una de las principales metodologías empleadas en el desarrollo para manejar datos es la  Creación, Lectura, Actualización y Borrado (CRUD) de información. En este apartado vamos a crear una pequeña creación de usuario en la base de datos.

Para empezar, nos hará falta la migración encargada de estructurar nuestra tabla básica. No entro en la creación de modelo porque será un ejemplo rápido y sencillo.

php artisan make:migration CreateTableStudents create=student

Este comando nos creará la migración CreateTableStudents con el id y el timestamp para la tabla students. La modificamos de manera que solo nos cree la ID y el NAME del alumno. Acto seguido ejecutamos la migración:

php artisan migrate

Ahora vamos a jugar con un controlador que albergue las funciones necesarias para la inserción en el formulario y la creación. Llamaremos al controlador StudInsertController y las funciones que tendrán serán insertForm() e insert(). Esta última recogerá la información obtenida de la clase Request.

La clase Request es utilizada para recoger las peticiones HTTP de la página. Podemos recibir URI con el método path(), o mostrar todos los inputs con el método all(), por ejemplo. Aunque para acceder a cualquier input siempre es de la misma manera:

$name = $request->input(‘name’);

Con el método insertForm() lo que estamos haciendo es únicamente mostrar la vista que contendrá nuestro formulario para insertar el estudiante. Y en el método insert(Request) vamos a guardar la información obtenido del input del formulario mediante la clase Request, la vamos a agregar mediante el método insert() de la DB (recordemos que no he fabricado el modelo, de haberlo hecho tan solo tenemos que llamar mediante el espacio de nombres al modelo Student) y por último mostramos un enlace de regreso al formulario.

OJO: En el caso de que usemos la manera recomendada, es decir, con Modelos en el VRM; debemos cambiar las sentencias Eloquent por otras más sencillas:

$estudiante = New Student;
$estudiante->name = $request->name;
$estudiante->save();

Procedemos a crear la vista para que funcione el formulario:

Como vemos hemos especificado en la propiedad action del formulario que nos dirija a la página de creación. Además, y muy importante; es agregar la llamada al middleware CSRF para evitar inyecciones de código malicioso mediante cross-site request forgery.

Por último, solo nos queda montar las rutas. Una será evidentemente del tipo GET para mostrar solo el formulario, mientras que la otra utilizaremos POST al enviar datos desde el formulario para ser procesados:

Para la ruta /insert queremos llamar al método insertform de nuestro controlador y para crear en la página /create llamamos al método insert que maneja el Request de la petición HTTP. Tal y como hemos visto anteriormente en el controlador.

Si nos vamos a la dirección http://localhost:8000/insert nos encontramos el formulario

Y al agregar un nombre nos redirige a la pantalla de /create

Si ahora observamos la base de datos, observamos que nuestros alumnos se han ido insertando sin ningún problema (obviamente a todo formulario hay que ponerle comprobadores y validadores para que no haya problemas)

 

I am the monster in your head.

Expandir abreviaciones de Emmet por tab en Atom

Es muy probable que en una instalación limpia de Atom.io queramos instalarnos el paquete de emmet. A todo buen desarrollador nos facilita mucho la vida. Pero yo como usuario de Linux y que venía de Sublime Text antes de conocer Atom, me encuentro que la costumbre de expandir el código con la tecla tab está cambiada y ahora el comando es algo más complejo: ctrl+windows+e.

Solo tenemos que decirle a nuestro mapa de teclas que la tecla tab funcione como lo hacía en el Sublime Text. Para añadir soporte en todos los lenguajes de programación debemos configurar un snippet en el keymap.cson (En Atom: Edit>Keymap…) y añadir al final del archivo:

'atom-text-editor:not([mini])':
   'tab': 'emmet:expand-abbreviation-with-tab'

Una vez añadido, reiniciamos Atom y podemos comprobar como ahora sí cuando escribimos alguna abreviación de Emmet y al pulsar la tecla tab funciona a la perfección.

 

I am the monster in your head.

Error crítico 41 Power-Kernel en Windows. Como solucionarlo

Me he consumido todo un fin de semana intentando arreglar el sobremesa donde tenía instalado un W10 Entp. debido a que cada vez que reiniciaba, ya fuera con el botón de reinicio, apagando presionando el botón de Power, desconectando la alimentación o incluso con el natural Inicio>Reiniciar; Windows no me llegaba a iniciar del todo correctamente. Parecía que no había ningún problema de componentes, porque mi placa está especializada en testearlos justo antes del inicio. Podía entrar en la BIOS, ver el logo de carga… pero a partir de ahí se congelaba todo y no iniciaba.

Cuando conseguía entrar por medio del arranque en modo seguro, me iba al Visor de Eventos del sistema para comprobar que estaba ocurriendo. Quitando las advertencias y errores típicos, me llama la atención un crítico con ID 41.

6403.Kernel Power

Buscando por Internet y probando bastantes métodos, incluso llegando a formatear y bajar a W7 (todo ello con drivers de gráfica instalados) no llegaba a comprender que estaba pasando realmente porque una vez arrancaba bien, todo funcionaba a la perfección. El problema venía cada vez que se reiniciaba el sistema e intentaba acceder de nuevo a Windows.

Entonces me encontré con este vídeo, y parece ser que la solución se hizo patente. Básicamente lo que se explica en el vídeo es la configuración de un nuevo plan de energía. Configurándolo en el Panel de Control del sistema, le activamos un “alto rendimiento” personal teniendo especial cuidado en desactivar que se apague el disco duro y desactivar todo lo relacionado con la suspensión.

Después de varios testeos: reinicio normal, reinicio con botón, apagado y encendido, …. parece ser que el problema se solucionó. Siempre aconsejar, tratar de probar diferentes campos de test para asegurarnos de que todo funciona correctamente.

 

I am the monster in your head.

Jets.js. El “instant search”

Mientras implementaba ciertas mejoras en un proyecto personal, me encontraba con la dificultad de buscar rápidamente un título mediante una etiqueta input de forma automatizada. Las opción era bastante clara con AJAX (bien con jQuery o con el ya famoso AngujarJS, pero que aún no logro dominar), pero como estoy implementando el uso de Bower para el tema de JavaScript me he topado con un paquete bastante interesante. Jets.js es un buscador nativo que su utilización es tan simple que da hasta risa. Veamos como implementarlo en nuestro proyecto: Sigue leyendo

INSTALACIÓN DE ATOM EN LINUX

Para la instalación de este potentísimo editor de texto únicamente tenemos que seguir los siguientes pasos.

  • Descargar del sitio oficial el paquete de instalación según nuestra distribución (mi caso: Ubuntu -> .deb)
  • Una vez descargado vamos al directorio donde lo tengamos descargado y ejecutamos
    • dpkg -i nombre-del-paquete-descargado
  • EXTRA: puede que nos de algún warning con respecto a la unión que existe entre Atom y Git. Lo que nos advertirá si es que no tenemos Git instalado. Pero Atom funcionará a la perfección

I am the monster in your head.