Como instalar bootstrap en laravel con npm

En este articulo vamos a ver como instalar bootstrap en Laravel mediante npm. Necesitamos tener npm instalado y un proyecto en Laravel.

Instalación de bootstrap

Ejecutamos el siguiente comando en la raíz del proyecto Laravel:

npm install bootstrap

Con esto lo que hacemos es descargar a la carpeta node_modules la librería bootstrap.

Veremos que se muestra algo como esto:

Y una vez el comando se completa se nos modifican 2 archivos, por un lado vemos en el archivo package.json que se ha instalado la última versión estable de bootstrap:

package.json

Y por otro vemos en package-lock.json que se registra lo que se descargó exactamente:

package-lock.json

Creación de archivos CSS y JS

Una vez tenemos el código de bootstrap descargado en al carpeta de node_modules lo que tenemos que hacer es crear los archivos CSS y JS que serán leídos por el navegador y con esto tendremos boostrap cargado.

Dependiendo de las versiones de Laravel es posible que tengamos el archivo resources/scss/app.scss o no, si no lo tenemos lo creamos y añadimos la siguiente línea:

@import '~bootstrap/scss/bootstrap';

Ahora nos vamos al archivo webpack.mix.js y comprobamos que la constante mix tenga los métodos js y sass con los siguientes parámetros:

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

Lo que hacemos es decirle a Laravel mix que compile el código de la entrada generando un archivo de salida en este caso el código del archivo resources/js/app.js lo compilará en el archivo public/js/app.js y el código de resources/sass/app.scss en public/css/app.css

Ahora ejecutamos el comando npm run para generar los archivos de public (usaremos prod para producción o dev para desarrollo):

 npm run prod

Carga de archivos CSS y JS por el navegador

Añadimos en el head la carga de los archivos css:

<link rel="stylesheet" href="{{ asset('css/app.css') }}">

Y al final del body cargamos el archivo js:

<script src="{{ asset('js/app.js') }}" defer></script>

Posibles errores

Si recibimos un error como este:

npm WARN bootstrap@5.1.1 requires a peer of @popperjs/core@^2.10.1 but none is installed. You must install peer dependencies yourself.

