All Projects → nhoizey → Jekyll Cloudinary

nhoizey / Jekyll Cloudinary

Licence: mit
Jekyll plugin adding a Liquid tag for Cloudinary, for better responsive images

Programming Languages

ruby
36898 projects - #4 most used programming language

Projects that are alternatives of or similar to Jekyll Cloudinary

Jekyll Spaceship
🚀 A Jekyll plugin to provide powerful supports for table, mathjax, plantuml, mermaid, emoji, video, audio, youtube, vimeo, dailymotion, soundcloud, spotify, etc.
Stars: ✭ 196 (+148.1%)
Mutual labels:  jekyll, jekyll-plugin, image
Jekyll Import
📥 The "jekyll import" command for importing from various blogs to Jekyll format.
Stars: ✭ 424 (+436.71%)
Mutual labels:  jekyll, jekyll-plugin
Jekyll Paginate V2
Pagination Generator for Jekyll 3 (enhanced replacement for the old built-in jekyll-paginate gem) ⛺
Stars: ✭ 412 (+421.52%)
Mutual labels:  jekyll, jekyll-plugin
Glightbox
Pure Javascript lightbox with mobile support. It can handle images, videos with autoplay, inline content and iframes
Stars: ✭ 702 (+788.61%)
Mutual labels:  image, responsive
Guillotine
jQuery plugin to crop images within an area (fully responsive), allowing to drag (touch support), zoom and rotate.
Stars: ✭ 318 (+302.53%)
Mutual labels:  image, responsive
Tifig
A fast HEIF image converter aimed at thumbnailing
Stars: ✭ 345 (+336.71%)
Mutual labels:  image, performance
Jekyll Redirect From
🔀 Seamlessly specify multiple redirections URLs for your pages and posts.
Stars: ✭ 630 (+697.47%)
Mutual labels:  jekyll, jekyll-plugin
jekyll-commonmark
CommonMark generator for Jekyll
Stars: ✭ 28 (-64.56%)
Mutual labels:  jekyll, jekyll-plugin
Jekyll Scholar
jekyll extensions for the blogging scholar
Stars: ✭ 872 (+1003.8%)
Mutual labels:  jekyll, jekyll-plugin
Laravel Image Optimizer
Optimize images in your Laravel app
Stars: ✭ 873 (+1005.06%)
Mutual labels:  image, performance
React Responsive Image
🖼️ A React responsive image component.
Stars: ✭ 36 (-54.43%)
Mutual labels:  image, responsive
Beautiful Jekyll
✨ Build a beautiful and simple website in literally minutes. Demo at https://beautifuljekyll.com
Stars: ✭ 3,778 (+4682.28%)
Mutual labels:  jekyll, responsive
Jekyll Gallery Generator
A Jekyll plugin that generates photo galleries from directories full of images.
Stars: ✭ 315 (+298.73%)
Mutual labels:  jekyll, jekyll-plugin
Sharp
High performance Node.js image processing, the fastest module to resize JPEG, PNG, WebP, AVIF and TIFF images. Uses the libvips library.
Stars: ✭ 21,131 (+26648.1%)
Mutual labels:  image, performance
Sqip
"SQIP" (pronounced \skwɪb\ like the non-magical folk of magical descent) is a SVG-based LQIP technique.
Stars: ✭ 3,074 (+3791.14%)
Mutual labels:  image, performance
React Native Fit Image
Responsive image component to fit perfectly itself.
Stars: ✭ 539 (+582.28%)
Mutual labels:  image, responsive
Jekyll Minibundle
A minimalistic asset bundling plugin for Jekyll
Stars: ✭ 65 (-17.72%)
Mutual labels:  jekyll, jekyll-plugin
jekyll-stickyposts
Jekyll Stickyposts - move selected posts to the top of the list
Stars: ✭ 23 (-70.89%)
Mutual labels:  jekyll, jekyll-plugin
jekyll-default-layout
Silently sets default layouts for Jekyll pages and posts
Stars: ✭ 45 (-43.04%)
Mutual labels:  jekyll, jekyll-plugin
Image Optimizer
Image optimization / compression library. This library is able to optimize png, jpg and gif files in very easy and handy way. It uses optipng, pngquant, pngcrush, pngout, gifsicle, jpegoptim and jpegtran tools.
Stars: ✭ 785 (+893.67%)
Mutual labels:  image, performance

