Artículo

Potenciando HTML sin usar templates engines con processhtml

Muchas veces queremos dar funcionalidades a nuestros archivos HTML como el poder usar variables o includes para para no tener que repetir los mismos trozos de código constantemente.

Lo más habitual en estos casos es utilar los llamados Template Engines como por ejemplo Jade. A veces preferimos una opción más sencilla o queremos poder escribir HTML.

Existe una librería llamada htmlprocessor que nos proporciona un sitema de dar dinamismo y nuestros archivos HTML por medio de un sistema de comentarios HTML.

Existen versiones para Grunt y para Gulp. Estando bien documenta el uso en Grunt, pero no así en Gulp. En este artículo aprenderemos sus características y veremos como usar gulp-processhtml.

Las directivas de processhtml

Las directivas de processhtml son simplres comentarios HTML del siguiente estilo.

<!-- build:<type>[:target] [inline] [value] -->
...
<!-- /build -->

En este comentario la palabra build le indica a processhtml que es un comentario a procesar los siguientes parámetros pueden ser los siguientes.

type

Se refiere al tipo de operación que queremos hacer, incluir otro archivo html, eliminar, modificar una script, css, etc.

  • Es obligatorio.
  • Los tipos pueden ser: js, css, remove, template o include. Además en este campo podemos añadir cualquier atributo html con el formato: [href], [src], etc.

target

Se utiliza para definir el ámbito en el que se ejecuta la sentencia. Los targets los definimos nosotros mismos, pueden ser cosas como: dist, dev, etc.

Se pueden usar varios targets a la vez

<!-- build:include:dist,dev header.html -->
<!-- /build -->

Por ejemplo en este caso el comentario sería sustituido por el contenido del archivo header.html si y solo si está definido como target dist o dev. Ya veremos más a delante como podemos definir un target y cambiar entre ellos.

Definir un target es opcional, si no definimos ninguno, se ejecutará siempre la sentencia.

inline

Este comando solo es aplicable cuando se usan los type css o js. Lo que hace es incluir en el mismo archivo html el contenido de un archivo javascript o css. Es muy útil para páginas estáticas en las que solo queremos un archivo.

value

El el nuevo valor, varía la función según el type. Lo veremos mejor con los ejemplos.

Es requerido por los type js, css, include y [attr]. Es opcional para los type remove, template y también es opcional para los type css y js cuando se han definido como inline, más abajo lo veremos mejor.

Vale, leyendo eso puedes que no te hayas enterado de mucho como va la historia, lo veras mejor con los ejemplos.

Javascript

<!-- build:js app.min.js -->
<script src="my/lib/path/lib.js"></script>
<script src="my/deep/development/path/script.js"></script>
<!-- /build -->

<!-- cambia a -->
<script src="app.min.js"></script>

En el código de arriba le estamos diciendo que sustituya todo lo que está entre los comentarios build por un script js llamado app.min.js.

¿Y que pasa si lo que queremos es que en vez de incluir un enlace al script queremos que nos meta en el mismo html todo el contenido de app.min.js, pues lo hacemos con el modificador inline.

<!-- build:js inline app.min.js -->
<script src="my/lib/path/lib.js"></script>
<script src="my/deep/development/path/script.js"></script>
<!-- /build -->

<!-- cambia a -->
<script>
  // Aquí meterá el código del archivo app.min.js
</script>

Como vemos el solo se encarga de poner las etiquetas adecuadas en cada caso.

¿Y si lo que queremos es que nos meta directamente el código js de todo lo que esta entre los comentarios en línea? También puedes.

<!-- build:js inline -->
<script src="my/lib/path/lib.js"></script>
<script src="my/deep/development/path/script.js"></script>
<!-- /build -->

<!-- changed to -->
<script>
  // Aquí pondrá el código de: my/lib/path/lib.js
  // y aquí el de: my/deep/development/path/script.js
</script>

Como vemos lo único que tenemos que hacer es no indicarle ningún value y cogerá los archivos que hay entre comentarios.

