Adminator-admin-dashboard Documentation

Adminator is easy to use and well design admin dashboard template with dark mode for web apps, websites, services and more

RAW Doc

1. Project Overview & Quickstart (puikinsh/Adminator-admin-dashboard)

File: docs/api/theme-api.md


This page has moved to https://adminator.colorlib.com/docs/theming/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/customization/components.md


This page has moved to https://adminator.colorlib.com/docs/architecture/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/customization/library-integrations.md


This page has moved to https://adminator.colorlib.com/docs/charts/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/customization/theme-system.md


This page has moved to https://adminator.colorlib.com/docs/theming/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/examples/theme-integration.md


This page has moved to https://adminator.colorlib.com/docs/theming/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/getting-started/build-deployment.md


This page has moved to https://adminator.colorlib.com/docs/deployment/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/getting-started/development.md


This page has moved to https://adminator.colorlib.com/docs/getting-started/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/getting-started/installation.md


This page has moved to https://adminator.colorlib.com/docs/getting-started/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.


File: docs/getting-started/project-structure.md


This page has moved to https://adminator.colorlib.com/docs/architecture/.

You'll be redirected automatically. If the browser doesn't redirect, click the link above.

The full Adminator documentation now lives at adminator.colorlib.com/docs/.

2. Official Technical Reference & Guides (puikinsh/docs)

File: README.md

11ty.dev πŸ•šβš‘οΈπŸŽˆπŸ€

The website and documentation for the Eleventy static site generator.

Running Locally

text
npm install
npm run get-new-data
npx @11ty/eleventy --serve

Browse to http://localhost:8080/ (8080 is the default but it’ll bump to a new port if that one is taken, so use whatever port shows up when you run the --serve command).

  • Refresh Supporters: npm run get-new-supporters

File: src/_data/plugins/readme.md

Eleventy Community Plugins

If you would like to add a plugin to this list, create a PR adding a JSON file with the plugins name as the filename and the following content:

json
{
	"npm": "the npm package name of your plugin",
	"author": "Your Twitter username",
	"description": "A description of the plugin"
}

File: src/docs/filters/collection-items.md


eleventyNavigation: parent: Filters key: Next or Previous Collection Item Filters title: "`get*CollectionItem`" order: 4 excerpt: "Get next or previous collection items for easy linking."

Get Next or Previous Collection Item Universal Filters

{% tableofcontents %}

`getPreviousCollectionItem` and `getNextCollectionItem` {% addedin "0.11.0" %}

Fetch the previous and next items in a collection when you pass in the current page object.

{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "nextprev"} %}
liquid
{% raw %}{% assign previousPost = collections.posts | getPreviousCollectionItem: page %}
{% assign nextPost = collections.posts | getNextCollectionItem: page %}{% endraw %}


{% raw %}{% assign previousPost = collections.posts | getPreviousCollectionItem %}
{% assign nextPost = collections.posts | getNextCollectionItem %}{% endraw %}
jinja2
{% raw %}{% set previousPost = collections.posts | getPreviousCollectionItem(page) %}
{% set nextPost = collections.posts | getNextCollectionItem(page) %}{% endraw %}


{% raw %}{% set previousPost = collections.posts | getPreviousCollectionItem %}
{% set nextPost = collections.posts | getNextCollectionItem %}{% endraw %}
text
*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*


*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*

Useful when you’d like to link to the previous or next template in your collection:

{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "nextprevlink"} %}

{% raw %}

liquid
{% if previousPost %}Previous Blog Post: [{{ previousPost.data.title }}]({{ previousPost.url }}){% endif %}
{% if nextPost %}Next Blog Post: [{{ nextPost.data.title }}]({{ nextPost.url }}){% endif %}

{% endraw %}

{% raw %}

jinja2
{% if previousPost %}Previous Blog Post: [{{ previousPost.data.title }}]({{ previousPost.url }}){% endif %}
{% if nextPost %}Next Blog Post: [{{ nextPost.data.title }}]({{ nextPost.url }}){% endif %}

