Bootstrap 4. Primeros pasos

icono de php Bootstrap es una colección de elementos, plantillas y componentes HTML, CSS y Javascript para crear rápidamente páginas web con un aspecto moderno y “responsivo” (¡menudo palabro!) al tamaño de pantalla de cualquier dispositivo. Su versión 4 se liberó hace un par de meses y aporta algunos cambios significativos como, por ejemplo, la inclusión de Popper como librería javascript para “tooltips” y otros elementos emergentes y la eliminación de las tipografías Glyphicons para introducir símbolos y pictogramas.

Podemos trabajar con Bootstrap bien descargandonosla en nuestro propio servidor web, o bien usando sus librerías directamente desde los CDN que nos ofrecen. Aquí usaremos este segundo método por sus evidentes ventajas de cara a montar una primera plantilla para pruebas. Necesitamos incluir simplemente el siguiente tag en :

<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />

Si vamos a usar los elementos javascript necesitamos incluir también las librerías correspondientes y, ademas, las de jquery y popper en nuestro proyecto las cuales también tienen disponible la posibilidad de enlazarlas directamente sin necesidad de descargarlas en local:

<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.1/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

IMPORTANTE: los enlaces anteriores corresponden a las versiones estables más recientes en el momento de escribir esto. No suelen eliminar las versiones anteriores, pero conviene que te cerciores si llegas a este texto en un futuro lejano.

Con todo esto, la plantilla mínima de HTML para empezar a trabajar (incluyendo los enlaces correspondientes a las librerías javascript comentados) sería esta:

<!DOCTYPE html>
<html lang="es">
    <head>
    	<meta charset="utf-8" />
    	<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
    	<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" />
    	<title>Plantilla Bootstrap</title>
  	</head>
  	<body>
		<h1>Plantilla Bootstrap</h1>

    
		<!-- Javascript opcional -->
		<!-- <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
    	     <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.1/umd/popper.min.js"></script>
    	     <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script> -->
  	</body>
</html>

Sosa, verdad? Claro, aún no hemos empezado a trabajar… Si quieres ver algo más impactante, bootstrap dispone de plantillas con algo mas de chicha para tus diseños. Las tienes disponibles en este enlace. Si prefieres empezar desde cero, tienes disponible un montón de La documentación bastante fácil de seguir que incluye multitud de ejemplos prácticos para empezar a trabajar desde el primer minuto.

Laravel 5.6. Estructura y primeros pasos: Autenticación de usuarios

icono de php Ya yenemos Laravel 5.6 instalado en alguno de los dos entornos que hemos visto antes. ¿Qué sigue? Lo primero, entender un poquito la estructura de directorios que nos ha creado composer. Sólo lo imprescindible. El resto lo iremos viendo a medida que avanzamos.

josemaria@valeria /var/www/html/prueba $ ls -la
total 236
drwxr-xr-x 12 root www-data   4096 mar  9 19:31 .
drwxr-xr-x  3 root www-data   4096 mar  9 18:29 ..
drwxr-xrwx  6 root www-data   4096 ene  3 17:52 app
-rwxr-xrwx  1 root www-data   1686 ene  3 17:52 artisan
drwxr-xrwx  3 root www-data   4096 ene  3 17:52 bootstrap
-rw-r--rw-  1 root www-data   1413 ene  3 17:52 composer.json
-rw-r--rw-  1 root www-data 143565 mar  8 07:37 composer.lock
drwxr-xrwx  2 root www-data   4096 ene  3 17:52 config
drwxr-xrwx  5 root www-data   4096 ene  3 17:52 database
-rw-r--r--  1 root www-data    612 mar  9 19:31 .env
-rw-r--r--  1 root www-data    565 ene  3 17:52 .env.example
-rw-r--r--  1 root www-data    111 ene  3 17:52 .gitattributes
-rw-r--r--  1 root www-data    146 ene  3 17:52 .gitignore
-rw-r--rw-  1 root www-data   1125 ene  3 17:52 package.json
-rw-r--rw-  1 root www-data   1040 ene  3 17:52 phpunit.xml
drwxr-xrwx  4 root www-data   4096 ene  3 17:52 public
-rw-r--rw-  1 root www-data   3550 ene  3 17:52 readme.md
drwxr-xrwx  5 root www-data   4096 ene  3 17:52 resources
drwxr-xrwx  2 root www-data   4096 ene  3 17:52 routes
-rw-r--rw-  1 root www-data    563 ene  3 17:52 server.php
drwxrwxrwx  5 root www-data   4096 ene  3 17:52 storage
drwxr-xrwx  4 root www-data   4096 ene  3 17:52 tests
drwxr-xrwx 36 root www-data   4096 mar  8 07:38 vendor
-rw-r--rw-  1 root www-data    549 ene  3 17:52 webpack.mix.js