Jekyll Cloudinary Liquid tag

Gem Version Gem Downloads

jekyll-cloudinary is a Jekyll plugin adding a Liquid tag to ease the use of Cloudinary for responsive images in your Markdown/Kramdown posts.

It builds the HTML for responsive images in the posts, using the srcset and sizes attributes for the <img /> tag (see the "varying size and density" section of this post if this is new for you, and why it's recommended to not use <picture> most of the time). URLs in the srcset are cloudinary URLs that fetch on-the-fly the post's images and resize them to several sizes.

You are in full control of the number of generated images and their sizes, and the sizes attribute that helps the browser decide which image to download. See the complete configuration options for details.

Here is the general syntax of this Liquid tag:

{% cloudinary cloudflare.png alt="Un schéma montrant l'apport de Cloudflare" caption="Un schéma montrant l'apport de Cloudflare" loading="lazy" %}

Table of contents

Installation

Sign up for free on Cloudinary! The free account should be enough for most blogs.

Add gem 'jekyll-cloudinary' to the jekyll_plugin group in your Gemfile:

source 'https://rubygems.org'

gem 'jekyll'

group :jekyll_plugins do
  gem 'jekyll-cloudinary'
end

Then run bundle to install the gem.

Configuration

Mandatory settings

Add cloudinary to your _config.yml and your Cloudinary "Cloud name" (find it in your Cloudinary dashboard):

cloudinary:
  cloud_name: <put here your Cloudinary "Cloud name">

Optional global settings

You can now define some global settings

cloudinary:
  
  only_prod: true
  verbose: true
  origin_url: https://another-domain.com

only_prod (default: false)

When set to true, this setting implies that responsive image HTML and Cloudinary URLs are generated only if the environnement is production.

For example:

  • if you run JEKYLL_ENV=production bundle exec jekyll build, you'll get the code to deploy, with srcset and Cloudinary URLs.
  • if you run JEKYLL_ENV=development bundle exec jekyll serve, you'll get code for local development, with standard <img src="…"> code and local URLs.

JEKYLL_ENV=development is the default value.

If you don't set only_prod or set it to false, responsive image HTML and Cloudinary URLs are always generated, whatever the environment. jekyll-cloudinary had only this behavior before version 1.11.0.

verbose (default: false)

When set to true, this setting will show messages in the console when something goes wrong, such as:

[Cloudinary] Couldn't find this image to check its width: /path/to/jekyll/_site/assets/img.jpg

or

[Cloudinary] Natural width of source image 'img.jpg' (720px) in _posts/2016-06-09-post.md not enough for creating 1600px version

origin_url

When origin_url is set, jekyll-cloudinary will use this URL rather than site.url as origin of the source images.

This allows you to store your source image on a different domain than your website.

Optional (but highly recommended) presets

You can now define the presets you need for your posts' images, starting with the default one:

Default preset

The default preset is the one you don't even have to mention when using the Liquid tag, and that will be used if a preset you use in the tag doesn't exist.

cloudinary:
  
  presets:
    default:
      min_width: 320
      max_width: 1600
      fallback_max_width: 800
      steps: 5
      sizes: "(min-width: 50rem) 50rem, 90vw"

This preset will generate five images 320 to 1600 pixels wide in the srcset and define sizes as "(min-width: 50rem) 50rem, 90vw". The fallback image defined in the src will have a width of 800 pixels.

With this preset, you only have to write this in your Markdown post:

{% cloudinary /assets/img.jpg alt="beautiful!" %}

To get this HTML:

<img
  src="http://res.cloudinary.com/<cloud_name>/image/fetch/c_limit,w_800,q_auto,f_auto/https://<your-domain>/assets/img.jpg"
  srcset="
    http://res.cloudinary.com/<cloud_name>/image/fetch/c_limit,w_320,q_auto,f_auto/https://<your-domain>/assets/img.jpg 320w,
    http://res.cloudinary.com/<cloud_name>/image/fetch/c_limit,w_640,q_auto,f_auto/https://<your-domain>/assets/img.jpg 640w
    http://res.cloudinary.com/<cloud_name>/image/fetch/c_limit,w_960,q_auto,f_auto/https://<your-domain>/assets/img.jpg 960w
    http://res.cloudinary.com/<cloud_name>/image/fetch/c_limit,w_1280,q_auto,f_auto/https://<your-domain>/assets/img.jpg 1280w
    http://res.cloudinary.com/<cloud_name>/image/fetch/c_limit,w_1600,q_auto,f_auto/https://<your-domain>/assets/img.jpg 1600w
    "
  sizes="(min-width: 50rem) 50rem, 90vw"
  alt="beautiful!"
  width="480"
  height="320"
/>

There is a true default default preset, but you're strongly encouraged to override it with your own default preset.

Additional presets

You can add other presets if you need several image sizes in your posts.

Here is an example for images that take only one third of the post width:

cloudinary:
  
  presets:
    
    onethird:
      min_width: 110
      max_width: 535
      fallback_max_width: 300
      steps: 3
      sizes: "(min-width: 50rem) 17rem, 30vw"
      attributes:
        class: "one3rd"
        loading: "lazy"

To use this additional preset, you will have to write this in your Markdown post:

{% cloudinary onethird /assets/img.jpg %}

The generated element will also get a class="one3rd" that can be useful for example with this CSS:

.one3rd {
  max-width: 33%;
  float: right;
  margin: 0 0 1em 1em;
}

Detailed preset settings

figure (default: auto)

This setting lets you decide what to do when there is a caption attribute in the Cloudinary Liquid tag.

The value can be:

  • auto (default): will generate a <figure> and <figcaption> only if there's a caption
  • never: will always generate a <img>, losing the caption
  • always: will always generate a <figure> and <figcaption>, even if there's no caption attribute

If a <figure> is generated and there are attributes (in the preset or the Liquid tag), they are added to the <img> if they are alt, title or loading, or to the <figure>.

min_width (default: 320)

max_width (default: 1200)

fallback_max_width (defaut: 1200)

steps (default: 5)

sizes (default: "100vw")

attributes (default: none)

You can define attributes that will be added to all images using this preset. Attributes are added without transformation to the generated element.

You should obviously not add to preset attributes that should have different values for each image, such as alt, caption, title, etc.

You can set a class, aria-* attributes for enhanced accessibility, or even data-* attributes you would like to use later with CSS or JavaScript.

Liquid tag values

You can use liquid variables inside the liquid tag.

For example, if you have the picture path in a thumbnail attribute of the YAML Front Matter, you can use it in the tag:

{% cloudinary {{ page.thumbnail }} alt="{{ page.title }} image" %}

Liquid tag attributes

You can add attributes to the liquid tag, after the image path:

{% cloudinary onethird /assets/selfie.jpg alt="My selfie" loading="eager" %}

Just like the ones from the preset settings, inline attributes are added without transformation to the generated element.

Recommended attributes

You should obviously define the alt attribute, mandatory for accessibility.

If you want the image to be inside a figure element, you probably also want to add a caption attribute. This is the only one that can act differently than other attributes, depending on the figure setting.

You can also set a title attribute, but there are really few use cases for it on images.

alt, caption and title attributes can contain Markdown.

Loading attribute

The loading attribute allows you to tell the browser how you want it to load this image.

From this article written by Addy Osmani:

The loading attribute allows a browser to defer loading offscreen images and iframes until users scroll near them. loading supports three values:

  • lazy: is a good candidate for lazy loading.
  • eager: is not a good candidate for lazy loading. Load right away.
  • auto: browser will determine whether or not to lazily load.

Not specifying the attribute at all will have the same impact as setting loading=auto.

Other interesting attributes

You can also use attributes to add a class, aria-* attributes for enhanced accessibility, or even data-* attributes you would like to use later with CSS or JavaScript.

Live example

Go to this post: https://nicolas-hoizey.com/2016/07/tout-change-rien-ne-change.html.

The source Markdown is here: https://github.com/nhoizey/nicolas-hoizey.com/blob/master/_posts/2016/07/13-tout-change-rien-ne-change/2016-07-13-tout-change-rien-ne-change.md.

The content is in french, yes, but look only at the images if you don't understand.

You'll find here:

These image types need different settings to deal with different sizes and position:

  • screenshot always use the full content width, if they're wide enough
  • logos are centered and take one half of the content width on small screens, and are floated and take one fourth of the content width on larger screens

This is how I use the Cloudinary Liquid tag for the Cloudinary logo and prices table screenshot:

{% cloudinary logo /assets/logos/cloudinary.png alt="Logo de Cloudinary" %}
{% cloudinary cloudinary-pricing.png alt="Les tarifs de Cloudinary" caption="Les tarifs de Cloudinary, dont l'offre gratuite déjà généreuse" %}

The only difference is that I explicitly use the logo preset for the logo. The other image uses the default preset.

Here is the necessary configuration for this:

cloudinary:
  cloud_name: 
  verbose: false
  presets:
    default:
      min_width: 320
      max_width: 1600
      fallback_max_width: 800
      steps: 5
      sizes: '(min-width: 50rem) 50rem, 90vw'
      figure: always
    logo:
      min_width: 80
      max_width: 400
      fallback_max_width: 200
      steps: 3
      sizes: '(min-width: 50rem) 13rem, (min-width: 40rem) 25vw, 45vw'
      figure: never
      attributes:
        class: logo

It generates these HTML fragments (pretty printed here), for the logo:

<img
  src="https://res.cloudinary.com/nho/image/fetch/c_limit,w_200,q_auto,f_auto/https://nicolas-hoizey.com/assets/logos/cloudinary.png"
  srcset="
    https://res.cloudinary.com/nho/image/fetch/c_limit,w_80,q_auto,f_auto/https://nicolas-hoizey.com/assets/logos/cloudinary.png 80w,
    https://res.cloudinary.com/nho/image/fetch/c_limit,w_240,q_auto,f_auto/https://nicolas-hoizey.com/assets/logos/cloudinary.png 240w,
    https://res.cloudinary.com/nho/image/fetch/c_limit,w_400,q_auto,f_auto/https://nicolas-hoizey.com/assets/logos/cloudinary.png 400w"
  sizes="
    (min-width: 50rem) 13rem,
    (min-width: 40rem) 25vw,
    45vw"
  class="logo"
  alt="Logo de Cloudinary"
  width="480"
  height="350"
/>

And for the screenshot:

<figure>
  <img
    src="https://res.cloudinary.com/nho/image/fetch/c_limit,w_800,q_auto,f_auto/https://nicolas-hoizey.com/2016/07/cloudinary-pricing.png"
    srcset="
      https://res.cloudinary.com/nho/image/fetch/c_limit,w_320,q_auto,f_auto/https://nicolas-hoizey.com/2016/07/cloudinary-pricing.png 320w,
      https://res.cloudinary.com/nho/image/fetch/c_limit,w_640,q_auto,f_auto/https://nicolas-hoizey.com/2016/07/cloudinary-pricing.png 640w,
      https://res.cloudinary.com/nho/image/fetch/c_limit,w_960,q_auto,f_auto/https://nicolas-hoizey.com/2016/07/cloudinary-pricing.png 960w,
      https://res.cloudinary.com/nho/image/fetch/c_limit,w_1208,q_auto,f_auto/https://nicolas-hoizey.com/2016/07/cloudinary-pricing.png 1208w"
    sizes="(min-width: 50rem) 50rem, 90vw"
    alt="Les tarifs de Cloudinary"
    width="1208"
    height="561"
  />
  <figcaption>Les tarifs de Cloudinary, dont l'offre gratuite déjà généreuse</figcaption>
</figure>

There are only 4 version in the srcset here because 2 of the 5 expected sizes are larger than the source image, and are replaced by one using the native source image width.

And here are the relevant parts of the accompanying CSS (in Sass form):

article {
  figure, img {
    margin: 2em auto;
    display: block;
    max-width: 100%;
    height: auto;
  }
}

.logo {
  display: block;
  margin: 1em auto;
  max-width: 50%;
  height: auto;

  @media (min-width: 40em) {
    max-width: 25%;
    float: right;
    margin: 0 0 1em 1em;
  }
}

Contributing

Thanks for your interest in contributing! There are many ways to contribute to this project. Get started here.

Do you use the plugin on a live site?

Add it to the "Sites" page of the wiki and please let me know on Twitter: @nhoizey

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].