Autonomía digital y tecnológica

Código e ideas para una internet distribuida

Pequeña guía de desarrollo rápido y optimizado de un theme de WordPress usando un starter theme, npm, gulp y sass

Imago voragine.net
[actualizado el ]

La mayor parte de los sitios web que funcionan con WordPress pueden hacerlo eligiendo un theme del repositorio oficial o de cualquier otro y personalizándolo con las opciones disponibles en el panel de control. Incluso si se necesita desarrollar un theme hoy día es buena idea no empezar de cero, sino usando una estructura básica, genérica ya desarrollada. Por otro lado es recomendable usar ciertas herramientas que produzcan un theme optimizado, que cargue lo más rápido posible, que se adapte a todo tipo de dispositivos. Esto pasa, además de por estructurar bien la información para minimizar las consultas a base de datos, por producir archivos CSS, JS minimizados e imágenes comprimidas y optimizadas que agilicen la carga. Un buen starter theme para WordPress facilita ambas cosas: una estructura genérica sobre la que empezar a construir rápidamente, y un entorno de desarrollo que permita automatizar las tareas de optimización e ir probando los avances ágilmente.

En este post comparto mi manera de trabajar: qué starter theme utilizo últimamente y cuál es el flujo de trabajo con él.

Understrap Starter theme

Undestrap es el starter theme que mejor se adapta a mi manera de desarrollar, que tiene todo lo que necesito:

  • npm para instalar y gestionar librerías y otras dependencias.
  • Gulp para automatizar rutinas: compilación de archivos de estilo y javascript, optimización de imágenes, carga de librerías y otras dependencias en la estructura del theme…
  • Brwsersync para ir probando el desarrollo en tiempo real en el navegador.
  • Bootstrap 4 como framework de maquetación.
  • understrap-child como child theme para no tocar el theme understrap y poder actualizarlo en cualquier momento.

Tiene una comunidad bastante activa: el repositorio del theme tiene 73 usuarios que mantiene el proyecto muy actualizado. Por ejemplo, cuando escribo esto theme funciona con la última versión 4.3.1 de bootstrap que salío hace menos de un mes. La comunidad ha desarrollado varios child themes. Algunos están disponibles libremente en la cuenta de github del proyecto, otros son de pago. La documentación del theme no es una maravilla, pero algo hay.

Instalar Understrap y todo lo necesario

node.js y npm

Para empezar a desarrollar con Understrap hace falta instalar primero el gestor de paquetes npm, que nos permitirá después instalar el resto de paquetes y librerías que usa Understrap; y node.js que permite levantar un servidor web en local para el desarrollo.

Como acostumbro en este blog cuento cómo instalar ambas dependencias en un entorno Debian 10 Buster. Versiones suficientemente actualizadas de npm y nodejs, aunque no las últimas, se puede instalar desde los repositorios oficiales de Debian:

sudo apt-get update
sudo apt install npm nodejs

Para instalar la última versión de node.js, que no es necesario para trabajar con Understrap, se pueden seguir las instrucción de Nodesource. Para instalar la última versión de npm se puede consultar su repositorio en github.

Cómo actualizar con npm las librerías que usa el theme

npm es muy útil para mantener actualizadas las librerías que usa el starter theme. Por ejemplo, si el framework Bootstrap libera una nueva versión, se puede incorporar a nuestros proyecto usando npm. Primero hay que moverse a la carpeta que contenga el theme. Con npm outdated se puede ver los paquetes que no están actualizados:

skotperez@lee:~$ cd understrap-child
skotperez@lee:~/understrap-child$ npm outdated
Package            Current  Wanted  Latest  Location
bootstrap            4.1.3   4.1.3   4.3.1  understrap-child
del                  3.0.0   3.0.0   4.1.0  understrap-child
gulp                 3.9.1   3.9.1   4.0.0  understrap-child
gulp-autoprefixer    5.0.0   5.0.0   6.0.0  understrap-child
gulp-clean-css      3.10.0  3.10.0   4.0.0  understrap-child
gulp-imagemin        4.1.0   4.1.0   5.0.3  understrap-child
gulp-sass            4.0.1   4.0.1   4.0.2  understrap-child
gulp-sourcemaps      2.6.4   2.6.4   2.6.5  understrap-child
gulp-uglify          3.0.1   3.0.2   3.0.2  understrap-child
popper.js           1.14.7  1.15.0  1.15.0  understrap-child
understrap           0.8.9   0.8.9   0.9.1  understrap-child