Es por que debemos tener instalado popperjs (esto solo pasa para poder instalar bootstrap ejecutamos el siguiente comando:

npm install @popperjs/core

Como trabajar con fechas en php

Para trabajar con fechas en php tenemos varias opciones, desde usar la función date a trabajar con timestamp. En este artículo vamos usar el objeto DateTime por la potencia que ofrece. Y para agregarle funcionalidades vamos agregar la librería Carbon.

La clase DateTime

La clase nativa que PHP nos proporciona para trabar con fechas.

Obtener la fecha actual

$fecha = new DateTime();

Ahora $fecha contiene la fecha en la que se ejecuta el código, si hacemos var_dump a este objeto obtendremos algo como esto:

var_dump del objeto DateTime

El constructor de la clase acepta dos parámetros opcionales, el primero una fecha y el segundo un objeto DateTimeZone. Si no pasamos el primer parámetro como en el ejemplo anterior se recoge la fecha actual.

Trabajar con una fecha concreta

Tenemos una fecha guardada en base de datos que queremos transformar al objeto DateTime para trabajar con ella, lo que tenemos que hacer es pasarsela como string al constructor de la clase DateTime como primer parámetro, por ejemplo:

$fecha = new DateTime('2008-08-07 18:11:31');

Ojo con esto, para que la fecha se inicie correctamente la fecha debe de estar en un formato especifico. Por ejemplo el formato que usamos en España «dia/mes/año» no nos sirve. Si creamos un objeto DateTime a partir de la fecha «01/02/2020» no vamos a crear el día uno de febrero de 2020, vamos a crear el día dos de Enero de 2020, esto es por que php espera la fecha en formato americano, mucho cuidado con esto. Puedes ver que formatos están admitidos en este enlace: https://www.php.net/manual/es/datetime.formats.php.

Yo recomiendo trabajar con el formato de MySQL por que es uno de los más extendidos y nos facilita el trabajo al usar esta base de datos. El formato de MySQL es «Año-mes-día hora:minuto:segundo» por ejemplo «2008-08-07 18:11:31».

Fechas con formato no admitido

¿Que pasa cuando queremos inicializar la clase DateTime a partir de una fecha con un formato que no admite el constructor o no es el que espera?

Vamos con el ejemplo anterior, tenemos la fecha «01/02/2020», si creamos un objeto DateTime como hemos dicho se va a crear el día dos de Enero de 2020, y queremos crear la fecha uno de Febrero de 2020 para esto tenemos que indicarle al objeto DateTime el formato en el que tenemos la fecha con su método estático createFromFormat, vamos a ver un ejemplo:

$fechaA = new DateTime('01/02/2020'); // Dos de Enero de 2020
$fechaB = DateTime::createFromFormat('d/m/Y', '01/02/2020'); // Uno de Febrero del 2020

De esta forma especificando el formato podemos iniciar cualquier fecha con el objeto DateTime, podemos ver como construir el formato en el siguiente enlace https://www.php.net/manual/es/datetime.createfromformat.php#refsect1-datetime.createfromformat-parameters

La librería Carbon

Carbon (https://carbon.nesbot.com/) es una extensión de la clase DateTime que nos aporta montón de funcionalidades extra para trabajar con fechas.

Instalación

Usamos composer para instalar carbon.

composer require nesbot/carbon

Como usamos esta librería

Carbon es una clase que extiende de la case nativa DateTime, por lo tanto la usamos de la misma forma que usamos el objeto DateTime.

<?php
require 'vendor/autoload.php';
use Carbon\Carbon;
$fecha = new Carbon();

La potencia de carbon

Carbon, añade al objeto DateTime múltiples métodos que agregan nuevas funcionalidades y facilitan otras. Podemos verlas en la documentación oficial https://carbon.nesbot.com/docs/

Algunos de los métodos que nos proporciona carbon:

$fecha->addMonth(); // Añade un mes a la fecha
$fecha->subMonth(); // Quita un mes a la fecha
$fecha->startOfYear(); // Setea la fecha al primer día del año con tiempo 00:00:00
$fecha->endOfDay(); // Setea la fecha último día del año con tiempo 23:59:59.999999
$fecha->diffForHumans($fecha2) // Devuelve la diferencia de dos fechas en texto por ejemplo "2 segundos antes" (para que el texto este en castellano hay que especificar la localización $fecha->locale('es');)

Aún más potencia

Si creamos una nueva clase que llamemos por ejemplo Fecha y la extendemos de Carbon tendremos toda la potencia de carbon con el objeto nativo DateTime y nuestros métodos personalizados, todo en la misma clase:

<?php

use Carbon\Carbon;

class Fecha extends Carbon
{
    function miMetodoPersonalizado() {
        
    }
}

Como instalar fontawesome en laravel

Fontawesome (https://fontawesome.com/) es una librería que nos proporciona un conjunto de iconos de forma gratuita que podemos usar en nuestra web. También dispone de un plan de pago para ampliar los iconos gratuitos. En este artículo vamos a ver como instalar fontawesome en laravel con npm y como usar sus iconos.

Instalación

Ejecuta el siguiente comando en la raíz del proyecto:

npm install --save @fortawesome/fontawesome-free

En el archivo package.json verás que se añade la dependencia @fortawesome/fontawesome-free

Añade en el archivo resources\sass\app.scss la siguiente linea:

@import '~@fortawesome/fontawesome-free/css/all.css';

Por ultimo ejecuta el siguiente comando en la raíz del proyecto:

npm run dev

Como usar los iconos

Lo único que tenemos que hacer una vez instalado es irnos al buscador https://fontawesome.com/icons?d=gallery y buscar el icono que necesitamos por emplo si escribimos «user» dentro de los iconos gratuitos nos salen los siguientes:

Seleccionamos el tercero y hacemos click en la etiqueta i, automáticamente esta etiqueta se nos copiará al portapapeles.

Lo pegamos en nuestra vista y listo:

<div class="card-body">
    @if (session('status'))
        <div class="alert alert-success" role="alert">
            {{ session('status') }}
        </div>
    @endif

    You are logged in! <i class="fas fa-user"></i>
</div>

Posibles problemas

La ruta de los recursos no se genera correctamente y los iconos no se muestran. Por defecto solo funciona si tenemos la aplicación en la raíz del dominio, de lo contrario veremos esta imagen:

Es decir si la url de la aplicación es «http://localhost/laravel/public/» no va a funcionar, necesitaríamos tenerla en «http://localhost/». Si estas en local puedes crear un virualhost para que apunte a la carpeta public de la aplicación.

Otra solución es usar setResourceRoot por ejemplo:

mix.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.setResourceRoot('../');

Donde antes teníamos un ruta como:

/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.eot?8e49b728413079dfd9ee45d0c58d54e4

Ahora tenemos la siguiente:

../fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.eot?8e49b728413079dfd9ee45d0c58d54e4

Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, bool given

ERROR

SOLUCIÓN: Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, bool given in

CAUSA

La función mysqli_query esta retornando false por que la sentencia sql está fallando.

SOLUCIÓN

Una vez hecho el mysqli_query() usa mysqli_error() para debugear la sentencia sql y ver que está fallando:

if(!$resultado) {
    var_dump(mysqli_error($link));
    exit;
}

Un ejemplo de como quedaría una consulta:

<?php

$host = 'localhost'; // La dirección de la base de datos, puede ser o un nombre de host o una dirección IP
$username = 'root'; // El usuario de la base de datos
$passwd = ''; // La contraseña del usuario
$dbname = 'demo'; // El esquema predeterminado para realizar las consultas

$link = mysqli_connect($host, $username, $passwd, $dbname);
if (mysqli_connect_errno()) {
    printf("Falló la conexión: %s\n", mysqli_connect_error());
    exit();
}

$query = "SELECT * FROM usuarios";
$resultado = mysqli_query($link, $query);
// Inserta este if
if(!$resultado) {
    var_dump(mysqli_error($link));
    exit;
}

while ($row = mysqli_fetch_assoc($resultado)) {
    printf ("%s (%s)\n", $row["id"], $row["nombre"]);
}

Caracteres extraños en acentos o símbolos

La solución universal para este tipo de problema es tener todo con codificación utf8. Este articulo repasa cinco puntos que debes de tener en cuenta para no tener problemas de codificación.

Los archivos con codificación uf8 sin bom

Todos los archivos que componen el proyecto tienen que tener codificación utf8 sin bom.

¿Como sabemos la codificación de un archivo? Hay muchas formas pero una de ella es abriendo el archivo con el notepad++ en la barra inferior podemos ver la codificación, tiene que salir UTF-8

Las páginas que genera la aplicación con charset utf8

Todas las páginas que genera la aplicación tienen que tener charset utf8 en el head.

Para ver si el charset esta correcto solo tenemos que inspeccionar el código fuente. Se suele indicar al inicio de la etiqueta head en documento html como en el siguiente ejemplo:

<!DOCTYPE html>
<html id="html" lang="es">
<head>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Mi web</title>

La conexión a base de datos con charset utf8

Si tu aplicación usa base de datos para guardar la conexión a esta se debe de configurar con el charset utf8. Hay varias formas de iniciar una conexión y cada una tiene su forma de configurar, voy a poner ejemplos de las 2 mas usadas, mysqli y pdo:

<?php
$mysqli = new mysqli("localhost", "mi_usuario", "mi_contraseña", "test");
// Justo después de abrir la conexión establecemos el charset a utf8
$mysqli->set_charset("utf8")
?>

Los esquemas con charset en utf8mb4 y collate en utf8mb4_unicode_ci

Podemos saber estos valores con la siguiente consulta:

SELECT * FROM information_schema.SCHEMATA WHERE schema_name = "nombre_esquema" 

Las tablas de cada esquema con collation utf8mb4_unicode_ci

Podemos consultar el cotejamiento de cada tabla desde phpmyadmin:

Como traducir los mensajes de validación de Laravel

Laravel por defecto viene con varios textos para los errores de validación en ingles por ejemplo:

Para traducirlos nos vamos al siguiente repositorio https://github.com/Laraveles/spanish, entramos en «resources/lang» y copiamos la carpeta «es» y el archivo «es.json» al directorio «resources/lang» de nuestro proyecto. Quedaría de la siguiente forma:

Ahora debemos decirle a laravel que coja las traducciones de la carpeta es y no de en. Nos vamos a «config/app.php» y en la clave «locale» indicamos «es».

'locale' => 'es',

Listo ya tenemos los textos por defecto traducidos:

Como configurar el Debugger en PHPStorm

En este artículo vamos a ver como configurar el debugger en phpstorm. Para esto necesitamos tener instalado el xdebug si no lo tienes revisa antes el siguiente articulo:
https://gragot.com/php/como-instalar-xdebug-en-windows/

1) Validar la configuración

Abrimos la configuración de phpstorm con (Ctrl + alt + s), nos vamos a Settings – Languages & Framewoks – PHP – Debug hacemos click en validate y corrige los problemas hasta obtener todo ok:

Posibles problemas

Remote debug is not enabled

Añade la siguiente linea al archivo php.ini

xdebug.remote_enable=1

2) Instalar en el navegador una extensión

Para que el debugger pueda capturar las peticiones http tenemos que indicarlo mediante una cookie, si la petición http no tiene esta cookie el debugger de phpstorm no la va a capturar. El nombre de la cookie tiene que ser XDEBUG_SESSION y el valor PHPSTORM. Lo que hace la extensión es insertar esta cookie en cada petición http que enviamos al servidor.

También puedes insertar manualmente esta cookie para enviar peticiones http sin la extensión del navegador, por ejemplo con postman.

Dependiendo del navegador tenemos varias extensiones disponibles , en este enlace podemos verlas
https://www.jetbrains.com/help/phpstorm/browser-debugging-extensions.html yo desarrollo con el firefox y la extensión que utilizo es esta:
https://addons.mozilla.org/en-US/firefox/addon/xdebug-ext-quantum/

3) Poner el phpstorm a escuchar las peticiones http