El directorio public ejerce de DocumentRoot. Allí encontraremos el index.php que da entrada a nuestra aplicación web así como las hojas de estilos, etc. El fichero .env que vemos aquí arriba en el directorio raiz de nuestra aplicación es el fichero de configuración principal. De hecho, puesto que vamos a empezar a trabajar con bases de datos en este momento podemos aprovechar para editar las siguientes directivas:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=laravel
DB_PASSWORD=secreto

Importante: aunque usemos mariadb la directiva DB_CONNECTION debe de ser mysql porque Laravel no entiende otra y, a fin de cuentas, ambas son compatibles a nivel binario. Para que Laravel sea capaz de hacer uso de esa base de datos debemos de crearla. A ella y al usuario que le hemos dicho que va a usar para manejarla. Entramos en nuestro gestor (mysql o mariadb) y ejecutamos lo siguiente:

CREATE DATABASE laravel;
CREATE USER laravel@localhost IDENTIFIED BY 'secreto';
GRANT ALL ON laravel.* TO laravel@localhost;

Vamos ahora a crear nuestro sistema de autenticación. Laravel viene ya con un módulo llamado User.php que reside en el directorio app. Para generar el resto de lo que necesitamos ejecutamos lo siguiente:

php artisan make:auth
php artisan migrate

La primera línea crea el código y rutas necesario para la gestión de usuarios. En particular, creará o modificará los siguientes ficheros:

routes/web.php
resources/views/auth/login.blade.php
resources/views/auth/register.blade.php
resources/views/auth/passwords/email.blade.php
resources/views/auth/passwords/reset.blade.php

La segunda instrucción crea la estructura de tablas necesaria en la base de datos que hemos configurado previamente. Si ahora volvemos a cargar la web de nuestro aplicación veremos que en la esquina superior derecha tenemos dos nuevos enlaces correspondientes a las funcionalidades de Login y Registro:

Laravel 5.6 con la funcionalidad de login y registro

Las pantallas de registro y login por defecto son estas:

Pantalla de registro en Laravel 5.6
Pantalla de login en Laravel 5.6

Y una vez hecho login vemos que en la barra de menú se nos identifica con nuestro nombre de usuario y tenemos la posibilidad de cerrar sesión:

Logout en Laravel 5.6

Si le echamos un vistazo a “las tripas” vemos que nos ha creado dos tablas una de las cuales, la de usuarios, es la que guardará la información relativa a los registros de usuarios.
Tablas creadas por Laravel 5.6 para la autenticación de usuarios

Además, tal y como está mandado, vemos que no almacena las contraseñas en claro sino un hash de las mismas:

hash de las passwords en Laravel 5.6

La castellanización de los recursos es tan sencilla como editar alguno de los ficheros php que hemos indicado anteriormente. Por ejemplo, el fichero login.blade.php es el que contiene la ventana de login y register.blade.php la de registro. Con muy poco esfuerzo tendremos las ventanas anteriores en perfecto castellano. Pero eso ya os lo dejo a vosotros 😉

Instalando Laravel en Windows 7 con XAMPP

icono de php Hace unos minutos hemos publicado la forma de instalar Laravel en una Debian con Apache. Vamos ahora a ver como se hace en un windows 7 con xampp. Imagino que hacerlo en cualquier otra versión de windows más moderna será igual de fácil.

Partimos entonces de ese windows instalado, funcionando, y con xampp también instalado y funcional. Lo primero que tenemos que instalarnos es composer, el gestor de paquetes PHP que utiliza Laravel para crear la estructura que necesistan sus proyectos. Para ello nos descargamos el instalador para windows y ya sabéis: siguiente-siguiente-siguiente-aceptar 😀

Y ya está. Ya tenemos todo lo que necesitamos. Vamos ahora a crear la estructura para nuestra primera aplicación con Laravel. La versión del framework en el momento de escribir esto es la 5.6. Suponemos que se llamará prueba y que la instalaremos en el directorio web por defecto que usa xampp. Nos vamos a la línea de comandos y, suponiendo que trabajamos sobre el disco C:, ejecutamos lo siguiente:

cd c:\xampp\htdocs
composer create-project laravel/laravel prueba --prefer-dist