Para actualizar los paquetes:

skotperez@lee:~/understrap-child$ npm install
> understrap-child@0.5.3 postinstall /home/skotperez/Documentos/m34/code/themes/understrap-child-alisal
> gulp copy-assets

[14:29:09] Using gulpfile ~/Documentos/m34/code/themes/understrap-child-alisal/gulpfile.js
[14:29:09] Starting 'copy-assets'...
[14:29:09] Finished 'copy-assets' after 611 ms
npm WARN bootstrap@4.1.3 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself.
npm WARN bootstrap@4.2.1 requires a peer of jquery@1.9.1 - 3 but none is installed. You must install peer dependencies yourself.
npm WARN gulp-imagemin@5.0.3 requires a peer of gulp@>=4 but none is installed. You must install peer dependencies yourself.
npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@1.2.7 (node_modules/fsevents):
npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@1.2.7: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"x64"})

added 67 packages in 94.097s

Cuando se ejecuta npm para actualizar, una vez que se han descargado las últimas versiones, se ejecuta gulp copy-assets para copiar las nuevas versiones a las ubicaciones adecuadas del theme, tal como se definen en gulpconfig.json, como se explica en el apartado sobre Gulp de este tutorial.

Usar ncu en lugar de npm para controlar qué librerías se actualizan

Si se quieren actualizar paquetes sin tener en cuenta el archivo package.json se puede hacer con ncu. Para ello hay que instalarlo primero:

skotperez@lee:~/understrap-child$ sudo npm install -g npm-check-updates
/usr/bin/npm-check-updates -> /usr/lib/node_modules/npm-check-updates/bin/npm-check-updates
/usr/bin/ncu -> /usr/lib/node_modules/npm-check-updates/bin/ncu
+ npm-check-updates@3.1.7
added 154 packages in 15.617s


   ╭─────────────────────────────────────╮
   │                                     │
   │   Update available 5.5.1 → 6.9.0    │
   │     Run npm i -g npm to update      │
   │                                     │
   ╰─────────────────────────────────────╯

En este caso, al instalar ncu, npm nos indica además que hay una actualización para el propio npm. Se puede actualizar también como nos indica:

skotperez@lee:~/understrap-child$ sudo npm i -g npm
/usr/bin/npx -> /usr/lib/node_modules/npm/bin/npx-cli.js
/usr/bin/npm -> /usr/lib/node_modules/npm/bin/npm-cli.js
+ npm@6.9.0
updated 1 package in 13.85s

Para comprobar las actualizaciones pendientes:

skotperez@lee:~/understrap-child$ ncu
Checking package.json
[====================] 30/30 100%

 bootstrap            4.1.3  →    4.3.1 
 browser-sync       ^2.23.6  →  ^2.26.3 
 del                 ^3.0.0  →   ^4.1.0 
 gulp                 3.9.1  →    4.0.0 
 gulp-autoprefixer   ^5.0.0  →   ^6.0.0 
 gulp-clean-css      ^3.9.2  →   ^4.0.0 
 gulp-cssnano        ^2.1.2  →   ^2.1.3 
 gulp-imagemin       ^4.1.0  →   ^5.0.3 
 gulp-plumber        ^1.2.0  →   ^1.2.1 
 gulp-rename         ^1.2.2  →   ^1.4.0 
 gulp-sass            4.0.1  →    4.0.2 
 gulp-sourcemaps      2.6.4  →    2.6.5 
 gulp-uglify         ^3.0.0  →   ^3.0.2 
 merge2              ^1.2.1  →   ^1.2.3 
 popper.js          ^1.12.9  →  ^1.15.0 
 understrap          ^0.8.6  →   ^0.9.1 

Run ncu -u to upgrade package.json

El mismo ncu nos dice cómo proceder:

skotperez@lee:~/understrap-child$ ncu -u
Upgrading package.json
[====================] 30/30 100%

 bootstrap            4.1.3  →    4.3.1 
 browser-sync       ^2.23.6  →  ^2.26.3 
 del                 ^3.0.0  →   ^4.1.0 
 gulp                 3.9.1  →    4.0.0 
 gulp-autoprefixer   ^5.0.0  →   ^6.0.0 
 gulp-clean-css      ^3.9.2  →   ^4.0.0 
 gulp-cssnano        ^2.1.2  →   ^2.1.3 
 gulp-imagemin       ^4.1.0  →   ^5.0.3 
 gulp-plumber        ^1.2.0  →   ^1.2.1 
 gulp-rename         ^1.2.2  →   ^1.4.0 
 gulp-sass            4.0.1  →    4.0.2 
 gulp-sourcemaps      2.6.4  →    2.6.5 
 gulp-uglify         ^3.0.0  →   ^3.0.2 
 merge2              ^1.2.1  →   ^1.2.3 
 popper.js          ^1.12.9  →  ^1.15.0 
 understrap          ^0.8.6  →   ^0.9.1 

Run npm install to install new versions.

Una vez actualizado el archivo package.json se puede ejecutar npm install para actualizar:

skotperez@lee:~/understrap-child$ npm install

Si se vuelve a comprobar las actualizaciones, se verá que todo está actualizado:

skotperez@lee:~/understrap-child$ ncu
Checking package.json
[====================] 30/30 100%
All dependencies match the latest package versions :)

Cómo solucionar errores de dependencias durante la instalación de las librerías

Si al actualizar hubiese algún error, aconsejo editar el archivo package.json con las versiones a las que se quiera volver y luego ejecutar npm install.

También se puede volver a una versión anterior de alguno de los paquetes. Por ejemplo, si se quiere hacer un downgrade de gulp a la versión 3.9.1:

skotperez@lee:~$ sudo npm install -g gulp@3.9.1

Y de manera local, solo para el proyecto:

skotperez@lee:~$ cd understrap-child
skotperez@lee:~/understrap-child$ npm install gulp@3.9.1

Understrap y el entorno de desarrollo

Una vez instalados npm y node.js se puede clonar Understrap desde el repo. Si como en mi caso se va a desarrollar usando el child theme de Understrap, hay que clonarlo también. Y luego usar npm para instalar gulp y browsersync y el resto de dependencias, y copiar las librerías necesarias desde node_modules a src:

skotperez@lee:~$ git clone https://github.com/understrap/understrap.git understrap
skotperez@lee:~$ git clone https://github.com/understrap/understrap-child.git understrap-child
skotperez@lee:~$ cd understrap-child
skotperez@lee:~/understrap-child$ npm install
skotperez@lee:~/understrap-child$ sudo npm install --global gulp-cli
skotperez@lee:~/understrap-child$ sudo npm install --global browser-sync
skotperez@lee:~/understrap-child$ gulp copy-assets

Dejo aquí una lista de los archivos que incluyen tanto understrap como understrap-child que conforman el entorno de desarrollo:

  • css/. Contiene los archivos CSS del theme, compilados a partir de los archivos Sass ubicados en sass/.
  • gulpconfig.json. Contiene las variables de configuración de Gulp: las ubicaciones en las que debe mirar para compilar, dónde colocar los archivos compilados, qué URL debe vigilar browsersync para crear el navegador de testeo…
  • gulpfile.js. Contiene la definición de las rutinas a automatizar con gulp.
  • node_modules/. Contiene los paquetes instalados con npm.
  • package.json. Contiene las dependencias de Understrap a instalar al ejecutar npm install, que se instalarán en node_modules.
  • package-lock.json. Contiene un registro de los paquetes instalados con npm.
  • sass/. Contiene los archivos Sass con las reglas para construir los CSS del theme.
  • src/. En las carpetas js/ y sass/ contiene los archivos fuente de las librerías que usa el theme que gulp copia desde node_modules/. En la carpeta images/ se alojarán las imágenes del theme que queramos que gulp comprima.

Gulp