En este punto lo único que tenemos que hacer es click en el siguiente botón (extremo superior derecha del ide)

Se nos quedaría con el siguiente icono:

4) Crear puntos de interrupción

Por último lo que tenemos que hacer es crear los puntos de interrupción, hacemos click entre el numero y el codigo y la linea se nos quedará marcada con un redondo rojo:

Como instalar xdebug en windows

En este artículo vamos a ver como instalar xdebug en windows, para comprobar la instalación de xdebug vamos a utilizar el siguiente código de ejemplo:

<?php
$array = [
    'string' => 'string',
    'int' => 1,
    'true' => true
];
var_dump($array)
?>

Si nuestro servidor no tiene xdebug instalado el código de ejemplo se verá de la siguiente forma:

Instalación

xdebug es una librería (un archivo con extensión .dll). Lo primero que tenemos que hacer es descargar este archivo .dll pero xdebug tiene muchas versiones y opciones.

Por ejemplo para la última versión de xdebug compatible con php 7.3
(en el momento de escribir este articulo es la 2.7.2) tenemos 4 opciones disponibles:

¿Entonces cual descargamos? xdebug tiene un asistente que nos va a solucionar este problema. Lo primero que tenemos que hacer es ejecutar phpinfo(), esta función va a imprimir por pantalla una serie de datos que tenemos que copiar íntegros, lo copiamos todo (control + a)

