Manipula imágenes en Blogger fácilmente

Siguiendo con las entradas de desarrollo, hoy te enseñare a crear una función para manipular las imágenes alojadas en Google a traves de Blogger, Google Fotos e incluso Youtube, ya sea empleando parámetros en la url o usando métodos incluidos en la sintaxis de Blogger.

Situación

Cuando intentamos realizar cambios específicos a datos de tipo imagen, nuestro código puede llegar a verse de la siguiente manera:

<b:if cond='data:view.featuredImage'>
  <img expr:src='resizeImage(data:view.featuredImage, 300,"4:3")'/>
</b:if>

Aquí solo estamos comprobando si existe una imagen destacada en la entrada, y en caso de que exista, cambiamos su tamaño. Ahora cuando aumentamos la complejidad de la lógica, el código puede llegar a ser muy difícil de leer y mantener:

<b:if cond='data:view.featuredImage'>
  <b:if cond='data:view.featuredImage.isYoutube'>
    <img expr:src='resizeImage(data:view.featuredImage.youtubeMaxResDefaultUrl, 300,"4:3")'/>
  <b:else/>
    <img expr:src='resizeImage(data:view.featuredImage, 300,"4:3")'/>
  </b:if>
</b:if>

Función en Blogger

Para evitar este tipo de situaciones, podemos crear una función en Blogger que se encargue específicamente de manipular las imágenes, de esta manera podemos reutilizar el código en cualquier parte de la plantilla, y si necesitamos realizar cambios, solo tendremos que modificar la inclusión.

<b:includable id='@image'>
  <b:comment><!--
  // @param {image} src - Url de la imagen
  // @param {string} [alt=data:messages.image] - Texto alternativo
  // @param {string} [id] - Identificador único
  // @param {string} [class] - Clases adicionales
  // @param {string} [width] - Ancho personalizado
  // @param {string} [height] - Alto personalizado
  // @param {number} [resize] - Nuevo tamaño de la imagen
  // @param {string} [ratio] - Relación de aspecto (4:3, 16:9 etc)
  // @param {string} [sizes] - Valores para el atributo sizes
  // @param {array} [srcset] - Tabla de dimensiones (genera srcset)
  // @param {string} [loading] - Valor para el atributo loading
  // @param {string} [params] - Parámetros adicionales (zkreations.com/image-params)
  --></b:comment>
  <b:if cond='data:src'>
    <b:with value='data:src.isYoutube
      ? data:src.youtubeMaxResDefaultUrl
      : data:src' var='source'>
    <b:with value='(data:resize
      ? resizeImage(data:source, data:resize, data:ratio)
      : (data:source))' var='image'>
      <b:tag expr:alt='data:alt ?: data:messages.image' name='img'>
        <b:attr name='b:whitespace' value='remove'/>
        <b:attr name='id' expr:value='data:id'/>
        <b:class cond='data:class' expr:name='data:class'/>
        <b:attr name='width' expr:value='data:width ?: data:image.width'/>
        <b:attr name='height' expr:value='data:height ?: data:image.height'/>
        <b:attr name='sizes' expr:value='data:sizes'/>
        <b:attr name='loading' expr:value='data:loading'/>
        <b:with value='[
          "content.com/img/a/",
          "content.com/blogger_img_proxy"
        ]' var='servers'> 
        <b:with value='data:params and (data:servers any (server => server in data:image))
          ? ("-" + data:params)
          : ""' var='params'>
          <b:attr name='src' expr:value='(data:srcset
            ? resizeImage(data:image, data:srcset.first, data:ratio)
            : data:image) + data:params'/>
        </b:with>
        </b:with>
        <b:if cond='data:srcset'>
          <b:attr name='srcset' expr:value='sourceSet(data:image, data:srcset, data:ratio)'/>
        </b:if>
      </b:tag>
    </b:with>
    </b:with>
  <b:else/>
    <b:comment render='true'>Parameter [src] is required.</b:comment>
  </b:if>
</b:includable>

Explicación

La función solo exige el parámetro src, el cual primero comprueba si la imagen pertenece a Youtube, y en caso de que sea así, cambia la url por la correspondiente a la de mayor resolución.

Tras comprobar la presencia de la imagen, será tratada con los parámetros que se le hayan pasado. En caso de que no se especifique ninguno, entregará la imagen original sin cambios. Si el parametro src no se especifica, verás un comentario HTML en su lugar.