CSS

Con los archivos CSS es bastante similar.

<!-- build:css style.min.css -->
<link rel="stylesheet" href="path/to/normalize.css">
<link rel="stylesheet" href="path/to/main.css">
<!-- /build -->

<!-- cambia -->
<link rel="stylesheet" href="style.min.css">
<!-- build:css inline -->
<link rel="stylesheet" href="path/to/normalize.css">
<link rel="stylesheet" href="path/to/main.css">
<!-- /build -->

<!-- cambia a -->
<style>
  /* path/to/normalize.css */
  /* path/to/main.css */
</style>
<!-- build:css inline style.min.css -->
<link rel="stylesheet" href="path/to/normalize.css">
<link rel="stylesheet" href="path/to/main.css">
<!-- /build -->

<!-- cambia a -->
<style>
  /* código de style.min.css */
</style>

Se puede ver que es igual solo que cambiando el tipo de js a css para que nos genere un link css y no uno javascropt.

Cambiando atributos

También nos permite cambiar atributos html, veamos algunos casos útiles

<!-- Cambiamos la ruta de los archivos js por js/ -->

<!-- build:[src] js/ -->
<script src="my/lib/path/lib.js"></script>
<script src="my/deep/development/path/script.js"></script>
<!-- /build -->

<!-- Así quedan una vez procesados -->
<script src="js/lib.js"></script>
<script src="js/script.js"></script>


<!-- También podemos cambiar la ruta del atributo href -->

<!-- build:[href] img/ -->
<link rel="apple-touch-icon-precomposed" href="skins/demo/img/icon.png">
<link rel="apple-touch-icon-precomposed" href="skins/demo/img/icon-72x72.png"
<!-- /build -->

<!-- Así quedan una vez procesados -->
<link rel="apple-touch-icon-precomposed" href="img/icon.png">
<link rel="apple-touch-icon-precomposed" href="img/icon-72x72.png" sizes="72x72">

<!-- Podemos cambiar tambien un atributo class -->

<!-- build:[class]:dist production -->
<html class="debug_mode">
<!-- /build -->

<!-- Cambia el valor a production solo si estamos en el target dist -->
<html class="production">

Especial atención al último caso donde podemos sustituir el valor de una clase en función del target en el que nos encontremos, útil para tests.

Haciendo includes

Una de las funciones más útiles la de poder incluir otros archivos html dentro del nuestro, muy útil para tener partes repetitivas como encabezados, menús o pie de página y poder incluirlos en todas las páginas.

<!-- build:include header.html -->
<p>Este párrafo será remplazado por el contenido del archivo header.html</p>
<!-- /build -->

<!-- build:include:dev dev/content.html -->
<p>Este párrafo será remplazado por el contenido del archivo dev/content.html si
    y solo si estamos en el target dev</p>
<!-- /build -->

<!-- build:include:dist dist/content.html -->
<p>Este párrafo será remplazado por el contenido del archivo dist/content.html si
    y solo si estamos en el target dist</p>
<!-- /build -->


<!-- Este último caso si nos encontramos en dist se incluirá el archivo footer.html,
sino no se incluirá nada -->

<!-- build:include:dist footer.html --><!-- /build -->

En la segunda parte veremos el uso de variables y como definir las tareas y propiedades con Gulp.

Comentarios

  • Juan Manuel Herrera Carrera

    Hola, compre tu libro, pero en la seccion de los include no lo hace, platicas de los include de header y eso y en ese entones no se habia instalado del gulp-processhtml, despues viene la instruccion de instalarlo, pero corro la tarea -gulp, pues es la default, y segun hace todo, pero el archivo destino index.html no me incluye el codigo html del header ni footer, continua con las etiquetas de comentario, hay alguna actualizacion de paquetes? gracias

  • Juan Manuel Herrera Carrera

    en l adocumentacion de gulp-htmlprocess vienen las opciones js css remove y replace, no viene indicada la de include. || https://www.npmjs.com/package/gulp-processhtml ||