En segundo lugar tenemos que crear el virtual host necesario para esta aplicación. Xampp usa para ello el archivo httpd-vhosts.conf que reside en el directorio c:\xampp\apache\conf\extra. Editamos este archivo y añadimos lo siguiente:

<VirtualHost *:80>
  DocumentRoot "C:\xampp\htdocs\prueba\public"
  DirectoryIndex index.php
  <Directory "C:\xampp\htdocs\prueba">
        AllowOverride All
  </Directory>
  ErrorLog "logs/pruebalaravel-error.log"
  CustomLog "logs/pruebalaravel-access.log" combined
</VirtualHost>

Y listo. Reiniciamos apache y abrimos un exporador. Si escribimos http://localhost veremos la página de bienvenida de Laravel:

Laravel 5.6 en windows con Xampp

Instalando Laravel en Debian 9

icono de php Repasando el “histórico” del blog que a menudo me sirve como memoria veo que he recurrido en los últimos 12 años a dos frameworks para php: cake y codeigniter. Ahora que me toca volver a decidirme por alguno y teniendo en cuenta que tengo totalmente olvidado a ambos he preguntado por ahí y todo el mundo parece estar de acuerdo en que lo mejor del momento es Laravel. La versión actual de Laravel es la 5.6. Vamos, pues, a por el tercero.

La instalación de Laravel es bien sencilla. En esta entrada tocaremos un entorno “clásico” en este blog: una Debian sin entorno gráfico. En una entrada posterior tocaremos la instalación en un windows 7 con Xampp que en este caso me resulta también imprescindible. Vamos a ello.

Partimos de una Debian 9.3.0 (la versión estable en el momento de escribir esto) recién instalada y sin ningún tipo de personalización. Lo primero que necesitamos instalar son ciertos paquetes de utilidades y el entorno web necesario para trabajar con laravel: apache2, php y mysql-server:

apt install curl unzip git
apt install apache2 libapache2-mod-php
apt install mysql-server
apt install php-mysql php-xml php-mbstring

En segundo lugar tenemos que instalar composer, un gestor de paquetes php que nos servirá para instalar el entorno necesario para trabajar con Laravel. Así:

cd /usr/local/bin
curl -sS https://getcomposer.org/installer | php

Esto bajará un archivo llamado composer.phar y lo depositará en el directorio /usr/local/bin. Y ya hemos acabado. ¿Y he leído por ahí que alguien decía que era difícil? ¡Tendrían que haber instalado alguna red Novell en su vida! 😀

Como decía, ya tenemos todo lo que necesitamos para crear nuestra primera aplicación con Laravel. Empezamos. Nuestro primer proyecto se llamará prueba y estará en el directorio /var/www/html/prueba. Lo primero que tenemos que hacer es hacer que composer nos cree toda la estructura necesaria:

cd /var/www/html
composer.phar create-project laravel/laravel prueba --prefer-dist

Asignamos los permisos adecuados en la estructura que se ha creado:

chgrp -R www-data /var/www/html/your-project
chmod -R 775 /var/www/html/your-project/storage

Creamos un virtual host adecuado en el directorio /etc/apache2/sites-availables. En mi caso le he puesto laravel.conf y el contenido creado es este:

<VirtualHost *:80>
    DocumentRoot /var/www/html/prueba/public
    DirectoryIndex index.php
    <Directory /var/www/html/prueba>
        AllowOverride All
    </Directory>
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

Por último, deshabilitamos el virtual host que apache crea por defecto, habilitamos el nuestro, habilitamos el modulo rewrite de apache y reiniciamos el servidor web:

a2dissite 000-default.conf
a2ensite laravel.conf
a2enmod rewrite
systemctl restart apache2

Si ahora apuntamos con un navegador a la ip de nuestra máquina debian veremos la página de inicio de Laravel:

Laravel 5.6 en Debian 9.4

Script desatendido para eliminar ficheros antiguos de un servidor ftp

Hace ya un tiempo que dejamos por aquí el “esqueleto” de un script para realizar una conexión y transferencia desatendida a un servidor ftp. La finalidad del mismo era automatizar los backups en nuestro hosting cuando lo que nos proporcionan para ello es este medio. Auxiliar a este tenía uno que eliminaba los backups antiguos, pero nunca llegué a estar demasiado satisfecho de él. Hace poco buscando mejorarlo vi una solución maravillosamente elegante en stackoverflow. El script original es este:

#!/bin/bash
# get a list of files and dates from ftp and remove files older than ndays
ftpsite="ftp.yourserver.com"
ftpuser="loginusername"
ftppass="password"
putdir="/public_ftp/admin/logs"

ndays=7

