From b45dae313016f56c33203d13642114a5b35b52ff Mon Sep 17 00:00:00 2001 From: Zach Leatherman Date: Wed, 25 Sep 2024 09:27:28 -0500 Subject: [PATCH] ESM docs for preprocessors, custom tags, dev servers, events, shortcodes, and transforms https://github.com/11ty/eleventy/issues/836 --- eleventy.config.js | 8 + src/_includes/snippets/config/liquidtags.njk | 59 +++++ .../snippets/config/nunjuckstags.njk | 73 ++++++ .../snippets/config/preprocessors-drafts.njk | 33 +++ .../snippets/config/preprocessors.njk | 45 ++++ src/_includes/snippets/config/transforms.njk | 52 ++++ src/_includes/snippets/configDefinition.njk | 22 ++ src/_includes/snippets/serve/vite-options.njk | 91 +++++++ src/_includes/snippets/serve/vite.njk | 29 +++ .../snippets/shortcodes/config-paired.njk | 51 ++++ src/_includes/snippets/shortcodes/config.njk | 51 ++++ src/_includes/snippets/shortcodes/intro.njk | 39 +++ src/_includes/snippets/shortcodes/paired.njk | 67 +++++ .../snippets/shortcodes/perengine-async.njk | 49 ++++ .../snippets/shortcodes/perengine.njk | 45 ++++ src/_includes/snippets/shortcodes/scoped.njk | 33 +++ src/docs/config-preprocessors.md | 30 +-- src/docs/custom-tags.md | 73 +----- src/docs/dev-server.md | 48 ++-- src/docs/events.md | 35 ++- src/docs/server-browsersync.md | 16 +- src/docs/server-vite.md | 47 +--- src/docs/shortcodes.md | 240 +----------------- src/docs/transforms.md | 32 +-- src/docs/watch-serve.md | 43 ++-- 25 files changed, 820 insertions(+), 491 deletions(-) create mode 100644 src/_includes/snippets/config/liquidtags.njk create mode 100644 src/_includes/snippets/config/nunjuckstags.njk create mode 100644 src/_includes/snippets/config/preprocessors-drafts.njk create mode 100644 src/_includes/snippets/config/preprocessors.njk create mode 100644 src/_includes/snippets/config/transforms.njk create mode 100644 src/_includes/snippets/configDefinition.njk create mode 100644 src/_includes/snippets/serve/vite-options.njk create mode 100644 src/_includes/snippets/serve/vite.njk create mode 100644 src/_includes/snippets/shortcodes/config-paired.njk create mode 100644 src/_includes/snippets/shortcodes/config.njk create mode 100644 src/_includes/snippets/shortcodes/intro.njk create mode 100644 src/_includes/snippets/shortcodes/paired.njk create mode 100644 src/_includes/snippets/shortcodes/perengine-async.njk create mode 100644 src/_includes/snippets/shortcodes/perengine.njk create mode 100644 src/_includes/snippets/shortcodes/scoped.njk diff --git a/eleventy.config.js b/eleventy.config.js index d244d54498..cb87f7dcf5 100644 --- a/eleventy.config.js +++ b/eleventy.config.js @@ -406,6 +406,14 @@ export default async function (eleventyConfig) { } }); + let ref = 0; + eleventyConfig.on("eleventy.before", () => { + ref = 0; + }); + eleventyConfig.addShortcode("uid", () => { + return `id-${++ref}`; + }); + eleventyConfig.addShortcode("image", shortcodes.image); eleventyConfig.addShortcode("avatarlocalcache", shortcodes.avatar); eleventyConfig.addShortcode("communityavatar", shortcodes.communityAvatar); diff --git a/src/_includes/snippets/config/liquidtags.njk b/src/_includes/snippets/config/liquidtags.njk new file mode 100644 index 0000000000..0d21fd0879 --- /dev/null +++ b/src/_includes/snippets/config/liquidtags.njk @@ -0,0 +1,59 @@ +{%- set tabid = "liquidtags" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +{% raw %} +```js +export default function (eleventyConfig) { + // Usage: {% uppercase myVar %} where myVar has a value of "alice" + // Usage: {% uppercase "alice" %} + eleventyConfig.addLiquidTag("uppercase", function (liquidEngine) { + return { + parse: function (tagToken, remainingTokens) { + this.str = tagToken.args; // myVar or "alice" + }, + render: async function (scope, hash) { + // Resolve variables + var str = await this.liquid.evalValue(this.str, scope); // "alice" + + // Do the uppercasing + return str.toUpperCase(); // "ALICE" + }, + }; + }); +}; +``` +{% endraw %} + +
+
+ +{% raw %} +```js +module.exports = function (eleventyConfig) { + // Usage: {% uppercase myVar %} where myVar has a value of "alice" + // Usage: {% uppercase "alice" %} + eleventyConfig.addLiquidTag("uppercase", function (liquidEngine) { + return { + parse: function (tagToken, remainingTokens) { + this.str = tagToken.args; // myVar or "alice" + }, + render: async function (scope, hash) { + // Resolve variables + var str = await this.liquid.evalValue(this.str, scope); // "alice" + + // Do the uppercasing + return str.toUpperCase(); // "ALICE" + }, + }; + }); +}; +``` +{% endraw %} + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/config/nunjuckstags.njk b/src/_includes/snippets/config/nunjuckstags.njk new file mode 100644 index 0000000000..ed9df54c47 --- /dev/null +++ b/src/_includes/snippets/config/nunjuckstags.njk @@ -0,0 +1,73 @@ +{%- set tabid = "njktags" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +{% raw %} +```js +export default function (eleventyConfig) { + // Usage: {% uppercase myVar %} where myVar has a value of "alice" + // Usage: {% uppercase "alice" %} + eleventyConfig.addNunjucksTag("uppercase", function (nunjucksEngine) { + return new (function () { + this.tags = ["uppercase"]; + + this.parse = function (parser, nodes, lexer) { + var tok = parser.nextToken(); + + var args = parser.parseSignature(null, true); + parser.advanceAfterBlockEnd(tok.value); + + return new nodes.CallExtensionAsync(this, "run", args); + }; + + this.run = function (context, myStringArg, callback) { + let ret = new nunjucksEngine.runtime.SafeString( + myStringArg.toUpperCase() + ); + callback(null, ret); + }; + })(); + }); +}; +``` +{% endraw %} + +
+
+ +{% raw %} +```js +module.exports = function (eleventyConfig) { + // Usage: {% uppercase myVar %} where myVar has a value of "alice" + // Usage: {% uppercase "alice" %} + eleventyConfig.addNunjucksTag("uppercase", function (nunjucksEngine) { + return new (function () { + this.tags = ["uppercase"]; + + this.parse = function (parser, nodes, lexer) { + var tok = parser.nextToken(); + + var args = parser.parseSignature(null, true); + parser.advanceAfterBlockEnd(tok.value); + + return new nodes.CallExtensionAsync(this, "run", args); + }; + + this.run = function (context, myStringArg, callback) { + let ret = new nunjucksEngine.runtime.SafeString( + myStringArg.toUpperCase() + ); + callback(null, ret); + }; + })(); + }); +}; +``` +{% endraw %} + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/config/preprocessors-drafts.njk b/src/_includes/snippets/config/preprocessors-drafts.njk new file mode 100644 index 0000000000..8492939609 --- /dev/null +++ b/src/_includes/snippets/config/preprocessors-drafts.njk @@ -0,0 +1,33 @@ +{%- set tabid = "preprocessors-drafts" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +export default function (eleventyConfig) { + eleventyConfig.addPreprocessor("drafts", "*", (data, content) => { + if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") { + return false; + } + }); +}; +``` + +
+
+ +```js +module.exports = function (eleventyConfig) { + eleventyConfig.addPreprocessor("drafts", "*", (data, content) => { + if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") { + return false; + } + }); +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/config/preprocessors.njk b/src/_includes/snippets/config/preprocessors.njk new file mode 100644 index 0000000000..98a459878e --- /dev/null +++ b/src/_includes/snippets/config/preprocessors.njk @@ -0,0 +1,45 @@ +{%- set tabid = "preprocessors" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +export default function (eleventyConfig) { + eleventyConfig.addPreprocessor("drafts", "njk,md,liquid", (data, content) => { + if(data.draft) { + // Ignore this file. + return false; + } + + // You can also modify the raw input of the template here too, be careful! + return `${content}`; + + // If you return nothing or `undefined`, no changes will be made to this template. + }); +}; +``` + +
+
+ +```js +module.exports = function (eleventyConfig) { + eleventyConfig.addPreprocessor("drafts", "njk,md,liquid", (data, content) => { + if(data.draft) { + // Ignore this file. + return false; + } + + // You can also modify the raw input of the template here too, be careful! + return `${content}`; + + // If you return nothing or `undefined`, no changes will be made to this template. + }); +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/config/transforms.njk b/src/_includes/snippets/config/transforms.njk new file mode 100644 index 0000000000..19938894ea --- /dev/null +++ b/src/_includes/snippets/config/transforms.njk @@ -0,0 +1,52 @@ +{# uses tabContent #} +{% set tabid %}tab-{% uid %}{% endset %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ {% highlight "js" %} +import htmlmin from "html-minifier-terser"; + +export default function (eleventyConfig) { + eleventyConfig.addTransform("htmlmin", function (content) { + if ((this.page.outputPath || "").endsWith(".html")) { + let minified = htmlmin.minify(content, { + useShortDoctype: true, + removeComments: true, + collapseWhitespace: true, + }); + + return minified; + } + + // If not an HTML output, return content as-is + return content; + }); +}; + {% endhighlight %} +
+
+ {% highlight "js" %} +const htmlmin = require("html-minifier-terser"); + +module.exports = function (eleventyConfig) { + eleventyConfig.addTransform("htmlmin", function (content) { + if ((this.page.outputPath || "").endsWith(".html")) { + let minified = htmlmin.minify(content, { + useShortDoctype: true, + removeComments: true, + collapseWhitespace: true, + }); + + return minified; + } + + // If not an HTML output, return content as-is + return content; + }); +}; + {% endhighlight %} +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/configDefinition.njk b/src/_includes/snippets/configDefinition.njk new file mode 100644 index 0000000000..28ec21beb4 --- /dev/null +++ b/src/_includes/snippets/configDefinition.njk @@ -0,0 +1,22 @@ +{# uses configCodeContent #} +{% set tabid %}tab-{% uid %}{% endset %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ {% highlight "js" %} +export default function (eleventyConfig) { +{{- configCodeContent | safe -}} +}; + {% endhighlight %} +
+
+ {% highlight "js" %} +module.exports = function (eleventyConfig) { +{{- configCodeContent | safe -}} +}; + {% endhighlight %} +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/serve/vite-options.njk b/src/_includes/snippets/serve/vite-options.njk new file mode 100644 index 0000000000..701e9f7c17 --- /dev/null +++ b/src/_includes/snippets/serve/vite-options.njk @@ -0,0 +1,91 @@ +{%- set tabid = "viteopts" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +import EleventyVitePlugin from "@11ty/eleventy-plugin-vite"; + +export default function (eleventyConfig) { + eleventyConfig.addPlugin(EleventyVitePlugin, { + tempFolderName: ".11ty-vite", // Default name of the temp folder + + // Options passed to the Eleventy Dev Server + // e.g. domdiff, enabled, etc. + + // Added in Vite plugin v2.0.0 + serverOptions: {}, + + // Defaults are shown: + viteOptions: { + clearScreen: false, + appType: "mpa", // New in v2.0.0 + + server: { + mode: "development", + middlewareMode: true, + }, + + build: { + mode: "production", + }, + + // New in v2.0.0 + resolve: { + alias: { + // Allow references to `node_modules` folder directly + "/node_modules": path.resolve(".", "node_modules"), + }, + }, + }, + }); +}; +``` + +
+
+ +```js +const EleventyVitePlugin = require("@11ty/eleventy-plugin-vite"); + +module.exports = function (eleventyConfig) { + eleventyConfig.addPlugin(EleventyVitePlugin, { + tempFolderName: ".11ty-vite", // Default name of the temp folder + + // Options passed to the Eleventy Dev Server + // e.g. domdiff, enabled, etc. + + // Added in Vite plugin v2.0.0 + serverOptions: {}, + + // Defaults are shown: + viteOptions: { + clearScreen: false, + appType: "mpa", // New in v2.0.0 + + server: { + mode: "development", + middlewareMode: true, + }, + + build: { + mode: "production", + }, + + // New in v2.0.0 + resolve: { + alias: { + // Allow references to `node_modules` folder directly + "/node_modules": path.resolve(".", "node_modules"), + }, + }, + }, + }); +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/serve/vite.njk b/src/_includes/snippets/serve/vite.njk new file mode 100644 index 0000000000..f009c5b31a --- /dev/null +++ b/src/_includes/snippets/serve/vite.njk @@ -0,0 +1,29 @@ +{%- set tabid = "vite" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +import EleventyVitePlugin from "@11ty/eleventy-plugin-vite"; + +export default function (eleventyConfig) { + eleventyConfig.addPlugin(EleventyVitePlugin); +}; +``` + +
+
+ +```js +const EleventyVitePlugin = require("@11ty/eleventy-plugin-vite"); + +module.exports = function (eleventyConfig) { + eleventyConfig.addPlugin(EleventyVitePlugin); +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/shortcodes/config-paired.njk b/src/_includes/snippets/shortcodes/config-paired.njk new file mode 100644 index 0000000000..75ebd002ff --- /dev/null +++ b/src/_includes/snippets/shortcodes/config-paired.njk @@ -0,0 +1,51 @@ +{%- set tabid = "config-paired" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +export default function (eleventyConfig) { + // Shortcodes added in this way are available in: + // * Markdown + // * Liquid + // * Nunjucks + // * Handlebars (not async) + // * JavaScript + + eleventyConfig.addPairedShortcode("user", function(content, firstName, lastName) { … }); + + // Async support for `addPairedShortcode` is new in Eleventy {{ "2.0.0-canary.24" | coerceVersion }} + eleventyConfig.addPairedShortcode("user", async function(content, myName) { /* … */ }); + + // Async method available + eleventyConfig.addPairedAsyncShortcode("user", async function(content, myName) { /* … */ }); +}; +``` + +
+
+ +```js +module.exports = function (eleventyConfig) { + // Shortcodes added in this way are available in: + // * Markdown + // * Liquid + // * Nunjucks + // * Handlebars (not async) + // * JavaScript + + eleventyConfig.addPairedShortcode("user", function(content, firstName, lastName) { … }); + + // Async support for `addPairedShortcode` is new in Eleventy {{ "2.0.0-canary.24" | coerceVersion }} + eleventyConfig.addPairedShortcode("user", async function(content, myName) { /* … */ }); + + // Async method available + eleventyConfig.addPairedAsyncShortcode("user", async function(content, myName) { /* … */ }); +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/shortcodes/config.njk b/src/_includes/snippets/shortcodes/config.njk new file mode 100644 index 0000000000..02a9cb7ff8 --- /dev/null +++ b/src/_includes/snippets/shortcodes/config.njk @@ -0,0 +1,51 @@ +{%- set tabid = "config" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +export default function (eleventyConfig) { + // Shortcodes added in this way are available in: + // * Markdown + // * Liquid + // * Nunjucks + // * Handlebars (not async) + // * JavaScript + + eleventyConfig.addShortcode("user", function(firstName, lastName) { … }); + + // Async-friendly in {{ "2.0.0-canary.24" | coerceVersion }} + eleventyConfig.addShortcode("user", async function(myName) { /* … */ }); + + // Direct async method available + eleventyConfig.addAsyncShortcode("user", async function(myName) { /* … */ }); +}; +``` + +
+
+ +```js +module.exports = function (eleventyConfig) { + // Shortcodes added in this way are available in: + // * Markdown + // * Liquid + // * Nunjucks + // * Handlebars (not async) + // * JavaScript + + eleventyConfig.addShortcode("user", function(firstName, lastName) { … }); + + // Async support for `addShortcode` is new in Eleventy {{ "2.0.0-canary.24" | coerceVersion }} + eleventyConfig.addShortcode("user", async function(myName) { /* … */ }); + + // Async method available + eleventyConfig.addAsyncShortcode("user", async function(myName) { /* … */ }); +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/shortcodes/intro.njk b/src/_includes/snippets/shortcodes/intro.njk new file mode 100644 index 0000000000..877ea6606b --- /dev/null +++ b/src/_includes/snippets/shortcodes/intro.njk @@ -0,0 +1,39 @@ + + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "shortcode"} %} +
+
sample.liquid
+{%- highlight "liquid" %}{% raw %} +{% user firstName, lastName %} +{% endraw %}{% endhighlight %} +

The comma between arguments is optional in Liquid templates.

+
sample.liquid
+{%- highlight "liquid" %}{% raw %} +{% user firstName lastName %} +{% endraw %}{% endhighlight %} +
+
+
sample.njk
+{%- highlight "jinja2" %}{% raw %} +{% user firstName, lastName %} +{% endraw %}{% endhighlight %} +

The comma between arguments is required in Nunjucks templates.

+
+
+
sample.11ty.js
+{%- highlight "js" %}{% raw %} +export default function({ firstName, lastName }) { + return `

${this.user(firstName, lastName)}

`; +}; +{% endraw %}{% endhighlight %} +
+
+
sample.11ty.cjs
+{%- highlight "js" %}{% raw %} +module.exports = function({ firstName, lastName }) { + return `

${this.user(firstName, lastName)}

`; +}; +{% endraw %}{% endhighlight %} +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/shortcodes/paired.njk b/src/_includes/snippets/shortcodes/paired.njk new file mode 100644 index 0000000000..8b7af30587 --- /dev/null +++ b/src/_includes/snippets/shortcodes/paired.njk @@ -0,0 +1,67 @@ + + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "pairedshortcodes"} %} +
+ +{% raw %} + +```liquid +{% user firstName, lastName %} + Hello {{ someOtherVariable }}. + + Hello {% anotherShortcode %}. +{% enduser %} +``` + +{% endraw %} + +The comma between arguments is **optional** in Liquid templates. + +
+
+ +{% raw %} + +```jinja2 +{% user firstName, lastName %} + Hello {{ someOtherVariable }}. + + Hello {% anotherShortcode %}. +{% enduser %} +``` + +{% endraw %} + +The comma between arguments is **required** in Nunjucks. + +
+
+ +```js +export default function (data) { + let userContent = `Hello ${data.someOtherVariable} + +Hello ${this.anotherShortCode()}`; + + // pass the content as the first parameter. + return `

${this.user(userContent, data.firstName, data.lastName)}

`; +}; +``` + +
+
+ +```js +module.exports = function (data) { + let userContent = `Hello ${data.someOtherVariable} + +Hello ${this.anotherShortCode()}`; + + // pass the content as the first parameter. + return `

${this.user(userContent, data.firstName, data.lastName)}

`; +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/shortcodes/perengine-async.njk b/src/_includes/snippets/shortcodes/perengine-async.njk new file mode 100644 index 0000000000..ff4d0429ab --- /dev/null +++ b/src/_includes/snippets/shortcodes/perengine-async.njk @@ -0,0 +1,49 @@ +{%- set tabid = "perengineasync" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +export default function (eleventyConfig) { + // Async-friendly + // Liquid is already async-friendly + eleventyConfig.addLiquidShortcode("user", async function() {}); + eleventyConfig.addPairedLiquidShortcode("user", async function(content) {}); + + // Nunjucks Async + eleventyConfig.addNunjucksAsyncShortcode("user", async function() {}); + eleventyConfig.addPairedNunjucksAsyncShortcode("user", async function(content) {}); + + // JavaScript Template function + // (make sure you `await` these when using in templates!) + eleventyConfig.addJavaScriptFunction("user", async function() {}); + eleventyConfig.addJavaScriptFunction("user", async function(content) {}); // Faux-paired shortcode +}; +``` + +
+
+ +```js +module.exports = function (eleventyConfig) { + // Async-friendly + // Liquid is already async-friendly + eleventyConfig.addLiquidShortcode("user", async function() {}); + eleventyConfig.addPairedLiquidShortcode("user", async function(content) {}); + + // Nunjucks Async + eleventyConfig.addNunjucksAsyncShortcode("user", async function() {}); + eleventyConfig.addPairedNunjucksAsyncShortcode("user", async function(content) {}); + + // JavaScript Template Function + // (make sure you `await` these when using in templates!) + eleventyConfig.addJavaScriptFunction("user", async function() {}); + eleventyConfig.addJavaScriptFunction("user", async function(content) {}); // Faux-paired shortcode +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/shortcodes/perengine.njk b/src/_includes/snippets/shortcodes/perengine.njk new file mode 100644 index 0000000000..039b8e3598 --- /dev/null +++ b/src/_includes/snippets/shortcodes/perengine.njk @@ -0,0 +1,45 @@ +{%- set tabid = "perengine" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +export default function (eleventyConfig) { + // Liquid + eleventyConfig.addLiquidShortcode("user", function(firstName, lastName) {}); + eleventyConfig.addPairedLiquidShortcode("user", function(content, firstName, lastName) {}); + + // Nunjucks + eleventyConfig.addNunjucksShortcode("user", function(firstName, lastName) {}); + eleventyConfig.addPairedNunjucksShortcode("user", function(content, firstName, lastName) {}); + + // JavaScript Template Function (New in 0.7.0) + eleventyConfig.addJavaScriptFunction("user", function(firstName, lastName) {}); + eleventyConfig.addJavaScriptFunction("user", function(content, firstName, lastName) {}); // Faux-paired shortcode +}; +``` + +
+
+ +```js +module.exports = function (eleventyConfig) { + // Liquid + eleventyConfig.addLiquidShortcode("user", function(firstName, lastName) {}); + eleventyConfig.addPairedLiquidShortcode("user", function(content, firstName, lastName) {}); + + // Nunjucks + eleventyConfig.addNunjucksShortcode("user", function(firstName, lastName) {}); + eleventyConfig.addPairedNunjucksShortcode("user", function(content, firstName, lastName) {}); + + // JavaScript Template Function (New in 0.7.0) + eleventyConfig.addJavaScriptFunction("user", function(firstName, lastName) {}); + eleventyConfig.addJavaScriptFunction("user", function(content, firstName, lastName) {}); // Faux-paired shortcode +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/_includes/snippets/shortcodes/scoped.njk b/src/_includes/snippets/shortcodes/scoped.njk new file mode 100644 index 0000000000..377f6a2d4f --- /dev/null +++ b/src/_includes/snippets/shortcodes/scoped.njk @@ -0,0 +1,33 @@ +{%- set tabid = "scoped" %} +
eleventy.config.js
+ + + {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %} +
+ +```js +export default function (eleventyConfig) { + // Make sure you’re not using an arrow function here: () => {} + eleventyConfig.addShortcode("myShortcode", function () { + // this.page + // this.eleventy + }); +}; +``` + +
+
+ +```js +module.exports = function (eleventyConfig) { + // Make sure you’re not using an arrow function here: () => {} + eleventyConfig.addShortcode("myShortcode", function () { + // this.page + // this.eleventy + }); +}; +``` + +
+
+
\ No newline at end of file diff --git a/src/docs/config-preprocessors.md b/src/docs/config-preprocessors.md index a1487547bc..7a070a2aaf 100644 --- a/src/docs/config-preprocessors.md +++ b/src/docs/config-preprocessors.md @@ -11,23 +11,7 @@ eleventyNavigation: The Preprocessor Configuration API allows you to intercept and modify the content in template files (_not_ [Layouts](/docs/layouts.md)) before they’re processed and rendered by Eleventy. -{% raw %} -```js -export default function(eleventyConfig) { - eleventyConfig.addProcessor("drafts", "njk,md,liquid", (data, content) => { - if(data.draft) { - // Ignore this file. - return false; - } - - // You can also modify the raw input of the template here too, be careful! - return `${content}`; - - // If you return nothing or `undefined`, no changes will be made to this template. - }); -}; -``` -{% endraw %} +{% include "snippets/config/preprocessors.njk" %} * The first argument is an arbitrary `name` (`String`) used for error messaging. * The second argument can be: @@ -46,14 +30,4 @@ Set `draft: true` anywhere in a file’s [data cascade](/docs/data-cascade/) and You might imagine how this could be extended to add a publishing date feature too: to exclude content from builds before a specific date set in a post’s front matter (or elsewhere in the data cascade). -{% raw %} -```js -export default function(eleventyConfig) { - eleventyConfig.addPreprocessor("drafts", "*", (data, content) => { - if(data.draft && process.env.ELEVENTY_RUN_MODE === "build") { - return false; - } - }); -}; -``` -{% endraw %} +{% include "snippets/config/preprocessors-drafts.njk" %} \ No newline at end of file diff --git a/src/docs/custom-tags.md b/src/docs/custom-tags.md index 5a7615aa55..9e3a5a5cb5 100644 --- a/src/docs/custom-tags.md +++ b/src/docs/custom-tags.md @@ -22,81 +22,16 @@ Custom Tags are unrelated to Eleventy’s [Collections using Tags](/docs/collect But, after all that, you can still add a Custom Tag using the [Configuration API](/docs/config/#using-the-configuration-api). - - - {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "customtag", subtractions: "js"} %} -
+## Liquid - [LiquidJS: Tags](https://liquidjs.com/tutorials/register-filters-tags.html) -{% codetitle ".eleventy.js" %} - -{% raw %} - -```js -module.exports = function (eleventyConfig) { - // Usage: {% uppercase myVar %} where myVar has a value of "alice" - // Usage: {% uppercase "alice" %} - eleventyConfig.addLiquidTag("uppercase", function (liquidEngine) { - return { - parse: function (tagToken, remainingTokens) { - this.str = tagToken.args; // myVar or "alice" - }, - render: async function (scope, hash) { - // Resolve variables - var str = await this.liquid.evalValue(this.str, scope); // "alice" - - // Do the uppercasing - return str.toUpperCase(); // "ALICE" - }, - }; - }); -}; -``` - -{% endraw %} +{% include "snippets/config/liquidtags.njk" %} See all of the [built-in tag implementations for LiquidJS](https://liquidjs.com/tags/overview.html). -
-
+## Nunjucks - [Nunjucks: Custom Tags](https://mozilla.github.io/nunjucks/api.html#custom-tags) -{% codetitle ".eleventy.js" %} - -{% raw %} - -```js -module.exports = function (eleventyConfig) { - // Usage: {% uppercase myVar %} where myVar has a value of "alice" - // Usage: {% uppercase "alice" %} - eleventyConfig.addNunjucksTag("uppercase", function (nunjucksEngine) { - return new (function () { - this.tags = ["uppercase"]; - - this.parse = function (parser, nodes, lexer) { - var tok = parser.nextToken(); - - var args = parser.parseSignature(null, true); - parser.advanceAfterBlockEnd(tok.value); - - return new nodes.CallExtensionAsync(this, "run", args); - }; - - this.run = function (context, myStringArg, callback) { - let ret = new nunjucksEngine.runtime.SafeString( - myStringArg.toUpperCase() - ); - callback(null, ret); - }; - })(); - }); -}; -``` - -{% endraw %} - -
-
-
+{% include "snippets/config/nunjuckstags.njk" %} diff --git a/src/docs/dev-server.md b/src/docs/dev-server.md index f603fce598..967313bb7f 100644 --- a/src/docs/dev-server.md +++ b/src/docs/dev-server.md @@ -29,10 +29,7 @@ _Read more detail on the [Eleventy Dev Server 1.0 release notes](https://github. You can configure the server with the new `setServerOptions` Configuration API method. -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} eleventyConfig.setServerOptions({ // Default values are shown: @@ -76,20 +73,14 @@ module.exports = function (eleventyConfig) { // for on-request processing (read more below). onRequest: {}, }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %}
Expand to see the Full options list -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} eleventyConfig.setServerOptions({ - // Show the server version number on the command line - showVersion: false, - // Change the name of the folder name used for injected scripts injectedScriptsFolder: ".11ty", @@ -105,8 +96,8 @@ module.exports = function (eleventyConfig) { // Alias for backwards compatibility, renamed to `domDiff` in Dev Server 1.0+ domdiff: true, }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %}
@@ -128,10 +119,7 @@ Try out the [`devcert-cli`](https://github.com/davewasmer/devcert-cli) package t {% addedin "3.0.0-alpha.7" %}{% addedin "Dev Server 2.0.0" %} Use the new `onRequest` object to configure some of your project to use on-request-time processing. The keys in this object represent strings from the [URL Pattern API](https://developer.mozilla.org/en-US/docs/Web/API/URL_Pattern_API). -{% codetitle ".eleventy.js" %} - -```js -module.exports = function(eleventyConfig) { +{% set configCodeContent %} eleventyConfig.setServerOptions({ onRequest: { "/": function({ url }) { @@ -153,15 +141,12 @@ module.exports = function(eleventyConfig) { } } }); -} -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} Works great with the [`process.env.ELEVENTY_RUN_MODE` environment variable](/docs/environment-vars/#eleventy-supplied) to change how your server operates during`--serve` mode. -{% codetitle ".eleventy.js" %} - -```js -module.exports = function(eleventyConfig) { +{% set configCodeContent %} // Intercept all requests during --serve mode. if(process.env.ELEVENTY_RUN_MODE === "serve") { eleventyConfig.setServerOptions({ @@ -173,8 +158,8 @@ module.exports = function(eleventyConfig) { } }); } -} -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} ## Advanced `chokidar` options @@ -192,10 +177,7 @@ npm install @11ty/eleventy-server-browsersync Then, enable it in your configuration file: -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} eleventyConfig.setServerOptions({ module: "@11ty/eleventy-server-browsersync", @@ -209,8 +191,8 @@ module.exports = function (eleventyConfig) { // Opt-out of the Browsersync snippet // snippet: false, }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} View the [full list of Browsersync options](https://browsersync.io/docs/options). diff --git a/src/docs/events.md b/src/docs/events.md index 5ee103eb49..dd96b075e6 100644 --- a/src/docs/events.md +++ b/src/docs/events.md @@ -23,15 +23,14 @@ Asynchronous callback function support added in v1.0. The `eleventy.before` event runs every time Eleventy starts building, so it will run before the start of each stand-alone build, as well as each time building starts as either part of `--watch` or `--serve`. To use it, attach the event handler to your Eleventy config: -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // Async-friendly in 1.0+ // Arguments added in 2.0+ eleventyConfig.on("eleventy.before", async ({ dir, runMode, outputMode }) => { // Run me before the build starts }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} ## `eleventy.after` {% addedin "1.0.0" %} @@ -39,8 +38,7 @@ module.exports = function (eleventyConfig) { The `eleventy.after` event runs every time Eleventy finishes building, so it will run after the end of each stand-alone build, as well as each time building ends as either part of `--watch` or `--serve`. To use it, attach the event handler to your Eleventy config: -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // Async-friendly in 1.0+ // Arguments added in 2.0+ eleventyConfig.on( @@ -49,15 +47,14 @@ module.exports = function (eleventyConfig) { // Run me after the build ends } ); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} ## Event arguments {% addedin "2.0.0" %} Eleventy now provides an object with metadata on the build as an argument to the `eleventy.before` and `eleventy.after` event callbacks. -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} eleventyConfig.on("eleventy.before", async ({ dir, runMode, outputMode }) => { // Read more below }); @@ -68,8 +65,8 @@ module.exports = function (eleventyConfig) { // Read more below } ); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} - `dir`: an object with current project directories, set in [your configuration file](https://www.11ty.dev/docs/config/#input-directory) (or populated with Eleventy defaults). - `dir.input` (default `"."`) @@ -98,16 +95,15 @@ module.exports = function (eleventyConfig) { The `eleventy.beforeWatch` event runs before a build is run _only_ if it's a re-run during `--watch` or `--serve`. This means it will neither run during the initial build nor during stand-alone builds. To use it, attach the event handler to your Eleventy config: -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // Async-friendly in 1.0+ eleventyConfig.on("eleventy.beforeWatch", async (changedFiles) => { // Run me before --watch or --serve re-runs // changedFiles is an array of files that changed // to trigger the watch/serve build }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} The `changedFiles` parameter was {% addedin "0.11.1" %}. @@ -115,12 +111,11 @@ The `changedFiles` parameter was {% addedin "0.11.1" %}. This event facilitates the [i18n plugin](/docs/plugins/i18n/) (but is available independent of it). -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // Async-friendly eleventyConfig.on("eleventy.contentMap", async ({ inputPathToUrl, urlToInputPath }) => { // inputPathToUrl is an object mapping input file paths to output URLs // urlToInputPath is an object mapping output URLs to input file paths }); -}; -``` \ No newline at end of file +{% endset %} +{% include "snippets/configDefinition.njk" %} \ No newline at end of file diff --git a/src/docs/server-browsersync.md b/src/docs/server-browsersync.md index 5a82022d3f..3aed7f48ab 100644 --- a/src/docs/server-browsersync.md +++ b/src/docs/server-browsersync.md @@ -16,24 +16,20 @@ Starting with Eleventy 2.0, the [Eleventy Dev Server](/docs/dev-server/) is now Useful if you want to change or override the default Browsersync configuration. Find the Eleventy defaults in [`EleventyServe.js`](https://github.com/11ty/eleventy/blob/master/src/EleventyServe.js). Take special note that Eleventy does not use Browsersync’s watch options and trigger reloads manually after our own internal watch methods are complete. See full options list on the [Browsersync documentation](https://browsersync.io/docs/options). -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} eleventyConfig.setBrowserSyncConfig({ notify: true, }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} ### Opt-out of the Browsersync JavaScript snippet {% addedin "1.0.0" %} New in [`browser-sync@2.27.1`](https://github.com/BrowserSync/browser-sync/issues/1882#issuecomment-867767056) {% addedin "1.0.0" %}. Opt-out of the JavaScript snippet normally injected by Browsersync. This disables Browsersync live-reloading. -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} eleventyConfig.setBrowserSyncConfig({ snippet: false, }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} diff --git a/src/docs/server-vite.md b/src/docs/server-vite.md index c3535c1477..6776a62382 100644 --- a/src/docs/server-vite.md +++ b/src/docs/server-vite.md @@ -30,57 +30,14 @@ A plugin to use [Vite](https://vitejs.dev/) with Eleventy 2.0+. npm install @11ty/eleventy-plugin-vite ``` -```js -const EleventyVitePlugin = require("@11ty/eleventy-plugin-vite"); - -module.exports = function (eleventyConfig) { - eleventyConfig.addPlugin(EleventyVitePlugin); -}; -``` +{% include "snippets/serve/vite.njk" %}
Expand for full list of options View the [full list of Vite Configuration options](https://vitejs.dev/config/). -```js -const EleventyVitePlugin = require("@11ty/eleventy-plugin-vite"); - -module.exports = function (eleventyConfig) { - eleventyConfig.addPlugin(EleventyVitePlugin, { - tempFolderName: ".11ty-vite", // Default name of the temp folder - - // Options passed to the Eleventy Dev Server - // e.g. domdiff, enabled, etc. - - // Added in Vite plugin v2.0.0 - serverOptions: {}, - - // Defaults are shown: - viteOptions: { - clearScreen: false, - appType: "mpa", // New in v2.0.0 - - server: { - mode: "development", - middlewareMode: true, - }, - - build: { - mode: "production", - }, - - // New in v2.0.0 - resolve: { - alias: { - // Allow references to `node_modules` folder directly - "/node_modules": path.resolve(".", "node_modules"), - }, - }, - }, - }); -}; -``` +{% include "snippets/serve/vite-options.njk" %} See the full list of [`serverOptions` on the Dev Server documentation](/docs/dev-server/). diff --git a/src/docs/shortcodes.md b/src/docs/shortcodes.md index 56e0af05e0..7563692972 100644 --- a/src/docs/shortcodes.md +++ b/src/docs/shortcodes.md @@ -10,7 +10,6 @@ tags: - related-custom-tags - related-nunjucks - related-liquid - - related-handlebars - related-javascript --- @@ -18,70 +17,13 @@ tags: {% tableofcontents %} -Various template engines can be extended with shortcodes for easy reusable content. This is sugar around Template Language [Custom Tags](/docs/custom-tags/). Shortcodes are supported in JavaScript, Liquid, Nunjucks, and Handlebars templates. +Various template engines can be extended with shortcodes for easy reusable content. This is sugar around Template Language [Custom Tags](/docs/custom-tags/). Shortcodes are supported in JavaScript, Liquid, Nunjucks templates. Here are a few examples: - - - {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "shortcode", additions: "hbs"} %} -
- {% codetitle "sample.liquid" %} -{%- highlight "liquid" %}{% raw %} -{% user firstName, lastName %} -{% endraw %}{% endhighlight %} -

The comma between arguments is optional in Liquid templates.

- {% codetitle "sample.liquid" %} -{%- highlight "liquid" %}{% raw %} -{% user firstName lastName %} -{% endraw %}{% endhighlight %} -
-
- {% codetitle "sample.njk" %} -{%- highlight "jinja2" %}{% raw %} -{% user firstName, lastName %} -{% endraw %}{% endhighlight %} -

The comma between arguments is required in Nunjucks templates.

-
-
- {% codetitle "sample.11ty.js" %} -{%- highlight "js" %}{% raw %} -module.exports = function({ firstName, lastName }) { - return `

${this.user(firstName, lastName)}

`; -}; -{% endraw %}{% endhighlight %} -
-
- {% codetitle "sample.hbs" %} -{%- highlight "handlebars" %}{% raw %} - -{{{ user firstName lastName }}} -{% endraw %}{%- endhighlight %} - {% callout "info" %}Note that if you return HTML in your Handlebars shortcode, you need to use the Handlebars triple-stash syntax (three opening and three closing curly brackets, e.g. {% raw %}{{{ shortcodeName }}}{% endraw %}) to avoid double-escaped HTML. If it’s double-escaped a paragraph tag may render as <p>{% endcallout %} -
-
-
+{% include "snippets/shortcodes/intro.njk" %} -{% codetitle ".eleventy.js" %} - -```js -module.exports = function(eleventyConfig) { - // Shortcodes added in this way are available in: - // * Markdown - // * Liquid - // * Nunjucks - // * Handlebars (not async) - // * JavaScript - - eleventyConfig.addShortcode("user", function(firstName, lastName) { … }); - - // Async support for `addShortcode` is new in Eleventy {{ "2.0.0-canary.24" | coerceVersion }} - eleventyConfig.addShortcode("user", async function(myName) { /* … */ }); - - // Async method available - eleventyConfig.addAsyncShortcode("user", async function(myName) { /* … */ }); -}; -``` +{% include "snippets/shortcodes/config.njk" %} A shortcode returns content (a JavaScript string or template literal) that is used in the template. You can use these however you’d like—you could even think of them as reusable components. @@ -94,109 +36,16 @@ Read more about using shortcodes on the individual Template Language documentati - [JavaScript `*.11ty.js`](/docs/languages/javascript/#javascript-template-functions) (with async support) - [Liquid `*.liquid`](/docs/languages/liquid/#shortcodes) (with async support) - [Nunjucks `*.njk`](/docs/languages/nunjucks/#shortcodes) (with async support) -- [Handlebars `*.hbs`](/docs/languages/handlebars/#shortcodes) (no async support) ## Paired Shortcodes The shortcodes we saw above were nice, I suppose. But really, they are not all that different from a filter. The real ultimate power of Shortcodes comes when they are paired. Paired Shortcodes have a start and end tag—and allow you to nest other template content inside! - - - {% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "pairedshortcodes", additions: "hbs"} %} -
- -{% codetitle "Liquid", "Syntax" %} - -{% raw %} - -```liquid -{% user firstName, lastName %} - Hello {{ someOtherVariable }}. - - Hello {% anotherShortcode %}. -{% enduser %} -``` - -{% endraw %} - -The comma between arguments is **optional** in Liquid templates. - -
-
- -{% codetitle "Nunjucks", "Syntax" %} - -{% raw %} - -```jinja2 -{% user firstName, lastName %} - Hello {{ someOtherVariable }}. - - Hello {% anotherShortcode %}. -{% enduser %} -``` - -{% endraw %} - -The comma between arguments is **required** in Nunjucks. - -
-
- -{% codetitle "Handlebars", "Syntax" %} - -{% raw %} - -```handlebars -{{#user firstName lastName}} - Hello - {{someOtherVariable}}. Hello - {{anotherShortcode}}. -{{/user}} -``` - -{% endraw %} - -
-
- -```js -module.exports = function (data) { - let userContent = `Hello ${data.someOtherVariable} - -Hello ${this.anotherShortCode()}`; - - // pass the content as the first parameter. - return `

${this.user(userContent, data.firstName, data.lastName)}

`; -}; -``` - -
-
-
+{% include "snippets/shortcodes/paired.njk" %} When adding paired shortcodes using the Configuration API, the first argument to your shortcode callback is the nested content. -{% codetitle ".eleventy.js" %} - -```js -module.exports = function(eleventyConfig) { - // Shortcodes added in this way are available in: - // * Markdown - // * Liquid - // * Nunjucks - // * Handlebars (not async) - // * JavaScript - - eleventyConfig.addPairedShortcode("user", function(content, firstName, lastName) { … }); - - // Async support for `addPairedShortcode` is new in Eleventy {{ "2.0.0-canary.24" | coerceVersion }} - eleventyConfig.addPairedShortcode("user", async function(content, myName) { /* … */ }); - - // Async method available - eleventyConfig.addPairedAsyncShortcode("user", async function(content, myName) { /* … */ }); -}; -``` +{% include "snippets/shortcodes/config-paired.njk" %} {% callout "info" %} Markdown files are pre-processed as Liquid templates by default—any shortcodes available in Liquid templates are also available in Markdown files. Likewise, if you change the template engine for Markdown files, the shortcodes available for that templating language will also be available in Markdown files. @@ -207,36 +56,10 @@ Read more about using paired shortcodes on the individual Template Language docu - [JavaScript `*.11ty.js`](/docs/languages/javascript/#javascript-template-functions) (with async support) - [Liquid `*.liquid`](/docs/languages/liquid/#shortcodes) (with async support) - [Nunjucks `*.njk`](/docs/languages/nunjucks/#shortcodes) (with async support) -- [Handlebars `*.hbs`](/docs/languages/handlebars/#shortcodes) (no async support) ## Asynchronous Shortcodes -This is supported by Liquid, Nunjucks, and JavaScript template types (Handlebars is not async-friendly). - -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { - // Async support for `addShortcode` and `addPairedShortcode` is new in Eleventy {{ "2.0.0-canary.24" | coerceVersion }} - eleventyConfig.addShortcode("single", async function (myName) { - /* … */ - }); - eleventyConfig.addPairedShortcode("paired", async function (content, myName) { - /* … */ - }); - - // Async methods available in Eleventy v0.10.0+ - eleventyConfig.addAsyncShortcode("single", async function (myName) { - /* … */ - }); - eleventyConfig.addPairedAsyncShortcode( - "paired", - async function (content, myName) { - /* … */ - } - ); -}; -``` +`addShortcode`, `addPairedShortcode` both accept `async` function callbacks as of Eleventy `{{ "2.0.0-canary.24" | coerceVersion }}`. `addAsyncShortcode` and `addPairedAsyncShortcode` also accept `async` function callbacks and have been available since Eleventy `v0.10.0`. ## Scoped Data in Shortcodes @@ -245,42 +68,13 @@ A few Eleventy-specific data properties are available to shortcode callbacks. - `this.page` {% addedin "0.11.0" %} - `this.eleventy` {% addedin "2.0.0-canary.5" %} -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { - // Make sure you’re not using an arrow function here: () => {} - eleventyConfig.addShortcode("myShortcode", function () { - // this.page - // this.eleventy - }); -}; -``` +{% include "snippets/shortcodes/scoped.njk" %} ## Per-Engine Shortcodes You can also specify different functionality for shortcodes in each engine, if you’d like. Using the `addShortcode` or `addPairedShortcode` function is equivalent to adding the shortcode to every supported template engine. -{% codetitle ".eleventy.js" %} - -```js -module.exports = function(eleventyConfig) { - // Liquid - eleventyConfig.addLiquidShortcode("user", function(firstName, lastName) {}); - eleventyConfig.addPairedLiquidShortcode("user", function(content, firstName, lastName) {}); - - // Nunjucks - eleventyConfig.addNunjucksShortcode("user", function(firstName, lastName) {}); - eleventyConfig.addPairedNunjucksShortcode("user", function(content, firstName, lastName) {}); - - // Handlebars - eleventyConfig.addHandlebarsShortcode("user", function(firstName, lastName) {}); - eleventyConfig.addPairedHandlebarsShortcode("user", function(content, firstName, lastName) {}); - - // JavaScript Template Function (New in 0.7.0) - eleventyConfig.addJavaScriptFunction("user", function(firstName, lastName) {}); - eleventyConfig.addJavaScriptFunction("user", function(content, firstName, lastName) {}); // Faux-paired shortcode -``` +{% include "snippets/shortcodes/perengine.njk" %} {% callout "info" %} Markdown files are pre-processed as Liquid templates by default—any shortcodes available in Liquid templates are also available in Markdown files. Likewise, if you change the template engine for Markdown files, the shortcodes available for that templating language will also be available in Markdown files. @@ -290,20 +84,4 @@ Markdown files are pre-processed as Liquid templates by default—any shortcodes Learn more about these on the individual template engine pages for [Nunjucks](/docs/languages/nunjucks/#asynchronous-shortcodes), [Liquid](/docs/languages/liquid/#asynchronous-shortcodes), and [`11ty.js` JavaScript](/docs/languages/javascript/#asynchronous-javascript-template-functions). -{% codetitle ".eleventy.js" %} - -```js - // Async-friendly - // Liquid is already async-friendly - eleventyConfig.addLiquidShortcode("user", async function() {}); - eleventyConfig.addPairedLiquidShortcode("user", async function(content) {}); - - // Nunjucks Async - eleventyConfig.addNunjucksAsyncShortcode("user", async function() {}); - eleventyConfig.addPairedNunjucksAsyncShortcode("user", async function(content) {}); - - // JavaScript Template Function (make sure you `await` these!) - eleventyConfig.addJavaScriptFunction("user", async function() {}); - eleventyConfig.addJavaScriptFunction("user", async function(content) {}); // Faux-paired shortcode -}; -``` +{% include "snippets/shortcodes/perengine-async.njk" %} \ No newline at end of file diff --git a/src/docs/transforms.md b/src/docs/transforms.md index 022f7fb5c1..bc1c22b6b4 100644 --- a/src/docs/transforms.md +++ b/src/docs/transforms.md @@ -11,10 +11,7 @@ Transforms can modify a template’s output. For example, use a transform to for {% callout "info", "md" %}The provided transform function **must** return the original or transformed content.{% endcallout %} -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // Can be sync or async eleventyConfig.addTransform("transform-name", async function (content) { console.log(this.page.inputPath); @@ -22,8 +19,8 @@ module.exports = function (eleventyConfig) { return content; // no changes made. }); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} Access to [Eleventy’s `page` variable](/docs/data-eleventy-supplied/#page-variable) (via `this.page`) was added in Eleventy v2.0. For previous versions, [consult the older versions of the docs](https://v1-0-2.11ty.dev/docs/config/#transforms). @@ -57,27 +54,6 @@ eleventyConfig.addTransform("second", () => {}); ### Minify HTML Output -{% codetitle ".eleventy.js" %} - -```js -const htmlmin = require("html-minifier-terser"); - -module.exports = function (eleventyConfig) { - eleventyConfig.addTransform("htmlmin", function (content) { - if ((this.page.outputPath || "").endsWith(".html")) { - let minified = htmlmin.minify(content, { - useShortDoctype: true, - removeComments: true, - collapseWhitespace: true, - }); - - return minified; - } - - // If not an HTML output, return content as-is - return content; - }); -}; -``` +{% include "snippets/config/transforms.njk" %} Note that `html-minifier-terser` has a [significant number of options](https://github.com/terser/html-minifier-terser?tab=readme-ov-file#options-quick-reference), most of which are disabled by default. diff --git a/src/docs/watch-serve.md b/src/docs/watch-serve.md index 06c6aacdca..d94b414951 100644 --- a/src/docs/watch-serve.md +++ b/src/docs/watch-serve.md @@ -20,13 +20,10 @@ Starting in Eleventy v2.0, we bundle a [dedicated Development Server](/docs/dev- The `addWatchTarget` config method allows you to manually add a file or directory for Eleventy to watch. When the file or the files in this directory change Eleventy will trigger a build. This is useful if Eleventy is not directly aware of any external file dependencies. -{% codetitle ".eleventy.js" %} - -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} eleventyConfig.addWatchTarget("./src/scss/"); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} **Advanced usage note:** This works with [`chokidar` under the hood](https://github.com/paulmillr/chokidar#api) and chokidar uses [`picomatch` for globbing](https://github.com/micromatch/picomatch): @@ -44,55 +41,47 @@ Previously, [the configuration API ignores for template processing](/docs/ignore New in {{ "2.0.0-canary.18" | coerceVersion }}, watch target ignores now have their own dedicated API: -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // Do not rebuild when README.md changes (You can use a glob here too) eleventyConfig.watchIgnores.add("README.md"); // Or delete entries too eleventyConfig.watchIgnores.delete("README.md"); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} The `watchIgnores` Set starts with a default `**/node_modules/**` entry. ## Watch JavaScript Dependencies {% addedin "0.7.0" %} -When in `--watch` mode, Eleventy will spider the dependencies of your [JavaScript Templates](/docs/languages/javascript/) (`.11ty.js`), [JavaScript Data Files](/docs/data-js/) (`.11tydata.js` or `_data/**/*.js`), or Configuration File (usually `.eleventy.js`) to watch those files too. Files in `node_modules` directories are ignored. This feature is _enabled by default_. - -{% codetitle ".eleventy.js" %} +When in `--watch` mode, Eleventy will spider the dependencies of your [JavaScript Templates](/docs/languages/javascript/) (`.11ty.js`), [JavaScript Data Files](/docs/data-js/) (`.11tydata.js` or `_data/**/*.js`), or Configuration File (usually `eleventy.config.js`) to watch those files too. Files in `node_modules` directories are ignored. This feature is _enabled by default_. -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // Enabled by default eleventyConfig.setWatchJavaScriptDependencies(false); -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} ## Add delay before re-running {% addedin "0.11.0" %} A hardcoded amount of time Eleventy will wait before triggering a new build when files have changes during `--watch` or `--serve` modes. You probably won’t need this, but is useful in some edge cases with other task runners (Gulp, Grunt, etc). -```js -module.exports = function (eleventyConfig) { +{% set configCodeContent %} // default is 0 eleventyConfig.setWatchThrottleWaitTime(100); // in milliseconds -}; -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} ## Advanced `chokidar` Configuration Advanced [`chokidar` options](https://github.com/paulmillr/chokidar) can be defined using the `setChokidarConfig` configuration API method: -{% codetitle ".eleventy.js" %} - -```js -module.exports = function(eleventyConfig) { +{% set configCodeContent %} eleventyConfig.setChokidarConfig({ usePolling: true, interval: 500, }); -} -``` +{% endset %} +{% include "snippets/configDefinition.njk" %} {% callout "warn", "md" %}If you’re using [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/) and your project exists _outside_ of your home directory (`~`), you will likely want to use the `usePolling` feature to ensure watching works correctly. This is a WSL limitation.{% endcallout %}