From 6d64bd2813e0d5db36fe4b6693db04043b2654a4 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 10 Nov 2023 16:41:13 -0600 Subject: [PATCH 01/64] v9 switches to ESM --- _data/metadata.js | 2 +- content/blog/blog.11tydata.js | 2 +- content/feed/feed.11tydata.js | 2 +- eleventy.config.drafts.js | 5 ++--- eleventy.config.images.js | 6 +++--- eleventy.config.js | 22 ++++++++++++---------- package.json | 3 ++- 7 files changed, 22 insertions(+), 20 deletions(-) diff --git a/_data/metadata.js b/_data/metadata.js index 5a5c99b..97faa8c 100644 --- a/_data/metadata.js +++ b/_data/metadata.js @@ -1,4 +1,4 @@ -module.exports = { +export default { title: "Eleventy Base Blog v8", url: "https://example.com/", language: "en", diff --git a/content/blog/blog.11tydata.js b/content/blog/blog.11tydata.js index 2d655b1..614f505 100644 --- a/content/blog/blog.11tydata.js +++ b/content/blog/blog.11tydata.js @@ -1,4 +1,4 @@ -module.exports = { +export default { tags: [ "posts" ], diff --git a/content/feed/feed.11tydata.js b/content/feed/feed.11tydata.js index ed3fec9..42ad826 100644 --- a/content/feed/feed.11tydata.js +++ b/content/feed/feed.11tydata.js @@ -1,3 +1,3 @@ -module.exports = { +export default { eleventyExcludeFromCollections: true } diff --git a/eleventy.config.drafts.js b/eleventy.config.drafts.js index 8eb92dc..daea903 100644 --- a/eleventy.config.drafts.js +++ b/eleventy.config.drafts.js @@ -24,10 +24,9 @@ function eleventyComputedExcludeFromCollections() { } }; -module.exports.eleventyComputedPermalink = eleventyComputedPermalink; -module.exports.eleventyComputedExcludeFromCollections = eleventyComputedExcludeFromCollections; +export { eleventyComputedPermalink, eleventyComputedExcludeFromCollections }; -module.exports = eleventyConfig => { +export default function(eleventyConfig) { eleventyConfig.addGlobalData("eleventyComputed.permalink", eleventyComputedPermalink); eleventyConfig.addGlobalData("eleventyComputed.eleventyExcludeFromCollections", eleventyComputedExcludeFromCollections); diff --git a/eleventy.config.images.js b/eleventy.config.images.js index 32a0269..b2c98b2 100644 --- a/eleventy.config.images.js +++ b/eleventy.config.images.js @@ -1,7 +1,7 @@ -const path = require("path"); -const eleventyImage = require("@11ty/eleventy-img"); +import path from "path"; +import eleventyImage from "@11ty/eleventy-img"; -module.exports = eleventyConfig => { +export default function(eleventyConfig) { function relativeToInputPath(inputPath, relativeFilePath) { let split = inputPath.split("/"); split.pop(); diff --git a/eleventy.config.js b/eleventy.config.js index 3fba4b7..807d26e 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,16 +1,18 @@ -const { DateTime } = require("luxon"); -const markdownItAnchor = require("markdown-it-anchor"); +import { DateTime } from "luxon"; +import markdownItAnchor from "markdown-it-anchor"; -const pluginRss = require("@11ty/eleventy-plugin-rss"); -const pluginSyntaxHighlight = require("@11ty/eleventy-plugin-syntaxhighlight"); -const pluginBundle = require("@11ty/eleventy-plugin-bundle"); -const pluginNavigation = require("@11ty/eleventy-navigation"); -const { EleventyHtmlBasePlugin } = require("@11ty/eleventy"); +import pluginRss from "@11ty/eleventy-plugin-rss"; +import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; +import pluginBundle from "@11ty/eleventy-plugin-bundle"; +import pluginNavigation from "@11ty/eleventy-navigation"; -const pluginDrafts = require("./eleventy.config.drafts.js"); -const pluginImages = require("./eleventy.config.images.js"); +import pluginDrafts from "./eleventy.config.drafts.js"; +import pluginImages from "./eleventy.config.images.js"; + +/** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */ +export default async function(eleventyConfig) { + const { EleventyHtmlBasePlugin } = await import("@11ty/eleventy"); -module.exports = function(eleventyConfig) { // Copy the contents of the `public` folder to the output folder // For example, `./public/css/` ends up in `_site/css/` eleventyConfig.addPassthroughCopy({ diff --git a/package.json b/package.json index e3340f0..118f343 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,8 @@ { "name": "eleventy-base-blog", - "version": "8.0.0", + "version": "9.0.0", "description": "A starter repository for a blog web site using the Eleventy site generator.", + "type": "module", "scripts": { "build": "npx @11ty/eleventy", "build-ghpages": "npx @11ty/eleventy --pathprefix=/eleventy-base-blog/", From 4c57a825da0de68dfdb9dad2ec7b7f448f825e27 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Sun, 14 Jan 2024 12:32:15 +1300 Subject: [PATCH 02/64] Status --- README.md | 2 +- _data/metadata.js | 2 +- _includes/layouts/base.njk | 4 ++-- content/404.md | 2 +- content/blog/fifthpost.md | 8 ++++---- content/blog/secondpost.md | 4 ++-- content/tag-pages.njk | 22 ++++++++++++++++++++++ content/tags-list.njk | 12 ------------ content/tags.njk | 25 +++++++------------------ eleventy.config.js | 14 ++++++++------ package.json | 8 ++++---- 11 files changed, 52 insertions(+), 51 deletions(-) create mode 100644 content/tag-pages.njk delete mode 100644 content/tags-list.njk diff --git a/README.md b/README.md index 7177590..5e21e4f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# eleventy-base-blog v8 +# eleventy-base-blog v9 A starter repository showing how to build a blog with the [Eleventy](https://www.11ty.dev/) site generator (using the [v2.0 release](https://www.11ty.dev/blog/eleventy-v2/)). diff --git a/_data/metadata.js b/_data/metadata.js index 97faa8c..7e8b636 100644 --- a/_data/metadata.js +++ b/_data/metadata.js @@ -1,5 +1,5 @@ export default { - title: "Eleventy Base Blog v8", + title: "Eleventy Base Blog v9", url: "https://example.com/", language: "en", description: "I am writing about my experiences as a naval navel-gazer.", diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 3b3226f..1308e54 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -7,8 +7,8 @@ {#- Atom and JSON feeds included by default #} - - + + {#- Uncomment this if you’d like folks to know that you used Eleventy to build your site! #} {#- #} diff --git a/content/404.md b/content/404.md index bd51f61..c8be2df 100644 --- a/content/404.md +++ b/content/404.md @@ -5,7 +5,7 @@ eleventyExcludeFromCollections: true --- # Content not found. -Go home. +Go home. + + + + + + <xsl:value-of select="atom:feed/atom:title"/> + + + + + + +
+
+

+ + + + + + + + + + + + + + + + + + + Web Feed Preview +

+

+

+

This preview only shows titles, but the actual feed contains the full content.

+ + + + + Visit Website → + +
+

Recent Items

+ +
+ + +
+ +
+

+ + + + + + +

+ + Published: + +
+
+
diff --git a/eleventy.config.js b/eleventy.config.js index 2b21b1c..35e3e9d 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -17,6 +17,8 @@ export default async function(eleventyConfig) { "./node_modules/prismjs/themes/prism-okaidia.css": "/css/prism-okaidia.css" }); + eleventyConfig.addPassthroughCopy("./content/feed/pretty-atom-feed.xsl"); + // Run Eleventy when these files change: // https://www.11ty.dev/docs/watch-serve/#add-your-own-watch-targets From 801f879b26453591aef8101b55accdfda5690d05 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 24 Apr 2024 17:31:41 -0500 Subject: [PATCH 12/64] Adds Eleventy link to footer. --- _includes/layouts/base.njk | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index d8eee56..4814c79 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -54,7 +54,9 @@ {{ content | safe }} -
+ From 53f130ffe0ca0de4dda29d202cf48b9aabb97bd5 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 24 Apr 2024 17:33:34 -0500 Subject: [PATCH 13/64] Additional comments for dir information --- eleventy.config.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index 35e3e9d..c745f12 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -131,8 +131,8 @@ export default async function(eleventyConfig) { // These are all optional: dir: { input: "content", // default: "." - includes: "../_includes", // default: "_includes" - data: "../_data", // default: "_data" + includes: "../_includes", // default: "_includes" (`input` relative) + data: "../_data", // default: "_data" (`input` relative) output: "_site" }, From fadb8ab03428fb2703c13f086566701bcb9656dd Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 25 Apr 2024 11:43:34 -0500 Subject: [PATCH 14/64] Configuration cleanup --- _config/filters.js | 40 +++++++++++++ content/about/index.md | 4 +- eleventy.config.js | 127 +++++++++++++++-------------------------- 3 files changed, 89 insertions(+), 82 deletions(-) create mode 100644 _config/filters.js diff --git a/_config/filters.js b/_config/filters.js new file mode 100644 index 0000000..feb3499 --- /dev/null +++ b/_config/filters.js @@ -0,0 +1,40 @@ +import { DateTime } from "luxon"; + +export default function(eleventyConfig) { + eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => { + // Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens + return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(format || "dd LLLL yyyy"); + }); + + eleventyConfig.addFilter("htmlDateString", (dateObj) => { + // dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string + return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd'); + }); + + // Get the first `n` elements of a collection. + eleventyConfig.addFilter("head", (array, n) => { + if(!Array.isArray(array) || array.length === 0) { + return []; + } + if( n < 0 ) { + return array.slice(n); + } + + return array.slice(0, n); + }); + + // Return the smallest number argument + eleventyConfig.addFilter("min", (...numbers) => { + return Math.min.apply(null, numbers); + }); + + // Return the keys used in an object + eleventyConfig.addFilter("getKeys", target => { + return Object.keys(target); + }); + + eleventyConfig.addFilter("filterTagList", function filterTagList(tags) { + return (tags || []).filter(tag => ["all", "posts"].indexOf(tag) === -1); + }); + +}; diff --git a/content/about/index.md b/content/about/index.md index 673fc8d..8c673a8 100644 --- a/content/about/index.md +++ b/content/about/index.md @@ -1,8 +1,8 @@ --- eleventyNavigation: - key: About Me + key: About order: 3 --- -# About Me +# About I am a person that writes stuff. diff --git a/eleventy.config.js b/eleventy.config.js index c745f12..dadc193 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,4 +1,3 @@ -import { DateTime } from "luxon"; import markdownItAnchor from "markdown-it-anchor"; import { InputPathToUrlTransformPlugin, HtmlBasePlugin } from "@11ty/eleventy"; @@ -8,16 +7,18 @@ import pluginBundle from "@11ty/eleventy-plugin-bundle"; import pluginNavigation from "@11ty/eleventy-navigation"; import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; +import pluginFilters from "./_config/filters.js"; + /** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */ export default async function(eleventyConfig) { // Copy the contents of the `public` folder to the output folder // For example, `./public/css/` ends up in `_site/css/` - eleventyConfig.addPassthroughCopy({ - "./public/": "/", - "./node_modules/prismjs/themes/prism-okaidia.css": "/css/prism-okaidia.css" - }); - - eleventyConfig.addPassthroughCopy("./content/feed/pretty-atom-feed.xsl"); + eleventyConfig + .addPassthroughCopy({ + "./public/": "/", + "./node_modules/prismjs/themes/prism-okaidia.css": "/css/prism-okaidia.css" + }) + .addPassthroughCopy("./content/feed/pretty-atom-feed.xsl"); // Run Eleventy when these files change: // https://www.11ty.dev/docs/watch-serve/#add-your-own-watch-targets @@ -50,41 +51,7 @@ export default async function(eleventyConfig) { }); // Filters - eleventyConfig.addFilter("readableDate", (dateObj, format, zone) => { - // Formatting tokens for Luxon: https://moment.github.io/luxon/#/formatting?id=table-of-tokens - return DateTime.fromJSDate(dateObj, { zone: zone || "utc" }).toFormat(format || "dd LLLL yyyy"); - }); - - eleventyConfig.addFilter("htmlDateString", (dateObj) => { - // dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string - return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd'); - }); - - // Get the first `n` elements of a collection. - eleventyConfig.addFilter("head", (array, n) => { - if(!Array.isArray(array) || array.length === 0) { - return []; - } - if( n < 0 ) { - return array.slice(n); - } - - return array.slice(0, n); - }); - - // Return the smallest number argument - eleventyConfig.addFilter("min", (...numbers) => { - return Math.min.apply(null, numbers); - }); - - // Return the keys used in an object - eleventyConfig.addFilter("getKeys", target => { - return Object.keys(target); - }); - - eleventyConfig.addFilter("filterTagList", function filterTagList(tags) { - return (tags || []).filter(tag => ["all", "posts"].indexOf(tag) === -1); - }); + eleventyConfig.addPlugin(pluginFilters); // Customize Markdown library settings: eleventyConfig.amendLibrary("md", mdLib => { @@ -111,42 +78,42 @@ export default async function(eleventyConfig) { // https://www.11ty.dev/docs/copy/#emulate-passthrough-copy-during-serve // eleventyConfig.setServerPassthroughCopyBehavior("passthrough"); - - return { - // Control which files Eleventy will process - // e.g.: *.md, *.njk, *.html, *.liquid - templateFormats: [ - "md", - "njk", - "html", - "liquid", - ], - - // Pre-process *.md files with: (default: `liquid`) - markdownTemplateEngine: "njk", - - // Pre-process *.html files with: (default: `liquid`) - htmlTemplateEngine: "njk", - - // These are all optional: - dir: { - input: "content", // default: "." - includes: "../_includes", // default: "_includes" (`input` relative) - data: "../_data", // default: "_data" (`input` relative) - output: "_site" - }, - - // ----------------------------------------------------------------- - // Optional items: - // ----------------------------------------------------------------- - - // If your site deploys to a subdirectory, change `pathPrefix`. - // Read more: https://www.11ty.dev/docs/config/#deploy-to-a-subdirectory-with-a-path-prefix - - // When paired with the HTML plugin https://www.11ty.dev/docs/plugins/html-base/ - // it will transform any absolute URLs in your HTML to include this - // folder name and does **not** affect where things go in the output folder. - - // pathPrefix: "/", - }; +}; + +export const config = { + // Control which files Eleventy will process + // e.g.: *.md, *.njk, *.html, *.liquid + templateFormats: [ + "md", + "njk", + "html", + "liquid", + ], + + // Pre-process *.md files with: (default: `liquid`) + markdownTemplateEngine: "njk", + + // Pre-process *.html files with: (default: `liquid`) + htmlTemplateEngine: "njk", + + // These are all optional: + dir: { + input: "content", // default: "." + includes: "../_includes", // default: "_includes" (`input` relative) + data: "../_data", // default: "_data" (`input` relative) + output: "_site" + }, + + // ----------------------------------------------------------------- + // Optional items: + // ----------------------------------------------------------------- + + // If your site deploys to a subdirectory, change `pathPrefix`. + // Read more: https://www.11ty.dev/docs/config/#deploy-to-a-subdirectory-with-a-path-prefix + + // When paired with the HTML plugin https://www.11ty.dev/docs/plugins/html-base/ + // it will transform any absolute URLs in your HTML to include this + // folder name and does **not** affect where things go in the output folder. + + // pathPrefix: "/", }; From 855f27468eb20bbef7559d6a64ab5be43c9ad118 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 1 May 2024 10:17:05 -0500 Subject: [PATCH 15/64] Upgrade dep, use built-in Bundle Plugin. --- eleventy.config.js | 8 ++++++-- package.json | 3 +-- public/css/index.css | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index dadc193..b0b94ef 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -3,7 +3,6 @@ import markdownItAnchor from "markdown-it-anchor"; import { InputPathToUrlTransformPlugin, HtmlBasePlugin } from "@11ty/eleventy"; import pluginRss from "@11ty/eleventy-plugin-rss"; import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; -import pluginBundle from "@11ty/eleventy-plugin-bundle"; import pluginNavigation from "@11ty/eleventy-navigation"; import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; @@ -26,13 +25,18 @@ export default async function(eleventyConfig) { // Watch content images for the image pipeline. eleventyConfig.addWatchTarget("content/**/*.{svg,webp,png,jpeg}"); + // Per-page bundles, see https://github.com/11ty/eleventy-plugin-bundle + // Adds the {% css %} paired shortcode + eleventyConfig.addBundle("css"); + // Do you want a {% js %} bundle shortcode too? + // eleventyConfig.addBundle("js"); + // Official plugins eleventyConfig.addPlugin(pluginRss); eleventyConfig.addPlugin(pluginSyntaxHighlight, { preAttributes: { tabindex: 0 } }); eleventyConfig.addPlugin(pluginNavigation); - eleventyConfig.addPlugin(pluginBundle); eleventyConfig.addPlugin(HtmlBasePlugin); eleventyConfig.addPlugin(InputPathToUrlTransformPlugin); diff --git a/package.json b/package.json index 46bdde7..afb8caf 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,9 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.9", + "@11ty/eleventy": "3.0.0-alpha.10", "@11ty/eleventy-img": "5.0.0-beta.1", "@11ty/eleventy-navigation": "^0.3.5", - "@11ty/eleventy-plugin-bundle": "^1.0.5", "@11ty/eleventy-plugin-rss": "^1.2.0", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "luxon": "^3.4.4", diff --git a/public/css/index.css b/public/css/index.css index 9000fe1..f38dda1 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -89,7 +89,8 @@ a[href]:active { color: var(--text-color-link-active); } -main { +main, +footer { padding: 1rem; } main :first-child { From 6b5d6bba1c58dc9026bed439e1c67f9a67cd4bc4 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Sat, 8 Jun 2024 20:58:22 -0500 Subject: [PATCH 16/64] Add virtual Atom and JSON feeds. Example for https://github.com/11ty/eleventy-plugin-rss/issues/47 --- content/feed/.virtual | 1 + content/feed/atom.njk | 31 ---------------------------- content/feed/feed.11tydata.js | 3 --- content/feed/json.njk | 29 -------------------------- eleventy.config.js | 38 +++++++++++++++++++++++++++++++++-- package.json | 2 +- 6 files changed, 38 insertions(+), 66 deletions(-) create mode 100644 content/feed/.virtual delete mode 100755 content/feed/atom.njk delete mode 100644 content/feed/feed.11tydata.js delete mode 100644 content/feed/json.njk diff --git a/content/feed/.virtual b/content/feed/.virtual new file mode 100644 index 0000000..0ee5e54 --- /dev/null +++ b/content/feed/.virtual @@ -0,0 +1 @@ +For RSS feed, Atom Feed, and JSON feed templates, see the plugin in eleventy.config.js diff --git a/content/feed/atom.njk b/content/feed/atom.njk deleted file mode 100755 index d8f8688..0000000 --- a/content/feed/atom.njk +++ /dev/null @@ -1,31 +0,0 @@ ---- -# Metadata comes from _data/metadata.js -permalink: /feed/feed.xml -eleventyNavigation: - key: Feed - order: 3 ---- - - - - {{ metadata.title }} - {{ metadata.description }} - - - {{ collections.posts | getNewestCollectionItemDate | dateToRfc3339 }} - {{ metadata.url }} - - {{ metadata.author.name }} - {{ metadata.author.email }} - - {%- for post in collections.posts | reverse %} - {%- set absolutePostUrl %}{{ post.url | htmlBaseUrl(metadata.url) }}{% endset %} - - {{ post.data.title }} - - {{ post.date | dateToRfc3339 }} - {{ absolutePostUrl }} - {{ post.templateContent | transformWithHtmlBase(absolutePostUrl, post.url) }} - - {%- endfor %} - diff --git a/content/feed/feed.11tydata.js b/content/feed/feed.11tydata.js deleted file mode 100644 index 3c76e38..0000000 --- a/content/feed/feed.11tydata.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - layout: false, -}; diff --git a/content/feed/json.njk b/content/feed/json.njk deleted file mode 100644 index 3b33b59..0000000 --- a/content/feed/json.njk +++ /dev/null @@ -1,29 +0,0 @@ ---- -# Metadata comes from _data/metadata.js -permalink: /feed/feed.json ---- -{ - "version": "https://jsonfeed.org/version/1.1", - "title": "{{ metadata.title }}", - "language": "{{ metadata.language }}", - "home_page_url": "{{ metadata.url | addPathPrefixToFullUrl }}", - "feed_url": "{{ permalink | htmlBaseUrl(metadata.url) }}", - "description": "{{ metadata.description }}", - "author": { - "name": "{{ metadata.author.name }}", - "url": "{{ metadata.author.url }}" - }, - "items": [ - {%- for post in collections.posts | reverse %} - {%- set absolutePostUrl = post.url | htmlBaseUrl(metadata.url) %} - { - "id": "{{ absolutePostUrl }}", - "url": "{{ absolutePostUrl }}", - "title": "{{ post.data.title }}", - "content_html": {% if post.templateContent %}{{ post.templateContent | transformWithHtmlBase(absolutePostUrl, post.url) | dump | safe }}{% else %}""{% endif %}, - "date_published": "{{ post.date | dateToRfc3339 }}" - } - {% if not loop.last %},{% endif %} - {%- endfor %} - ] -} diff --git a/eleventy.config.js b/eleventy.config.js index b0b94ef..72bcb31 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,7 +1,7 @@ import markdownItAnchor from "markdown-it-anchor"; import { InputPathToUrlTransformPlugin, HtmlBasePlugin } from "@11ty/eleventy"; -import pluginRss from "@11ty/eleventy-plugin-rss"; +import { feedPlugin } from "@11ty/eleventy-plugin-rss"; import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; import pluginNavigation from "@11ty/eleventy-navigation"; import { eleventyImageTransformPlugin } from "@11ty/eleventy-img"; @@ -32,7 +32,37 @@ export default async function(eleventyConfig) { // eleventyConfig.addBundle("js"); // Official plugins - eleventyConfig.addPlugin(pluginRss); + eleventyConfig.addPlugin(feedPlugin, { + files: { + json: "/feed/feed.json", + atom: "/feed/feed.xml", + // "rss": "/feed/rss.xml", + }, + stylesheet: { + atom: "pretty-atom-feed.xsl", + }, + templateData: { + atom: { + eleventyNavigation: { + key: "Feed", + order: 3 + } + } + }, + collectionName: "posts", + limit: 10, + metadata: { + language: "en", + title: "Blog Title", + subtitle: "This is a longer description about your blog.", + base: "https://example.com/", + author: { + name: "Your Name", + email: "me@example.com" + } + } + }); + eleventyConfig.addPlugin(pluginSyntaxHighlight, { preAttributes: { tabindex: 0 } }); @@ -44,9 +74,12 @@ export default async function(eleventyConfig) { eleventyConfig.addPlugin(eleventyImageTransformPlugin, { // File extensions to process in _site folder extensions: "html", + // Output formats for each image. formats: ["avif", "webp", "auto"], + // widths: ["auto"], + defaultAttributes: { // e.g. assigned on the HTML tag will override these values. loading: "lazy", @@ -92,6 +125,7 @@ export const config = { "njk", "html", "liquid", + "11ty.js", ], // Pre-process *.md files with: (default: `liquid`) diff --git a/package.json b/package.json index afb8caf..70f369e 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@11ty/eleventy": "3.0.0-alpha.10", "@11ty/eleventy-img": "5.0.0-beta.1", "@11ty/eleventy-navigation": "^0.3.5", - "@11ty/eleventy-plugin-rss": "^1.2.0", + "@11ty/eleventy-plugin-rss": "^2.0.0-beta.5", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "luxon": "^3.4.4", "markdown-it-anchor": "^8.6.7", From df8fb9b546eb0f95284c1d27be4b488ee8110409 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Sat, 8 Jun 2024 20:58:41 -0500 Subject: [PATCH 17/64] Upgrade dep --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 70f369e..58e7bee 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { "@11ty/eleventy": "3.0.0-alpha.10", - "@11ty/eleventy-img": "5.0.0-beta.1", + "@11ty/eleventy-img": "5.0.0-beta.4", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^2.0.0-beta.5", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", From c5045eb8f303a01e3bf643ea55a597cbfc1c9eb3 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Sun, 9 Jun 2024 07:43:29 -0500 Subject: [PATCH 18/64] Upgrade RSS dep --- eleventy.config.js | 24 +++++++++--------------- package.json | 2 +- 2 files changed, 10 insertions(+), 16 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index 72bcb31..98004b2 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -33,24 +33,18 @@ export default async function(eleventyConfig) { // Official plugins eleventyConfig.addPlugin(feedPlugin, { - files: { - json: "/feed/feed.json", - atom: "/feed/feed.xml", - // "rss": "/feed/rss.xml", - }, - stylesheet: { - atom: "pretty-atom-feed.xsl", - }, + outputPath: "/feed/feed.xml", + stylesheet: "pretty-atom-feed.xsl", templateData: { - atom: { - eleventyNavigation: { - key: "Feed", - order: 3 - } + eleventyNavigation: { + key: "Feed", + order: 3 } }, - collectionName: "posts", - limit: 10, + collection: { + name: "posts", + limit: 10, + }, metadata: { language: "en", title: "Blog Title", diff --git a/package.json b/package.json index 58e7bee..d50cd20 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "@11ty/eleventy": "3.0.0-alpha.10", "@11ty/eleventy-img": "5.0.0-beta.4", "@11ty/eleventy-navigation": "^0.3.5", - "@11ty/eleventy-plugin-rss": "^2.0.0-beta.5", + "@11ty/eleventy-plugin-rss": "^2.0.0-beta.6", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "luxon": "^3.4.4", "markdown-it-anchor": "^8.6.7", From f7feb1676b9069da597ae81a731b8651d250a3b8 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Mon, 10 Jun 2024 17:21:25 -0500 Subject: [PATCH 19/64] Upgrade deps --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d50cd20..f93a19d 100644 --- a/package.json +++ b/package.json @@ -34,14 +34,14 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.10", + "@11ty/eleventy": "3.0.0-alpha.11", "@11ty/eleventy-img": "5.0.0-beta.4", "@11ty/eleventy-navigation": "^0.3.5", - "@11ty/eleventy-plugin-rss": "^2.0.0-beta.6", + "@11ty/eleventy-plugin-rss": "^2.0.0-beta.7", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "luxon": "^3.4.4", "markdown-it-anchor": "^8.6.7", - "zod": "^3.23.4", - "zod-validation-error": "^3.2.0" + "zod": "^3.23.8", + "zod-validation-error": "^3.3.0" } } From c1d0bf93019559e17ac66d19bfa23f6e46310035 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 12 Jun 2024 10:41:34 -0500 Subject: [PATCH 20/64] Update deps --- eleventy.config.js | 18 +++++++++--------- package.json | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index 98004b2..45326ee 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -32,6 +32,14 @@ export default async function(eleventyConfig) { // eleventyConfig.addBundle("js"); // Official plugins + eleventyConfig.addPlugin(pluginSyntaxHighlight, { + preAttributes: { tabindex: 0 } + }); + eleventyConfig.addPlugin(pluginNavigation); + eleventyConfig.addPlugin(HtmlBasePlugin); + eleventyConfig.addPlugin(InputPathToUrlTransformPlugin); + + // Atom Feed eleventyConfig.addPlugin(feedPlugin, { outputPath: "/feed/feed.xml", stylesheet: "pretty-atom-feed.xsl", @@ -51,19 +59,11 @@ export default async function(eleventyConfig) { subtitle: "This is a longer description about your blog.", base: "https://example.com/", author: { - name: "Your Name", - email: "me@example.com" + name: "Your Name" } } }); - eleventyConfig.addPlugin(pluginSyntaxHighlight, { - preAttributes: { tabindex: 0 } - }); - eleventyConfig.addPlugin(pluginNavigation); - eleventyConfig.addPlugin(HtmlBasePlugin); - eleventyConfig.addPlugin(InputPathToUrlTransformPlugin); - // Image optimization: https://www.11ty.dev/docs/plugins/image/#eleventy-transform eleventyConfig.addPlugin(eleventyImageTransformPlugin, { // File extensions to process in _site folder diff --git a/package.json b/package.json index f93a19d..fe020e3 100644 --- a/package.json +++ b/package.json @@ -34,10 +34,10 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.11", + "@11ty/eleventy": "3.0.0-alpha.13", "@11ty/eleventy-img": "5.0.0-beta.4", "@11ty/eleventy-navigation": "^0.3.5", - "@11ty/eleventy-plugin-rss": "^2.0.0-beta.7", + "@11ty/eleventy-plugin-rss": "2.0.0-beta.8", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "luxon": "^3.4.4", "markdown-it-anchor": "^8.6.7", From 499ca5e655d1954ebaf903fa5855a1839018773b Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 16 Jul 2024 09:38:01 -0500 Subject: [PATCH 21/64] Update JS front matter name, use cross-env where available, adds build-nocolor script --- _config/filters.js | 2 +- content/blog/fifthpost.md | 2 +- content/tag-pages.njk | 2 +- package.json | 12 +++++++----- 4 files changed, 10 insertions(+), 8 deletions(-) diff --git a/_config/filters.js b/_config/filters.js index feb3499..4af2fe8 100644 --- a/_config/filters.js +++ b/_config/filters.js @@ -8,7 +8,7 @@ export default function(eleventyConfig) { eleventyConfig.addFilter("htmlDateString", (dateObj) => { // dateObj input: https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string - return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd'); + return DateTime.fromJSDate(dateObj, { zone: "utc" }).toFormat('yyyy-LL-dd'); }); // Get the first `n` elements of a collection. diff --git a/content/blog/fifthpost.md b/content/blog/fifthpost.md index da2e95e..6ff059b 100644 --- a/content/blog/fifthpost.md +++ b/content/blog/fifthpost.md @@ -1,4 +1,4 @@ ----node +---js const title = "This is a fifth post (draft)"; const date = "2023-01-23"; const draft = true; diff --git a/content/tag-pages.njk b/content/tag-pages.njk index 9533be9..33b7abf 100644 --- a/content/tag-pages.njk +++ b/content/tag-pages.njk @@ -1,4 +1,4 @@ ----node +---js // diff --git a/eleventy.config.js b/eleventy.config.js index 45326ee..753bba8 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -1,6 +1,4 @@ -import markdownItAnchor from "markdown-it-anchor"; - -import { InputPathToUrlTransformPlugin, HtmlBasePlugin } from "@11ty/eleventy"; +import { IdAttributePlugin, InputPathToUrlTransformPlugin, HtmlBasePlugin } from "@11ty/eleventy"; import { feedPlugin } from "@11ty/eleventy-plugin-rss"; import pluginSyntaxHighlight from "@11ty/eleventy-plugin-syntaxhighlight"; import pluginNavigation from "@11ty/eleventy-navigation"; @@ -28,8 +26,8 @@ export default async function(eleventyConfig) { // Per-page bundles, see https://github.com/11ty/eleventy-plugin-bundle // Adds the {% css %} paired shortcode eleventyConfig.addBundle("css"); - // Do you want a {% js %} bundle shortcode too? - // eleventyConfig.addBundle("js"); + // Adds the {% js %} paired shortcode + eleventyConfig.addBundle("js"); // Official plugins eleventyConfig.addPlugin(pluginSyntaxHighlight, { @@ -84,20 +82,27 @@ export default async function(eleventyConfig) { // Filters eleventyConfig.addPlugin(pluginFilters); - // Customize Markdown library settings: - eleventyConfig.amendLibrary("md", mdLib => { - mdLib.use(markdownItAnchor, { - permalink: markdownItAnchor.permalink.ariaHidden({ - placement: "after", - class: "header-anchor", - symbol: "#", - ariaHidden: false, - }), - level: [1,2,3,4], - slugify: eleventyConfig.getFilter("slugify") - }); + eleventyConfig.addPlugin(IdAttributePlugin, { + // by default we use Eleventy’s built-in `slugify` filter: + // slugify: eleventyConfig.getFilter("slugify"), + // default: + // selector: "h1,h2,h3,h4,h5,h6", }); + // Customize Markdown library settings: + // eleventyConfig.amendLibrary("md", mdLib => { + // mdLib.use(markdownItAnchor, { + // permalink: markdownItAnchor.permalink.ariaHidden({ + // placement: "after", + // class: "header-anchor", + // symbol: "#", + // ariaHidden: false, + // }), + // level: [1,2,3,4], + // slugify: eleventyConfig.getFilter("slugify") + // }); + // }); + eleventyConfig.addShortcode("currentBuildDate", () => { return (new Date()).toISOString(); }); diff --git a/package.json b/package.json index ec9f28f..d25756c 100644 --- a/package.json +++ b/package.json @@ -35,14 +35,13 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.16", + "@11ty/eleventy": "3.0.0-alpha.17", "@11ty/eleventy-img": "5.0.0-beta.5", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "2.0.0-beta.8", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "cross-env": "^7.0.3", "luxon": "^3.4.4", - "markdown-it-anchor": "^8.6.7", "zod": "^3.23.8", "zod-validation-error": "^3.3.0" } diff --git a/public/css/index.css b/public/css/index.css index f38dda1..c48c8e4 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -257,25 +257,25 @@ header { } /* Direct Links / Markdown Headers */ -.header-anchor { +.heading-anchor { text-decoration: none; font-style: normal; font-size: 1em; margin-left: .1em; } -a[href].header-anchor, -a[href].header-anchor:visited { +a[href].heading-anchor, +a[href].heading-anchor:visited { color: transparent; } -a[href].header-anchor:focus, -a[href].header-anchor:hover { +a[href].heading-anchor:focus, +a[href].heading-anchor:hover { text-decoration: underline; } -a[href].header-anchor:focus, -:hover > a[href].header-anchor { +a[href].heading-anchor:focus, +:hover > a[href].heading-anchor { color: #aaa; } -h2 + .header-anchor { +h2 + .heading-anchor { font-size: 1.5em; } diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js new file mode 100644 index 0000000..0c1b706 --- /dev/null +++ b/public/js/heading-anchors.js @@ -0,0 +1,37 @@ +// Thank you to https://github.com/daviddarnes/heading-anchors + +class HeadingAnchors extends HTMLElement { + static register(tagName) { + if ("customElements" in window) { + customElements.define(tagName || "heading-anchors", HeadingAnchors); + } + } + + connectedCallback() { + this.headings.forEach((heading) => { + if(!heading.querySelector("a.direct-link") || heading.hasAttribute("data-heading-anchors-optout")) { + heading.append(this.anchor(heading)); + } + }); + } + + anchor(heading) { + // TODO this would be good use case for shadow dom + let anchor = document.createElement("a"); + anchor.setAttribute("data-pagefind-ignore", ""); + anchor.href = `#${heading.id}`; + anchor.classList.add("heading-anchor"); + anchor.innerHTML = `Jump to heading`; + return anchor; + } + + get headings() { + return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`)); + } + + get selector() { + return this.getAttribute("selector") || "h1,h2,h3,h4" + } +} + +HeadingAnchors.register(); From eb0e826cd93441e9f5b736f9568e59c6773dd17f Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 16 Jul 2024 15:46:26 -0500 Subject: [PATCH 25/64] Spacing tweak for heading-anchor --- public/css/index.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/css/index.css b/public/css/index.css index c48c8e4..cd9d0bf 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -256,12 +256,12 @@ header { margin-right: 1em; } -/* Direct Links / Markdown Headers */ +/* Direct Links / Headings */ .heading-anchor { text-decoration: none; font-style: normal; font-size: 1em; - margin-left: .1em; + margin-left: .25em; } a[href].heading-anchor, a[href].heading-anchor:visited { From 90ebe99c52e002787c1bcf7a11652be203dba887 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 25 Jul 2024 16:06:34 -0500 Subject: [PATCH 26/64] Upgrade dep, housekeeping --- content/blog/blog.11tydata.js | 4 ++++ eleventy.config.js | 14 -------------- package.json | 2 +- 3 files changed, 5 insertions(+), 15 deletions(-) diff --git a/content/blog/blog.11tydata.js b/content/blog/blog.11tydata.js index ea58351..1a1e976 100644 --- a/content/blog/blog.11tydata.js +++ b/content/blog/blog.11tydata.js @@ -6,6 +6,8 @@ export default { "posts" ], "layout": "layouts/post.njk", + + // Draft blog posts, validate `draft` front matter eleventyDataSchema: function(data) { let result = z.object({ draft: z.boolean().or(z.undefined()), @@ -15,6 +17,8 @@ export default { throw fromZodError(result.error); } }, + + // Draft blog posts, exclude from builds and collections eleventyComputed: { permalink: (data) => { // Always skip during non-watch/serve builds diff --git a/eleventy.config.js b/eleventy.config.js index 753bba8..e56ad2d 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -89,20 +89,6 @@ export default async function(eleventyConfig) { // selector: "h1,h2,h3,h4,h5,h6", }); - // Customize Markdown library settings: - // eleventyConfig.amendLibrary("md", mdLib => { - // mdLib.use(markdownItAnchor, { - // permalink: markdownItAnchor.permalink.ariaHidden({ - // placement: "after", - // class: "header-anchor", - // symbol: "#", - // ariaHidden: false, - // }), - // level: [1,2,3,4], - // slugify: eleventyConfig.getFilter("slugify") - // }); - // }); - eleventyConfig.addShortcode("currentBuildDate", () => { return (new Date()).toISOString(); }); diff --git a/package.json b/package.json index d25756c..3752045 100644 --- a/package.json +++ b/package.json @@ -38,7 +38,7 @@ "@11ty/eleventy": "3.0.0-alpha.17", "@11ty/eleventy-img": "5.0.0-beta.5", "@11ty/eleventy-navigation": "^0.3.5", - "@11ty/eleventy-plugin-rss": "2.0.0-beta.8", + "@11ty/eleventy-plugin-rss": "^2.0.2", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "cross-env": "^7.0.3", "luxon": "^3.4.4", From fb94d9a0528388285ee4d458ad5a37279b4feda6 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 30 Jul 2024 16:47:49 -0500 Subject: [PATCH 27/64] Update deps --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 3752045..de08ca6 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.17", - "@11ty/eleventy-img": "5.0.0-beta.5", + "@11ty/eleventy": "3.0.0-alpha.18", + "@11ty/eleventy-img": "5.0.0-beta.9", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^2.0.2", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", From abcb5d723d0c24308ddaaeb203d842f5a3636a12 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 31 Jul 2024 15:42:28 -0500 Subject: [PATCH 28/64] Upgrade to 3.0 beta --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index de08ca6..5f7c21e 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.18", + "@11ty/eleventy": "^3.0.0-beta.1", "@11ty/eleventy-img": "5.0.0-beta.9", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^2.0.2", From c69813304412f07062c7ce4cc34bffd67640c4a1 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Sat, 3 Aug 2024 19:56:43 -0500 Subject: [PATCH 29/64] Update Node version! --- .nvmrc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.nvmrc b/.nvmrc index b6a7d89..209e3ef 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +20 From 5ca43c3568122451b47e0460469f0799c9cf46a0 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 8 Aug 2024 15:28:59 -0500 Subject: [PATCH 31/64] Allow heading to take focus from anchor link --- public/js/heading-anchors.js | 1 + 1 file changed, 1 insertion(+) diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index 0c1b706..ea9d6cd 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -11,6 +11,7 @@ class HeadingAnchors extends HTMLElement { this.headings.forEach((heading) => { if(!heading.querySelector("a.direct-link") || heading.hasAttribute("data-heading-anchors-optout")) { heading.append(this.anchor(heading)); + heading.setAttribute("tabindex", "-1"); } }); } From b5a00fd77607cce83952c0e9c0969e506c41a310 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 9 Aug 2024 15:48:14 -0500 Subject: [PATCH 32/64] Updates to heading-anchors for accessibility. --- content/blog/thirdpost.md | 2 +- public/css/index.css | 23 ------------- public/js/heading-anchors.js | 64 ++++++++++++++++++++++++++++++++---- 3 files changed, 58 insertions(+), 31 deletions(-) diff --git a/content/blog/thirdpost.md b/content/blog/thirdpost.md index bdea878..7241473 100644 --- a/content/blog/thirdpost.md +++ b/content/blog/thirdpost.md @@ -25,7 +25,7 @@ function myCommand() { console.log('Test'); ``` -### Unstyled +### Heading with a [link](#code) Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day, going forward, a new normal that has evolved from generation X is on the runway heading towards a streamlined cloud solution. User generated content in real-time will have multiple touchpoints for offshoring. diff --git a/public/css/index.css b/public/css/index.css index cd9d0bf..b75d493 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -256,26 +256,3 @@ header { margin-right: 1em; } -/* Direct Links / Headings */ -.heading-anchor { - text-decoration: none; - font-style: normal; - font-size: 1em; - margin-left: .25em; -} -a[href].heading-anchor, -a[href].heading-anchor:visited { - color: transparent; -} -a[href].heading-anchor:focus, -a[href].heading-anchor:hover { - text-decoration: underline; -} -a[href].heading-anchor:focus, -:hover > a[href].heading-anchor { - color: #aaa; -} - -h2 + .heading-anchor { - font-size: 1.5em; -} diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index ea9d6cd..03134af 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -1,4 +1,5 @@ // Thank you to https://github.com/daviddarnes/heading-anchors +// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/#what-are-anchor-links-exactly%3F class HeadingAnchors extends HTMLElement { static register(tagName) { @@ -7,22 +8,71 @@ class HeadingAnchors extends HTMLElement { } } + static defaultSelector = "h2,h3,h4"; + + static featureTest() { + return "replaceSync" in CSSStyleSheet.prototype; + } + + static css = ` +.heading-anchor { + text-decoration: none; +} +/* For headings that already have links */ +:is(h1, h2, h3, h4, h5, h6):has(a[href]:not(.heading-anchor)):is(:hover, :focus-within) .heading-anchor:after { + content: "#"; + content: "#" / ""; +} +.heading-anchor:focus:after, +.heading-anchor:hover:after { + content: "#"; + content: "#" / ""; +} +.heading-anchor:after { + margin-left: .25em; + color: #aaa; +}`; + + constructor() { + if (!HeadingAnchors.featureTest()) { + return; + } + + super(); + + let sheet = new CSSStyleSheet(); + sheet.replaceSync(HeadingAnchors.css); + document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]; + } + connectedCallback() { + if (!HeadingAnchors.featureTest()) { + return; + } + this.headings.forEach((heading) => { - if(!heading.querySelector("a.direct-link") || heading.hasAttribute("data-heading-anchors-optout")) { - heading.append(this.anchor(heading)); - heading.setAttribute("tabindex", "-1"); + if(!heading.hasAttribute("data-heading-anchors-optout")) { + let anchor = this.getAnchorElement(heading); + if(heading.querySelector(":scope a[href]")) { + // Fallback if the heading already has a link + anchor.setAttribute("aria-label", `Jump to section: ${heading.textContent}`); + heading.appendChild(anchor); + } else { + // entire heading is a link + for(let child of heading.childNodes) { + anchor.appendChild(child); + } + heading.appendChild(anchor); + } } }); } - anchor(heading) { - // TODO this would be good use case for shadow dom + getAnchorElement(heading) { let anchor = document.createElement("a"); anchor.setAttribute("data-pagefind-ignore", ""); anchor.href = `#${heading.id}`; anchor.classList.add("heading-anchor"); - anchor.innerHTML = `Jump to heading`; return anchor; } @@ -31,7 +81,7 @@ class HeadingAnchors extends HTMLElement { } get selector() { - return this.getAttribute("selector") || "h1,h2,h3,h4" + return this.getAttribute("selector") || HeadingAnchors.defaultSelector; } } From c87bda3621ddb2772097793fc159df3d288215ef Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 9 Aug 2024 16:38:07 -0500 Subject: [PATCH 33/64] Fix issue with anchor links reflowing --- eleventy.config.js | 3 +-- public/js/heading-anchors.js | 10 +++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index e56ad2d..350ac9a 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -85,8 +85,7 @@ export default async function(eleventyConfig) { eleventyConfig.addPlugin(IdAttributePlugin, { // by default we use Eleventy’s built-in `slugify` filter: // slugify: eleventyConfig.getFilter("slugify"), - // default: - // selector: "h1,h2,h3,h4,h5,h6", + // selector: "h1,h2,h3,h4,h5,h6", // default }); eleventyConfig.addShortcode("currentBuildDate", () => { diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index 03134af..67debf6 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -20,17 +20,18 @@ class HeadingAnchors extends HTMLElement { } /* For headings that already have links */ :is(h1, h2, h3, h4, h5, h6):has(a[href]:not(.heading-anchor)):is(:hover, :focus-within) .heading-anchor:after { - content: "#"; - content: "#" / ""; + opacity: 1; } .heading-anchor:focus:after, .heading-anchor:hover:after { - content: "#"; - content: "#" / ""; + opacity: 1; } .heading-anchor:after { + content: "#"; + content: "#" / ""; margin-left: .25em; color: #aaa; + opacity: 0; }`; constructor() { @@ -70,7 +71,6 @@ class HeadingAnchors extends HTMLElement { getAnchorElement(heading) { let anchor = document.createElement("a"); - anchor.setAttribute("data-pagefind-ignore", ""); anchor.href = `#${heading.id}`; anchor.classList.add("heading-anchor"); return anchor; From cdd2fd7a424342ba1804a0ce984c70a1a9f652e9 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Mon, 26 Aug 2024 14:53:52 -0500 Subject: [PATCH 34/64] Upgrade accessibility of heading-anchors component to prefer sibling links (if anchor position available) --- public/css/index.css | 4 ++ public/js/heading-anchors.js | 106 ++++++++++++++++++++++++----------- 2 files changed, 78 insertions(+), 32 deletions(-) diff --git a/public/css/index.css b/public/css/index.css index b75d493..00f39b5 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -256,3 +256,7 @@ header { margin-right: 1em; } +/* Anchor links color */ +a[href]:is(:link, :visited).heading-a { + color: #aaa; +} diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index 67debf6..e630072 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -1,5 +1,5 @@ // Thank you to https://github.com/daviddarnes/heading-anchors -// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/#what-are-anchor-links-exactly%3F +// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ class HeadingAnchors extends HTMLElement { static register(tagName) { @@ -8,61 +8,97 @@ class HeadingAnchors extends HTMLElement { } } + static attributes = { + exclude: "data-heading-anchors-exclude" + }; + + static classes = { + anchor: "heading-a", + heading: "heading-a-h", // only used for nested method + } + static defaultSelector = "h2,h3,h4"; static featureTest() { - return "replaceSync" in CSSStyleSheet.prototype; + return ; } static css = ` -.heading-anchor { +.${HeadingAnchors.classes.anchor} { text-decoration: none; -} -/* For headings that already have links */ -:is(h1, h2, h3, h4, h5, h6):has(a[href]:not(.heading-anchor)):is(:hover, :focus-within) .heading-anchor:after { - opacity: 1; -} -.heading-anchor:focus:after, -.heading-anchor:hover:after { - opacity: 1; -} -.heading-anchor:after { - content: "#"; - content: "#" / ""; - margin-left: .25em; - color: #aaa; + font-weight: 400; opacity: 0; + transition: opacity .15s; + padding-left: .25em; + padding-right: .25em; +} +/* nested */ +:is(h1,h2,h3,h4,h5,h6):is(:focus, :hover) .${HeadingAnchors.classes.anchor}, +/* sibling */ +:is(h1,h2,h3,h4,h5,h6) + .${HeadingAnchors.classes.anchor}:is(:focus, :hover), +:is(h1,h2,h3,h4,h5,h6):is(:focus,:hover) + .${HeadingAnchors.classes.anchor} { + opacity: 1; +} +@supports not (anchor-name: none) { + .${HeadingAnchors.classes.heading} { + position: relative; + } + .${HeadingAnchors.classes.anchor} { + position: absolute; + left: 0; + transform: translateX(-100%); + } +} +@supports (anchor-name: none) { + .${HeadingAnchors.classes.anchor} { + position: absolute; + right: anchor(left); + top: anchor(top); + } }`; + get supportsTest() { + return "replaceSync" in CSSStyleSheet.prototype; + } + + get supportsAnchorPosition() { + return CSS.supports("anchor-name: none"); + } + constructor() { - if (!HeadingAnchors.featureTest()) { + super(); + + if(!this.supportsTest) { return; } - super(); - let sheet = new CSSStyleSheet(); sheet.replaceSync(HeadingAnchors.css); document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]; } connectedCallback() { - if (!HeadingAnchors.featureTest()) { + if (!this.supportsTest) { return; } - this.headings.forEach((heading) => { - if(!heading.hasAttribute("data-heading-anchors-optout")) { + this.headings.forEach((heading, index) => { + if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) { let anchor = this.getAnchorElement(heading); - if(heading.querySelector(":scope a[href]")) { - // Fallback if the heading already has a link - anchor.setAttribute("aria-label", `Jump to section: ${heading.textContent}`); - heading.appendChild(anchor); + + // Prefers anchor position approach for better accessibility + // https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ + if(this.supportsAnchorPosition) { + let anchorName = `--h-a_${index}`; + heading.style.anchorName = anchorName; + anchor.style.positionAnchor = anchorName; + + let fontSize = parseInt(getComputedStyle(heading).getPropertyValue("font-size"), 10); + anchor.style.fontSize = `${(fontSize / 16).toFixed(3)}em`; + + heading.after(anchor); } else { - // entire heading is a link - for(let child of heading.childNodes) { - anchor.appendChild(child); - } + heading.classList.add(HeadingAnchors.classes.heading); heading.appendChild(anchor); } } @@ -72,7 +108,13 @@ class HeadingAnchors extends HTMLElement { getAnchorElement(heading) { let anchor = document.createElement("a"); anchor.href = `#${heading.id}`; - anchor.classList.add("heading-anchor"); + anchor.classList.add(HeadingAnchors.classes.anchor); + if(this.supportsAnchorPosition) { + anchor.innerHTML = `Jump to section titled: ${heading.textContent}`; + } else { + anchor.innerHTML = ``; + } + return anchor; } From 6f64905ca6f428521b1e6607f43140d8f41efaf6 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Mon, 26 Aug 2024 15:06:38 -0500 Subject: [PATCH 35/64] Swap to focus-within for focus styles in FF --- public/js/heading-anchors.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index e630072..f0bdccd 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -33,10 +33,10 @@ class HeadingAnchors extends HTMLElement { padding-right: .25em; } /* nested */ -:is(h1,h2,h3,h4,h5,h6):is(:focus, :hover) .${HeadingAnchors.classes.anchor}, +:is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) .${HeadingAnchors.classes.anchor}, /* sibling */ -:is(h1,h2,h3,h4,h5,h6) + .${HeadingAnchors.classes.anchor}:is(:focus, :hover), -:is(h1,h2,h3,h4,h5,h6):is(:focus,:hover) + .${HeadingAnchors.classes.anchor} { +:is(h1,h2,h3,h4,h5,h6) + .${HeadingAnchors.classes.anchor}:is(:focus-within, :hover), +:is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) + .${HeadingAnchors.classes.anchor} { opacity: 1; } @supports not (anchor-name: none) { From f7d1e3d2eeb8dd4b81bdba231a6a96663c976633 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Mon, 26 Aug 2024 16:44:53 -0500 Subject: [PATCH 36/64] A few minor cleanup tweaks to heading-anchors --- public/js/heading-anchors.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index f0bdccd..5eff13f 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -10,7 +10,7 @@ class HeadingAnchors extends HTMLElement { static attributes = { exclude: "data-heading-anchors-exclude" - }; + } static classes = { anchor: "heading-a", @@ -25,6 +25,7 @@ class HeadingAnchors extends HTMLElement { static css = ` .${HeadingAnchors.classes.anchor} { + position: absolute; text-decoration: none; font-weight: 400; opacity: 0; @@ -44,14 +45,12 @@ class HeadingAnchors extends HTMLElement { position: relative; } .${HeadingAnchors.classes.anchor} { - position: absolute; left: 0; transform: translateX(-100%); } } @supports (anchor-name: none) { .${HeadingAnchors.classes.anchor} { - position: absolute; right: anchor(left); top: anchor(top); } @@ -89,12 +88,12 @@ class HeadingAnchors extends HTMLElement { // Prefers anchor position approach for better accessibility // https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ if(this.supportsAnchorPosition) { - let anchorName = `--h-a_${index}`; + let anchorName = `--ha_${index}`; heading.style.anchorName = anchorName; anchor.style.positionAnchor = anchorName; let fontSize = parseInt(getComputedStyle(heading).getPropertyValue("font-size"), 10); - anchor.style.fontSize = `${(fontSize / 16).toFixed(3)}em`; + anchor.style.fontSize = `${fontSize / 16}em`; heading.after(anchor); } else { From dc5ab2ef6372de744be5484ada4958a4342073ea Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Mon, 26 Aug 2024 16:56:02 -0500 Subject: [PATCH 37/64] Move to position anchor after the heading to simplify base use case (no relative positioning at all) --- public/js/heading-anchors.js | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index 5eff13f..834ccfa 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -17,7 +17,7 @@ class HeadingAnchors extends HTMLElement { heading: "heading-a-h", // only used for nested method } - static defaultSelector = "h2,h3,h4"; + static defaultSelector = "h2,h3,h4,h5,h6"; static featureTest() { return ; @@ -33,6 +33,7 @@ class HeadingAnchors extends HTMLElement { padding-left: .25em; padding-right: .25em; } + /* nested */ :is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) .${HeadingAnchors.classes.anchor}, /* sibling */ @@ -40,18 +41,14 @@ class HeadingAnchors extends HTMLElement { :is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) + .${HeadingAnchors.classes.anchor} { opacity: 1; } -@supports not (anchor-name: none) { - .${HeadingAnchors.classes.heading} { - position: relative; - } - .${HeadingAnchors.classes.anchor} { - left: 0; - transform: translateX(-100%); - } -} @supports (anchor-name: none) { + /* purely for anchoring */ + .${HeadingAnchors.classes.heading}:after { + content: ""; + anchor-name: var(--ha_anchor); + } .${HeadingAnchors.classes.anchor} { - right: anchor(left); + left: anchor(right); top: anchor(top); } }`; @@ -89,15 +86,15 @@ class HeadingAnchors extends HTMLElement { // https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ if(this.supportsAnchorPosition) { let anchorName = `--ha_${index}`; - heading.style.anchorName = anchorName; + heading.style.setProperty("--ha_anchor", anchorName); anchor.style.positionAnchor = anchorName; let fontSize = parseInt(getComputedStyle(heading).getPropertyValue("font-size"), 10); anchor.style.fontSize = `${fontSize / 16}em`; + heading.classList.add(HeadingAnchors.classes.heading); heading.after(anchor); } else { - heading.classList.add(HeadingAnchors.classes.heading); heading.appendChild(anchor); } } From 2b40c3c7a43d3d211d534e9e238b2bbf059e93ee Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Mon, 26 Aug 2024 17:23:06 -0500 Subject: [PATCH 38/64] Copy tweaks --- _includes/layouts/home.njk | 4 ++-- content/blog/fourthpost/fourthpost.md | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/_includes/layouts/home.njk b/_includes/layouts/home.njk index cfb97f6..6e75d04 100644 --- a/_includes/layouts/home.njk +++ b/_includes/layouts/home.njk @@ -1,11 +1,11 @@ --- layout: layouts/base.njk --- - + {%- css %}{% include "public/css/message-box.css" %}{% endcss %}
    -
  1. Edit the _data/metadata.js with your blog’s information.
  2. +
  3. Edit _data/metadata.js with your blog’s information.
  4. (Optional) Edit eleventy.config.js with your configuration preferences.
  5. Delete this message from _includes/layouts/home.njk.
diff --git a/content/blog/fourthpost/fourthpost.md b/content/blog/fourthpost/fourthpost.md index 8307e7b..776583a 100644 --- a/content/blog/fourthpost/fourthpost.md +++ b/content/blog/fourthpost/fourthpost.md @@ -1,5 +1,5 @@ --- -title: This is my fourth post! +title: This is my fourth post description: This is a post on My Blog about touchpoints and circling wagons. date: 2018-09-30 tags: second tag From 2df6143099c2457138e3e5b5dc9b30428fb3e14a Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Mon, 26 Aug 2024 17:33:39 -0500 Subject: [PATCH 39/64] Tweak to class names, allow override text content --- public/css/index.css | 2 +- public/js/heading-anchors.js | 17 ++++++++++++----- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/public/css/index.css b/public/css/index.css index 00f39b5..34799a2 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -257,6 +257,6 @@ header { } /* Anchor links color */ -a[href]:is(:link, :visited).heading-a { +a[href]:is(:link, :visited).ha { color: #aaa; } diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js index 834ccfa..0b3b6d5 100644 --- a/public/js/heading-anchors.js +++ b/public/js/heading-anchors.js @@ -9,12 +9,13 @@ class HeadingAnchors extends HTMLElement { } static attributes = { - exclude: "data-heading-anchors-exclude" + exclude: "data-ha-exclude", + content: "data-ha-text" } static classes = { - anchor: "heading-a", - heading: "heading-a-h", // only used for nested method + anchor: "ha", + heading: "ha-h", // only used for nested method } static defaultSelector = "h2,h3,h4,h5,h6"; @@ -101,14 +102,20 @@ class HeadingAnchors extends HTMLElement { }); } + getText(heading) { + return heading.getAttribute(HeadingAnchors.attributes.content) || "#"; + } + getAnchorElement(heading) { let anchor = document.createElement("a"); anchor.href = `#${heading.id}`; anchor.classList.add(HeadingAnchors.classes.anchor); + + let text = this.getText(heading); if(this.supportsAnchorPosition) { - anchor.innerHTML = `Jump to section titled: ${heading.textContent}`; + anchor.innerHTML = `Jump to section titled: ${heading.textContent}`; } else { - anchor.innerHTML = ``; + anchor.innerHTML = ``; } return anchor; From d791163e123ee1f632859fd3bce9a56eee3cd8b5 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 29 Aug 2024 15:28:33 -0500 Subject: [PATCH 40/64] Swap to use zachleat/heading-anchors for heading anchor links. --- _includes/layouts/base.njk | 2 +- content/blog/thirdpost.md | 2 +- package.json | 3 + public/css/index.css | 4 -- public/js/heading-anchors.js | 133 ----------------------------------- 5 files changed, 5 insertions(+), 139 deletions(-) delete mode 100644 public/js/heading-anchors.js diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 8b7eea6..6e6eddd 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -33,7 +33,7 @@ {#- Renders the CSS bundle using a separate file, if you can't set CSP directive style-src: 'unsafe-inline' #} {#- #} - {%- js %}{% include "public/js/heading-anchors.js" %}{% endjs %} + {%- js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %} Skip to main content diff --git a/content/blog/thirdpost.md b/content/blog/thirdpost.md index 7241473..e333b46 100644 --- a/content/blog/thirdpost.md +++ b/content/blog/thirdpost.md @@ -10,7 +10,7 @@ Leverage agile frameworks to provide a robust synopsis for high level overviews. ## Code -### Styled (with Syntax) +### This is a very long heading that I want to wrap This is a very long heading that I want to wrap This is a very long heading that I want to wrap This is a very long heading that I want to wrap Bring to the table win-win survival strategies to ensure proactive domination. At the end of the day, going forward, a new normal that has evolved from generation X is on the runway heading towards a streamlined cloud solution. User generated content in real-time will have multiple touchpoints for offshoring. diff --git a/package.json b/package.json index 5f7c21e..0881e8a 100644 --- a/package.json +++ b/package.json @@ -44,5 +44,8 @@ "luxon": "^3.4.4", "zod": "^3.23.8", "zod-validation-error": "^3.3.0" + }, + "dependencies": { + "@zachleat/heading-anchors": "^1.0.0" } } diff --git a/public/css/index.css b/public/css/index.css index 34799a2..b75d493 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -256,7 +256,3 @@ header { margin-right: 1em; } -/* Anchor links color */ -a[href]:is(:link, :visited).ha { - color: #aaa; -} diff --git a/public/js/heading-anchors.js b/public/js/heading-anchors.js deleted file mode 100644 index 0b3b6d5..0000000 --- a/public/js/heading-anchors.js +++ /dev/null @@ -1,133 +0,0 @@ -// Thank you to https://github.com/daviddarnes/heading-anchors -// Thank you to https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ - -class HeadingAnchors extends HTMLElement { - static register(tagName) { - if ("customElements" in window) { - customElements.define(tagName || "heading-anchors", HeadingAnchors); - } - } - - static attributes = { - exclude: "data-ha-exclude", - content: "data-ha-text" - } - - static classes = { - anchor: "ha", - heading: "ha-h", // only used for nested method - } - - static defaultSelector = "h2,h3,h4,h5,h6"; - - static featureTest() { - return ; - } - - static css = ` -.${HeadingAnchors.classes.anchor} { - position: absolute; - text-decoration: none; - font-weight: 400; - opacity: 0; - transition: opacity .15s; - padding-left: .25em; - padding-right: .25em; -} - -/* nested */ -:is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) .${HeadingAnchors.classes.anchor}, -/* sibling */ -:is(h1,h2,h3,h4,h5,h6) + .${HeadingAnchors.classes.anchor}:is(:focus-within, :hover), -:is(h1,h2,h3,h4,h5,h6):is(:focus-within, :hover) + .${HeadingAnchors.classes.anchor} { - opacity: 1; -} -@supports (anchor-name: none) { - /* purely for anchoring */ - .${HeadingAnchors.classes.heading}:after { - content: ""; - anchor-name: var(--ha_anchor); - } - .${HeadingAnchors.classes.anchor} { - left: anchor(right); - top: anchor(top); - } -}`; - - get supportsTest() { - return "replaceSync" in CSSStyleSheet.prototype; - } - - get supportsAnchorPosition() { - return CSS.supports("anchor-name: none"); - } - - constructor() { - super(); - - if(!this.supportsTest) { - return; - } - - let sheet = new CSSStyleSheet(); - sheet.replaceSync(HeadingAnchors.css); - document.adoptedStyleSheets = [...document.adoptedStyleSheets, sheet]; - } - - connectedCallback() { - if (!this.supportsTest) { - return; - } - - this.headings.forEach((heading, index) => { - if(!heading.hasAttribute(HeadingAnchors.attributes.exclude)) { - let anchor = this.getAnchorElement(heading); - - // Prefers anchor position approach for better accessibility - // https://amberwilson.co.uk/blog/are-your-anchor-links-accessible/ - if(this.supportsAnchorPosition) { - let anchorName = `--ha_${index}`; - heading.style.setProperty("--ha_anchor", anchorName); - anchor.style.positionAnchor = anchorName; - - let fontSize = parseInt(getComputedStyle(heading).getPropertyValue("font-size"), 10); - anchor.style.fontSize = `${fontSize / 16}em`; - - heading.classList.add(HeadingAnchors.classes.heading); - heading.after(anchor); - } else { - heading.appendChild(anchor); - } - } - }); - } - - getText(heading) { - return heading.getAttribute(HeadingAnchors.attributes.content) || "#"; - } - - getAnchorElement(heading) { - let anchor = document.createElement("a"); - anchor.href = `#${heading.id}`; - anchor.classList.add(HeadingAnchors.classes.anchor); - - let text = this.getText(heading); - if(this.supportsAnchorPosition) { - anchor.innerHTML = `Jump to section titled: ${heading.textContent}`; - } else { - anchor.innerHTML = ``; - } - - return anchor; - } - - get headings() { - return this.querySelectorAll(this.selector.split(",").map(entry => `${entry.trim()}[id]`)); - } - - get selector() { - return this.getAttribute("selector") || HeadingAnchors.defaultSelector; - } -} - -HeadingAnchors.register(); From ff7ca75a786e71166dac9ec08506df019f2f72ea Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 30 Aug 2024 10:33:12 -0500 Subject: [PATCH 41/64] Update dep --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0881e8a..f4d5b13 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,6 @@ "zod-validation-error": "^3.3.0" }, "dependencies": { - "@zachleat/heading-anchors": "^1.0.0" + "@zachleat/heading-anchors": "^1.0.1" } } From ca8c6893ccdd04f4728be12c9f8640ebf9c5ae41 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 5 Sep 2024 11:25:06 -0500 Subject: [PATCH 42/64] Upgrade dependencies --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index f4d5b13..337e197 100644 --- a/package.json +++ b/package.json @@ -35,15 +35,15 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "^3.0.0-beta.1", + "@11ty/eleventy": "3.0.0-alpha.19", "@11ty/eleventy-img": "5.0.0-beta.9", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^2.0.2", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", "cross-env": "^7.0.3", - "luxon": "^3.4.4", + "luxon": "^3.5.0", "zod": "^3.23.8", - "zod-validation-error": "^3.3.0" + "zod-validation-error": "^3.3.1" }, "dependencies": { "@zachleat/heading-anchors": "^1.0.1" From e23efa3569aa0ad1bf01bf6818c39e19e4ee49ef Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 5 Sep 2024 16:07:41 -0500 Subject: [PATCH 43/64] Adds barebones View Transition API --- public/css/index.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/public/css/index.css b/public/css/index.css index b75d493..1cfa083 100644 --- a/public/css/index.css +++ b/public/css/index.css @@ -41,6 +41,10 @@ box-sizing: border-box; } +@view-transition { + navigation: auto; +} + html, body { padding: 0; From ffa7c673cd4b9fb999596e97dc8b5b11073fa594 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 5 Sep 2024 16:10:34 -0500 Subject: [PATCH 44/64] Change the sample CSS string --- _includes/layouts/base.njk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 6e6eddd..00c55c6 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -22,7 +22,7 @@ #} {#- Add an arbitrary string to the bundle #} - {%- css %}* { box-sizing: border-box; }{% endcss %} + {%- css %}/* This is an arbitrary CSS string added to the bundle */{% endcss %} {#- Add the contents of a file to the bundle #} {%- css %}{% include "public/css/index.css" %}{% endcss %} {#- Or add from node_modules #} From 5eca0a303525922b8a5a46b595d106218fd306ae Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 11 Sep 2024 16:14:43 -0500 Subject: [PATCH 45/64] Upgrade deps, tweaks to bundle comments --- _includes/layouts/base.njk | 18 +++++++++++------- _includes/layouts/post.njk | 2 +- eleventy.config.js | 11 +++++++---- package.json | 2 +- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 00c55c6..537f398 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -14,25 +14,29 @@ {#- #} {#- - CSS bundles are provided via the `eleventy-plugin-bundle` plugin: - 1. You can add to them using `{% css %}` - 2. You can get from them using `{% getBundle "css" %}` or `{% getBundleFileUrl "css" %}` - 3. You can do the same for JS: {% js %}{% endjs %} and - 4. Learn more: https://github.com/11ty/eleventy-plugin-bundle + Plain-text bundles are provided via the `eleventy-plugin-bundle` plugin: + 1. CSS: + * Add to a per-page bundle using `{% css %}{% endcss %}` + * Retrieve bundle content using `{% getBundle "css" %}` or `{% getBundleFileUrl "css" %}` + 2. Or for JavaScript: + * Add to a per-page bundle using `{% js %}{% endjs %}` + * Retrieve via `{% getBundle "js" %}` or `{% getBundleFileUrl "js" %}` + 3. Learn more: https://github.com/11ty/eleventy-plugin-bundle #} {#- Add an arbitrary string to the bundle #} {%- css %}/* This is an arbitrary CSS string added to the bundle */{% endcss %} {#- Add the contents of a file to the bundle #} {%- css %}{% include "public/css/index.css" %}{% endcss %} - {#- Or add from node_modules #} + {#- Or you can add from node_modules #} {# {%- css %}{% include "node_modules/prismjs/themes/prism-okaidia.css" %}{% endcss %} #} - {#- Render the CSS bundle using Inlined CSS (for the fastest site performance in production) #} + {#- Render the CSS bundle using inlined CSS (for the fastest site performance in production) #} {#- Renders the CSS bundle using a separate file, if you can't set CSP directive style-src: 'unsafe-inline' #} {#- #} + {#- Add the heading-anchors web component to the JavaScript bundle #} {%- js %}{% include "node_modules/@zachleat/heading-anchors/heading-anchors.js" %}{% endjs %} diff --git a/_includes/layouts/post.njk b/_includes/layouts/post.njk index 78166f3..d1827cf 100644 --- a/_includes/layouts/post.njk +++ b/_includes/layouts/post.njk @@ -1,7 +1,7 @@ --- layout: layouts/base.njk --- -{# Only include the syntax highlighter CSS on blog posts #} +{# Only include the syntax highlighter CSS on blog posts, included with the CSS per-page bundle #} {%- css %}{% include "node_modules/prismjs/themes/prism-okaidia.css" %}{% endcss %} {%- css %}{% include "public/css/prism-diff.css" %}{%- endcss %}

{{ title }}

diff --git a/eleventy.config.js b/eleventy.config.js index 350ac9a..c73e75e 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -12,8 +12,7 @@ export default async function(eleventyConfig) { // For example, `./public/css/` ends up in `_site/css/` eleventyConfig .addPassthroughCopy({ - "./public/": "/", - "./node_modules/prismjs/themes/prism-okaidia.css": "/css/prism-okaidia.css" + "./public/": "/" }) .addPassthroughCopy("./content/feed/pretty-atom-feed.xsl"); @@ -25,9 +24,13 @@ export default async function(eleventyConfig) { // Per-page bundles, see https://github.com/11ty/eleventy-plugin-bundle // Adds the {% css %} paired shortcode - eleventyConfig.addBundle("css"); + eleventyConfig.addBundle("css", { + toFileDirectory: "dist", + }); // Adds the {% js %} paired shortcode - eleventyConfig.addBundle("js"); + eleventyConfig.addBundle("js", { + toFileDirectory: "dist", + }); // Official plugins eleventyConfig.addPlugin(pluginSyntaxHighlight, { diff --git a/package.json b/package.json index 337e197..ba2f26d 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.19", + "@11ty/eleventy": "3.0.0-alpha.20", "@11ty/eleventy-img": "5.0.0-beta.9", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^2.0.2", From 4fad5c688899f555b58207ce77e448fa3b06ed13 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 11 Sep 2024 16:15:15 -0500 Subject: [PATCH 46/64] Remove Netlify plugins --- netlify.toml | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/netlify.toml b/netlify.toml index 5a8db0f..1bc23a7 100644 --- a/netlify.toml +++ b/netlify.toml @@ -1,24 +1,3 @@ [build] publish = "_site" command = "npm run build" - -[[plugins]] - - # Opt-in to the Netlify Lighthouse plugin (choose one): - - # 1. Go to your site on https://app.netlify.com and navigate to the Integrations tab, search for the `Lighthouse` plugin - # 2. Or via `npm install -D @netlify/plugin-lighthouse` - - # Read more: https://github.com/netlify/netlify-plugin-lighthouse - - package = "@netlify/plugin-lighthouse" - - # optional, fails build when a category is below a threshold - [plugins.inputs.thresholds] - performance = 1.0 - accessibility = 1.0 - best-practices = 1.0 - seo = 1.0 - - [plugins.inputs] - output_path = "reports/lighthouse/index.html" From 1ad494cfd2cbd80c4315c5698cfe91f136c91790 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 11 Sep 2024 16:34:56 -0500 Subject: [PATCH 47/64] Mitigate #171 by using `js` front matter type instead of YAML. --- content/about/index.md | 9 +++++---- content/blog.njk | 9 +++++---- content/blog/firstpost.md | 3 +-- content/blog/secondpost.md | 3 +-- content/blog/thirdpost.md | 4 +--- content/index.njk | 12 +++++++----- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/content/about/index.md b/content/about/index.md index 8c673a8..fba58a9 100644 --- a/content/about/index.md +++ b/content/about/index.md @@ -1,7 +1,8 @@ ---- -eleventyNavigation: - key: About - order: 3 +---js +const eleventyNavigation = { + key: "About", + order: 3 +}; --- # About diff --git a/content/blog.njk b/content/blog.njk index 1f7d876..c11fdf8 100644 --- a/content/blog.njk +++ b/content/blog.njk @@ -1,7 +1,8 @@ ---- -eleventyNavigation: - key: Archive - order: 2 +---js +const eleventyNavigation = { + key: "Archive", + order: 2 +}; ---

Archive

diff --git a/content/blog/firstpost.md b/content/blog/firstpost.md index 0557716..97db357 100644 --- a/content/blog/firstpost.md +++ b/content/blog/firstpost.md @@ -2,8 +2,7 @@ title: This is my first post. description: This is a post on My Blog about agile frameworks. date: 2018-05-01 -tags: - - another tag +tags: another tag --- Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive innovation via workplace diversity and empowerment. diff --git a/content/blog/secondpost.md b/content/blog/secondpost.md index 008fdc8..b308bff 100644 --- a/content/blog/secondpost.md +++ b/content/blog/secondpost.md @@ -2,8 +2,7 @@ title: This is my second post with a much longer title. description: This is a post on My Blog about leveraging agile frameworks. date: 2018-07-04 -tags: - - number 2 +tags: number 2 --- Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive innovation via workplace diversity and empowerment. diff --git a/content/blog/thirdpost.md b/content/blog/thirdpost.md index e333b46..7a95dd6 100644 --- a/content/blog/thirdpost.md +++ b/content/blog/thirdpost.md @@ -2,9 +2,7 @@ title: This is my third post. description: This is a post on My Blog about win-win survival strategies. date: 2018-08-24 -tags: - - second tag - - posts with two tags +tags: ["second tag", "posts with two tags"] --- Leverage agile frameworks to provide a robust synopsis for high level overviews. Iterative approaches to corporate strategy foster collaborative thinking to further the overall value proposition. Organically grow the holistic world view of disruptive innovation via workplace diversity and empowerment. diff --git a/content/index.njk b/content/index.njk index 260b20c..f7d17e1 100644 --- a/content/index.njk +++ b/content/index.njk @@ -1,8 +1,10 @@ ---- -eleventyNavigation: - key: Home - order: 1 -numberOfLatestPostsToShow: 3 +---js +const eleventyNavigation = { + key: "Home", + order: 1 +}; + +const numberOfLatestPostsToShow = 3; --- {% set postsCount = collections.posts | length %} {% set latestPostsCount = postsCount | min(numberOfLatestPostsToShow) %} From 31235827fc0ca93b4bb0372e3808d3ee218ce40b Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 24 Sep 2024 12:18:16 -0500 Subject: [PATCH 48/64] Drastically simplify the drafts workflow --- _data/eleventyDataSchema.js | 13 +++++++++++++ content/blog/blog.11tydata.js | 34 ---------------------------------- eleventy.config.js | 7 +++++++ 3 files changed, 20 insertions(+), 34 deletions(-) create mode 100644 _data/eleventyDataSchema.js diff --git a/_data/eleventyDataSchema.js b/_data/eleventyDataSchema.js new file mode 100644 index 0000000..ca764ec --- /dev/null +++ b/_data/eleventyDataSchema.js @@ -0,0 +1,13 @@ +import { z } from "zod"; +import { fromZodError } from 'zod-validation-error'; + +export default function(data) { + // Draft content, validate `draft` front matter + let result = z.object({ + draft: z.boolean().or(z.undefined()), + }).safeParse(data); + + if(result.error) { + throw fromZodError(result.error); + } +} diff --git a/content/blog/blog.11tydata.js b/content/blog/blog.11tydata.js index 1a1e976..614f505 100644 --- a/content/blog/blog.11tydata.js +++ b/content/blog/blog.11tydata.js @@ -1,40 +1,6 @@ -import { z } from "zod"; -import { fromZodError } from 'zod-validation-error'; - export default { tags: [ "posts" ], "layout": "layouts/post.njk", - - // Draft blog posts, validate `draft` front matter - eleventyDataSchema: function(data) { - let result = z.object({ - draft: z.boolean().or(z.undefined()), - }).safeParse(data); - - if(result.error) { - throw fromZodError(result.error); - } - }, - - // Draft blog posts, exclude from builds and collections - eleventyComputed: { - permalink: (data) => { - // Always skip during non-watch/serve builds - if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") { - return false; - } - - return data.permalink; - }, - eleventyExcludeFromCollections: (data) => { - // Always exclude from non-watch/serve builds - if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") { - return true; - } - - return data.eleventyExcludeFromCollections; - } - } }; diff --git a/eleventy.config.js b/eleventy.config.js index c73e75e..668f6ee 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -8,6 +8,13 @@ import pluginFilters from "./_config/filters.js"; /** @param {import("@11ty/eleventy").UserConfig} eleventyConfig */ export default async function(eleventyConfig) { + // Drafts, see also _data/eleventyDataSchema.js + eleventyConfig.addPreprocessor("drafts", "*", (data, content) => { + if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") { + return false; + } + }); + // Copy the contents of the `public` folder to the output folder // For example, `./public/css/` ends up in `_site/css/` eleventyConfig From 18b3f4927b441f7e8e4163f6180c76078f196fbc Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:16:59 -0500 Subject: [PATCH 49/64] Try out no trailing slash urls --- eleventy.config.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eleventy.config.js b/eleventy.config.js index 668f6ee..efb85cd 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -15,6 +15,16 @@ export default async function(eleventyConfig) { } }); + eleventyConfig.addUrlTransform((page) => { + if (page.url.endsWith(".html")) { + return page.url.slice(0, -1 * ".html".length); + } + }); + eleventyConfig.addGlobalData("permalink", () => { + return (data) => + `${data.page.filePathStem}.${data.page.outputFileExtension}`; + }); + // Copy the contents of the `public` folder to the output folder // For example, `./public/css/` ends up in `_site/css/` eleventyConfig From fd37a6ffac14d3091d8b03a190b5ba9e2ffb08b4 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:18:39 -0500 Subject: [PATCH 50/64] Use trailingslash: false --- vercel.json | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 vercel.json diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..e85d6c0 --- /dev/null +++ b/vercel.json @@ -0,0 +1,3 @@ +{ + "trailingSlash": false +} From 107e6ca8d0b0291703aef8a81bb4fb0b9d1a9eed Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:19:55 -0500 Subject: [PATCH 51/64] One more test --- vercel.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vercel.json b/vercel.json index e85d6c0..1e9c7bc 100644 --- a/vercel.json +++ b/vercel.json @@ -1,3 +1,3 @@ { - "trailingSlash": false + "trailingSlash": true } From 7d0680976672915d43249275e6bf4b2679f62033 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:21:14 -0500 Subject: [PATCH 52/64] Revert trailing slash tests --- eleventy.config.js | 10 ---------- vercel.json | 3 --- 2 files changed, 13 deletions(-) delete mode 100644 vercel.json diff --git a/eleventy.config.js b/eleventy.config.js index efb85cd..668f6ee 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -15,16 +15,6 @@ export default async function(eleventyConfig) { } }); - eleventyConfig.addUrlTransform((page) => { - if (page.url.endsWith(".html")) { - return page.url.slice(0, -1 * ".html".length); - } - }); - eleventyConfig.addGlobalData("permalink", () => { - return (data) => - `${data.page.filePathStem}.${data.page.outputFileExtension}`; - }); - // Copy the contents of the `public` folder to the output folder // For example, `./public/css/` ends up in `_site/css/` eleventyConfig diff --git a/vercel.json b/vercel.json deleted file mode 100644 index 1e9c7bc..0000000 --- a/vercel.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "trailingSlash": true -} From 26f58f9269b591ba64c75c4076ba6dbedc000c14 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:29:57 -0500 Subject: [PATCH 53/64] One more test --- vercel.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 vercel.json diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..9861173 --- /dev/null +++ b/vercel.json @@ -0,0 +1 @@ +{ "trailingSlash": false } From ef4e52d57dcdbe13e1693de01b731951a49bf57c Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:31:53 -0500 Subject: [PATCH 54/64] Remove trailing slash from URLs --- eleventy.config.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eleventy.config.js b/eleventy.config.js index 668f6ee..cbb1cae 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -15,6 +15,16 @@ export default async function(eleventyConfig) { } }); + eleventyConfig.addUrlTransform((page) => { + if (page.url.endsWith(".html")) { + return page.url.slice(0, -1 * ".html".length); + } + }); + // eleventyConfig.addGlobalData("permalink", () => { + // return (data) => + // `${data.page.filePathStem}.${data.page.outputFileExtension}`; + // }); + // Copy the contents of the `public` folder to the output folder // For example, `./public/css/` ends up in `_site/css/` eleventyConfig From fb5caf353bed1384a9f38f0b24433b33b1d2a496 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:32:47 -0500 Subject: [PATCH 55/64] Remove trailing slash from URLs --- eleventy.config.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/eleventy.config.js b/eleventy.config.js index cbb1cae..81cac4a 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -16,10 +16,15 @@ export default async function(eleventyConfig) { }); eleventyConfig.addUrlTransform((page) => { - if (page.url.endsWith(".html")) { - return page.url.slice(0, -1 * ".html".length); + if (page.url.endsWith("/")) { + return page.url.slice(0, -1); } }); + // eleventyConfig.addUrlTransform((page) => { + // if (page.url.endsWith(".html")) { + // return page.url.slice(0, -1 * ".html".length); + // } + // }); // eleventyConfig.addGlobalData("permalink", () => { // return (data) => // `${data.page.filePathStem}.${data.page.outputFileExtension}`; From f9522c3cb7f5f0d26d538ea5196eb7e13ea6c5da Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:33:37 -0500 Subject: [PATCH 56/64] One more try --- eleventy.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eleventy.config.js b/eleventy.config.js index 81cac4a..f465257 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -16,7 +16,7 @@ export default async function(eleventyConfig) { }); eleventyConfig.addUrlTransform((page) => { - if (page.url.endsWith("/")) { + if (page.outputPath?.endsWith(".html") && url.endsWith("/")) { return page.url.slice(0, -1); } }); From 644b1f09f036e96fa2e140b5825e0cc894c55bd5 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 16:35:42 -0500 Subject: [PATCH 57/64] URL only --- eleventy.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eleventy.config.js b/eleventy.config.js index f465257..985a8ca 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -16,7 +16,7 @@ export default async function(eleventyConfig) { }); eleventyConfig.addUrlTransform((page) => { - if (page.outputPath?.endsWith(".html") && url.endsWith("/")) { + if (page.url.length > 1 && page.url.endsWith("/")) { return page.url.slice(0, -1); } }); From 33f30bc106546e06c238c7f8f98249bd9b69ba20 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 17:00:14 -0500 Subject: [PATCH 58/64] Revert --- eleventy.config.js | 15 --------------- vercel.json | 1 - 2 files changed, 16 deletions(-) delete mode 100644 vercel.json diff --git a/eleventy.config.js b/eleventy.config.js index 985a8ca..668f6ee 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -15,21 +15,6 @@ export default async function(eleventyConfig) { } }); - eleventyConfig.addUrlTransform((page) => { - if (page.url.length > 1 && page.url.endsWith("/")) { - return page.url.slice(0, -1); - } - }); - // eleventyConfig.addUrlTransform((page) => { - // if (page.url.endsWith(".html")) { - // return page.url.slice(0, -1 * ".html".length); - // } - // }); - // eleventyConfig.addGlobalData("permalink", () => { - // return (data) => - // `${data.page.filePathStem}.${data.page.outputFileExtension}`; - // }); - // Copy the contents of the `public` folder to the output folder // For example, `./public/css/` ends up in `_site/css/` eleventyConfig diff --git a/vercel.json b/vercel.json deleted file mode 100644 index 9861173..0000000 --- a/vercel.json +++ /dev/null @@ -1 +0,0 @@ -{ "trailingSlash": false } From 07bd6d8affed32629148ec4463b6ec09b1701d0b Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Fri, 27 Sep 2024 17:04:09 -0500 Subject: [PATCH 59/64] Always use trailingSlash: true on Vercel --- vercel.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 vercel.json diff --git a/vercel.json b/vercel.json new file mode 100644 index 0000000..a9d5b12 --- /dev/null +++ b/vercel.json @@ -0,0 +1 @@ +{ "trailingSlash": true } From c8a2c186bcb67df46cdb78348490dff7bf2bcf37 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 1 Oct 2024 15:42:41 -0500 Subject: [PATCH 60/64] Upgrade a few deps, move a few things around. Remove the dual feeds (JSON still supported) --- README.md | 5 ++--- _includes/layouts/base.njk | 5 +---- content/{about/index.md => about.md} | 0 content/tag-pages.njk | 4 +++- eleventy.config.js | 2 +- package.json | 4 ++-- 6 files changed, 9 insertions(+), 11 deletions(-) rename content/{about/index.md => about.md} (100%) diff --git a/README.md b/README.md index 1e97ede..6001144 100644 --- a/README.md +++ b/README.md @@ -45,13 +45,12 @@ Or you can run [debug mode](https://www.11ty.dev/docs/debugging/) to see all the ## Features -- Using [Eleventy v2.0](https://www.11ty.dev/blog/eleventy-v2/) with zero-JavaScript output. +- Using [Eleventy v3](https://github.com/11ty/eleventy/releases/tag/v3.0.0) with zero-JavaScript output. - Content is exclusively pre-rendered (this is a static site). - Can easily [deploy to a subfolder without changing any content](https://www.11ty.dev/docs/plugins/html-base/) - All URLs are decoupled from the content’s location on the file system. - Configure templates via the [Eleventy Data Cascade](https://www.11ty.dev/docs/data-cascade/) - **Performance focused**: four-hundos Lighthouse score out of the box! - - [View the Lighthouse report for the latest build](https://eleventy-base-blog.netlify.app/reports/lighthouse/) courtesy of the [Netlify Lighthouse plugin](https://github.com/netlify/netlify-plugin-lighthouse). - _0 Cumulative Layout Shift_ - _0ms Total Blocking Time_ - Local development live reload provided by [Eleventy Dev Server](https://www.11ty.dev/docs/dev-server/). @@ -68,8 +67,8 @@ Or you can run [debug mode](https://www.11ty.dev/docs/debugging/) to see all the - Images can be co-located with blog post files. - Per page CSS bundles [via `eleventy-plugin-bundle`](https://github.com/11ty/eleventy-plugin-bundle). - Built-in [syntax highlighter](https://www.11ty.dev/docs/plugins/syntaxhighlight/) (zero-JavaScript output). +- Draft content: use `draft: true` to mark any template as a draft. Drafts are **only** included during `--serve`/`--watch` and are excluded from full builds. This is driven by the `addPreprocessor` configuration API in `eleventy.config.js`. Schema validator will show an error if non-boolean value is set in data cascade. - Blog Posts - - Draft posts: use `draft: true` to mark a blog post as a draft. Drafts are **only** included during `--serve`/`--watch` and are excluded from full builds. This is driven by the `eleventyExcludeFromCollections` and `permalink` computed data in the `content/blog/blog.11tydata.js` directory data file. Schema validator will show an error if non-boolean value is set in data cascade. - Automated next/previous links - Accessible deep links to headings - Generated Pages diff --git a/_includes/layouts/base.njk b/_includes/layouts/base.njk index 537f398..57a29a2 100644 --- a/_includes/layouts/base.njk +++ b/_includes/layouts/base.njk @@ -5,10 +5,7 @@ {{ title or metadata.title }} - - {#- Atom and JSON feeds included by default #} - - + {#- Uncomment this if you’d like folks to know that you used Eleventy to build your site! #} {#- #} diff --git a/content/about/index.md b/content/about.md similarity index 100% rename from content/about/index.md rename to content/about.md diff --git a/content/tag-pages.njk b/content/tag-pages.njk index 33b7abf..a69aeef 100644 --- a/content/tag-pages.njk +++ b/content/tag-pages.njk @@ -5,9 +5,11 @@ const pagination = { size: 1, alias: "tag", filter: ["all", "posts"], - addAllPagesToCollections: true, + // addAllPagesToCollections: true, }; +const eleventyExcludeFromCollections = true; + const eleventyComputed = { title: "Tagged '{{ tag }}'", permalink: function(data) { diff --git a/eleventy.config.js b/eleventy.config.js index 668f6ee..6ebf287 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -47,8 +47,8 @@ export default async function(eleventyConfig) { eleventyConfig.addPlugin(HtmlBasePlugin); eleventyConfig.addPlugin(InputPathToUrlTransformPlugin); - // Atom Feed eleventyConfig.addPlugin(feedPlugin, { + type: "atom", // or "rss", "json" outputPath: "/feed/feed.xml", stylesheet: "pretty-atom-feed.xsl", templateData: { diff --git a/package.json b/package.json index ba2f26d..6a16961 100644 --- a/package.json +++ b/package.json @@ -35,8 +35,8 @@ }, "homepage": "https://github.com/11ty/eleventy-base-blog#readme", "devDependencies": { - "@11ty/eleventy": "3.0.0-alpha.20", - "@11ty/eleventy-img": "5.0.0-beta.9", + "@11ty/eleventy": "^3.0.0", + "@11ty/eleventy-img": "^5.0.0", "@11ty/eleventy-navigation": "^0.3.5", "@11ty/eleventy-plugin-rss": "^2.0.2", "@11ty/eleventy-plugin-syntaxhighlight": "^5.0.0", From a13b19d5c202ea853802beee9580580f12df6bfa Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 1 Oct 2024 15:47:38 -0500 Subject: [PATCH 61/64] Minor tweak to readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6001144..5d1c3fb 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Or you can run [debug mode](https://www.11ty.dev/docs/debugging/) to see all the - Accessible deep links to headings - Generated Pages - Home, Archive, and About pages. - - [Feeds for Atom and JSON](https://www.11ty.dev/docs/plugins/rss/) + - [Feeds for Atom (with easy swap to RSS or JSON](https://www.11ty.dev/docs/plugins/rss/) - `sitemap.xml` - Zero-maintenance tag pages ([View on the Demo](https://eleventy-base-blog.netlify.app/tags/)) - Content not found (404) page From 0a5175f4f207ef11cf52d362de0c17681c768f18 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 1 Oct 2024 15:48:55 -0500 Subject: [PATCH 62/64] Yet another README copy tweak --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index cd00c02..b0cbba4 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ Or you can run [debug mode](https://www.11ty.dev/docs/debugging/) to see all the - Accessible deep links to headings - Generated Pages - Home, Archive, and About pages. - - [Feeds for Atom (with easy swap to RSS or JSON](https://www.11ty.dev/docs/plugins/rss/) + - [Atom feed included (with easy one-line swap to use RSS or JSON](https://www.11ty.dev/docs/plugins/rss/) - `sitemap.xml` - Zero-maintenance tag pages ([View on the Demo](https://eleventy-base-blog.netlify.app/tags/)) - Content not found (404) page @@ -104,9 +104,6 @@ Deploy this Eleventy site in just a few clicks on these services: - Use the `eleventyNavigation` key (via the [Eleventy Navigation plugin](https://www.11ty.dev/docs/plugins/navigation/)) in your front matter to add a template to the top level site navigation. This is in use on `content/index.njk` and `content/about/index.md`. - Content can be in _any template format_ (blog posts needn’t exclusively be markdown, for example). Configure your project’s supported templates in `eleventy.config.js` -> `templateFormats`. - The `public` folder in your input directory will be copied to the output folder (via `addPassthroughCopy` in the `eleventy.config.js` file). This means `./public/css/*` will live at `./_site/css/*` after your build completes. -- Provides two content feeds: - - `content/feed/feed.njk` - - `content/feed/json.njk` - This project uses three [Eleventy Layouts](https://www.11ty.dev/docs/layouts/): - `_includes/layouts/base.njk`: the top level HTML structure - `_includes/layouts/home.njk`: the home page template (wrapped into `base.njk`) From c79179c2bf5f0833e0934e74f5e60b9b44f7e077 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 1 Oct 2024 15:49:23 -0500 Subject: [PATCH 63/64] Deployment copy tweaks --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index b0cbba4..f3e2c21 100644 --- a/README.md +++ b/README.md @@ -90,12 +90,11 @@ Or you can run [debug mode](https://www.11ty.dev/docs/debugging/) to see all the Deploy this Eleventy site in just a few clicks on these services: +- Read more about [Deploying an Eleventy project](https://www.11ty.dev/docs/deployment/) to the web. - [Deploy this to **Netlify**](https://app.netlify.com/start/deploy?repository=https://github.com/11ty/eleventy-base-blog) - [Deploy this to **Vercel**](https://vercel.com/import/project?template=11ty%2Feleventy-base-blog) - Look in `.github/workflows/gh-pages.yml.sample` for information on Deploying to **GitHub Pages**. - [Try it out on **Stackblitz**](https://stackblitz.com/github/11ty/eleventy-base-blog) -- If you run Eleventy locally you can drag your `_site` folder to [`netlify.com/drop`](https://netlify.com/drop) to upload it without using `git`. -- Read more about [Deploying an Eleventy project](https://www.11ty.dev/docs/deployment/) to the web. ### Implementation Notes From 9b0cb972e0d1a6486cc7e388c87986ee8c63c2ae Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Tue, 1 Oct 2024 15:54:03 -0500 Subject: [PATCH 64/64] Change navigation order --- eleventy.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eleventy.config.js b/eleventy.config.js index 6ebf287..09ee084 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -54,7 +54,7 @@ export default async function(eleventyConfig) { templateData: { eleventyNavigation: { key: "Feed", - order: 3 + order: 4 } }, collection: {