Tagged “eleventy”
-
Recently I set up a new page on this site to list the books I've read: https://alansuspect.dev/books/
There is probably more I could do with it but getting it working in the first place was my main concern.
I started using Bookwyrm a few years ago to track my reading, and last year switched over to my own self-hosted version so I had more control over the RSS and API feeds (mainly by using the latest version).
My instance/user sits here and my read list here. Initially I was looking at the RSS feed option to import into my site but then I discovered there is also a JSON feed, which I find cleaner.
The JSON feed just gives an overview though, I knew the code would need to check the pages from 'first' to 'last' to get all the books in my list.
At this point I had to I needed to enlist the help of a code AI since JS isn't my strong suit. I've made my thoughts on AI clear elsewhere but suffice it to say it does make me feel icky to use one.
My focus was:
-
Get details from JSON feed
-
Follow links and references in the feed to fetch further info (e.g. use the author number to fetch author details like name, etc).
-
Cobble it all together to display the data on the front end
Here's how I did it:
In fetchBooks.js in the root of my eleventy project I start by setting up my URL as a variable I can use throughout the code:
const baseUrl = 'https://books.alansuspect.dev/user/read/books/read'; const shelfUrl = `${baseUrl}.json`;After some error checking we find how many pages we'll have to loop through:
const shelfData = await shelfResponse.json(); const totalPages = new URL(shelfData.last).searchParams.get('page'); const books = [];Now we have a place to put our book data once we've fetched it. Then we have a for loop to loop through the pages and grab our data:
for (let page = 1; page <= totalPages; page++) { const pageUrl = `${baseUrl}.json?page=${page}`; const response = await fetch(pageUrl); if (!response.ok) { throw new Error(`Error fetching page ${page}: ${response.statusText}`); } const data = await response.json(); if (data.orderedItems) { books.push(...data.orderedItems); } }And finally return the data with a sort of latest:
return books.sort((a, b) => new Date(b.publishedDate) - new Date(a.publishedDate));This gets the data, but what to do with it? I then made a new file in _data called books.js. This code takes the book data, finds the author URL in Bookwyrm and grabs the authors data.
There are a few shortcomings to Bookwyrm's API where I can only access specific data, for example I can't access my Reading Goals or get each year's worth of read books instead of just all books.
Below are the full files in case you want to try it yourself, and if you make any improvements let me know! I'd like to see if a more experienced dev can squeeze more out of it. Also I'll probably change the code over to eleventy-fetch at some point too.
fetchBooks.js
import fetch from 'node-fetch'; const fetchBooks = async () => { const baseUrl = 'https://books.alansuspect.dev/user/read/books/read'; const shelfUrl = `${baseUrl}.json`; const shelfResponse = await fetch(shelfUrl); if (!shelfResponse.ok) { throw new Error(`Failed to fetch shelf data: ${shelfResponse.statusText}`); } const shelfData = await shelfResponse.json(); const totalPages = new URL(shelfData.last).searchParams.get('page'); const books = []; for (let page = 1; page <= totalPages; page++) { const pageUrl = `${baseUrl}.json?page=${page}`; const response = await fetch(pageUrl); if (!response.ok) { throw new Error(`Error fetching page ${page}: ${response.statusText}`); } const data = await response.json(); if (data.orderedItems) { books.push(...data.orderedItems); } } // Sort books by published date (most recent first) return books.sort((a, b) => new Date(b.publishedDate) - new Date(a.publishedDate)); }; export default fetchBooks;_data/books.js
import fetchBooks from '../fetchBooks.js'; import fetch from 'node-fetch'; const fetchAuthorName = async (authorUrl) => { try { const response = await fetch(`${authorUrl}.json`); if (!response.ok) { throw new Error(`Failed to fetch author: ${response.statusText}`); } const authorData = await response.json(); return authorData.name || 'Unknown Author'; } catch (error) { console.error(`Error fetching author ${authorUrl}:`, error); return 'Unknown Author'; } }; export default async () => { try { const books = await fetchBooks(); // console.log('Fetched books:', books); const processedBooks = await Promise.all( books.map(async (book) => { let authorNames = 'Unknown Author'; if (book.authors && book.authors.length > 0) { const authorPromises = book.authors.map(authorUrl => fetchAuthorName(authorUrl)); const names = await Promise.all(authorPromises); authorNames = names.join(', '); } return { ...book, authorNames }; }) ); return { books: processedBooks || [] }; } catch (error) { console.error('Error fetching books:', error); return { books: [] }; } }; -
-
testing!
-
Well I did it, I've officially had an active blog for a year now.
I think it's the longest I've ever kept a blog going - and at 14 posts I'm not exactly winning any records - but sticking to things isn't my forté so I'm pretty chuffed with myself.
Looking back, I've enjoyed playing with Eleventy (more to come on that in future posts); discovering itch.io and all the amazing games on there; and also finding bitsy and making several fun games.
So here's to the next year, and seeing what else I can add to this site.
-
I had a spare moment yesterday [sorry, a what?] so I jumped in with the most straight-forward looking option to try out - PagesCMS.
I have no affiliation with this platform so anything positive below is sincere and I will continue to review it as I use it as my CMS.
It was actually even easier than I expected to set up, although I did go with the hosted version rather than trying to host it myself since their instructions only cover Vercel and involve setting up a database, which I don't have time to manage at this point.
For those not aware - as I wasn't a few days ago - PagesCMS connects to your GitHub account and manages the flat files you have in there before they get built. It is also completely customisable in terms of what you can choose to edit since you point the CMS to the content, it doesn't take over or try to make you do things you don't want to. You can edit posts, but also any custom post types you have and single pages as well. Saving them will update your repository and in turn trigger a build of your site if you have that set up.
Once the initial account signup process is done (via GitHub) I am presented with a dashboard where I can see my current repository, add new ones, create a new project or even add another GitHub account.
The most important thing you need to do is add a config file. The docs are well written and even have an 11ty example config file to get you started.
My blog is based off the eleventy-base-blog-v8 so is a little out of date and honestly at some point I plan on changing it to something homemade - but that's getting off on a tangent. The downside here is that I wrote additional pieces of text content (such as the blurb on my homepage) like this:
module.exports = { description: "I'm a web developer based in Australia. I build with Wordpress, Shopify and now also Eleventy, sometimes mixing them all together.", }But in the config file it only likes JSON for this format, so 'description' doesn't auto-populate and is uneditable. I'm not sure if this was something I did for some reason, or if v8 of the blog did this and was changed for v9.
This also goes for my About page and site meta as well; it's not an issue as I'm not planning on changing these immediately, but worth noting for future reference.
Another issue I ran into was getting my post tags working. I like the way these work in Eleventy, generating a post list for each tag and wanted to be able to edit these easily in the CMS too. After searching the GitHub issues page I came across the answer, which it turned out was also in their docs all along. Here's the important part of my config file covering the posts:
content: - name: blog label: Blog type: collection path: 'content/blog' filename: "{fields.title}.md" view: fields: [ title, description, date, tags ] fields: - name: title label: Title type: string - name: description label: Description type: string - name: date label: Date type: date - name: tags label: Tags type: string list: true fields: - name: tag label: Tag type: string - name: body label: Body type: rich-textIn this config I added:
-
'filename' - I added this in because I like to use the title as the post slug. In Obsidian I was doing this manually in the frontmatter so it's nice to automate it. You can also use variables like {year} to build a slug.
-
fields > name: tags - this got my tags in place by using the 'list' field type. It will then repeat the fields within for each entry, so here I just have a single text field for each tag.
However, although this creates a nice interface for adding new tags and correctly adds the tags frontmatter to my post, the build fails each time and I cannot figure out why.
This is how the tags selection should look in the CMS, but unfortunately when I add any tags it breaks the build:

If I can get this working it will mean I can keep adding tags, the only downside is I can't see tags I've already added to reuse but I tend to write them off the cuff anyway. Also in the config you can have min/max settings to limit these options as well.
This is my first post written using PagesCMS (and that above is my first embedded image in the entire blog so fingers crossed) so we'll see how it goes, but I would like to get my tags working.
I mentioned earlier about changing my blog theme and having a functional CMS has made me think about how I want to redo that as well, but I also need to figure out what I want from this blog too.
If you are currently manually editing your markdown files for your Eleventy blog and want an easier way to handle things, give it a shot. I'll try and keep updates on using it and any issues I may run into.
-
-
Is there a flat-file CMS I could point to my Eleventy dev folder that would act as a nice front end to manage the Markdown content?
I've looked at a few (such as Grav, TinaCMS, Pico CMS, SpinalCMS) but they seem to do their own thing and manage files/site themselves, whereas I'd want Eleventy to handle everything and just have a nice UI instead of dealing with files.
The idea being when you save a post/page (.md file) it would update the e.g. GitHub repo and trigger the build. Any ideas?
Bonus points for being open source and also an accommodating free plan, or at least decent upgrade levels that don't go from free to $500 pm for an additional seat.
Mattrbld looks good but I'm not sure how mature/stable it is and so does PagesCMS if it can do what I'm after. I guess it also depends on hosting and my options there too.
-
I keep coming back to reading about web components.
The opportunity to try them out hasn't come up yet but I still don't think I get it. Is it just another way of sneaking JavaScript into a site build? Do they work without JavaScript?
With all the Eleventy talk about moving to Font Awesome and their Web Awesome stuff I really want to learn it and like it, but I'm coming at it from an HTML/CSS-only standpoint (static sites lend themselves to a lack of JS) and am trying to understand how it carefully adds to a build, instead of taking it over or relying on JS. Or maybe I'm way off.
For several years now I've used "builders" for some clients, mostly on WordPress, which are a swamp of JavaScript and awful performance. So as I look to simpler project builds in the future I want to factor in nice solutions for things that aren't going to turn into a hassle down the line.
The idea of browsers supporting it sounds fantastic though. Maybe I'll figure it out one day.
-
I started using Obsidian a few months ago, after first moving to Quillpad from Google Notes when I decided to de-Google. It is a pretty powerful editor and note taker but I hadn't really looked into what it could do until I saw a post on Mastodon about using it to edit posts in Eleventy. Neat!
This is basically a test post to see if I can use Obsidian as a CMS. Let's see if it works.
Update: it works!
-
I've made this site to post about dev stuff I'm working on, and other fun things.
It's built using Eleventy which I've been playing around with a lot recently, especially trying to hook up WordPress as a CMS.
So that's probably what I'll be talking about. Oh and customising a Miyoo Mini Plus V3 with cool ROMs.
See all tags.