Skip to content

Commit

Permalink
Eleventy supplied data ESM docs 11ty/eleventy#836
Browse files Browse the repository at this point in the history
  • Loading branch information
zachleat committed Sep 24, 2024
1 parent b034685 commit 2010962
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 46 deletions.
29 changes: 29 additions & 0 deletions src/_includes/snippets/permalinks/advanced.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{%- set tabid = "advanced" %}
<div class="codetitle codetitle-right-md">recipes.11tydata.js</div>
<is-land on:visible import="/js/seven-minute-tabs.js">
<seven-minute-tabs class="tabs-flush" persist sync>
{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %}
<div id="{{ tabid }}-jsesm" role="tabpanel">

```js
export default {
permalink: function ({ title }) {
return `/recipes/${this.slugify(title)}`;
},
};
```

</div>
<div id="{{ tabid }}-jscjs" role="tabpanel">

```js
module.exports = {
permalink: function ({ title }) {
return `/recipes/${this.slugify(title)}`;
},
};
```

</div>
</seven-minute-tabs>
</is-land>
27 changes: 27 additions & 0 deletions src/_includes/snippets/permalinks/dynperm.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{%- set tabid = "dynperm" %}
<div class="codetitle codetitle-right-md">eleventy.config.js</div>
<is-land on:visible import="/js/seven-minute-tabs.js">
<seven-minute-tabs class="tabs-flush" persist sync>
{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %}
<div id="{{ tabid }}-jsesm" role="tabpanel">

```js
export default function (eleventyConfig) {
// Enabled by default
eleventyConfig.setDynamicPermalinks(false);
};
```

</div>
<div id="{{ tabid }}-jscjs" role="tabpanel">

```js
module.exports = function (eleventyConfig) {
// Enabled by default
eleventyConfig.setDynamicPermalinks(false);
};
```

</div>
</seven-minute-tabs>
</is-land>
31 changes: 31 additions & 0 deletions src/_includes/snippets/permalinks/global.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{%- set tabid = "global" %}
<div class="codetitle codetitle-right-md">eleventy.config.js</div>
<is-land on:visible import="/js/seven-minute-tabs.js">
<seven-minute-tabs class="tabs-flush" persist sync>
{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %}
<div id="{{ tabid }}-jsesm" role="tabpanel">

```js
export default function(eleventyConfig) {
eleventyConfig.addGlobalData("permalink", () => {
return (data) =>
`${data.page.filePathStem}.${data.page.outputFileExtension}`;
});
};
```

</div>
<div id="{{ tabid }}-jscjs" role="tabpanel">

```js
module.exports = function(eleventyConfig) {
eleventyConfig.addGlobalData("permalink", () => {
return (data) =>
`${data.page.filePathStem}.${data.page.outputFileExtension}`;
});
};
```

</div>
</seven-minute-tabs>
</is-land>
39 changes: 39 additions & 0 deletions src/_includes/snippets/permalinks/i18n.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
{%- set tabid = "i18n" %}
<div class="codetitle codetitle-right-md">eleventy.config.js</div>
<is-land on:visible import="/js/seven-minute-tabs.js">
<seven-minute-tabs class="tabs-flush" persist sync>
{% renderFile "./src/_includes/syntax-chooser-tablist.11ty.js", {id: tabid, only: "jsesm,jscjs"} %}
<div id="{{ tabid }}-jsesm" role="tabpanel">

```js
export default function (eleventyConfig) {
eleventyConfig.addUrlTransform(({ url }) => {
// `url` is guaranteed to be a string here even if you’re using `permalink: false`
if (url.match(/\.[a-z]{2}\.html$/i)) {
return url.slice(0, -1 * ".en.html".length) + "/";
}

// Returning undefined skips the url transform.
});
};
```

</div>
<div id="{{ tabid }}-jscjs" role="tabpanel">

```js
module.exports = function (eleventyConfig) {
eleventyConfig.addUrlTransform(({ url }) => {
// `url` is guaranteed to be a string here even if you’re using `permalink: false`
if (url.match(/\.[a-z]{2}\.html$/i)) {
return url.slice(0, -1 * ".en.html".length) + "/";
}

// Returning undefined skips the url transform.
});
};
```

</div>
</seven-minute-tabs>
</is-land>
23 changes: 4 additions & 19 deletions src/docs/data-eleventy-supplied.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,10 @@ The `fileSlug` variable is mapped from `inputPath`, and is useful for creating y

The `filePathStem` variable is mapped from `inputPath`, and is useful if you’ve inherited a project that doesn’t use clean [permalinks](/docs/permalinks/).

<div id="changing-your-projects-default-permalinks"></div>