{% endraw %}

text
*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*


*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*

The Collections documentation outlines the default sorting algorithm and how to override it.

`getCollectionItemIndex` {% addedin "2.0.0-canary.19" %}

The getCollectionItemIndex filter returns the 0-based numeric index of the current (or passed) page in the collection.

{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "getitemindex"} %}

{% raw %}

liquid
{% assign index = collections.posts | getCollectionItemIndex %}

Or pass it in:
{% assign index = collections.posts | getCollectionItemIndex: page %}

{% endraw %}

{% raw %}

jinja2
{% set index = collections.posts | getCollectionItemIndex %}

Or pass it in:
{% set index = collections.posts | getCollectionItemIndex(page) %}

{% endraw %}

text
*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*


*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*

`getCollectionItem`

For completeness, a getCollectionItem filter is also included that fetches the current page from a collection.

{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "getitem"} %}
liquid
{% raw %}{% assign currentPost = collections.posts | getCollectionItem: page %}{% endraw %}


{% raw %}{% assign currentPost = collections.posts | getCollectionItem %}{% endraw %}
jinja2
{% raw %}{% set currentPost = collections.posts | getCollectionItem(page) %}{% endraw %}


{% raw %}{% set currentPost = collections.posts | getCollectionItem %}{% endraw %}
text
*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*


*This example has not yet been addedβ€”you can swap to another template language above! Or maybe you want to contribute it? {% include "edit-on-github.njk" %}*

File: src/docs/filters/inputpath-to-url.md


eleventyNavigation: parent: Filters key: inputPathToUrl Filter title: "`inputPathToUrl`" order: 4 excerpt: "Map a template’s input path to its output URL."

`inputPathToUrl` Universal Filter

{% addedin "v3.0.0-alpha.5" %} Map a file’s location and to the template’s output URL. Very useful for robust hyperlinking allowing you to change your output URLs without breaking content links! Eleventy 3.0 memoizes this filter.

{% callout "info", "md" -%}
This filter is an alternative to the InputPath To Url Plugin, which provides an Eleventy transform that is less verbose but a bit slower.
{%- endcallout %}

Inspired by GitHub issue #84.

Usage

{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "inputpathtourl"} %}

{% raw %}