Accedemos a la web https://xdebug.org/wizard.php y pegamos la información proporcionada por phpinfo() en el textarea:

Una vez copiado, hacemos click en «Analyse my phpinfo() output»

Se nos muestra una nueva página con información de nuestro sistema y las instrucciones para instalar xDebug:

En el punto uno tenemos un enlace a la librería exacta que es compatible con nuestro sistema. Descargamos este archivo y lo movemos a la dirección que nos muestra el punto dos. Modificamos el archivo php.ini, tenemos su ruta en el punto tres y añadimos una nueva linea, la que nos indica el punto tres (zend_extension = …). Por último reiniciamos apache.

Una vez finalizada la instalación el código de ejemplo se verá de la siguiente forma:

Laravel Mix

Laravel Mix proporciona una API fluida para definir los pasos de compilación de Webpack utilizando varios procesadores de CSS y JavaScript comunes

DEFINICIóN Oficial

El objetivo es, entre otras cosas, procesar todo nuestro código css, minificarlo y combinarlo en un solo archivo. Lo mismo para el código javascript, minificar, ofuscar y combinar todo el código en un solo archivo. Con laravel mix nuestras páginas web son mas seguras y rápidas.

Laravel mix está optimizado para usar con laravel, pero se puede utilizar en cualquier aplicación web, tenga laravel o no. Este artículo lo enfocaremos a una aplicación sin laravel.