You can use this feature to [globally change your project’s default permalinks](/docs/permalinks.md#change-permalinks-globally-for-a-project).

{% callout "info" %}<strong>Careful with this one!</strong> Remember that <a href="/docs/permalinks/#cool-uris-dont-change">Cool URIs don’t change</a>.{% endcallout %}

If you absolutely need a file extension on your output, you might use it like this:
Expand All @@ -122,25 +126,6 @@ This example output uses the above permalink value.
| `"2018-01-01-myFile.md"` | `"myFile"` | `myFile.html` |
| `"myDir/myFile.md"` | `"myDir/myFile"` | `myDir/myFile.html` |

#### Changing your project’s default permalinks

{% addedin "2.0.0-canary.9" %} [Deep-link to `3c49f22`](https:/11ty/eleventy/commit/3c49f22b31b10e5dae0daf661a54750875ae5d0f).

Want to change `resource.md` to write to `/resource.html` instead of `/resource/index.html`? Use this configuration API code sample.

{% codetitle ".eleventy.js" %}

```js
module.exports = function (eleventyConfig) {
eleventyConfig.addGlobalData("permalink", () => {
return (data) =>
`${data.page.filePathStem}.${data.page.outputFileExtension}`;
});
};
```

{% callout "warn", "md" %}When using this approach for URLs _without_ trailing slashes (file `/resource.html` ▶︎ url `/resource`), please do note that using trailing slashes with `index.html` files (file `/resource/index.html` ▶︎ url `/resource/`) is a bit friendlier on various JAMstack hosting providers. You may encounter unexpected 404 errors—make [sure you study up on how this works and test appropriately!](https://www.zachleat.com/web/trailing-slash/#results-table)!{% endcallout %}

## `eleventy` Variable {% addedin "1.0.0" %}

```js
Expand Down
39 changes: 12 additions & 27 deletions src/docs/permalinks.md
Original file line number Diff line number Diff line change
Expand Up @@ -216,19 +216,21 @@ permalink: "index.json"

## Advanced Usage

### Dynamic permalinks for a directory of content templates
### Change permalinks globally for a project

{% addedin "2.0.0-canary.9" %}Want to change `resource.md` to write to `/resource.html` instead of `/resource/index.html`? This uses [global data via the configuration API](/docs/data-global-custom.md) but you could set this using a [Global Data file](/docs/data-global.md) too.

{% include "snippets/permalinks/global.njk" %}

{% callout "warn", "md" %}When using this approach for URLs _without_ trailing slashes (file `/resource.html` ▶︎ url `/resource`), please do note that using trailing slashes with `index.html` files (file `/resource/index.html` ▶︎ url `/resource/`) is a bit friendlier on various JAMstack hosting providers. You may encounter unexpected 404 errors—make [sure you study up on how this works and test appropriately!](https://www.zachleat.com/web/trailing-slash/#results-table)!{% endcallout %}

### Change permalinks for one directory

Let's say you have a directory of content templates like `recipes/cookies.md` and `recipes/soup.md` and 50 more. Each of these content templates has a title in their frontmatter. While you could manually set a permalink in the frontmatter of each recipe you can also dynamically generate the permalink inside a [Directory Data File](/docs/data-template-dir/) like `recipes.11tydata.js`.

Because of the order of the [data cascade](/docs/data-cascade/) the title of a content template is not immediately available in the directory data file. However, `permalink` is a special case of implied [Computed Data](docs/data-computed/) and will have this data available. Inside of your directory data file `recipes.11tydata.js` you could write this:

```javascript
module.exports = {
permalink: function ({ title }) {
return `/recipes/${this.slugify(title)}`;
},
};
```
{% include "snippets/permalinks/advanced.njk" %}

The title will be [slugified](/docs/filters/slugify/) to be URL-friendly.

Expand All @@ -249,18 +251,7 @@ Say we want two or more files on the file system (e.g. `about.en.html` and `abou

This example matches any `.xx.html` URL:

```js
module.exports = function (eleventyConfig) {
eleventyConfig.addUrlTransform(({ url }) => {
// `url` is guaranteed to be a string here even if you’re using `permalink: false`
if (url.match(/\.[a-z]{2}\.html$/i)) {
return url.slice(0, -1 * ".en.html".length) + "/";
}

// Returning undefined skips the url transform.
});
};
```
{% include "snippets/permalinks/i18n.njk" %}

This approach unlocks functionality for the default build mode of Eleventy but you could also achieve some of the same functionality using the [Edge](/docs/plugins/edge/) or [Serverless plugins](/docs/plugins/serverless/).

Expand All @@ -283,14 +274,8 @@ dynamicPermalink: false

Eleventy includes a global configuration option to disable dynamic templating altogether. This will save a few template renders and is probably marginally faster, too.

{% codetitle ".eleventy.js" %}

```js
module.exports = function (eleventyConfig) {
// Enabled by default
eleventyConfig.setDynamicPermalinks(false);
};
```
{% include "snippets/permalinks/dynperm.njk" %}

### Ignore the output directory {% addedin "0.1.4" %}

Expand Down

0 comments on commit 2010962

Please sign in to comment.