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 5a5c99b4ea..97faa8c4aa 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 2d655b167f..614f50508e 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 ed3fec9905..42ad826052 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 8eb92dc30f..daea903c03 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 32a02690f7..b2c98b2137 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 3fba4b71b3..807d26e165 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 e3340f0bda..118f3431e4 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 7177590a99..5e21e4f2b9 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 97faa8c4aa..7e8b63622d 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 3b3226fcc9..1308e54eb7 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 bd51f6149b..c8be2dfc51 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 2b21b1c94d..35e3e9de48 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 d8eee56436..4814c79838 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 35e3e9de48..c745f12590 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 0000000000..feb34993c4 --- /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 673fc8d7b0..8c673a8f93 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 c745f12590..dadc1930a9 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 dadc1930a9..b0b94ef068 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 46bdde72d0..afb8cafd6e 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 9000fe19d0..f38dda1a65 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 0000000000..0ee5e54075 --- /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 d8f8688718..0000000000 --- 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 3c76e3879e..0000000000 --- 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 3b33b59ac4..0000000000 --- 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 b0b94ef068..72bcb31745 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 afb8cafd6e..70f369efe3 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 70f369efe3..58e7bee70c 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 72bcb31745..98004b2072 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 58e7bee70c..d50cd20bbe 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 d50cd20bbe..f93a19dec0 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 98004b2072..45326ee3fc 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 f93a19dec0..fe020e3a52 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 feb34993c4..4af2fe826f 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 da2e95e7ef..6ff059b6ff 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 9533be9a4c..33b7abfad2 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 45326ee3fc..753bba828c 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 ec9f28f2cc..d25756c59e 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 f38dda1a65..c48c8e4cb1 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 0000000000..0c1b7068c7 --- /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 c48c8e4cb1..cd9d0bf486 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 ea58351f7b..1a1e976ea7 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 753bba828c..e56ad2d08b 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 d25756c59e..3752045e3d 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 3752045e3d..de08ca66b5 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 de08ca66b5..5f7c21e06e 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 b6a7d89c68..209e3ef4b6 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -16 +20 From b3351bd600f8838fbcf060ec73401be26ae68954 Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Thu, 8 Aug 2024 15:01:03 -0500 Subject: [PATCH 30/64] CI 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 0c1b7068c7..ea9d6cd277 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 bdea878906..7241473e23 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 cd9d0bf486..b75d493e16 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 ea9d6cd277..03134af0c5 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 e56ad2d08b..350ac9a6f9 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 03134af0c5..67debf6772 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 b75d493e16..00f39b5a00 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 67debf6772..e630072188 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 e630072188..f0bdccd301 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 f0bdccd301..5eff13fc91 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 5eff13fc91..834ccfa06a 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 cfb97f61eb..6e75d04487 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 8307e7b70d..776583ad41 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 00f39b5a00..34799a27da 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 834ccfa06a..0b3b6d5f01 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 8b7eea6eb5..6e6eddd828 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 7241473e23..e333b46d9b 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 5f7c21e06e..0881e8a31d 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 34799a27da..b75d493e16 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 0b3b6d5f01..0000000000 --- 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 0881e8a31d..f4d5b13cac 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 f4d5b13cac..337e1978d8 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 b75d493e16..1cfa083199 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 6e6eddd828..00c55c65e4 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 00c55c65e4..537f3984a5 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 78166f320f..d1827cf830 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 350ac9a6f9..c73e75ef7f 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 337e1978d8..ba2f26dac4 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 5a8db0fcbe..1bc23a7f21 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 8c673a8f93..fba58a9007 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 1f7d876418..c11fdf8a05 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 0557716d98..97db357b1e 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 008fdc8d41..b308bff380 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 e333b46d9b..7a95dd6edf 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 260b20cf1d..f7d17e1425 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 0000000000..ca764ec313 --- /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 1a1e976ea7..614f50508e 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 c73e75ef7f..668f6ee8b4 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 668f6ee8b4..efb85cdbc5 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 0000000000..e85d6c0b6d --- /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 e85d6c0b6d..1e9c7bc398 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 efb85cdbc5..668f6ee8b4 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 1e9c7bc398..0000000000 --- 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 0000000000..9861173f5e --- /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 668f6ee8b4..cbb1cae011 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 cbb1cae011..81cac4a7dc 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 81cac4a7dc..f4652576aa 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 f4652576aa..985a8ca2ca 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 985a8ca2ca..668f6ee8b4 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 9861173f5e..0000000000 --- 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 0000000000..a9d5b12d01 --- /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 1e97edecd5..60011442a3 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 537f3984a5..57a29a23df 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 33b7abfad2..a69aeef116 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 668f6ee8b4..6ebf287e84 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 ba2f26dac4..6a16961a7f 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 60011442a3..5d1c3fbf4c 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 cd00c02baf..b0cbba4941 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 b0cbba4941..f3e2c21b0a 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 6ebf287e84..09ee08479c 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: {