Open headapples opened 4 years ago
@headapples I don't know if this can be enough for you needs, but I'm developing a plugin to manage responsive images with Eleventy: eleventy-plugin-images-responsiver
The aim is to allow content authors to write simple Markdown syntax for images, which should make it compatible with any Markdown based CMS. I already use it on a site where authors use Forestry.
It is also supposed to support any image storing system and CDN. I'm using Cloudinary, but Mark Llobrera uses Netlify Large Media: https://github.com/nhoizey/images-responsiver/issues/14
Thanks for taking the time to reply Nic, I appreciate it. A lot of people just skim read and don't actually think about the use case so it's great when someone replies properly. I did look at your plugin briefly when searching for solutions but for some reason it didn't stick as right for this use case, but I will give it another look now and get back to you. Thanks again.
@headapples you might find the documentation a bit strange right now, because yesterday I merged two repositories into one single monorepo, and the docs are not showing this yet.
Feel free to open issues in my repo if you have specific questions, to not bother people here. 🙏
Thanks Nic, I will do that. If the plugin can output responsive markup from a field input on Netlify CMS then it should work..........
I love Eleventy and believe it's the best baseline approach for web based projects available. Something like Svelte/Sapper can be added to parts of a project later on so I see them as something to reach for when required and the HTML/Static Site Generator workflow as the starter for most projects.
I'm currently stuck on the best approach to a problem and wanted to reach out to Zach and the Community to get some guidance, as I also saw it as a great way to learn about the different approaches to solve a problem. I feel sure other people can benefit from understanding the different layers of an SSG/11ty/Jamstack project and therefore the different approaches and how to choose the best one.
I know this question is quite broad but I am seriously stuck on the best approach and also sincerely believe it shows the different ways you can approach a problem and therefore might be useful to lots of different people working on lots of different SSG/Netlify CMS type projects.
Also a special shout out to @danfascia, who I know has had detailed discussions with Zach (and Jason from LearnwithJason YT channel) because I went to medical school with him in Edinburgh and he was a top bloke. Thought Dan might have some ideas about how to approach this as well.
The problem I'm trying to solve is how to allow a non-technical content editor, using Netlify CMS to add an image to a page and then have it automatically converted into responsive image markup, using the picture element and using Netlify Large Media image transformation query parameters for each image "src".
The number of images could be different on each page, from a single images to some pages that have a long list of images like a gallery. The image elements cannot therefore be hard coded into the templates.
Just to be clear, I want a Picture element, with srcset and sizes (and the img tag with src as fallback) that is populated with netlify large media query parameters for image tranformations. The content editor will upload to the Media gallery of Netlify CMS which is connected to Netlify Large Media and then choose which images to add to each page from the CMS, probably using the Image Widget (although I have considered a custom widget as mentioned below).
I've considered every possible way to do this and wanted to share them here as a learning experience and also hopefully to get some direction on the best option and how to decide.
What I've done already and considered. I already know how to setup Netlify Large Media, Git LFS and know about the Netlify Large Media gallery plugin for Netlify CMS>
The CMS/Markdown level: using something like markdown-it with markdown-it-responsive to create responsive image tag from the image chosen by the client. While this could get access to the filename of the image, could this approach actually output the correct HTML/picture element with different netlify image transform parameters?
Using a library like JSDOM to parse the actual HTML in the output folder of the site and find the image elements on each page and append the netlify query parameters to them.
Using a Netlify CMS plugin. These are great if the number of images is already known and they are hard coded into the templates but that is not my use case. Because the client is simply adding them from Netlify CMS I have no idea how many are already on each page.
Javascript data files. One of the issues on this repo covers this use case and was answered by Zach. He suggested using Fast-glob to iterate over a folder of images and then using javascript data files to save these to a collection. This collection could then be accessed via looping over them in the chosen templating language in Eleventy. This works really well but it displays all the images in the folder whereas i would like only the images on a chosen page to be displayed. Is there some way for Netlify CMS to send the images chosen for a certain page to a javascript data file for each page?
Some built in Eleventy Data that I'm missing or not understanding. Does 11ty have access to enough data about a page to find all the image elements on it? Something like "page.img" so that I can then iterate over all the images on a page and create responsive images markup with picture elements for each?
A custom Netlify CMS widget (which is a React Component as far as I understand it). Having spent several days thinking through this problem this feels like the direction to go. Can I create a custom widget that takes an input from the editor using Netlify CMS which chooses an image file from the Media gallery (in this case Netlify Large Media working with Netlify CMS) and then outputs responsive markup with the picture element from this single image file? This would be populated with netlify image transform query parameters for each image src. As any HTML is also valid in a markdown file, this feels like the most elegant and simple solution if it's possible to make a custom react component (Netlify CMS widget) that simply takes the input (as chosen image file from the media gallery) and outputs HTML markup for a responsive image (picture element).
Something else entirely from the Node or Javascript ecosystem, that would allow iterating over the final html files in the site, finding the images on each page and outputting responsive markup for each.
Sharp Image gallery. I know there is the option to produce responsive image variants in my build step using the Sharp library but I don't want to inflict these extra build times on the client, and this option also leaves me with the same problem of allowing Netlify CMS to choose an unknown number of images for each page.
Another choice of CMS. I love Netlify CMS and would prefer to use this great open source project if possible, but am I missing a much easier solution that would be provided by another CMS. I've looked briefly at Sanity, Contentful and Forestry but didn't feel like any of these solved this problem either. I already have a Netlify Business Plan and am looking at upgrading Gitlab for more build minutes so I'm not looking to add an extra expense for the CMS as well unless it's the only solution. I'd also like to avoid Graph QL if possible as it feels like overkill.
So yes, I am a bit stuck about the best way to approach this. I can only find solutions that either iterate over a global folder of images (with no way to be specific about which page they are on) or else solutions that use markup that is hard coded into the template and therefore require a known number of images.
After Zach very kindly replied to my tweet today saying he'd noodle on it for a while, he also made the suggestion to use eleventy-img as a starting point. I'd already read through the docs for this, but now wonder if it might work by simply allowing a Netlify CMS user to upload to the image folder that is used as the source for this plugin, and then using the image widget to pick an image from the dist folder for this plugin. The only problem I can see with this is that it wouldn't actually supply the required HTML markup. The plugin is returning this markup somewhere as data, so it's just how to allow it to be accessed with one click by a widget in the CMS..........
And my very final though on approaches is simply using Netlify CMS to input a list of image file names in the front matter. This can then be accessed and iterated over. I really feel like I might be missing a simple way to allow a content editor to add a list of filenames to front matter.
OR: make every image it's own piece of content, in it's own template. For example "image1.njk". This would allow the content editor using the CMS to use several tags. It would then be possible to create gallery or category pages based on each tag. This approach would also allow the correct responsive image markup with a picture element to be hard coded into the 11ty template. This takes care of the categories and gallery part of the problem, but how do I then allow each image to be chosen for any random page in the future? Is there some way to allow Netlify CMS to create an <%include> and to select the "image1.njk" or "image2.njk" as the thing to include in the page?
And yet another approach is setting the global or local media library upload to output only a filename, and then simply adding the dynamic url parameters in your content/templates. This example uses Cloudinary but it's the same idea: https://community.netlify.com/t/cloudinary-responsive-images/19661
To further highlight the numerous approaches to the SSG/CMS workflow, yet another approach to this problem occurred to me this afternoon:
This last option (the two step one shown directly above) would certainly work so it's probably between this and the custom CMS widget approach in my opinion but I would appreciate anyone else's thoughts on this.