Antes de comenzar a desarrollar es conveniente echar un vistazo a la configuración de gulp para personalizarlo según nuestra manera de trabajar. Las variables de configuración de gulp están en gulpconfig.json:

{
  "browserSyncOptions" : {
    "proxy": "localhost/wordpress/",
    "notify": false
  },
  "browserSyncWatchFiles" : [
    "./css/*.min.css",
    "./js/*.min.js",
    "./**/*.php"
  ],
  "paths" : {
    "js": "./js",
    "css": "./css",
    "img": "./images",
                "imgsrc": "./src/images",
    "sass": "./sass",
    "node": "./node_modules/",
    "bower": "./bower_components/",
    "dev": "./src",
    "dist": "./dist",
    "distprod": "./dist-product",
    "vendor": ""
  }
}

La opción proxy permite configurar la URL de la instalación de WordPress en localhost que se quiere asociar al servidor de desarrollo. Los tipos de archivo listados en browserSyncWatchFiles son los que serán vigilados por Browsersync y que cuando se modifiquen harán que el navegador se recargue automáticamente para poder ver los cambios. En paths se pueden definir todas las ubicaciones que usa gulp para buscar los archivos CSS, JS y de imagen que compilará, minimizará y optimizará. Estas ubicaciones están vigiladas por gulp que tratará automáticamente todos los archivos que se guarden en ellas.

Los distintos comandos de gulp están definidos en gulpfile.js. Este archivo está bien documentado: cada comando está precedido de una explicación. Por ejemplo:

// Run:
// gulp imagemin
// Running image optimizing task
gulp.task( 'imagemin', function() {
    gulp.src( paths.imgsrc + '/**' )
    .pipe( imagemin() )
    .pipe( gulp.dest( paths.img ) );
});

gulp imagemin comprime las imágenes alojadas en src/images y guardarlas en images/.

Para lanzar el navegador de desarrollo se puede ejecutar gulp watch-bs:

// Run:
// gulp watch-bs
// Starts watcher with browser-sync. Browser-sync reloads page automatically on your browser
gulp.task( 'watch-bs', ['browser-sync', 'watch', 'scripts'], function() { 
} );

Los comandos definidos en gulpfile.js se pueden modificar fácilmente. Por ejemplo, el comando gulp copy-assets copia las librerías usadas por el theme de node_modules/ a src/:

// Run:
// gulp copy-assets.
// Copy all needed dependency assets files from bower_component assets to themes /js, /scss and /fonts folder. Run this task after bower install or bower update

////////////////// All Bootstrap SASS  Assets /////////////////////////
gulp.task( 'copy-assets', function() {

////////////////// All Bootstrap 4 Assets /////////////////////////
// Copy all JS files
    var stream = gulp.src( paths.node + 'bootstrap/dist/js/**/*.js' )
        .pipe( gulp.dest( paths.dev + '/js/bootstrap4' ) );

// Copy all Bootstrap SCSS files
    gulp.src( paths.node + 'bootstrap/scss/**/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/bootstrap4' ) );

////////////////// End Bootstrap 4 Assets /////////////////////////

// Copy all Font Awesome Fonts
    gulp.src( paths.node + 'font-awesome/fonts/**/*.{ttf,woff,woff2,eot,svg}' )
        .pipe( gulp.dest( './fonts' ) );

// Copy all Font Awesome SCSS files
    gulp.src( paths.node + 'font-awesome/scss/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/fontawesome' ) );


// _s SCSS files
    gulp.src( paths.node + 'undescores-for-npm/sass/media/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/underscores' ) );

// _s JS files into /src/js
    gulp.src( paths.node + 'undescores-for-npm/js/skip-link-focus-fix.js' )
        .pipe( gulp.dest( paths.dev + '/js' ) );

// Copy Popper JS files
    gulp.src( paths.node + 'popper.js/dist/umd/popper.min.js' )
        .pipe( gulp.dest( paths.js + paths.vendor ) );
    gulp.src( paths.node + 'popper.js/dist/umd/popper.js' )
        .pipe( gulp.dest( paths.js + paths.vendor ) );

// UnderStrap SCSS files
    gulp.src( paths.node + 'understrap/sass/**/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/understrap' ) );

    return stream;
});