Esta funcion la puedes encontrar en mi proyecto de tema para desarrollar plantillas de Blogger llamado Hamlet, te recomiendo hecharle un vistazo al repositorio para que puedas entener mejor como funciona.

Modo de uso

Agrega la inclusión como un marcado predeterminado de Blogger de tipo "Common" y ya podrás incluirlo en donde necesites trabajar con imágenes. Ahora le daremos un repaso a los parámetros.

Url de la imagen

Recomiendo que la imagen esté alojada en servidores de Google a través de Blogger, Google Fotos o Youtube. Si proviene de un servidor externo, Blogger entregará el resultado a través de proxy y esto ademas de ser perjudicial en rendimiento, en ocasiones la imagen no se mostrará.

<b:include data='{ src: data:view.featuredImage }' name='@image'/>
<img src='/s1600/demo.png'/>

Texto alternativo

El texto alternativo que se mostrará cuando la imagen no se pueda cargar. Por defecto se usa una etiqueta de datos data:messages.image cuando no se especifica.

<b:include data='{
    src: data:view.featuredImage,
    alt: "Texto alternativo"
  }' name='@image'/>
<img src='/s1600/demo.png' alt='Texto alternativo'/>

Identificador y clases

Simplemente se agregan los atributos id y class a la etiqueta img.

<b:include data='{
    src: data:view.featuredImage,
    id: "NombreUnico",
    class: "ejemplo"
  }' name='@image'/>
<img src='/s1600/demo.png' class='ejemplo' id='NombreUnico'/>

Tamaño y relación de aspecto

Estos parametros probablemente son los más importantes y los que nos interesan, ya que manipulan las dimensiones y aspecto que tendra la imagen final. Además los atributos width y height se agregarán automáticamente si la relación de aspecto está especificada.

<b:include data='{
    src: data:view.featuredImage,
    resize: 300,
    ratio: "4:3"
  }' name='@image'/>
<img src='/w300-h225-p-k-no-nu/demo.png' height='225' width='300'/>

Tabla de dimensiones

Se genera el atributo srcset con las dimensiones especificadas. El primer valor de la tabla será el tamaño de la imagen original, y el resto se usará dependiendo del tamaño de la pantalla del usuario.

<b:include data='{
    src: data:view.featuredImage,
    srcset: [300, 600, 900]
  }' name='@image'/>

Altura y ancho

Si necesitas un tamaño personalizado, puedes usar los atributos width y height, estos parámetros tendrán prioridad sobre el tamaño tras especificar resize y ratio.

<b:include data='{
    src: data:view.featuredImage,
    width: 300,
    height: 200
  }' name='@image'/>

Atributo sizes

El atributo sizes se usa para especificar el tamaño de la imagen dependiendo del tamaño de la pantalla del usuario. Si deseas saber mas sobre este atributo, puedes consultar la documentación en Mozilla sobre imágenes responsivas.

<b:include data='{
    src: data:view.featuredImage,
    sizes: "(max-width: 600px) 100vw, 50vw"
  }' name='@image'/>

Atributo loading

El atributo loading nos permite usar carga diferida nativa en el navegador, es realmente uno de los atributos mas potentes que podemos usar. Si deseas saber mas sobre este atributo, puedes consultar la documentación en Mozilla sobre carga diferida.

<b:include data='{
    src: data:view.featuredImage,
    loading: "lazy"
  }' name='@image'/>

Parámetros adicionales

Si necesitas agregar parámetros de imagen, puedes especificar params. Este parámetro solo se aplicará a las imágenes alojadas en Blogger del nuevo servidor. Si deseas saber más puedes consultar mi articulo sobre los parámetros adicionales.

<b:include data='{
    src: data:view.featuredImage,
    params: "rw-e30"
  }' name='@image'/>

Conclusión

Cuando el proyecto crece, es importante mantener el código limpio y legible. Con esta función, podemos manipular las imágenes de una manera mas sencilla y eficiente, ademas de poder reutilizar el código en cualquier parte de la plantilla, también podemos modificarlo fácilmente en caso de que sea necesario.

Como siempre suelo hacer para este tipo de aportes, encontrarás un tema de desarrollo en los adjuntos para que puedas experimentar con la función y entender mejor su uso. Si te ha gustado este aporte no olvides compartirlo, lo apreciaré mucho.