liquid
[Home]({{ )

{% endraw %}

{% raw %}

jinja2
[Home]({{ )

{% endraw %}

{% raw %}

js
export default function (data) {
	return `[Home](${this.inputPathToUrl()`;
}

{% endraw %}

{% raw %}

js
module.exports = function (data) {
	return `[Home](${this.inputPathToUrl()`;
};

{% endraw %}

Renders as [Home](/).

  • The paths used here should be relative to the input directory though they can be relative to the project root (the former is simpler and more robust).
  • If an inputPath match can not be found, this filter will throw an error.
  • When pointing to a Pagination template, the first URL in the pagination set is returned.

← Back to Filters documentation.


File: src/docs/filters/log.md


eleventyNavigation: parent: Filters key: log Filter title: "`log`" order: 3 excerpt: "`console.log` inside templates."

`log` Universal Filter

{% addedin "0.11.0" %} An easy way to console.log anything from inside of a template file.

{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "log"} %}

{% raw %}

liquid
{{ "My Title" | log }}

{% endraw %}

{% raw %}

jinja2
{{ "My Title" | log }}

{% endraw %}

{% raw %}

js
export default function (data) {
	// Caveat: you have access to `console.log` here, so probably use that.
	return this.log("My Title");
};

{% endraw %}

{% raw %}

js
module.exports = function (data) {
	// Caveat: you have access to `console.log` here, so probably use that.
	return this.log("My Title");
};

{% endraw %}

is functionally the same as running console.log("My Title") inside of your template.

Using `log` in filter chains {% addedin "2.0.0-canary.13"%}

You can drop log in between any filter chain you already have and it will log the incoming data and pass it through to the next filter.

{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: "log-chain-demo", subtractions: "js,cjs,hbs"} %}

{% codetitle "Liquid", "Syntax" %}

{% raw %}

liquid
{{ "My Title" | log | upcase }}

This is the same as:
{% assign temp = "My Title" %}
{{ temp | log }}
{{ temp | upcase }}

{% endraw %}

{% codetitle "Nunjucks", "Syntax" %}

{% raw %}

jinja2
{{ "My Title" | log | upper }}

This is the same as:
{% set temp = "My Title" %}
{{ temp | log }}
{{ temp | upper }}

{% endraw %}


← Back to Filters documentation.


File: src/docs/filters/render-transforms.md


eleventyNavigation: parent: Filters key: renderTransforms Filter title: "`renderTransforms`" excerpt: "Render project transforms on an arbitrary block of content." excludeFromSidebar: true

`renderTransforms` Universal Filter

{% addedin "v3.0.0-alpha.11" %}It’s unlikely you’ll need to use this filter!

Transforms are applied for you automatically as part of Eleventy’s pipeline. However, (as an example) transforms limited to html files are not applied in other contexts (e.g. an RSS .xml, Atom .xml, or JSON feed .json).

The renderTransforms filter is used in the RSS plugin (v2.0 or newer). You can find sample usage of this filter on the RSS plugin feed examples.

More background at GitHub issue #3294.


← Back to Filters documentation.


File: src/docs/filters/slug.md


eleventyNavigation: parent: Filters key: slug Filter title: "`slug`" order: 2.1 excerpt: 'Similar to but deprecated in favor of `slugify`' excludeFromSidebar: true

`slug` Universal Filter

{% callout "warn", "md" %}Starting in Eleventy v1.0.0 it is recommended to use the slugify Universal Filter instead of slug. For backwards compatibility, slug is still included and supported but slugify has better default behavior for URLs with special characters. If you want to swap slug to slugify wholesale in old projects, please read this warning about breaking URLs. Be careful!{% endcallout %}

Uses the slugify npm package to convert a string into a URL slug. Can be used in pagination or permalinks.

{% codetitle "slug.md" %}
{% raw %}

yaml
---
title: "My Title"
permalink: "/{{ title | slug }}/"
---
Outputs to `/my-title/`.

{% endraw %}


File: src/docs/filters/slugify.md


`slugify` Universal Filter {% addedin "1.0.0" %}

Uses the @sindresorhus/slugify npm package to convert a string into a URL slug. Typically used with permalinks. Eleventy 3.0 memoizes this filter.

{% codetitle "slugify.md" %}
{% raw %}

yaml
---
title: "My Title"
permalink: "/{{ title | slugify }}/"
---
Outputs to `/my-title/`.

{% endraw %}

{% callout "info", "md" %}In versions prior to 1.0.0, the slug Universal Filter was used. To maintain backwards compatibility moving forward, slug is still included and supported but slugify is now recommended as best practiceβ€”it has better default behavior for URLs with special characters.{% endcallout %}

{% callout "warn", "md" %}slugify currently ignores characters for Japanese, Chinese, and others. If you need to slugify these characters, add your own universal filter with an alternative library like limax or transliteration. (More context at Issue #2537){% endcallout %}

Changing `slug` to `slugify`

If you’re trying to migrate the content in a pre-1.0 project from using the slug filter to the (new in v1.0) slugify filter (note: this is optionalβ€”you can leave them as-is!), you must take extra care to make sure that any existing URLs don’t change.

The Upgrade Helper plugin will compare the slug and slugify versions of your URLs to see if there are any that require extra attention (thank you to Peter deHaan for the assist here!).


File: src/docs/filters/url.md


eleventyNavigation: parent: Filters key: url Filter title: "`url`" order: 1 excerpt: Normalize absolute paths in your content, allows easily changing deploy subdirectories for your project.

`url` Universal Filter

{% callout "info", "md" %}If you need to deploy your site to a subfolder, it’s recommended to use the simpler [HTML `` plugin](/docs/plugins/html-base/) {% addedin "2.0.0-canary.15" %} with pathPrefix instead of having to litter the url filter throughout your content moving forward!{% endcallout %}

Works with the pathPrefix configuration option to properly normalize absolute paths in your content with the pathPrefix added. Useful if you host your site on GitHub Pages, which normally live in a subdirectory, e.g. https://11ty.github.io/eleventy-base-blog/. We set pathPrefix: "/eleventy-base-blog/" and our absolute links all have this prepended to the beginning.

Note that if you don’t need pathPrefix (or don’t ever plan on moving your site’s top-level directory structure), you probably don’t need to use the url filter.

{% raw %}

html
[Liquid or Nunjucks Link (from string)]({{ )
[Liquid or Nunjucks Link (from variable)]({{ post.url | url }})

{% endraw %}

Sample URL Transformations

Sample URL pathPrefix Return value
'' '/' '.' ⚠️ This style is probably not what you wantβ€”careful!
'/' '/' '/'
'./' '/' './'
'..' '/' '..'
'myDir' '/' 'myDir' ⚠️ This style is not safe for globally linking to other content. Be careful!
'/myDir/' '/' '/myDir/'
'./myDir/' '/' 'myDir/' ⚠️ This style is not safe for globally linking to other content. Be careful!
'../myDir/' '/' '../myDir/'
Sample URL pathPrefix Return value
'' '/rootDir/' '.' ⚠️ This style is probably not what you wantβ€”careful!
'/' '/rootDir/' '/rootDir/'
'./' '/rootDir/' './'
'..' '/rootDir/' '..'
'myDir' '/rootDir/' 'myDir' ⚠️ This style is probably not what you wantβ€”careful!
'/myDir/' '/rootDir/' '/rootDir/myDir/'
'./myDir/' '/rootDir/' 'myDir/' ⚠️ This style is probably not what you wantβ€”careful!
'../myDir/' '/rootDir/' '../myDir/'

File: src/docs/languages/custom.md


eleventyNavigation: parent: Template Languages key: Custom pinned: true order: 4 excerpt: Use your own template language relatedKey: customlang relatedTitle: Template Languageβ€”Custom layout: layouts/langs.njk

{% tableofcontents "open" %}

Eleventy Short Name File Extension npm Package
(Any) .* (Any) (Any)

Eleventy now allows the addition of custom template extensions, meaning that you can use Eleventy to process any arbitrary file extension and compile it to your site’s output folder. This feature is {% addedin "1.0.0" %}.

Introductory Example: `*.clowd`

clowd is a pretend templating language that we’ve just created. It uses the .clowd file extension. The purpose of the language is to translate any occurrences of the word cloud to the word butt instead.

{% set codeContent %}
export default function (eleventyConfig) {
// Add as a valid extension to process
// Alternatively, add this to the list of formats you pass to the --formats CLI argument
eleventyConfig.addTemplateFormats("clowd");

text
// "clowd" here means that the extension will apply to any .clowd file
eleventyConfig.addExtension("clowd", {
	compile: async (inputContent) => {
		// Replace any instances of cloud with butt
		let output = inputContent.replace(/cloud/gi, "butt");

		return async () => {
			return output;
		};
	},
});

};
{% endset %}
{% include "snippets/configDefinition.njk" %}

{% callout "info", "md-block" -%}
Situations where you might want to use addExtension but probably shouldn’t:

  1. If you want to post-process the content of an existing template language (a file extension already processed by Eleventy), use a Configuration API Transform instead.
  2. If you want to pre-process md or html files using another template language, change the Default Template Engine for Markdown Files or HTML Files, respectively. This can also be done on a per-template basis. We will likely add additional hooks for preprocessing in the future.
    {%- endcallout %}

Example: Add Sass support to Eleventy

For a more realistic sample, here’s an example of Eleventy looking for all .scss files in a project’s input directory to process them to your output directory.

{% set codeContent %}
// Don’t forget to npm install sass!
import * as sass from "sass";

export default function (eleventyConfig) {
eleventyConfig.addTemplateFormats("scss");

text
// Creates the extension for use
eleventyConfig.addExtension("scss", {
	outputFileExtension: "css", // optional, default: "html"

	// `compile` is called once per .scss file in the input directory
	compile: async function (inputContent) {
		let result = sass.compileString(inputContent);

		// This is the render function, `data` is the full data cascade
		return async (data) => {
			return result.css;
		};
	},
});

};
{% endset %}
{% include "snippets/configDefinition.njk" %}

We’re using compileString from the Sass library above for speed benefits over their asynchronous counterparts (reported by the Sass documentation).

Note also that the data is not used in the above example. This is the full Eleventy data cascade and may be more useful in other templating languages.

The above extension would process a file located at subdir/test.scss to the output directory at _site/subdir/test.css.

Using `inputPath`

You can pass in both the file’s inputPath and the Eleventy includes folder to provide a set of directories to look for when using Sass’ @use, @forward, and @import features. Read more about loadPaths on the Sass documentation.

{% codetitle "eleventy.config.js" %}

diff-js
// some configuration omitted…
+compile: function (inputContent, inputPath) {
+	let { dir } = path.parse(inputPath);

let result = sass.compileString(inputContent, {
+		loadPaths: [
+			dir || ".",
+			this.config.dir.includes
+		]
	});

	return (data) => {
		return result.css;
	};
}
// …

Make special note of the this.config.dir.includes folder above. Declaring your includes folder means that you don’t need to prefix any file paths with the includes folder name (e.g. _includes/_code.scss can be consumed with @use "code").

Registering Dependencies {% addedin "2.0.0-canary.19" %}

Eleventy includes two features to improve the performance of custom template compilation:

  1. A compilation cache, which you can optionally disable with compileOptions.cache
  2. Hooks for incremental builds (via the --incremental command line flag)

To facilitate these features, if a template syntax allows use of other templates (think @use in Sass or webc:import in WebC), Eleventy needs to know about the dependencies a template file relies on. This is heavily dependent on each template compiler.

In our Sass example, this is exposed by Sass via the loadedUrls property from the compileString function, and you can see an example of how we register our dependencies in the compile method below:

diff-js
// some configuration omitted…
compile: function (inputContent, inputPath) {
	let result = sass.compileString(inputContent);

+	this.addDependencies(inputPath, result.loadedUrls);

	return async (data) => {
		return result.css;
	};
}
// …

addDependencies’s first parameter is the parent template file path. The second parameter is an Array of child file paths used by the template. The dependencies can be either relative or absolute paths and we will normalize them as needed.

Skipping a template from inside of the `compile` function

To add support for Sass’ underscore convention (file names that start with an underscore aren’t written to the output directory), just return early in the compile function (don’t return a render function).

diff-js
// some configuration omitted…
compile: async function (inputContent, inputPath) {
	let parsed = path.parse(inputPath);
+	if(parsed.name.startsWith("_")) {
+		return;
+	}

	let result = sass.compileString(inputContent);

	return async (data) => {
		return result.css;
	};
}
// …

Note that files inside of the _includes folder are left out of processing by default, so if you store your sass @use, @forward, and @import files in there you’ll get this for free (see the Using inputPath example above)!

This functionality is more-or-less identical to the compileOptions permalink: false overrides, documented later on this page.

Aliasing an Existing Template Language

{% addedin "2.0.0-canary.19" %} If key is the only property in the options object, we treat the extension as an alias and use the existing upstream template syntax.

{% set codeContent %}
export default function (eleventyConfig) {
eleventyConfig.addExtension("11ty.jsx", {
key: "11ty.js",
});

text
// Or, you can pass an array of extensions in {{ "2.0.0-canary.19" | coerceVersion }} or newer.
eleventyConfig.addExtension(["11ty.jsx", "11ty.ts", "11ty.tsx"], {
	key: "11ty.js",
});

};
{% endset %}
{% include "snippets/configDefinition.njk" %}

You can read about the above approach (and see more detailed examples of its usage) on the TypeScript, JSX, or MDX documentation pages.

{% addedin "3.0.0-alpha.11" %} key needn’t be the only property in the options object. If you want to add your own compile function, keep reading!

{% addedin "3.0.0-alpha.11" %} Breaking Change: Starting in Eleventy 3.0 you must add the new alias to your declared template formats for the new template type to be processed.

Overriding or Extending an Existing Template Language

You can override or extend existing template languages too! (Thank you to Ben Holmes for this contribution).

In these example, we switch from the Eleventy default markdown-it to marked for markdown processing.

{% set codeContent %}
import { marked } from "marked";

export default function (eleventyConfig) {
eleventyConfig.addExtension("md", {
compile: function (inputContent, inputPath) {
let html = marked.parse(inputContent);

text
return function (data) {
			// Example: use `marked` only if useMarked is set in the Data Cascade
			if (data.useMarked) {
				return html;
			}

			// You can also access the default `markdown-it` renderer here:
			return this.defaultRenderer(data);
		};
	},
});

};
{% endset %}
{% include "snippets/configDefinition.njk" %}

Note that overriding md opts-out of the default pre-processing by another template language Markdown Files. As mentioned elsewhere, improvements to add additional hooks for preprocessing will likely come later.

You can override a template language once. Any attempts to override an more than once via addExtension will throw an error.

{% addedin "3.0.0-alpha.11" %} Adding key in the options object unlocks use of the target defaultRenderer. You can read about this approach (and see examples of its usage) on the TypeScript, JSX, or MDX documentation pages (all of which use key: "11ty.js" to extend JavaScript templates).

Access to Existing Filters and Shortcodes

If you want to add support for universal filters and shortcodes in your custom template language, you can do so with the following configuration API methods. Related GitHub #3310.

  • eleventyConfig.getFilter(name) {% addedin "0.10.0" %}
  • eleventyConfig.getFilters() {% addedin "3.0.0-alpha.15" %}
  • eleventyConfig.getShortcode(name) {% addedin "3.0.0-alpha.15" %}
  • eleventyConfig.getShortcodes() {% addedin "3.0.0-alpha.15" %}
  • eleventyConfig.getPairedShortcode(name) {% addedin "3.0.0-alpha.15" %}
  • eleventyConfig.getPairedShortcodes() {% addedin "3.0.0-alpha.15" %}

Full Options List

`compile`

  • Required for new file extensions. Optional for aliases.

compile is an async-friendly function that takes two parameters:

  • inputContent: the full content of the file to parse (as a string).
  • inputPath: the path to the file (as a string, useful for looking up relative imports)

compile can return:

  • nothing (undefined) to indicate that the file should be ignored and not used as a page
  • a render function (also async-friendly)
js
// some configuration truncated …
	compile: async (inputContent, inputPath) => {
		return async () => {
			return inputContent;
		};
	},

The render function is passed the merged data object (i.e. the full Data Cascade available inside templates). The render function returned from compile is called once per output file generated (one for basic templates and more for paginated templates).

{% callout "info", "md" %}inputContent will not include front matter. This will have been parsed, removed, and inserted into the Data Cascade. Also note that if read: false (as documented below), inputContent will be undefined.{% endcallout %}

Advanced: Adding Eleventy’s Scoped Data to your Compile Function

Shortcodes and Filters both provide access to page and eleventy (via this.page and this.eleventy specifically). If you’d like to add the same for your custom template, you can do so via the augmentFunctionContext method.

js
compile: function(compileFn) {
		return function(data) {
			// Binds this.page and this.eleventy to your render context (and any future additions added later)
			let renderFn = eleventyConfig.augmentFunctionContext(compileFn, {
				source: data,

				// Overwrite existing values?
				// overwrite: true,

				// Lazily fetch the key using `getter`
				// lazy: false,
				// getter: (key, context) => context?.[key];
			});

			return renderFn(data);
		};
	}

`outputFileExtension`

  • Optional: Defaults to html

When the output file is written to the file system, what file extension should be used?

`init`

  • Optional

An async-friendly function that runs once (no matter how many files use the extension) for any additional setup at the beginning before any compilation or rendering.

Note that init will not re-run on watch/serve mode. If you’d like something that runs before every build, use the eleventy.before event.

js
// some configuration truncated …
  init: async function() {
    // has access to current configuration settings in `this.config`
  },

`read`

  • Optional: Defaults to true

Set to false to opt out of reading the contents of files from the file system. This is useful if you’re using an external bundler to read the files.

js
// some configuration truncated …
  read: false,

Use with compileOptions.setCacheKey to get more fine-grained control over how the template is cached.

`useLayouts` {% addedin "v3.0.0-alpha.14" %}

  • Optional: Defaults to true

Whether or not Layouts will be applied to this template language. This will also exclude data from layout files to play a part in the data cascade of this template type as well. Related GitHub #2830.

`useJavaScriptImport` {% addedin "v3.0.0-beta.2" %}

Use the JavaScript loader instead of reading from the file system. If enabled, this takes precedence over read option.

js
useJavaScriptImport: true,
	getInstanceFromInputPath: async function(inputPath) {
		let mod = await import(inputPath);
		return mod.default;
	},
	compile: (compileFn) => compileFn,

`getData` and `getInstanceFromInputPath`

  • Optional

Controls if and how additional data should be retrieved from a JavaScript object to populate the Data Cascade. If your templates aren’t compiling JavaScript objects, you probably won’t need this.

Notably, this is separate from (in addition to) front matter parsing (which requires read: true).

js
// some configuration truncated …
	// `false` is the default
	getData: false, // no additional data is used
js
// some configuration truncated …
  getData: async function(inputPath) {
    // DIY, this object will be merged into data cascade
    return {};
  },
js
// some configuration truncated …
  // get the `data` property from the instance.
  getData: ["data"],
  // * `getData: true` is aliased to ["data"]
  // * You can use more than one property name! ["data", "otherPropName"]

  getInstanceFromInputPath: function(inputPath) {
    // Return the JavaScript object from which the `data` property will be retrieved.
    let instance = doSomethingMyselfToFetchAJavaScriptObject(inputPath);
    return instance;
  }

Advanced Use Case: overriding getData keys for one instance

If the JavaScript object returned from getInstanceFromInputPath has an eleventyDataKey property, this is used to override the keys returned from the getData Array for this specific instance only. Anything you can pass into a new Set() constructor works here (Array, Map, another Set).

js
// some configuration truncated …
  // if getData is `false`, `eleventyDataKey` will not be used.
  getData: true,

  getInstanceFromInputPath: function(inputPath) {
    return {
      // Overrides `getData` for this instance
      eleventyDataKey: ["myOverrideData"],

      // Will not be used
      data: {
        notAvailableOnGlobalData: 456
      },

      // Will be used.
      myOverrideData: {
        availableOnGlobalData: 123
      }
    }
  },

In the above example, the data cascade will include a top-level variable availableOnGlobalData with a value of 123. Using eleventyDataKey overrides any keys set in getData, which means (for this instance) data will be ignored and notAvailableOnGlobalData will not be present.

`compileOptions`

Optional. This has the same signature as the compile function and expects a reusable render function to be returned.

js
// some configuration truncated …
  compileOptions: {
    permalink: function(contents, inputPath) {
      return (data) => {
        // Return a string to override: you’ll want to use `data.page`
        // Or `return;` (return undefined) to fallback to default behavior
      }
    }
  },
  • Don’t compile permalink strings in the parent template language
    • permalink: "raw" (new default in v3.0, related GitHub #2780)
  • Don’t write any files to the file system:
    • permalink: false
    • permalink: (contents, inputPath) => false
    • permalink: (contents, inputPath) => ((data) => false)
  • Override the default permalink function (return a string to override)
    • permalink: (contents, inputPath) => "…"
    • permalink: (contents, inputPath) => ((data) => "…") (use the data cascade)
    • If you return nothing (or undefined), this will revert to the default permalink behavior.

This provides another way to implement Sass’ underscore convention to skip writing the file to the output directory:

{% codetitle "eleventy.config.js" %}

js
// … some configuration truncated
  compileOptions: {
    permalink: function(contents, inputPath) {
      let parsed = path.parse(inputPath);
      if(parsed.name.startsWith("_")) {
        return false;
      }
    }
  },

`compileOptions.spiderJavaScriptDependencies`

  • Optional: Defaults to false

Enable to use Eleventy to spider and watch files require’d in these templates. This allows you to control the Watch JavaScript Dependencies feature on a per-template language basis. Most template languages will want the default here and keep this feature disabled.

`compileOptions.cache` for advanced control of caching

  • Optional: Defaults to the value of read

This controls caching for the compilation step and saves the compiled template function for reuse. For more efficient cleanup (and long term memory use), these caches are now segmented by inputPath ({% addedin "2.0.0-canary.19" %}).

By default, whether or not this cache is enabled is tied to boolean value of read. If read: true, then cache will also be true. It’s unlikely you will need this, but you can override this to mismatch read.

You can also granularly control the caching key using a getCacheKey callback. It might be useful to change this when using read: false and contents are unavailable.

{% callout "info", "md" %}If you’re using {{ "2.0.0-canary.19" | coerceVersion }} or newer, you shouldn’t need a getCacheKey callback. It is preferred to use the addDependencies method in the compile callback instead!{% endcallout %}

Expand to see the default getCacheKey implementation (you can override this!)

js
// some configuration truncated …
  read: false,
  compileOptions: {
    cache: true,
    getCacheKey: function(contents, inputPath) {
      // return contents; // this is the default in 1.0

      // return inputPath + contents; // this is the new default in {{ "2.0.0-canary.16" | coerceVersion }}

      return inputPath; // override to cache by inputPath (this means the compile function will not get called when the file contents change)

      // Conditionally opt-out of cache with `return false`
      // if(someArbitraryCondition) {
      //   return false;
      // }
    }
  },

`isIncrementalMatch`

{% callout "info", "md" %}If you’re using {{ "2.0.0-canary.19" | coerceVersion }} or newer, you shouldn’t need an isIncrementalMatch callback. It is preferred to use the addDependencies method in the compile callback instead!{% endcallout %}

  • Optional

A callback used for advanced control of template dependency matching. This determines if a modified file (from a watch/serve rebuild) is relevant to each known full template file. If the callback returns true, the template will be rendered. If the callback returns false, the template will be skipped.

Expand to see the default isIncrementalMatch implementation (you can override this!)

js
// some configuration truncated …
  // Called once for each template (matching this custom template’s file extension) in your project.
  isIncrementalMatch: function(modifiedFile) {
    // is modifiedFile relevant to this.inputPath?
    if (this.isFileRelevantToInputPath) {
      // True if they are the same file
      // Or if they are related by any `addDependencies` relationships
      return true;
    }

    // If `modifiedFile` is not a full template (maybe an include or layout)
    // and we have no record of any dependencies for this file, we re-render everything
    if (!this.doesFileHaveDependencies && !this.isFullTemplate) {
      return true;
    }

    // Skip it
    return false;
  },

You can see more advanced override implementations in @11ty/eleventy-plugin-webc and @11ty/eleventy-plugin-vue.