Instalación

Para instalar laravel mix necesitamos tener instalado npm, nos situamos en la raíz del proyecto y ejecutamos los siguientes comandos:

npm init -y
npm install laravel-mix --save-dev
npm install cross-env --save-dev
cp node_modules/laravel-mix/setup/webpack.mix.js ./

npm init: Creamos el archivo package.json, con -y omitimos el cuestionario y el archivo se creara con datos por defecto.

Editamos el archivo package.json y sustituímos la propiedad «scripts»:

"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
},

Por el siguiente código:

"scripts": {
  "dev": "npm run development",
  "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
  "watch": "npm run development -- --watch",
  "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
  "prod": "npm run production",
  "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
},

Preparación

Ahora vamos a preparar nuestros archivos css para ser procesados y combinados en un solo archivo. Creamos un archivo llamado app.scss en un directorio que no sea público por el navegador, por ejemplo «resources/sass», en este archivo importamos todos nuestros archivos

@import "bootstrap.scss";
@import "tema.scss";
@import "flexslider.scss";
@import "custom.scss";
@import "josefin_sans.scss";
@import "roboto_condensed.scss";

Modificamos el archivo webpack.mix.js para indicar con mix.sass la ruta de del archivo app.scss y la ruta del archivo css, que genera laravel mix después de procesar nuestro archivo app.scss:

mix.sass('resources/sass/app.scss', 'src/app/webroot/css');

Ahora vamos a preparar nuestros archivos js. Modificamos el archivo
webpack.mix.js y usamos mix.combine para combinar nuestros archivos js. Como primer parámetro, le pasamos las rutas de los archivos js en un array y, como segundo parámetro, la ruta del archivo js resultante procesado por laravel mix:

mix.combine([
    'resources/js/jquery-2.1.4.min.js',
    'resources/js/main.js',
    'resources/js/bootstrap.js',
    'resources/js/classie.js',
    'resources/js/jarallax.js',
    'resources/js/jquery.flexslider.js',
    'resources/js/custom.js'
], 'src/app/webroot/js/app.js');

Ejecución

Por último solo tenemos que ejecutar los comandos que van a procesar tanto nuestro código css como nuestro código javascript. Tenemos los comandos dev, pensado para desarrollo (no minifica ni ofusca el código) y prod, que lo usaremos para producción:

npm run dev
npm run prod

Ventajas y resultado

Vamos a ver un ejemplo de una web en la que hemos aplicado laravel mix
para procesar sus archivos css y js .

Antes

Resultado de google page speed
Solicitudes http para cargar la web

Después


Resultado de google page speed

Solicitudes http para cargar la web

¿Qué ha pasado?

En primer lugar, vemos que para cargar la web en un primer momento necesitábamos 23 solicitudes, después de aplicar laravel mix solo 12. Esto se debe a que todos los archivos css y js (11) ahora se encuentran combinados en 2, uno que tiene todo el código css y otro tiene todo el código js. Con esto reducimos los tiempos de carga.

Por otro lado vemos que gracias a la minificación y la ofuscación logramos, por un lado, mejorar la seguridad de nuestra web y, por otro, reducir el tamaño de los datos recibidos. Esto ayuda a consumir menos datos en nuestras tarifas y por supuesto, acorta los tiempos de carga en nuestra web.

Por último, vemos la valoración de google page speed donde nuestra puntuación mejora notablemente.

Más información

Página oficial de laravel mix: https://laravel-mix.com
Página oficial de webpack: https://webpack.js.org/

PHP Warning: Xdebug MUST be loaded as a Zend extension

ERROR

PHP Warning: Xdebug MUST be loaded as a Zend extension

Este error lo podemos ver en varias situaciones:

  • Ejecutando php por CLI
  • Instalando composer
  • Actualizando composer

CAUSA

Tenemos xdebug cargado como sin zend_extension

SOLUCIÓN

Cargar la extensión xdebug como zend_extension

1) Abrimos el php.ini
2) Localizamos la siguiente linea donde cargamos la extensión xdebug, en mi caso es la siguiente:

extension=php_xdebug.dll

3) Sustituimos la palabra «extension» por «zend_extension» quedando en mi caso, de las siguiente forma:

zend_extension=php_xdebug.dll

4) Reiniciamos el apache