@anydigital/eleventy-bricks 1.0.0-alpha.17 → 1.0.0-alpha.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.prettierrc.json +3 -0
- package/README.md +310 -201
- package/package.json +2 -4
- package/src/admin/index.html +3 -4
- package/src/do/package.json +4 -9
- package/src/eleventy.config.js +22 -23
- package/src/{setAttrFilter.js → filters/attr.js} +5 -6
- package/src/filters/attr_concat.js +65 -0
- package/src/filters/attr_concat.test.js +205 -0
- package/src/filters/if.js +39 -0
- package/src/filters/if.test.js +63 -0
- package/src/filters/merge.js +47 -0
- package/src/filters/merge.test.js +51 -0
- package/src/{removeTagFilter.js → filters/remove_tag.js} +3 -3
- package/src/{removeTagFilter.test.js → filters/remove_tag.test.js} +1 -1
- package/src/filters/where_in.js +49 -0
- package/src/filters/where_in.test.js +148 -0
- package/src/index.cjs +2 -2
- package/src/index.js +58 -18
- package/src/siteData.js +3 -3
- package/src/bricks.js +0 -125
- package/src/byAttrFilter.js +0 -35
- package/src/byAttrFilter.test.js +0 -105
- package/src/mergeFilter.js +0 -57
- package/src/mergeFilter.test.js +0 -64
package/README.md
CHANGED
|
@@ -17,27 +17,35 @@ You can use this library in two ways:
|
|
|
17
17
|
Import and use the entire plugin. You can configure which helpers to enable using the options parameter:
|
|
18
18
|
|
|
19
19
|
**ES Modules:**
|
|
20
|
+
|
|
20
21
|
```javascript
|
|
21
22
|
import eleventyBricks from "@anydigital/eleventy-bricks";
|
|
22
23
|
|
|
23
|
-
export default function(eleventyConfig) {
|
|
24
|
+
export default function (eleventyConfig) {
|
|
24
25
|
eleventyConfig.addPlugin(eleventyBricks, {
|
|
25
|
-
mdAutoRawTags: true
|
|
26
|
+
mdAutoRawTags: true,
|
|
27
|
+
mdAutoNl2br: true,
|
|
28
|
+
siteData: true,
|
|
29
|
+
filters: ["attr", "where_in", "merge", "remove_tag", "if", "attr_concat"],
|
|
26
30
|
});
|
|
27
|
-
|
|
31
|
+
|
|
28
32
|
// Your other configuration...
|
|
29
33
|
}
|
|
30
34
|
```
|
|
31
35
|
|
|
32
36
|
**CommonJS:**
|
|
37
|
+
|
|
33
38
|
```javascript
|
|
34
39
|
const eleventyBricks = require("@anydigital/eleventy-bricks");
|
|
35
40
|
|
|
36
|
-
module.exports = function(eleventyConfig) {
|
|
41
|
+
module.exports = function (eleventyConfig) {
|
|
37
42
|
eleventyConfig.addPlugin(eleventyBricks, {
|
|
38
|
-
mdAutoRawTags: true
|
|
43
|
+
mdAutoRawTags: true,
|
|
44
|
+
mdAutoNl2br: true,
|
|
45
|
+
siteData: true,
|
|
46
|
+
filters: ["attr", "where_in", "merge", "remove_tag", "if", "attr_concat"],
|
|
39
47
|
});
|
|
40
|
-
|
|
48
|
+
|
|
41
49
|
// Your other configuration...
|
|
42
50
|
};
|
|
43
51
|
```
|
|
@@ -49,37 +57,61 @@ module.exports = function(eleventyConfig) {
|
|
|
49
57
|
Import only the specific helpers you need without using the plugin:
|
|
50
58
|
|
|
51
59
|
**ES Modules:**
|
|
52
|
-
```javascript
|
|
53
|
-
import { bricks, mdAutoRawTags, mdAutoNl2br, setAttrFilter, byAttrFilter, mergeFilter, removeTagFilter, siteData } from "@anydigital/eleventy-bricks";
|
|
54
60
|
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
```javascript
|
|
62
|
+
import {
|
|
63
|
+
mdAutoRawTags,
|
|
64
|
+
mdAutoNl2br,
|
|
65
|
+
setAttrFilter,
|
|
66
|
+
whereInFilter,
|
|
67
|
+
mergeFilter,
|
|
68
|
+
removeTagFilter,
|
|
69
|
+
ifFilter,
|
|
70
|
+
attrConcatFilter,
|
|
71
|
+
siteData,
|
|
72
|
+
} from "@anydigital/eleventy-bricks";
|
|
73
|
+
|
|
74
|
+
export default function (eleventyConfig) {
|
|
57
75
|
mdAutoRawTags(eleventyConfig);
|
|
58
76
|
mdAutoNl2br(eleventyConfig);
|
|
59
77
|
setAttrFilter(eleventyConfig);
|
|
60
|
-
|
|
78
|
+
whereInFilter(eleventyConfig);
|
|
61
79
|
mergeFilter(eleventyConfig);
|
|
62
80
|
removeTagFilter(eleventyConfig);
|
|
81
|
+
ifFilter(eleventyConfig);
|
|
82
|
+
attrConcatFilter(eleventyConfig);
|
|
63
83
|
siteData(eleventyConfig);
|
|
64
|
-
|
|
84
|
+
|
|
65
85
|
// Your other configuration...
|
|
66
86
|
}
|
|
67
87
|
```
|
|
68
88
|
|
|
69
89
|
**CommonJS:**
|
|
70
|
-
```javascript
|
|
71
|
-
const { bricks, mdAutoRawTags, mdAutoNl2br, setAttrFilter, byAttrFilter, mergeFilter, removeTagFilter, siteData } = require("@anydigital/eleventy-bricks");
|
|
72
90
|
|
|
73
|
-
|
|
74
|
-
|
|
91
|
+
```javascript
|
|
92
|
+
const {
|
|
93
|
+
mdAutoRawTags,
|
|
94
|
+
mdAutoNl2br,
|
|
95
|
+
setAttrFilter,
|
|
96
|
+
whereInFilter,
|
|
97
|
+
mergeFilter,
|
|
98
|
+
removeTagFilter,
|
|
99
|
+
ifFilter,
|
|
100
|
+
attrConcatFilter,
|
|
101
|
+
siteData,
|
|
102
|
+
} = require("@anydigital/eleventy-bricks");
|
|
103
|
+
|
|
104
|
+
module.exports = async function (eleventyConfig) {
|
|
75
105
|
await mdAutoRawTags(eleventyConfig);
|
|
76
106
|
await mdAutoNl2br(eleventyConfig);
|
|
77
107
|
await setAttrFilter(eleventyConfig);
|
|
78
|
-
await
|
|
108
|
+
await whereInFilter(eleventyConfig);
|
|
79
109
|
await mergeFilter(eleventyConfig);
|
|
80
110
|
await removeTagFilter(eleventyConfig);
|
|
111
|
+
await ifFilter(eleventyConfig);
|
|
112
|
+
await attrConcatFilter(eleventyConfig);
|
|
81
113
|
await siteData(eleventyConfig);
|
|
82
|
-
|
|
114
|
+
|
|
83
115
|
// Your other configuration...
|
|
84
116
|
};
|
|
85
117
|
```
|
|
@@ -90,134 +122,35 @@ module.exports = async function(eleventyConfig) {
|
|
|
90
122
|
|
|
91
123
|
When using the plugin (Option 1), you can configure which helpers to enable:
|
|
92
124
|
|
|
93
|
-
| Option
|
|
94
|
-
|
|
95
|
-
| `
|
|
96
|
-
| `
|
|
97
|
-
| `
|
|
98
|
-
| `
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
125
|
+
| Option | Type | Default | Description |
|
|
126
|
+
| --------------- | --------------- | ------- | ---------------------------------------------------------------- |
|
|
127
|
+
| `mdAutoRawTags` | boolean | `false` | Enable the mdAutoRawTags preprocessor for Markdown files |
|
|
128
|
+
| `mdAutoNl2br` | boolean | `false` | Enable the mdAutoNl2br preprocessor to convert \n to `<br>` tags |
|
|
129
|
+
| `siteData` | boolean | `false` | Enable site.year and site.prod global data |
|
|
130
|
+
| `filters` | array of string | `[]` | Array of filter names to enable (see Available Filters section) |
|
|
131
|
+
|
|
132
|
+
**Available filter names for the `filters` array:**
|
|
133
|
+
|
|
134
|
+
- `'attr'` - Override object attributes
|
|
135
|
+
- `'where_in'` - Filter collections by attribute values
|
|
136
|
+
- `'merge'` - Merge arrays or objects
|
|
137
|
+
- `'remove_tag'` - Remove HTML elements from content
|
|
138
|
+
- `'if'` - Inline conditional/ternary operator
|
|
139
|
+
- `'attr_concat'` - Concatenate values to an attribute array
|
|
103
140
|
|
|
104
141
|
**Example:**
|
|
142
|
+
|
|
105
143
|
```javascript
|
|
106
144
|
eleventyConfig.addPlugin(eleventyBricks, {
|
|
107
|
-
bricks: true,
|
|
108
145
|
mdAutoRawTags: true,
|
|
109
|
-
|
|
110
|
-
siteData: true
|
|
146
|
+
mdAutoNl2br: true,
|
|
147
|
+
siteData: true,
|
|
148
|
+
filters: ["attr", "where_in", "merge", "remove_tag", "if", "attr_concat"],
|
|
111
149
|
});
|
|
112
150
|
```
|
|
113
151
|
|
|
114
152
|
## Available 11ty Helpers
|
|
115
153
|
|
|
116
|
-
### bricks
|
|
117
|
-
|
|
118
|
-
A dependency management system for Eleventy that automatically collects and injects CSS and JavaScript dependencies (both external and inline) per page. This allows brick components to declare their dependencies, and the system will inject them in the correct location in your HTML.
|
|
119
|
-
|
|
120
|
-
**Why use this?**
|
|
121
|
-
|
|
122
|
-
When building reusable components (bricks) in Eleventy, you often need to include CSS and JavaScript dependencies. Instead of manually adding these to every page, `bricks` automatically:
|
|
123
|
-
- Collects dependencies from all bricks used on a page
|
|
124
|
-
- Categorizes them (external CSS, external JS, inline styles, inline scripts)
|
|
125
|
-
- Injects them in the correct location in your HTML output
|
|
126
|
-
|
|
127
|
-
**How it works:**
|
|
128
|
-
|
|
129
|
-
1. Use the `bricksDependencies` shortcode in your base template to mark where dependencies should be injected
|
|
130
|
-
2. Use the `brick` shortcode to register and render brick components that declare their dependencies
|
|
131
|
-
3. The system automatically collects all dependencies and injects them when the page is built
|
|
132
|
-
|
|
133
|
-
**Usage:**
|
|
134
|
-
|
|
135
|
-
1. Enable `bricks` in your Eleventy config:
|
|
136
|
-
|
|
137
|
-
```javascript
|
|
138
|
-
import { bricks } from "@anydigital/eleventy-bricks";
|
|
139
|
-
|
|
140
|
-
export default function(eleventyConfig) {
|
|
141
|
-
bricks(eleventyConfig);
|
|
142
|
-
// Or use as plugin:
|
|
143
|
-
// eleventyConfig.addPlugin(eleventyBricks, { bricks: true });
|
|
144
|
-
}
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
2. Add the `bricksDependencies` shortcode in your base template (typically in the `<head>` section):
|
|
148
|
-
|
|
149
|
-
```njk
|
|
150
|
-
<head>
|
|
151
|
-
<meta charset="UTF-8">
|
|
152
|
-
<title>My Site</title>
|
|
153
|
-
{% bricksDependencies [
|
|
154
|
-
... (global dependencies can be set here) ...
|
|
155
|
-
] %}
|
|
156
|
-
<!-- Other head content -->
|
|
157
|
-
</head>
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
3. Create brick components that declare their dependencies:
|
|
161
|
-
|
|
162
|
-
```javascript
|
|
163
|
-
// myBrick.js
|
|
164
|
-
export default {
|
|
165
|
-
dependencies: [
|
|
166
|
-
'https://cdn.example.com/library.css',
|
|
167
|
-
'https://cdn.example.com/library.js'
|
|
168
|
-
],
|
|
169
|
-
style: `
|
|
170
|
-
.my-component { color: blue; }
|
|
171
|
-
`,
|
|
172
|
-
script: `
|
|
173
|
-
console.log('Component initialized');
|
|
174
|
-
`,
|
|
175
|
-
render: function() {
|
|
176
|
-
return '<div class="my-component">Hello World</div>';
|
|
177
|
-
}
|
|
178
|
-
};
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
4. Use the `brick` shortcode in your templates:
|
|
182
|
-
|
|
183
|
-
```njk
|
|
184
|
-
{% set myBrick = require('./myBrick.js') %}
|
|
185
|
-
{% brick myBrick %}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
**Brick Component Structure:**
|
|
189
|
-
|
|
190
|
-
A brick component is a JavaScript object with the following optional properties:
|
|
191
|
-
|
|
192
|
-
- `dependencies`: Array of URLs to external CSS or JavaScript files (e.g., `['https://cdn.example.com/style.css', 'https://cdn.example.com/script.js']`)
|
|
193
|
-
- `style`: String containing inline CSS
|
|
194
|
-
- `script`: String containing inline JavaScript
|
|
195
|
-
- `render`: Function that returns the HTML markup for the component
|
|
196
|
-
|
|
197
|
-
**Output:**
|
|
198
|
-
|
|
199
|
-
The system will automatically inject all dependencies in the order they were registered:
|
|
200
|
-
|
|
201
|
-
```html
|
|
202
|
-
<head>
|
|
203
|
-
<meta charset="UTF-8">
|
|
204
|
-
<title>My Site</title>
|
|
205
|
-
<link rel="stylesheet" href="https://cdn.example.com/library.css">
|
|
206
|
-
<style>.my-component { color: blue; }</style>
|
|
207
|
-
<script src="https://cdn.example.com/library.js"></script>
|
|
208
|
-
<script>console.log('Component initialized');</script>
|
|
209
|
-
<!-- Other head content -->
|
|
210
|
-
</head>
|
|
211
|
-
```
|
|
212
|
-
|
|
213
|
-
**Features:**
|
|
214
|
-
|
|
215
|
-
- Automatic dependency collection per page
|
|
216
|
-
- Categorizes dependencies (CSS vs JS, external vs inline)
|
|
217
|
-
- Deduplicates dependencies (using Sets internally)
|
|
218
|
-
- Works with both external URLs and inline code
|
|
219
|
-
- Clears registry before each build to prevent stale data
|
|
220
|
-
|
|
221
154
|
### mdAutoRawTags
|
|
222
155
|
|
|
223
156
|
Prevents Nunjucks syntax from being processed in Markdown files by automatically wrapping `{{`, `}}`, `{%`, and `%}` with `{% raw %}` tags.
|
|
@@ -233,7 +166,7 @@ When writing documentation or tutorials about templating in Markdown files, you
|
|
|
233
166
|
```javascript
|
|
234
167
|
import { mdAutoRawTags } from "@anydigital/eleventy-bricks";
|
|
235
168
|
|
|
236
|
-
export default function(eleventyConfig) {
|
|
169
|
+
export default function (eleventyConfig) {
|
|
237
170
|
mdAutoRawTags(eleventyConfig);
|
|
238
171
|
// Or use as plugin:
|
|
239
172
|
// eleventyConfig.addPlugin(eleventyBricks, { mdAutoRawTags: true });
|
|
@@ -243,6 +176,7 @@ export default function(eleventyConfig) {
|
|
|
243
176
|
**Example:**
|
|
244
177
|
|
|
245
178
|
Before `mdAutoRawTags`, writing this in Markdown:
|
|
179
|
+
|
|
246
180
|
```markdown
|
|
247
181
|
Use {{ variable }} to output variables.
|
|
248
182
|
```
|
|
@@ -264,7 +198,7 @@ Markdown tables don't support multi-line content in cells. By using `\n` in your
|
|
|
264
198
|
```javascript
|
|
265
199
|
import { mdAutoNl2br } from "@anydigital/eleventy-bricks";
|
|
266
200
|
|
|
267
|
-
export default function(eleventyConfig) {
|
|
201
|
+
export default function (eleventyConfig) {
|
|
268
202
|
mdAutoNl2br(eleventyConfig);
|
|
269
203
|
// Or use as plugin:
|
|
270
204
|
// eleventyConfig.addPlugin(eleventyBricks, { mdAutoNl2br: true });
|
|
@@ -274,39 +208,41 @@ export default function(eleventyConfig) {
|
|
|
274
208
|
**Example:**
|
|
275
209
|
|
|
276
210
|
In your Markdown file:
|
|
211
|
+
|
|
277
212
|
```markdown
|
|
278
|
-
| Column 1
|
|
279
|
-
|
|
213
|
+
| Column 1 | Column 2 |
|
|
214
|
+
| ---------------------- | --------------------------------- |
|
|
280
215
|
| Line 1\nLine 2\nLine 3 | Another cell\nWith multiple lines |
|
|
281
216
|
```
|
|
282
217
|
|
|
283
218
|
Will render as:
|
|
219
|
+
|
|
284
220
|
```html
|
|
285
|
-
<td>Line 1<br
|
|
286
|
-
<td>Another cell<br
|
|
221
|
+
<td>Line 1<br />Line 2<br />Line 3</td>
|
|
222
|
+
<td>Another cell<br />With multiple lines</td>
|
|
287
223
|
```
|
|
288
224
|
|
|
289
225
|
**Note:** This processes literal `\n` sequences (backslash followed by 'n'), not actual newline characters. Type `\n` in your source files where you want line breaks.
|
|
290
226
|
|
|
291
|
-
###
|
|
227
|
+
### attr
|
|
292
228
|
|
|
293
229
|
A filter that creates a new object with an overridden attribute value. This is useful for modifying data objects in templates without mutating the original.
|
|
294
230
|
|
|
295
231
|
**Why use this?**
|
|
296
232
|
|
|
297
|
-
When working with Eleventy data, you sometimes need to modify an object's properties for a specific use case. The `
|
|
233
|
+
When working with Eleventy data, you sometimes need to modify an object's properties for a specific use case. The `attr` filter provides a clean way to create a modified copy of an object without affecting the original.
|
|
298
234
|
|
|
299
235
|
**Usage:**
|
|
300
236
|
|
|
301
|
-
1. Enable `
|
|
237
|
+
1. Enable the `attr` filter in your Eleventy config:
|
|
302
238
|
|
|
303
239
|
```javascript
|
|
304
240
|
import { setAttrFilter } from "@anydigital/eleventy-bricks";
|
|
305
241
|
|
|
306
|
-
export default function(eleventyConfig) {
|
|
242
|
+
export default function (eleventyConfig) {
|
|
307
243
|
setAttrFilter(eleventyConfig);
|
|
308
244
|
// Or use as plugin:
|
|
309
|
-
// eleventyConfig.addPlugin(eleventyBricks, {
|
|
245
|
+
// eleventyConfig.addPlugin(eleventyBricks, { filters: ['attr'] });
|
|
310
246
|
}
|
|
311
247
|
```
|
|
312
248
|
|
|
@@ -314,7 +250,7 @@ export default function(eleventyConfig) {
|
|
|
314
250
|
|
|
315
251
|
```njk
|
|
316
252
|
{# Create a modified version of a page object #}
|
|
317
|
-
{% set modifiedPage = page |
|
|
253
|
+
{% set modifiedPage = page | attr('title', 'New Title') %}
|
|
318
254
|
|
|
319
255
|
<h1>{{ modifiedPage.title }}</h1>
|
|
320
256
|
<p>Original title: {{ page.title }}</p>
|
|
@@ -341,49 +277,50 @@ A new object with the specified attribute set to the given value. The original o
|
|
|
341
277
|
|
|
342
278
|
```njk
|
|
343
279
|
{# Override a single attribute #}
|
|
344
|
-
{% set updatedPost = post |
|
|
280
|
+
{% set updatedPost = post | attr('featured', true) %}
|
|
345
281
|
|
|
346
|
-
{# Chain multiple
|
|
347
|
-
{% set modifiedPost = post
|
|
348
|
-
|
|
|
349
|
-
|
|
|
282
|
+
{# Chain multiple attr filters #}
|
|
283
|
+
{% set modifiedPost = post
|
|
284
|
+
| attr('category', 'blog')
|
|
285
|
+
| attr('priority', 1)
|
|
350
286
|
%}
|
|
351
287
|
|
|
352
288
|
{# Use in loops #}
|
|
353
289
|
{% for item in collection %}
|
|
354
|
-
{% set enhancedItem = item |
|
|
290
|
+
{% set enhancedItem = item | attr('processed', true) %}
|
|
355
291
|
{# ... use enhancedItem ... #}
|
|
356
292
|
{% endfor %}
|
|
357
293
|
```
|
|
358
294
|
|
|
359
|
-
###
|
|
295
|
+
### where_in
|
|
360
296
|
|
|
361
|
-
A filter that filters collection items by attribute value. It checks if an item's attribute matches a target value. If the attribute is an array, it checks if the array includes the target value.
|
|
297
|
+
A filter that filters collection items by attribute value. It checks if an item's attribute matches a target value. If the attribute is an array, it checks if the array includes the target value. Supports nested attribute names using dot notation.
|
|
362
298
|
|
|
363
299
|
**Why use this?**
|
|
364
300
|
|
|
365
|
-
When working with Eleventy collections, you often need to filter items based on front matter data. The `
|
|
301
|
+
When working with Eleventy collections, you often need to filter items based on front matter data. The `where_in` filter provides a flexible way to filter by any attribute, with special handling for array attributes (like tags) and support for nested properties using dot notation.
|
|
366
302
|
|
|
367
303
|
**Usage:**
|
|
368
304
|
|
|
369
|
-
1. Enable `
|
|
305
|
+
1. Enable the `where_in` filter in your Eleventy config:
|
|
370
306
|
|
|
371
307
|
```javascript
|
|
372
|
-
import {
|
|
308
|
+
import { whereInFilter } from "@anydigital/eleventy-bricks";
|
|
373
309
|
|
|
374
|
-
export default function(eleventyConfig) {
|
|
375
|
-
|
|
310
|
+
export default function (eleventyConfig) {
|
|
311
|
+
whereInFilter(eleventyConfig);
|
|
376
312
|
// Or use as plugin:
|
|
377
|
-
// eleventyConfig.addPlugin(eleventyBricks, {
|
|
313
|
+
// eleventyConfig.addPlugin(eleventyBricks, { filters: ['where_in'] });
|
|
378
314
|
}
|
|
379
315
|
```
|
|
380
316
|
|
|
381
317
|
2. Use the filter in your templates:
|
|
382
318
|
|
|
383
319
|
**Filter by exact attribute match:**
|
|
320
|
+
|
|
384
321
|
```njk
|
|
385
322
|
{# Get all posts with category 'blog' #}
|
|
386
|
-
{% set blogPosts = collections.all |
|
|
323
|
+
{% set blogPosts = collections.all | where_in('data.category', 'blog') %}
|
|
387
324
|
|
|
388
325
|
{% for post in blogPosts %}
|
|
389
326
|
<h2>{{ post.data.title }}</h2>
|
|
@@ -391,9 +328,10 @@ export default function(eleventyConfig) {
|
|
|
391
328
|
```
|
|
392
329
|
|
|
393
330
|
**Filter by array attribute (tags):**
|
|
331
|
+
|
|
394
332
|
```njk
|
|
395
333
|
{# Get all posts that include 'javascript' tag #}
|
|
396
|
-
{% set jsPosts = collections.all |
|
|
334
|
+
{% set jsPosts = collections.all | where_in('data.tags', 'javascript') %}
|
|
397
335
|
|
|
398
336
|
{% for post in jsPosts %}
|
|
399
337
|
<h2>{{ post.data.title }}</h2>
|
|
@@ -403,13 +341,13 @@ export default function(eleventyConfig) {
|
|
|
403
341
|
**Parameters:**
|
|
404
342
|
|
|
405
343
|
- `collection`: The collection to filter (array of items)
|
|
406
|
-
- `attrName`: The attribute name to check (string)
|
|
344
|
+
- `attrName`: The attribute name to check (string, supports dot notation for nested properties)
|
|
407
345
|
- `targetValue`: The value to match against (any type)
|
|
408
346
|
|
|
409
347
|
**Features:**
|
|
410
348
|
|
|
411
349
|
- Works with any attribute in front matter
|
|
412
|
-
-
|
|
350
|
+
- Supports dot notation for nested properties (e.g., `'data.tags'`, `'data.author.name'`)
|
|
413
351
|
- Special handling for array attributes (uses `includes()` check)
|
|
414
352
|
- Returns empty array if collection is invalid
|
|
415
353
|
- Filters out items without the specified attribute
|
|
@@ -417,6 +355,7 @@ export default function(eleventyConfig) {
|
|
|
417
355
|
**Examples:**
|
|
418
356
|
|
|
419
357
|
Front matter:
|
|
358
|
+
|
|
420
359
|
```yaml
|
|
421
360
|
---
|
|
422
361
|
title: My Post
|
|
@@ -427,18 +366,19 @@ priority: 1
|
|
|
427
366
|
```
|
|
428
367
|
|
|
429
368
|
Template usage:
|
|
369
|
+
|
|
430
370
|
```njk
|
|
431
|
-
{# Filter by category #}
|
|
432
|
-
{% set blogPosts = collections.all |
|
|
371
|
+
{# Filter by category (using dot notation for nested properties) #}
|
|
372
|
+
{% set blogPosts = collections.all | where_in('data.category', 'blog') %}
|
|
433
373
|
|
|
434
374
|
{# Filter by tag (array) #}
|
|
435
|
-
{% set jsTutorials = collections.all |
|
|
375
|
+
{% set jsTutorials = collections.all | where_in('data.tags', 'javascript') %}
|
|
436
376
|
|
|
437
377
|
{# Filter by numeric value #}
|
|
438
|
-
{% set highPriority = collections.all |
|
|
378
|
+
{% set highPriority = collections.all | where_in('data.priority', 1) %}
|
|
439
379
|
|
|
440
380
|
{# Chain filters #}
|
|
441
|
-
{% set recentBlogPosts = collections.all |
|
|
381
|
+
{% set recentBlogPosts = collections.all | where_in('data.category', 'blog') | reverse | limit(5) %}
|
|
442
382
|
```
|
|
443
383
|
|
|
444
384
|
### merge
|
|
@@ -451,21 +391,22 @@ When working with data in templates, you often need to combine multiple arrays o
|
|
|
451
391
|
|
|
452
392
|
**Usage:**
|
|
453
393
|
|
|
454
|
-
1. Enable `merge` in your Eleventy config:
|
|
394
|
+
1. Enable the `merge` filter in your Eleventy config:
|
|
455
395
|
|
|
456
396
|
```javascript
|
|
457
397
|
import { mergeFilter } from "@anydigital/eleventy-bricks";
|
|
458
398
|
|
|
459
|
-
export default function(eleventyConfig) {
|
|
399
|
+
export default function (eleventyConfig) {
|
|
460
400
|
mergeFilter(eleventyConfig);
|
|
461
401
|
// Or use as plugin:
|
|
462
|
-
// eleventyConfig.addPlugin(eleventyBricks, {
|
|
402
|
+
// eleventyConfig.addPlugin(eleventyBricks, { filters: ['merge'] });
|
|
463
403
|
}
|
|
464
404
|
```
|
|
465
405
|
|
|
466
406
|
2. Use the filter in your templates:
|
|
467
407
|
|
|
468
408
|
**Merge arrays:**
|
|
409
|
+
|
|
469
410
|
```njk
|
|
470
411
|
{# Combine two arrays #}
|
|
471
412
|
{% set allItems = featured | merge(regular) %}
|
|
@@ -479,6 +420,7 @@ export default function(eleventyConfig) {
|
|
|
479
420
|
```
|
|
480
421
|
|
|
481
422
|
**Merge objects:**
|
|
423
|
+
|
|
482
424
|
```njk
|
|
483
425
|
{# Merge configuration objects #}
|
|
484
426
|
{% set defaultConfig = { theme: 'light', lang: 'en' } %}
|
|
@@ -506,15 +448,15 @@ export default function(eleventyConfig) {
|
|
|
506
448
|
|
|
507
449
|
```njk
|
|
508
450
|
{# Combine featured and regular posts #}
|
|
509
|
-
{% set featuredPosts = collections.all |
|
|
510
|
-
{% set regularPosts = collections.all |
|
|
451
|
+
{% set featuredPosts = collections.all | where_in('data.featured', true) %}
|
|
452
|
+
{% set regularPosts = collections.all | where_in('data.featured', false) %}
|
|
511
453
|
{% set allPosts = featuredPosts | merge(regularPosts) %}
|
|
512
454
|
|
|
513
455
|
{# Merge page metadata with defaults #}
|
|
514
|
-
{% set defaultMeta = {
|
|
456
|
+
{% set defaultMeta = {
|
|
515
457
|
author: 'Site Admin',
|
|
516
458
|
category: 'general',
|
|
517
|
-
comments: false
|
|
459
|
+
comments: false
|
|
518
460
|
} %}
|
|
519
461
|
{% set pageMeta = defaultMeta | merge(page.data) %}
|
|
520
462
|
|
|
@@ -527,25 +469,25 @@ export default function(eleventyConfig) {
|
|
|
527
469
|
{% set config = defaults | merge(siteConfig, pageConfig, userPrefs) %}
|
|
528
470
|
```
|
|
529
471
|
|
|
530
|
-
###
|
|
472
|
+
### remove_tag
|
|
531
473
|
|
|
532
474
|
A filter that removes a specified HTML element from provided HTML content. It removes the tag along with its content, including self-closing tags.
|
|
533
475
|
|
|
534
476
|
**Why use this?**
|
|
535
477
|
|
|
536
|
-
When working with content from external sources or user-generated content, you may need to strip certain HTML tags for security or presentation purposes. The `
|
|
478
|
+
When working with content from external sources or user-generated content, you may need to strip certain HTML tags for security or presentation purposes. The `remove_tag` filter provides a simple way to remove unwanted tags like `<script>`, `<style>`, or any other HTML elements from your content.
|
|
537
479
|
|
|
538
480
|
**Usage:**
|
|
539
481
|
|
|
540
|
-
1. Enable `
|
|
482
|
+
1. Enable the `remove_tag` filter in your Eleventy config:
|
|
541
483
|
|
|
542
484
|
```javascript
|
|
543
485
|
import { removeTagFilter } from "@anydigital/eleventy-bricks";
|
|
544
486
|
|
|
545
|
-
export default function(eleventyConfig) {
|
|
487
|
+
export default function (eleventyConfig) {
|
|
546
488
|
removeTagFilter(eleventyConfig);
|
|
547
489
|
// Or use as plugin:
|
|
548
|
-
// eleventyConfig.addPlugin(eleventyBricks, {
|
|
490
|
+
// eleventyConfig.addPlugin(eleventyBricks, { filters: ['remove_tag'] });
|
|
549
491
|
}
|
|
550
492
|
```
|
|
551
493
|
|
|
@@ -553,7 +495,7 @@ export default function(eleventyConfig) {
|
|
|
553
495
|
|
|
554
496
|
```njk
|
|
555
497
|
{# Remove all script tags from content #}
|
|
556
|
-
{% set cleanContent = htmlContent |
|
|
498
|
+
{% set cleanContent = htmlContent | remove_tag('script') %}
|
|
557
499
|
|
|
558
500
|
{{ cleanContent | safe }}
|
|
559
501
|
```
|
|
@@ -576,30 +518,187 @@ export default function(eleventyConfig) {
|
|
|
576
518
|
```njk
|
|
577
519
|
{# Remove scripts from user-generated content #}
|
|
578
520
|
{% set userContent = '<p>Hello</p><script>alert("XSS")</script><p>World</p>' %}
|
|
579
|
-
{% set safeContent = userContent |
|
|
521
|
+
{% set safeContent = userContent | remove_tag('script') %}
|
|
580
522
|
{# Result: '<p>Hello</p><p>World</p>' #}
|
|
581
523
|
|
|
582
524
|
{# Strip specific formatting tags #}
|
|
583
525
|
{% set formatted = '<div><strong>Bold</strong> and <em>italic</em> text</div>' %}
|
|
584
|
-
{% set noStrong = formatted |
|
|
526
|
+
{% set noStrong = formatted | remove_tag('strong') %}
|
|
585
527
|
{# Result: '<div>Bold and <em>italic</em> text</div>' #}
|
|
586
528
|
|
|
587
|
-
{# Chain multiple
|
|
529
|
+
{# Chain multiple remove_tag filters for multiple tags #}
|
|
588
530
|
{% set richContent = page.content %}
|
|
589
|
-
{% set stripped = richContent
|
|
590
|
-
|
|
|
591
|
-
|
|
|
592
|
-
|
|
|
531
|
+
{% set stripped = richContent
|
|
532
|
+
| remove_tag('script')
|
|
533
|
+
| remove_tag('style')
|
|
534
|
+
| remove_tag('iframe')
|
|
593
535
|
%}
|
|
594
536
|
|
|
595
537
|
{# Remove images for text-only preview #}
|
|
596
|
-
{% set textOnly = htmlContent |
|
|
538
|
+
{% set textOnly = htmlContent | remove_tag('img') %}
|
|
597
539
|
```
|
|
598
540
|
|
|
599
541
|
**Security Note:**
|
|
600
542
|
|
|
601
543
|
While this filter can help sanitize HTML content, it should not be relied upon as the sole security measure. For critical security requirements, use a dedicated HTML sanitization library on the server side before content reaches your templates.
|
|
602
544
|
|
|
545
|
+
### if
|
|
546
|
+
|
|
547
|
+
An inline conditional/ternary operator filter that returns one value if a condition is truthy, and another if it's falsy. Similar to Nunjucks' inline if syntax.
|
|
548
|
+
|
|
549
|
+
**Why use this?**
|
|
550
|
+
|
|
551
|
+
When you need simple conditional values in templates without verbose if/else blocks, the `if` filter provides a clean inline solution. It's especially useful for class names, attributes, or displaying alternate text based on conditions.
|
|
552
|
+
|
|
553
|
+
**Usage:**
|
|
554
|
+
|
|
555
|
+
1. Enable the `if` filter in your Eleventy config:
|
|
556
|
+
|
|
557
|
+
```javascript
|
|
558
|
+
import { ifFilter } from "@anydigital/eleventy-bricks";
|
|
559
|
+
|
|
560
|
+
export default function (eleventyConfig) {
|
|
561
|
+
ifFilter(eleventyConfig);
|
|
562
|
+
// Or use as plugin:
|
|
563
|
+
// eleventyConfig.addPlugin(eleventyBricks, { filters: ['if'] });
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
2. Use the filter in your templates:
|
|
568
|
+
|
|
569
|
+
```njk
|
|
570
|
+
{# Basic usage #}
|
|
571
|
+
<div class="{{ 'active' | if: isActive, 'inactive' }}">Status</div>
|
|
572
|
+
|
|
573
|
+
{# Without falsy value (defaults to empty string) #}
|
|
574
|
+
<span class="{{ 'highlight' | if: shouldHighlight }}">Text</span>
|
|
575
|
+
|
|
576
|
+
{# With variable values #}
|
|
577
|
+
{% set status = 'Published' | if: post.published, 'Draft' %}
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
**Parameters:**
|
|
581
|
+
|
|
582
|
+
- `trueValue`: The value to return if condition is truthy
|
|
583
|
+
- `condition`: The condition to evaluate
|
|
584
|
+
- `falseValue`: The value to return if condition is falsy (optional, defaults to empty string)
|
|
585
|
+
|
|
586
|
+
**Features:**
|
|
587
|
+
|
|
588
|
+
- Returns `trueValue` if condition is truthy, otherwise returns `falseValue`
|
|
589
|
+
- Treats empty objects `{}` as falsy
|
|
590
|
+
- Default `falseValue` is an empty string if not provided
|
|
591
|
+
- Works with any data type for values
|
|
592
|
+
|
|
593
|
+
**Examples:**
|
|
594
|
+
|
|
595
|
+
```njk
|
|
596
|
+
{# Toggle CSS classes #}
|
|
597
|
+
<button class="{{ 'btn-primary' | if: isPrimary, 'btn-secondary' }}">
|
|
598
|
+
Click me
|
|
599
|
+
</button>
|
|
600
|
+
|
|
601
|
+
{# Display different text #}
|
|
602
|
+
<p>{{ 'Online' | if: user.isOnline, 'Offline' }}</p>
|
|
603
|
+
|
|
604
|
+
{# Use with boolean values #}
|
|
605
|
+
{% set isEnabled = true %}
|
|
606
|
+
<div>{{ 'Enabled' | if: isEnabled, 'Disabled' }}</div>
|
|
607
|
+
|
|
608
|
+
{# Conditional attribute values #}
|
|
609
|
+
<input type="checkbox" {{ 'checked' | if: isChecked }}>
|
|
610
|
+
|
|
611
|
+
{# With numeric values #}
|
|
612
|
+
<span class="{{ 'has-items' | if: items.length }}">
|
|
613
|
+
{{ items.length }} items
|
|
614
|
+
</span>
|
|
615
|
+
|
|
616
|
+
{# Chain with other filters #}
|
|
617
|
+
{% set cssClass = 'featured' | if: post.featured | upper %}
|
|
618
|
+
```
|
|
619
|
+
|
|
620
|
+
### attr_concat
|
|
621
|
+
|
|
622
|
+
A filter that concatenates values to an attribute array, returning a new object with the combined array. Useful for adding items to arrays like tags, classes, or other list-based attributes.
|
|
623
|
+
|
|
624
|
+
**Why use this?**
|
|
625
|
+
|
|
626
|
+
When working with objects that have array attributes (like tags), you often need to add additional values without mutating the original object. The `attr_concat` filter provides a clean way to combine existing array values with new ones, automatically handling duplicates.
|
|
627
|
+
|
|
628
|
+
**Usage:**
|
|
629
|
+
|
|
630
|
+
1. Enable the `attr_concat` filter in your Eleventy config:
|
|
631
|
+
|
|
632
|
+
```javascript
|
|
633
|
+
import { attrConcatFilter } from "@anydigital/eleventy-bricks";
|
|
634
|
+
|
|
635
|
+
export default function (eleventyConfig) {
|
|
636
|
+
attrConcatFilter(eleventyConfig);
|
|
637
|
+
// Or use as plugin:
|
|
638
|
+
// eleventyConfig.addPlugin(eleventyBricks, { filters: ['attr_concat'] });
|
|
639
|
+
}
|
|
640
|
+
```
|
|
641
|
+
|
|
642
|
+
2. Use the filter in your templates:
|
|
643
|
+
|
|
644
|
+
```njk
|
|
645
|
+
{# Add tags to a post object #}
|
|
646
|
+
{% set enhancedPost = post | attr_concat('tags', ['featured', 'popular']) %}
|
|
647
|
+
|
|
648
|
+
{# Add a single value #}
|
|
649
|
+
{% set updatedPost = post | attr_concat('tags', 'important') %}
|
|
650
|
+
|
|
651
|
+
{# Add values from a JSON string #}
|
|
652
|
+
{% set modifiedPost = post | attr_concat('tags', '["new", "trending"]') %}
|
|
653
|
+
```
|
|
654
|
+
|
|
655
|
+
**Parameters:**
|
|
656
|
+
|
|
657
|
+
- `obj`: The object to modify
|
|
658
|
+
- `attr`: The attribute name (must be an array or will be treated as one)
|
|
659
|
+
- `values`: Values to concatenate (can be an array, JSON string array, or single value)
|
|
660
|
+
|
|
661
|
+
**Returns:**
|
|
662
|
+
|
|
663
|
+
A new object with the specified attribute containing the combined unique array. The original object is not modified.
|
|
664
|
+
|
|
665
|
+
**Features:**
|
|
666
|
+
|
|
667
|
+
- Non-mutating: Creates a new object, leaving the original unchanged
|
|
668
|
+
- Automatically removes duplicates using Set
|
|
669
|
+
- Handles multiple input types: arrays, JSON string arrays, or single values
|
|
670
|
+
- Creates the attribute as an empty array if it doesn't exist
|
|
671
|
+
- Logs an error if the existing attribute is not an array
|
|
672
|
+
|
|
673
|
+
**Examples:**
|
|
674
|
+
|
|
675
|
+
```njk
|
|
676
|
+
{# Add multiple tags #}
|
|
677
|
+
{% set post = { title: 'My Post', tags: ['javascript'] } %}
|
|
678
|
+
{% set enhancedPost = post | attr_concat('tags', ['tutorial', 'beginner']) %}
|
|
679
|
+
{# Result: { title: 'My Post', tags: ['javascript', 'tutorial', 'beginner'] } #}
|
|
680
|
+
|
|
681
|
+
{# Add single value #}
|
|
682
|
+
{% set updatedPost = post | attr_concat('tags', 'featured') %}
|
|
683
|
+
{# Result: { title: 'My Post', tags: ['javascript', 'tutorial', 'beginner', 'featured'] } #}
|
|
684
|
+
|
|
685
|
+
{# No duplicates #}
|
|
686
|
+
{% set deduped = post | attr_concat('tags', ['javascript', 'advanced']) %}
|
|
687
|
+
{# Result: Only 'advanced' is added, 'javascript' already exists #}
|
|
688
|
+
|
|
689
|
+
{# Chain multiple attr_concat filters #}
|
|
690
|
+
{% set finalPost = post
|
|
691
|
+
| attr_concat('tags', 'popular')
|
|
692
|
+
| attr_concat('categories', ['tech', 'programming'])
|
|
693
|
+
%}
|
|
694
|
+
|
|
695
|
+
{# Use in loops to enhance collection items #}
|
|
696
|
+
{% for item in collections.posts %}
|
|
697
|
+
{% set enhancedItem = item | attr_concat('data.tags', 'blog') %}
|
|
698
|
+
{# ... use enhancedItem ... #}
|
|
699
|
+
{% endfor %}
|
|
700
|
+
```
|
|
701
|
+
|
|
603
702
|
### siteData
|
|
604
703
|
|
|
605
704
|
Adds global site data to your Eleventy project, providing commonly needed values that can be accessed in all templates.
|
|
@@ -615,7 +714,7 @@ Many websites need access to the current year (for copyright notices) and enviro
|
|
|
615
714
|
```javascript
|
|
616
715
|
import { siteData } from "@anydigital/eleventy-bricks";
|
|
617
716
|
|
|
618
|
-
export default function(eleventyConfig) {
|
|
717
|
+
export default function (eleventyConfig) {
|
|
619
718
|
siteData(eleventyConfig);
|
|
620
719
|
// Or use as plugin:
|
|
621
720
|
// eleventyConfig.addPlugin(eleventyBricks, { siteData: true });
|
|
@@ -625,6 +724,7 @@ export default function(eleventyConfig) {
|
|
|
625
724
|
2. Use the global data in your templates:
|
|
626
725
|
|
|
627
726
|
**Current Year:**
|
|
727
|
+
|
|
628
728
|
```njk
|
|
629
729
|
<footer>
|
|
630
730
|
<p>© {{ site.year }} Your Company Name. All rights reserved.</p>
|
|
@@ -632,8 +732,9 @@ export default function(eleventyConfig) {
|
|
|
632
732
|
```
|
|
633
733
|
|
|
634
734
|
**Environment Check:**
|
|
735
|
+
|
|
635
736
|
```njk
|
|
636
|
-
{% if site.
|
|
737
|
+
{% if site.prod %}
|
|
637
738
|
<!-- Production-only features -->
|
|
638
739
|
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_TRACKING_ID"></script>
|
|
639
740
|
{% else %}
|
|
@@ -645,7 +746,7 @@ export default function(eleventyConfig) {
|
|
|
645
746
|
**Available Data:**
|
|
646
747
|
|
|
647
748
|
- `site.year`: The current year as a number (e.g., `2026`)
|
|
648
|
-
- `site.
|
|
749
|
+
- `site.prod`: Boolean indicating if running in production mode (`true` for `eleventy build`, `false` for `eleventy serve`)
|
|
649
750
|
|
|
650
751
|
**Features:**
|
|
651
752
|
|
|
@@ -661,12 +762,12 @@ export default function(eleventyConfig) {
|
|
|
661
762
|
<p>Copyright © {{ site.year }} My Site</p>
|
|
662
763
|
|
|
663
764
|
{# Conditional loading of analytics #}
|
|
664
|
-
{% if site.
|
|
765
|
+
{% if site.prod %}
|
|
665
766
|
<script src="/analytics.js"></script>
|
|
666
767
|
{% endif %}
|
|
667
768
|
|
|
668
769
|
{# Different behavior in dev vs prod #}
|
|
669
|
-
{% if site.
|
|
770
|
+
{% if site.prod %}
|
|
670
771
|
<link rel="stylesheet" href="/css/styles.min.css">
|
|
671
772
|
{% else %}
|
|
672
773
|
<link rel="stylesheet" href="/css/styles.css">
|
|
@@ -676,10 +777,14 @@ export default function(eleventyConfig) {
|
|
|
676
777
|
|
|
677
778
|
### Additional Exports
|
|
678
779
|
|
|
679
|
-
The plugin also exports the following for advanced usage:
|
|
780
|
+
The plugin also exports the following utility functions for advanced usage:
|
|
680
781
|
|
|
681
782
|
- `transformAutoRaw(content)`: The transform function used by `mdAutoRawTags` preprocessor. Can be used programmatically to wrap Nunjucks syntax with raw tags.
|
|
682
783
|
- `transformNl2br(content)`: The transform function used by `mdAutoNl2br` preprocessor. Can be used programmatically to convert `\n` sequences to `<br>` tags.
|
|
784
|
+
- `merge(first, ...rest)`: The core merge function used by the `merge` filter. Can be used programmatically to merge arrays or objects.
|
|
785
|
+
- `removeTag(html, tagName)`: The core function used by the `remove_tag` filter. Can be used programmatically to remove HTML tags from content.
|
|
786
|
+
- `iff(trueValue, condition, falseValue)`: The core conditional function used by the `if` filter. Can be used programmatically as a ternary operator.
|
|
787
|
+
- `attrConcat(obj, attr, values)`: The core function used by the `attr_concat` filter. Can be used programmatically to concatenate values to an attribute array.
|
|
683
788
|
|
|
684
789
|
## Starter Configuration Files
|
|
685
790
|
|
|
@@ -690,19 +795,22 @@ The package includes pre-configured starter files in `node_modules/@anydigital/e
|
|
|
690
795
|
#### eleventy.config.js
|
|
691
796
|
|
|
692
797
|
A fully-configured Eleventy config file with:
|
|
798
|
+
|
|
693
799
|
- All eleventy-bricks plugins enabled
|
|
694
800
|
- Eleventy Navigation plugin
|
|
695
|
-
- Markdown-it with anchors
|
|
801
|
+
- Markdown-it with anchors and attributes
|
|
696
802
|
- YAML data support
|
|
697
803
|
- CLI input directory support
|
|
698
804
|
- Symlink support for development
|
|
699
805
|
|
|
700
806
|
**Required dependencies:**
|
|
807
|
+
|
|
701
808
|
```bash
|
|
702
|
-
npm install @11ty/eleventy-navigation markdown-it markdown-it-anchor js-yaml minimist
|
|
809
|
+
npm install @11ty/eleventy-navigation markdown-it markdown-it-anchor markdown-it-attrs js-yaml minimist
|
|
703
810
|
```
|
|
704
811
|
|
|
705
812
|
**Symlink to your project:**
|
|
813
|
+
|
|
706
814
|
```bash
|
|
707
815
|
ln -s node_modules/@anydigital/eleventy-bricks/src/eleventy.config.js eleventy.config.js
|
|
708
816
|
```
|
|
@@ -712,6 +820,7 @@ ln -s node_modules/@anydigital/eleventy-bricks/src/eleventy.config.js eleventy.c
|
|
|
712
820
|
A ready-to-use Sveltia CMS admin interface for content management.
|
|
713
821
|
|
|
714
822
|
**Symlink to your project:**
|
|
823
|
+
|
|
715
824
|
```bash
|
|
716
825
|
mkdir -p admin
|
|
717
826
|
ln -s ../node_modules/@anydigital/eleventy-bricks/src/admin/index.html admin/index.html
|
|
@@ -852,7 +961,7 @@ npx download-files --output public
|
|
|
852
961
|
## Requirements
|
|
853
962
|
|
|
854
963
|
- Node.js >= 18.0.0
|
|
855
|
-
- Eleventy >=
|
|
964
|
+
- Eleventy >= 3.0.0
|
|
856
965
|
|
|
857
966
|
## License
|
|
858
967
|
|