Si se quiere añadir por ejemplo la librería Isotope a los archivos del theme, se puede añadir las siguientes líneas al comando gulp copy-assets:

// Run:
// gulp copy-assets.
// Copy all needed dependency assets files from bower_component assets to themes /js, /scss and /fonts folder. Run this task after bower install or bower update

////////////////// All Bootstrap SASS  Assets /////////////////////////
gulp.task( 'copy-assets', function() {

////////////////// All Bootstrap 4 Assets /////////////////////////
// Copy all JS files
    var stream = gulp.src( paths.node + 'bootstrap/dist/js/**/*.js' )
        .pipe( gulp.dest( paths.dev + '/js/bootstrap4' ) );

// Copy all Bootstrap SCSS files
    gulp.src( paths.node + 'bootstrap/scss/**/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/bootstrap4' ) );

////////////////// End Bootstrap 4 Assets /////////////////////////

// Copy all Font Awesome Fonts
    gulp.src( paths.node + 'font-awesome/fonts/**/*.{ttf,woff,woff2,eot,svg}' )
        .pipe( gulp.dest( './fonts' ) );

// Copy all Font Awesome SCSS files
    gulp.src( paths.node + 'font-awesome/scss/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/fontawesome' ) );


// _s SCSS files
    gulp.src( paths.node + 'undescores-for-npm/sass/media/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/underscores' ) );

// _s JS files into /src/js
    gulp.src( paths.node + 'undescores-for-npm/js/skip-link-focus-fix.js' )
        .pipe( gulp.dest( paths.dev + '/js' ) );

// Copy Popper JS files
    gulp.src( paths.node + 'popper.js/dist/umd/popper.min.js' )
        .pipe( gulp.dest( paths.js + paths.vendor ) );
    gulp.src( paths.node + 'popper.js/dist/umd/popper.js' )
        .pipe( gulp.dest( paths.js + paths.vendor ) );

// UnderStrap SCSS files
    gulp.src( paths.node + 'understrap/sass/**/*.scss' )
        .pipe( gulp.dest( paths.dev + '/sass/understrap' ) );

// Copy Isotope JS files
    gulp.src( paths.node + 'isotope-layout/dist/isotope.pkgd.min.js' )
        .pipe( gulp.dest( paths.js ) );
    gulp.src( paths.node + 'isotope-layout/dist/isotope.pkgd.js' )
        .pipe( gulp.dest( paths.js ) );

    return stream;
});

Previamente, si el paquete no está instalado, se tiene que instalar usando npm.

skotperez@lee:~/understrap-child$ npm install isotope-layout --save

Bootstrap

Understrap viene preparado para usar Bootstrap: los archivos PHP del theme incluyen las clases de bootstrap y los archivos Sass de bootstrap vienen incluidos también. Las variables de bootstrap se pueden sobreescribir en el archivo sass/theme/_child_theme_variables.scss. Para un listado completo de variables se puede consultar el archivo src/sass/bootstrap4/_variables.scss.

Otros starter themes

Por si alguien quiere probar algún otro Starter theme para WordPress aquí dejo una lista de los que he probado en algún momento:

HTML5 Blank
Realmente un starter theme. Lo más básico que he encontrado. No incluye entorno de desarrollo. Enlace al repositorio del proyecto.
_s

Es el starter theme de Automattic, la empresa detrás del desarrollo del WordPress, lo que da ciertas garantías de continuidad del proyecto. Su web permite generar un theme mínimamente personalizado basado en Underscore, lo cual agiliza el desarrollo al principio. Enlace al repositorio del proyecto.

Bootstrap Starter Theme for WordPress
Starter theme basado en el framework Bootstrap. Permite generar un theme con las variables de bootstrap personalizadas desde su web.Enlace al repositorio del proyecto.
WordPress Starter Theme
Tiene todo lo necesario, aunque algo desactualizado (último cambio hace 4 años), lo que hace necesario actualizar todos los módulos antes de empezar a desarrollar. Enlace al repositorio del proyecto.

Dejar un comentario

No hay comentarios en esta entrada.
*
*

 

No hay trackbacks