Construction a Easy Symbol Gallery with Eleventy

For some time now I have been that means to check out the Symbol plugin for Eleventy and this week I in spite of everything were given round to development a easy demo. I am not positive I used the plugin precisely as meant (I am nice for the usage of device the flawed manner!), however when I wrapped my head across the plugin, it used to be moderately easy to get it running. My thought used to be this:

  • Get started with a folder of “uncooked” photographs. The theory being I may just simply unload in footage proper from my telephone or somewhere else.
  • Use Eleventy (and the Symbol plugin) to create a regular measurement model of each and every symbol
  • Use Eleventy (and the Symbol plugin) to create a thumbnail of each and every symbol
  • In my web page, show the thumbnails with a possibility to view the unique (and by means of authentic I nonetheless imply the nicer model constructed from the uncooked reproduction)

I were given my demo up and working right here (https://imagegallery-eta.vercel.app/) and the supply is to be had as smartly (https://github.com/iandroid.eu/eleventy-demos/tree/grasp/imagegallery).

So how did I construct it? I started by means of simply enjoying with the plugin. I wrote this in .eleventy.js:

const Symbol = require("@11ty/eleventy-img");
const glob = require("glob-promise"); const THUMB = 250;
const FULL = 650; (async () => { let choices = { widths: [THUMB,FULL], codecs: ['jpeg'], filenameFormat:serve as(identity, src, width, layout, choices) { let origFilename = src.cut up('/').pop(); //strip off the document kind, this is able to most likely be one line of fancier JS let portions = origFilename.cut up('.'); portions.pop(); origFilename = portions.sign up for('.'); if(width === THUMB) go back `thumb-${origFilename}.${layout}`; else go back `${origFilename}.${layout}`; } }; let information = wait for glob('./rawphotos/*.{jpg,jpeg,png,gif}'); for(const f of information) { console.log('doing f',f); let md = wait for Symbol(f, choices); }; })();

I exploit a glob library to get the entire photographs from my rawphotos folder. For each and every, I name the Symbol plugin with choices for width (250 and 650), codecs (simply JPG), and I custom designed the filename to stay the unique identify (minus the unique extension) and upload thumb- in entrance of the thumbnail variations.

Once I ran this, it correctly added the information to my img folder:

(*1*)

Cool – so whilst that labored, I then had an enchanting downside. I had to combine this right into a “actual” Eleventy web page with an .eleventy.js that did different issues as smartly. Right here used to be my first strive (spoiler, it did not paintings):

const Symbol = require("@11ty/eleventy-img");
const glob = require("glob-promise"); const THUMB = 250;
const FULL = 650; async serve as generateImages() { let choices = { widths: [THUMB,FULL], codecs: ['jpeg'], filenameFormat:serve as(identity, src, width, layout, choices) { let origFilename = src.cut up('/').pop(); //strip off the document kind, this is able to most likely be one line of fancier JS let portions = origFilename.cut up('.'); portions.pop(); origFilename = portions.sign up for('.'); if(width === THUMB) go back `thumb-${origFilename}.${layout}`; else go back `${origFilename}.${layout}`; } }; let information = wait for glob('./rawphotos/*.{jpg,jpeg,png,gif}'); for(const f of information) { console.log('doing f',f); let md = wait for Symbol(f, choices); }; }; module.exports = serve as(eleventyConfig) { eleventyConfig.on('beforeBuild', async () => { console.log('beforeBuild'); wait for generateImages(); console.log('photographs achieved'); });
};

I principally moved my good judgment right into a serve as, generateImages, and used the beforeBuild Eleventy tournament. Alternatively, you’ll be able to’t use wait for on this serve as. I imply you can, however it would possibly not paintings correctly. It is a identified malicious program this is already fastened… for the now not but launched 1.0 model. I am having a bet it is going to be quickly.

For now, I merely took the code to generate the photographs and moved it right into a script, doImage.js:

const Symbol = require("@11ty/eleventy-img");
const glob = require("glob-promise"); const THUMB = 250;
const FULL = 650; (async () => { let choices = { widths: [THUMB,FULL], codecs: ['jpg'], filenameFormat:serve as(identity, src, width, layout, choices) { let origFilename = src.cut up('/').pop(); //strip off the document kind, this is able to most likely be one line of fancier JS let portions = origFilename.cut up('.'); portions.pop(); origFilename = portions.sign up for('.'); if(width === THUMB) go back `thumb-${origFilename}.${layout}`; else go back `${origFilename}.${layout}`; } }; let information = wait for glob('./rawphotos/*.{jpg,jpeg,png,gif}'); for(const f of information) { console.log(`processing ${f}`); wait for Symbol(f, choices); }; })();

Then I wrote code in .eleventy.js to learn those photographs and cause them to to be had to templates. I am going backward and forward between the usage of information information and collections, however made up our minds on a set these days.

const Symbol = require("@11ty/eleventy-img");
const glob = require("glob-promise"); module.exports = serve as(eleventyConfig) { eleventyConfig.addPassthroughCopy("img"); eleventyConfig.addPassthroughCopy("css"); eleventyConfig.addWatchTarget("css"); eleventyConfig.addCollection('photographs', async collectionApi => { let information = wait for glob('./img/*.jpeg'); //Now filter out to non thumb- let photographs = information.filter out(f => { go back f.indexOf('./img/thumb-') !== 0; }); let assortment = photographs.map(i => { go back { trail: i, thumbpath: i.substitute('./img/', './img/thumb-') } }); go back assortment; }); };

Principally, scan the img folder for information, forget about the thumbnails, and go back an array of paths that still comprises the thumb trail.

To make this paintings with the script, my construct command would want to glance one thing like: node doImages && eleventy.

To make use of this, I spent five mins Googling for “javascript symbol litebox libraries” and settled on CSSBox, which is a straightforward CSS handiest answer. After including the CSS script to my structure, all I needed to do used to be output my photographs and use the kinds that the library sought after. I needed to do slightly of good judgment to deal with the former and subsequent arrows.

---
structure: major
--- <h1>Symbol Gallery</h1> <div identity="gallery">
{% for symbol in collections.photographs %} <div elegance="cssbox"> <a href="#symbol{{forloop.index}}" identity="symbol{{forloop.index}}"><img src="{{symbol.thumbpath}}" elegance="cssbox_thumb"> <span elegance="cssbox_full"><img src="{{symbol.trail}}"></span></a> <a category="cssbox_close" href="#void"></a> {% if forloop.first == false %} <a category="cssbox_prev" href="#symbol{ minus: 1 }">&lt;</a> {% endif %} {% if forloop.remaining == false %} <a category="cssbox_next" href="#symbol{ plus: 1}">&gt;</a> {% endif %} </div>
{% endfor %}
</div> 

For essentially the most phase easy, however I struggled with Liquid’s syntac for addition. I saved looking to do {{ x + 1 }} which does not paintings.

That is it. As I mentioned, the Symbol plugin is lovely simple to make use of and I kinda want I had taken a take a look at it sooner than. My use of it (resizing and renaming) is solely one instance. You’ll be able to even have it generate HTML for you which ones is lovely tough. Let me know what you assume!

Picture by means of Soragrit Wongsa on Unsplash