# work out our cutoff date
MM=`date --date="$ndays days ago" +%b`
DD=`date --date="$ndays days ago" +%d`

echo removing files older than $MM $DD

# get directory listing from remote source
listing=`ftp -i -n $ftpsite <<EOMYF 
user $ftpuser $ftppass
binary
cd $putdir
ls
quit
EOMYF
`
lista=( $listing )

# loop over our files
for ((FNO=0; FNO<${#lista[@]}; FNO+=9));do
  # month (element 5), day (element 6) and filename (element 8)
  #echo Date ${lista[`expr $FNO+5`]} ${lista[`expr $FNO+6`]}          File: ${lista[`expr $FNO+8`]}

  # check the date stamp
  if [ ${lista[`expr $FNO+5`]}=$MM ];
  then
    if [[ ${lista[`expr $FNO+6`]} -lt $DD ]];
    then
      # Remove this file
      echo "Removing ${lista[`expr $FNO+8`]}"
      ftp -i -n $ftpsite <<EOMYF2 
      user $ftpuser $ftppass
      binary
      cd $putdir
      delete ${lista[`expr $FNO+8`]}
      quit
EOMYF2

    fi
  fi
done

Por comentarlo un poco y “ganarnos el pan”, el script tiene tres bloques: el primero de definición de variables que tendrás que personalizar con tus datos (hasta la línea 8 incluida), el segundo en el que se realiza una conexión con el servidor y se obtiene un listado de todos los ficheros que están en el directorio que indicamos (hasta la línea 25) y por último un tercer bloque en el que se realiza el borrado propiamente dicho.

En el primer bloque la variable ndays en la línea 8 define la máxima antigüedad de los ficheros que no se eliminaran (7 días en este caso) y la variable putdir en la 6 el directorio del servidor ftp donde dejamos los archivos. Si, como yo, dejas los backups directamente en el raiz del servidor ftp puedes eliminar (o comentar) las líneas 6, 20 y 42

En el segundo bloque, la línea 14 indica la fecha límite de los ficheros que se conservaran. Todos los anteriores a esta se eliminarán. Si no quieres que aparezca en la salida puedes eliminarla o comentarla.

En el tercer bloque, si quieres hacer pruebas de que el script funciona antes de lanzarlo en modo real, puedes comentar la línea 43. Esto te mostrará en la consola los ficheros que se eliminarían pero no te los borrará realmente con lo cual podrás comprobar que el script hace lo que realmente necesitas. La línea 38 es la que te muestra el fichero que va a borrarse. Puedes eliminarla o comentarla también cuando ya no te interese. Por último, la línea 30 que aparece comentada muestra un listado de todos los ficheros del servidor ftp antes de realizar el borrado. Puedes descomentarla también para evaluar si está trabajando de forma correcta.

Chuletillas (y XXXXV) – Integrar comandos MySQL en un shell script

chuletaExisten diversas formas de integrar comandos de MySQL dentro de un shell script de linux. La más cómoda, creo, es utilizar el parámetro -e del cliente en línea de myql. Por ejemplo, así:

#!/bin/sh
# comandos bash...
mysql -u usuario -p -e "CREATE DATABASE ejemplo;"
#comandos bash...

Lo que pasa es que así puesto sirve de bien poco porque nos va a pedir el password de forma interactiva. Para evitarlo podemos poner la password en el propio archivo del script. No es un método elegante ni especialmente seguro, pero en entornos poco críticos sirve perfectamente:

#!/bin/sh
PASSWORD=mipassword
# comandos bash...
mysql -u usuario --password=$PASSWORD -e "CREATE DATABASE ejemplo;"
#comandos bash...

Por último, si tenemos que ejecutar varios comandos, lo más cómodo es escribirlos uno a continuación de otro en un archivo independiente (con extensión sql por claridad) y ejecutarlos usando el comando source de mysql:

#!/bin/sh
PASSWORD=mipassword
# comandos bash...
mysql -u usuario --password=$PASSWORD -e "source /opt/sripts/imysql/importar_databases.sql"
#comandos bash...
NOTA: Todo lo dicho aquí sirve igualmente para MariaDB

Nombres de fichero con marcas de tiempo o secuenciales

chuleta A veces necesitamos generar ficheros a intervalos regulares en un determinado directorio sin perder los creados anteriormente. Para hacerlo de forma automática y desde un script es necesario que los nombres de los ficheros generados sean diferentes en cada ocasión. Existen distintas formas de hacer esto. Os voy a contar mis dos favoritas con un ejemplo en el que volcamos en el fichero un listado con los procesos en ejecución en el momento de crearlo.

En el primer método creamos un fichero cuya marca distintiva es un número secuencial que empieza por el 0 y que se irá incrementando de 1 en 1. En este ejemplo los ficheros creados serán ps_0.txt, ps_1.txt, etc.

#!/bin/sh
cd /var/archivos/
numero=$(ls ps* | wc -l)
fichero=ps_$numero.txt
ps aux --sort -rss > $fichero

El segundo método usa una marca de tiempo que incluye año, mes, día, hora y minuto. Al generar el fichero en el momento de escribir este texto el nombre sería ps_20160401-17:55.txt

#!/bin/sh
cd /var/archivos/
fecha=`date +%Y%m%d-%H:%M`
fichero=ps_$fecha.txt
ps aux --sort -rss > $fichero

Script desatendido de conexión a un servidor FTP

Al contratar espacio de backup en la mayoría de las empresas de hosting la opción más habitual sigue siendo a través de FTP. Para automatizar las copias de forma desatendida necesitamos programar estas, habitualmente lanzando un script a través de cron. Si buscas un modelo para construir el tuyo puedes hacerlo a partir de este:

#!/bin/sh

HOST='ip_del_ftp_server'
USER='nombre_de_usuario'
PASSWD='password'

ftp -n -i $HOST <<END_SCRIPT
quote USER $USER
quote PASS $PASSWD
cd /file_backups
lcd /home/administrador/file_backups
mput *
cd /mysql_backups
lcd /home/administrador/mysql_backups
mput *
quit
END_SCRIPT
exit 0

El script supone que ya tenemos los ficheros que queremos copiar en dos directorios locales: /home/adminstrador/file_backups y /home/administrador/mysql_backups. Haremos la copia en dos directorios del servidor ftp que se llaman /file_backups y mysql_backups. Los parámetros -n y -i de la conexión al servidor desactivan, respectivamente, el autologin y el modo interactivo (para evitar que el servidor ftp nos pida confirmación en cada operación de copia).

Manual de HTML, CSS (y algo de Javascript)

lenguajes Recopilación ordenada de apuntes de diferentes módulos (Lenguajes de marcas, Implementación de aplicaciones web, etc.) que, unidos, constituyen un completo manual de casi 130 páginas, válido tanto para quien quiera iniciarse en la realización de páginas web como para quien desee aprender algunos trucos avanzados (transpariencias, contorneos, menús, solapas, etc) o quiera empezar a manejar alguna de las nuevas características de HTML5 (canvas, geolocalización, etc.).

El manual se complementa con todos los ejemplos que se se citan en él y alguno más y que pueden descargarse integramente desde aquí.

Descargar “HTML & CSS”

Codelite, un IDE multiplataforma para C y C++

Binary Hacía mucho, mucho tiempo que no le dedicaba tanto tiempo a la programación como este año y lo primero que tuve que hacer fue buscarme un buen IDE para trabajar en C/C++. El principal requisito que debía de cumplir (aparte de, por supuesto, que fuese funcional y cómodo) era ser multiplataforma. Si además era software libre, mejor que mejor.

La única herramienta que conocía con estas características era Eclipse con el plugin CDT para trabajar en C/C++ pero a mi juicio resulta demasiado pesado. En otras ocasiones había trabajado con Anjuta o con Kdevelop pero el primero es demasiado sobrio y sólo funciona en GNU/Linux y el segundo es demasiado aparatoso y, aunque podría funcionar sobre windows, mis experiencias usando aplicaciones de KDE sobre el entorno de ventanitas de Redmon no han sido nada favorables hasta la fecha.

En esto estaba, cuando llegué a este hilo de Barrapunto de finales del año pasado y apartando a un lado a trolls y fundamentalistas varios me quedé con dos herramientas plenamente satisfactorias: Codelite, mi elegida, y Code::Blocks, una meritoria finalista.

Codelite

Codelite es un IDE ligero, cómodo y muy funcional, con buenas herramientas para debug, con binarios para prácticamente todas las plataformas y las distribuciones más comunes, soporte para plugins (algunos de ellos muy útiles) y con un grupo de desarrollo muy, muy, activo. A esta hora ya hay nuevos binarios para Fedora 12, Ubuntu 9.10 y OpenSuse 11.2. La verdad es que me ha dejado tan buen sabor de boca desde el primer momento que ni le he dado una oportunidad a su competidor, pero a primera vista me ha parecido que se trata de un proyecto mucho menos activo (las últimas aportaciones al proyecto son de marzo de 2008).