@anydigital/11ty-bricks 1.0.0-alpha.6 → 1.0.0-alpha.8
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/README.md +280 -65
- package/package.json +1 -1
- package/src/{bricksRegistry.js → bricks.js} +4 -4
- package/src/byAttrFilter.js +35 -0
- package/src/byAttrFilter.test.js +105 -0
- package/src/fragments.js +34 -0
- package/src/index.cjs +15 -9
- package/src/index.js +17 -12
- package/src/markdown.js +58 -0
- package/src/{autoRaw.test.js → markdown.test.js} +66 -1
- package/src/setAttrFilter.js +17 -0
- package/src/autoRaw.js +0 -28
- package/src/bricks/_gtm.njk +0 -16
- package/src/bricks/_nav.njk +0 -10
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ import eleventyBricks from "@anydigital/11ty-bricks";
|
|
|
22
22
|
|
|
23
23
|
export default function(eleventyConfig) {
|
|
24
24
|
eleventyConfig.addPlugin(eleventyBricks, {
|
|
25
|
-
|
|
25
|
+
mdAutoRawTags: true // Enable mdAutoRawTags preprocessor (default: false)
|
|
26
26
|
});
|
|
27
27
|
|
|
28
28
|
// Your other configuration...
|
|
@@ -35,7 +35,7 @@ const eleventyBricks = require("@anydigital/11ty-bricks");
|
|
|
35
35
|
|
|
36
36
|
module.exports = function(eleventyConfig) {
|
|
37
37
|
eleventyConfig.addPlugin(eleventyBricks, {
|
|
38
|
-
|
|
38
|
+
mdAutoRawTags: true // Enable mdAutoRawTags preprocessor (default: false)
|
|
39
39
|
});
|
|
40
40
|
|
|
41
41
|
// Your other configuration...
|
|
@@ -48,11 +48,11 @@ Import only the specific helpers you need without using the plugin:
|
|
|
48
48
|
|
|
49
49
|
**ES Modules:**
|
|
50
50
|
```javascript
|
|
51
|
-
import {
|
|
51
|
+
import { bricks, mdAutoRawTags } from "@anydigital/11ty-bricks";
|
|
52
52
|
|
|
53
53
|
export default function(eleventyConfig) {
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
bricks(eleventyConfig);
|
|
55
|
+
mdAutoRawTags(eleventyConfig);
|
|
56
56
|
|
|
57
57
|
// Your other configuration...
|
|
58
58
|
}
|
|
@@ -60,11 +60,11 @@ export default function(eleventyConfig) {
|
|
|
60
60
|
|
|
61
61
|
**CommonJS:**
|
|
62
62
|
```javascript
|
|
63
|
-
const {
|
|
63
|
+
const { bricks, mdAutoRawTags } = require("@anydigital/11ty-bricks");
|
|
64
64
|
|
|
65
65
|
module.exports = function(eleventyConfig) {
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
bricks(eleventyConfig);
|
|
67
|
+
mdAutoRawTags(eleventyConfig);
|
|
68
68
|
|
|
69
69
|
// Your other configuration...
|
|
70
70
|
};
|
|
@@ -76,57 +76,64 @@ When using the plugin (Option 1), you can configure which helpers to enable:
|
|
|
76
76
|
|
|
77
77
|
| Option | Type | Default | Description |
|
|
78
78
|
|--------|------|---------|-------------|
|
|
79
|
-
| `
|
|
80
|
-
| `
|
|
79
|
+
| `bricks` | boolean | `false` | Enable the bricks system for dependency management |
|
|
80
|
+
| `mdAutoRawTags` | boolean | `false` | Enable the mdAutoRawTags preprocessor for Markdown files |
|
|
81
|
+
| `mdAutoNl2br` | boolean | `false` | Enable the mdAutoNl2br preprocessor to convert \n to `<br>` tags |
|
|
82
|
+
| `fragments` | boolean | `false` | Enable the fragment shortcode for including content from fragments |
|
|
83
|
+
| `setAttrFilter` | boolean | `false` | Enable the setAttr filter for overriding object attributes |
|
|
84
|
+
| `byAttrFilter` | boolean | `false` | Enable the byAttr filter for filtering collections by attribute values |
|
|
81
85
|
|
|
82
86
|
**Example:**
|
|
83
87
|
```javascript
|
|
84
88
|
eleventyConfig.addPlugin(eleventyBricks, {
|
|
85
|
-
|
|
86
|
-
|
|
89
|
+
bricks: true,
|
|
90
|
+
mdAutoRawTags: true,
|
|
91
|
+
byAttrFilter: true
|
|
87
92
|
});
|
|
88
93
|
```
|
|
89
94
|
|
|
90
95
|
## Available 11ty Helpers
|
|
91
96
|
|
|
92
|
-
###
|
|
97
|
+
### bricks
|
|
93
98
|
|
|
94
99
|
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.
|
|
95
100
|
|
|
96
101
|
**Why use this?**
|
|
97
102
|
|
|
98
|
-
When building reusable components (bricks) in Eleventy, you often need to include CSS and JavaScript dependencies. Instead of manually adding these to every page, `
|
|
103
|
+
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:
|
|
99
104
|
- Collects dependencies from all bricks used on a page
|
|
100
105
|
- Categorizes them (external CSS, external JS, inline styles, inline scripts)
|
|
101
106
|
- Injects them in the correct location in your HTML output
|
|
102
107
|
|
|
103
108
|
**How it works:**
|
|
104
109
|
|
|
105
|
-
1. Use the `
|
|
110
|
+
1. Use the `bricksDependencies` shortcode in your base template to mark where dependencies should be injected
|
|
106
111
|
2. Use the `brick` shortcode to register and render brick components that declare their dependencies
|
|
107
112
|
3. The system automatically collects all dependencies and injects them when the page is built
|
|
108
113
|
|
|
109
114
|
**Usage:**
|
|
110
115
|
|
|
111
|
-
1. Enable `
|
|
116
|
+
1. Enable `bricks` in your Eleventy config:
|
|
112
117
|
|
|
113
118
|
```javascript
|
|
114
|
-
import {
|
|
119
|
+
import { bricks } from "@anydigital/11ty-bricks";
|
|
115
120
|
|
|
116
121
|
export default function(eleventyConfig) {
|
|
117
|
-
|
|
122
|
+
bricks(eleventyConfig);
|
|
118
123
|
// Or use as plugin:
|
|
119
|
-
// eleventyConfig.addPlugin(eleventyBricks, {
|
|
124
|
+
// eleventyConfig.addPlugin(eleventyBricks, { bricks: true });
|
|
120
125
|
}
|
|
121
126
|
```
|
|
122
127
|
|
|
123
|
-
2. Add the `
|
|
128
|
+
2. Add the `bricksDependencies` shortcode in your base template (typically in the `<head>` section):
|
|
124
129
|
|
|
125
130
|
```njk
|
|
126
131
|
<head>
|
|
127
132
|
<meta charset="UTF-8">
|
|
128
133
|
<title>My Site</title>
|
|
129
|
-
{%
|
|
134
|
+
{% bricksDependencies [
|
|
135
|
+
... (global dependencies can be set here) ...
|
|
136
|
+
] %}
|
|
130
137
|
<!-- Other head content -->
|
|
131
138
|
</head>
|
|
132
139
|
```
|
|
@@ -192,101 +199,309 @@ The system will automatically inject all dependencies in the order they were reg
|
|
|
192
199
|
- Works with both external URLs and inline code
|
|
193
200
|
- Clears registry before each build to prevent stale data
|
|
194
201
|
|
|
195
|
-
###
|
|
202
|
+
### mdAutoRawTags
|
|
196
203
|
|
|
197
204
|
Prevents Nunjucks syntax from being processed in Markdown files by automatically wrapping `{{`, `}}`, `{%`, and `%}` with `{% raw %}` tags.
|
|
198
205
|
|
|
199
206
|
**Why use this?**
|
|
200
207
|
|
|
201
|
-
When writing documentation or tutorials about templating in Markdown files, you often want to show Nunjucks/Liquid syntax as literal text. This
|
|
208
|
+
When writing documentation or tutorials about templating in Markdown files, you often want to show Nunjucks/Liquid syntax as literal text. This preprocessor automatically escapes these special characters so they display as-is instead of being processed by the template engine.
|
|
209
|
+
|
|
210
|
+
**Usage:**
|
|
211
|
+
|
|
212
|
+
1. Enable `mdAutoRawTags` in your Eleventy config:
|
|
213
|
+
|
|
214
|
+
```javascript
|
|
215
|
+
import { mdAutoRawTags } from "@anydigital/11ty-bricks";
|
|
216
|
+
|
|
217
|
+
export default function(eleventyConfig) {
|
|
218
|
+
mdAutoRawTags(eleventyConfig);
|
|
219
|
+
// Or use as plugin:
|
|
220
|
+
// eleventyConfig.addPlugin(eleventyBricks, { mdAutoRawTags: true });
|
|
221
|
+
}
|
|
222
|
+
```
|
|
202
223
|
|
|
203
224
|
**Example:**
|
|
204
225
|
|
|
205
|
-
Before `
|
|
226
|
+
Before `mdAutoRawTags`, writing this in Markdown:
|
|
206
227
|
```markdown
|
|
207
228
|
Use {{ variable }} to output variables.
|
|
208
229
|
```
|
|
209
230
|
|
|
210
|
-
Would try to process `{{ variable }}` as a template variable. With `
|
|
231
|
+
Would try to process `{{ variable }}` as a template variable. With `mdAutoRawTags`, it displays exactly as written.
|
|
211
232
|
|
|
212
|
-
|
|
233
|
+
### mdAutoNl2br
|
|
213
234
|
|
|
214
|
-
|
|
235
|
+
Automatically converts `\n` sequences to `<br>` tags in Markdown content. This is particularly useful for adding line breaks inside Markdown tables where standard newlines don't work.
|
|
215
236
|
|
|
216
|
-
|
|
237
|
+
**Why use this?**
|
|
238
|
+
|
|
239
|
+
Markdown tables don't support multi-line content in cells. By using `\n` in your content, this preprocessor will convert it to `<br>` tags, allowing you to display line breaks within table cells and other content.
|
|
217
240
|
|
|
218
241
|
**Usage:**
|
|
219
242
|
|
|
220
|
-
1.
|
|
243
|
+
1. Enable `mdAutoNl2br` in your Eleventy config:
|
|
221
244
|
|
|
222
|
-
```
|
|
223
|
-
{
|
|
245
|
+
```javascript
|
|
246
|
+
import { mdAutoNl2br } from "@anydigital/11ty-bricks";
|
|
247
|
+
|
|
248
|
+
export default function(eleventyConfig) {
|
|
249
|
+
mdAutoNl2br(eleventyConfig);
|
|
250
|
+
// Or use as plugin:
|
|
251
|
+
// eleventyConfig.addPlugin(eleventyBricks, { mdAutoNl2br: true });
|
|
252
|
+
}
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
**Example:**
|
|
256
|
+
|
|
257
|
+
In your Markdown file:
|
|
258
|
+
```markdown
|
|
259
|
+
| Column 1 | Column 2 |
|
|
260
|
+
|----------|----------|
|
|
261
|
+
| Line 1\nLine 2\nLine 3 | Another cell\nWith multiple lines |
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Will render as:
|
|
265
|
+
```html
|
|
266
|
+
<td>Line 1<br>Line 2<br>Line 3</td>
|
|
267
|
+
<td>Another cell<br>With multiple lines</td>
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**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.
|
|
271
|
+
|
|
272
|
+
### fragment
|
|
273
|
+
|
|
274
|
+
A shortcode that includes content from fragment files stored in the `_fragments` directory. The content will be processed by the template engine.
|
|
275
|
+
|
|
276
|
+
**Why use this?**
|
|
277
|
+
|
|
278
|
+
Fragments allow you to organize reusable content snippets in a dedicated directory and include them in your templates. This is useful for:
|
|
279
|
+
- Reusable content blocks
|
|
280
|
+
- Shared template sections
|
|
281
|
+
- Component-like content organization
|
|
282
|
+
|
|
283
|
+
**Usage:**
|
|
284
|
+
|
|
285
|
+
1. Enable `fragment` in your Eleventy config:
|
|
286
|
+
|
|
287
|
+
```javascript
|
|
288
|
+
import { fragment } from "@anydigital/11ty-bricks";
|
|
289
|
+
|
|
290
|
+
export default function(eleventyConfig) {
|
|
291
|
+
fragment(eleventyConfig);
|
|
292
|
+
// Or use as plugin:
|
|
293
|
+
// eleventyConfig.addPlugin(eleventyBricks, { fragments: true });
|
|
294
|
+
}
|
|
224
295
|
```
|
|
225
296
|
|
|
226
|
-
2.
|
|
297
|
+
2. Create fragment files in the `_fragments` directory (relative to your input directory):
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
your-project/
|
|
301
|
+
_fragments/
|
|
302
|
+
header.njk
|
|
303
|
+
footer.njk
|
|
304
|
+
callout.md
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
3. Use the `fragment` shortcode in your templates:
|
|
227
308
|
|
|
228
309
|
```njk
|
|
229
|
-
{
|
|
310
|
+
{% fragment "header.njk" %}
|
|
311
|
+
|
|
312
|
+
<main>
|
|
313
|
+
<!-- Your content -->
|
|
314
|
+
</main>
|
|
315
|
+
|
|
316
|
+
{% fragment "footer.njk" %}
|
|
230
317
|
```
|
|
231
318
|
|
|
232
319
|
**Parameters:**
|
|
233
320
|
|
|
234
|
-
- `
|
|
235
|
-
- `curPage`: Current page object (use Eleventy's `page` variable)
|
|
321
|
+
- `path`: The path to the fragment file relative to the `_fragments` directory
|
|
236
322
|
|
|
237
323
|
**Features:**
|
|
238
324
|
|
|
239
|
-
-
|
|
240
|
-
-
|
|
241
|
-
-
|
|
242
|
-
-
|
|
325
|
+
- Reads files from `_fragments` directory in your input directory
|
|
326
|
+
- Content is processed by the template engine
|
|
327
|
+
- Supports any template language that Eleventy supports
|
|
328
|
+
- Shows helpful error comment if fragment is not found
|
|
329
|
+
|
|
330
|
+
**Example:**
|
|
243
331
|
|
|
244
|
-
|
|
332
|
+
Create `_fragments/callout.njk`:
|
|
333
|
+
```njk
|
|
334
|
+
<div class="callout callout-{{ type | default('info') }}">
|
|
335
|
+
{{ content }}
|
|
336
|
+
</div>
|
|
337
|
+
```
|
|
245
338
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
</nav>
|
|
339
|
+
Use it in your template:
|
|
340
|
+
```njk
|
|
341
|
+
{% set type = "warning" %}
|
|
342
|
+
{% set content = "This is important!" %}
|
|
343
|
+
{% fragment "callout.njk" %}
|
|
252
344
|
```
|
|
253
345
|
|
|
254
|
-
###
|
|
346
|
+
### setAttr
|
|
347
|
+
|
|
348
|
+
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.
|
|
255
349
|
|
|
256
|
-
|
|
350
|
+
**Why use this?**
|
|
351
|
+
|
|
352
|
+
When working with Eleventy data, you sometimes need to modify an object's properties for a specific use case. The `setAttr` filter provides a clean way to create a modified copy of an object without affecting the original.
|
|
257
353
|
|
|
258
354
|
**Usage:**
|
|
259
355
|
|
|
260
|
-
1.
|
|
356
|
+
1. Enable `setAttr` in your Eleventy config:
|
|
357
|
+
|
|
358
|
+
```javascript
|
|
359
|
+
import { setAttr } from "@anydigital/11ty-bricks";
|
|
360
|
+
|
|
361
|
+
export default function(eleventyConfig) {
|
|
362
|
+
setAttr(eleventyConfig);
|
|
363
|
+
// Or use as plugin:
|
|
364
|
+
// eleventyConfig.addPlugin(eleventyBricks, { setAttrFilter: true });
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
2. Use the filter in your templates:
|
|
261
369
|
|
|
262
370
|
```njk
|
|
263
|
-
{
|
|
371
|
+
{# Create a modified version of a page object #}
|
|
372
|
+
{% set modifiedPage = page | setAttr('title', 'New Title') %}
|
|
373
|
+
|
|
374
|
+
<h1>{{ modifiedPage.title }}</h1>
|
|
375
|
+
<p>Original title: {{ page.title }}</p>
|
|
264
376
|
```
|
|
265
377
|
|
|
266
|
-
|
|
378
|
+
**Parameters:**
|
|
379
|
+
|
|
380
|
+
- `obj`: The object to modify
|
|
381
|
+
- `key`: The attribute name to set (string)
|
|
382
|
+
- `value`: The value to set for the attribute (any type)
|
|
383
|
+
|
|
384
|
+
**Returns:**
|
|
385
|
+
|
|
386
|
+
A new object with the specified attribute set to the given value. The original object is not modified.
|
|
387
|
+
|
|
388
|
+
**Features:**
|
|
389
|
+
|
|
390
|
+
- Non-mutating: Creates a new object, leaving the original unchanged
|
|
391
|
+
- Works with any object type
|
|
392
|
+
- Supports any attribute name and value type
|
|
393
|
+
- Can be chained with other filters
|
|
394
|
+
|
|
395
|
+
**Examples:**
|
|
267
396
|
|
|
268
397
|
```njk
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
398
|
+
{# Override a single attribute #}
|
|
399
|
+
{% set updatedPost = post | setAttr('featured', true) %}
|
|
400
|
+
|
|
401
|
+
{# Chain multiple setAttr filters #}
|
|
402
|
+
{% set modifiedPost = post
|
|
403
|
+
| setAttr('category', 'blog')
|
|
404
|
+
| setAttr('priority', 1)
|
|
405
|
+
%}
|
|
406
|
+
|
|
407
|
+
{# Use in loops #}
|
|
408
|
+
{% for item in collection %}
|
|
409
|
+
{% set enhancedItem = item | setAttr('processed', true) %}
|
|
410
|
+
{# ... use enhancedItem ... #}
|
|
411
|
+
{% endfor %}
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
### byAttr
|
|
415
|
+
|
|
416
|
+
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.
|
|
417
|
+
|
|
418
|
+
**Why use this?**
|
|
419
|
+
|
|
420
|
+
When working with Eleventy collections, you often need to filter items based on front matter data. The `byAttr` filter provides a flexible way to filter by any attribute, with special handling for array attributes (like tags).
|
|
421
|
+
|
|
422
|
+
**Usage:**
|
|
423
|
+
|
|
424
|
+
1. Enable `byAttr` in your Eleventy config:
|
|
425
|
+
|
|
426
|
+
```javascript
|
|
427
|
+
import { byAttr } from "@anydigital/11ty-bricks";
|
|
428
|
+
|
|
429
|
+
export default function(eleventyConfig) {
|
|
430
|
+
byAttr(eleventyConfig);
|
|
431
|
+
// Or use as plugin:
|
|
432
|
+
// eleventyConfig.addPlugin(eleventyBricks, { byAttrFilter: true });
|
|
433
|
+
}
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
2. Use the filter in your templates:
|
|
437
|
+
|
|
438
|
+
**Filter by exact attribute match:**
|
|
439
|
+
```njk
|
|
440
|
+
{# Get all posts with category 'blog' #}
|
|
441
|
+
{% set blogPosts = collections.all | byAttr('category', 'blog') %}
|
|
442
|
+
|
|
443
|
+
{% for post in blogPosts %}
|
|
444
|
+
<h2>{{ post.data.title }}</h2>
|
|
445
|
+
{% endfor %}
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
**Filter by array attribute (tags):**
|
|
449
|
+
```njk
|
|
450
|
+
{# Get all posts that include 'javascript' tag #}
|
|
451
|
+
{% set jsPosts = collections.all | byAttr('tags', 'javascript') %}
|
|
452
|
+
|
|
453
|
+
{% for post in jsPosts %}
|
|
454
|
+
<h2>{{ post.data.title }}</h2>
|
|
455
|
+
{% endfor %}
|
|
277
456
|
```
|
|
278
457
|
|
|
279
458
|
**Parameters:**
|
|
280
459
|
|
|
281
|
-
|
|
282
|
-
- `
|
|
460
|
+
- `collection`: The collection to filter (array of items)
|
|
461
|
+
- `attrName`: The attribute name to check (string)
|
|
462
|
+
- `targetValue`: The value to match against (any type)
|
|
283
463
|
|
|
284
464
|
**Features:**
|
|
285
465
|
|
|
286
|
-
-
|
|
287
|
-
-
|
|
288
|
-
-
|
|
289
|
-
-
|
|
466
|
+
- Works with any attribute in front matter
|
|
467
|
+
- Handles both `item.data.attrName` and `item.attrName` patterns
|
|
468
|
+
- Special handling for array attributes (uses `includes()` check)
|
|
469
|
+
- Returns empty array if collection is invalid
|
|
470
|
+
- Filters out items without the specified attribute
|
|
471
|
+
|
|
472
|
+
**Examples:**
|
|
473
|
+
|
|
474
|
+
Front matter:
|
|
475
|
+
```yaml
|
|
476
|
+
---
|
|
477
|
+
title: My Post
|
|
478
|
+
category: blog
|
|
479
|
+
tags: [javascript, tutorial, beginner]
|
|
480
|
+
priority: 1
|
|
481
|
+
---
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
Template usage:
|
|
485
|
+
```njk
|
|
486
|
+
{# Filter by category #}
|
|
487
|
+
{% set blogPosts = collections.all | byAttr('category', 'blog') %}
|
|
488
|
+
|
|
489
|
+
{# Filter by tag (array) #}
|
|
490
|
+
{% set jsTutorials = collections.all | byAttr('tags', 'javascript') %}
|
|
491
|
+
|
|
492
|
+
{# Filter by numeric value #}
|
|
493
|
+
{% set highPriority = collections.all | byAttr('priority', 1) %}
|
|
494
|
+
|
|
495
|
+
{# Chain filters #}
|
|
496
|
+
{% set recentBlogPosts = collections.all | byAttr('category', 'blog') | reverse | limit(5) %}
|
|
497
|
+
```
|
|
498
|
+
|
|
499
|
+
### Additional Exports
|
|
500
|
+
|
|
501
|
+
The plugin also exports the following for advanced usage:
|
|
502
|
+
|
|
503
|
+
- `transformAutoRaw(content)`: The transform function used by `mdAutoRawTags` preprocessor. Can be used programmatically to wrap Nunjucks syntax with raw tags.
|
|
504
|
+
- `transformNl2br(content)`: The transform function used by `mdAutoNl2br` preprocessor. Can be used programmatically to convert `\n` sequences to `<br>` tags.
|
|
290
505
|
|
|
291
506
|
## CLI Helper Commands
|
|
292
507
|
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export function
|
|
1
|
+
export function bricks(eleventyConfig) {
|
|
2
2
|
|
|
3
3
|
// Brick Registry System
|
|
4
4
|
// Global registry to track dependencies per page
|
|
@@ -23,7 +23,7 @@ export function bricksRegistry(eleventyConfig) {
|
|
|
23
23
|
});
|
|
24
24
|
|
|
25
25
|
// brick shortcode: registers and renders a brick component
|
|
26
|
-
eleventyConfig.addShortcode("brick", function(brickModule) {
|
|
26
|
+
eleventyConfig.addShortcode("brick", function(brickModule, ...args) {
|
|
27
27
|
const registry = getPageRegistry(this.page);
|
|
28
28
|
|
|
29
29
|
if (!brickModule) return '';
|
|
@@ -47,14 +47,14 @@ export function bricksRegistry(eleventyConfig) {
|
|
|
47
47
|
|
|
48
48
|
// Render the brick using render() macro
|
|
49
49
|
if (brickModule.render && typeof brickModule.render === 'function') {
|
|
50
|
-
return brickModule.render();
|
|
50
|
+
return brickModule.render(...args);
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
return '';
|
|
54
54
|
});
|
|
55
55
|
|
|
56
56
|
// bricksRegistry shortcode: outputs placeholder and base dependencies
|
|
57
|
-
eleventyConfig.addShortcode("
|
|
57
|
+
eleventyConfig.addShortcode("bricksDependencies", function(dependencies = []) {
|
|
58
58
|
const registry = getPageRegistry(this.page);
|
|
59
59
|
|
|
60
60
|
// Register root dependencies if provided (categorized later in transform)
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* byAttr filter - Filter collection items by attribute value
|
|
3
|
+
*
|
|
4
|
+
* This filter takes a collection, an attribute name, and a target value,
|
|
5
|
+
* and returns items where the attribute matches the target value.
|
|
6
|
+
* If the attribute is an array, it checks if the array includes the target value.
|
|
7
|
+
*
|
|
8
|
+
* @param {Object} eleventyConfig - The Eleventy configuration object
|
|
9
|
+
*/
|
|
10
|
+
export function byAttrFilter(eleventyConfig) {
|
|
11
|
+
eleventyConfig.addFilter("byAttr", function(collection, attrName, targetValue) {
|
|
12
|
+
if (!collection || !Array.isArray(collection)) {
|
|
13
|
+
return [];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
return collection.filter(item => {
|
|
17
|
+
// Get the attribute value from the item's data
|
|
18
|
+
const attrValue = item?.data?.[attrName] ?? item?.[attrName];
|
|
19
|
+
|
|
20
|
+
// If attribute doesn't exist, skip this item
|
|
21
|
+
if (attrValue === undefined || attrValue === null) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// If the attribute is an array, check if it includes the target value
|
|
26
|
+
if (Array.isArray(attrValue)) {
|
|
27
|
+
return attrValue.includes(targetValue);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Otherwise, do a direct comparison
|
|
31
|
+
return attrValue === targetValue;
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { describe, it } from 'node:test';
|
|
2
|
+
import assert from 'node:assert';
|
|
3
|
+
import { byAttrFilter } from './byAttrFilter.js';
|
|
4
|
+
|
|
5
|
+
describe('byAttr filter', () => {
|
|
6
|
+
let filterFn;
|
|
7
|
+
|
|
8
|
+
// Mock eleventyConfig to capture the filter function
|
|
9
|
+
const mockEleventyConfig = {
|
|
10
|
+
addFilter(name, fn) {
|
|
11
|
+
if (name === 'byAttr') {
|
|
12
|
+
filterFn = fn;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Register the filter
|
|
18
|
+
byAttrFilter(mockEleventyConfig);
|
|
19
|
+
|
|
20
|
+
it('should filter items by exact attribute match', () => {
|
|
21
|
+
const collection = [
|
|
22
|
+
{ data: { category: 'blog' }, title: 'Post 1' },
|
|
23
|
+
{ data: { category: 'news' }, title: 'Post 2' },
|
|
24
|
+
{ data: { category: 'blog' }, title: 'Post 3' }
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
const result = filterFn(collection, 'category', 'blog');
|
|
28
|
+
assert.strictEqual(result.length, 2);
|
|
29
|
+
assert.strictEqual(result[0].title, 'Post 1');
|
|
30
|
+
assert.strictEqual(result[1].title, 'Post 3');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('should filter items when attribute is an array (includes check)', () => {
|
|
34
|
+
const collection = [
|
|
35
|
+
{ data: { tags: ['javascript', 'tutorial'] }, title: 'Post 1' },
|
|
36
|
+
{ data: { tags: ['python', 'tutorial'] }, title: 'Post 2' },
|
|
37
|
+
{ data: { tags: ['javascript', 'advanced'] }, title: 'Post 3' }
|
|
38
|
+
];
|
|
39
|
+
|
|
40
|
+
const result = filterFn(collection, 'tags', 'javascript');
|
|
41
|
+
assert.strictEqual(result.length, 2);
|
|
42
|
+
assert.strictEqual(result[0].title, 'Post 1');
|
|
43
|
+
assert.strictEqual(result[1].title, 'Post 3');
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should return empty array when collection is not an array', () => {
|
|
47
|
+
const result = filterFn(null, 'category', 'blog');
|
|
48
|
+
assert.strictEqual(result.length, 0);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should filter out items without the specified attribute', () => {
|
|
52
|
+
const collection = [
|
|
53
|
+
{ data: { category: 'blog' }, title: 'Post 1' },
|
|
54
|
+
{ data: {}, title: 'Post 2' },
|
|
55
|
+
{ data: { category: 'blog' }, title: 'Post 3' }
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
const result = filterFn(collection, 'category', 'blog');
|
|
59
|
+
assert.strictEqual(result.length, 2);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should work with attribute directly on item (not in data)', () => {
|
|
63
|
+
const collection = [
|
|
64
|
+
{ category: 'blog', title: 'Post 1' },
|
|
65
|
+
{ category: 'news', title: 'Post 2' },
|
|
66
|
+
{ category: 'blog', title: 'Post 3' }
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
const result = filterFn(collection, 'category', 'blog');
|
|
70
|
+
assert.strictEqual(result.length, 2);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
it('should handle mixed data structures', () => {
|
|
74
|
+
const collection = [
|
|
75
|
+
{ data: { category: 'blog' }, title: 'Post 1' },
|
|
76
|
+
{ category: 'blog', title: 'Post 2' },
|
|
77
|
+
{ data: { category: 'news' }, title: 'Post 3' }
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
const result = filterFn(collection, 'category', 'blog');
|
|
81
|
+
assert.strictEqual(result.length, 2);
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
it('should handle array that does not include target value', () => {
|
|
85
|
+
const collection = [
|
|
86
|
+
{ data: { tags: ['python', 'tutorial'] }, title: 'Post 1' },
|
|
87
|
+
{ data: { tags: ['ruby', 'guide'] }, title: 'Post 2' }
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
const result = filterFn(collection, 'tags', 'javascript');
|
|
91
|
+
assert.strictEqual(result.length, 0);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should handle different value types', () => {
|
|
95
|
+
const collection = [
|
|
96
|
+
{ data: { priority: 1 }, title: 'Post 1' },
|
|
97
|
+
{ data: { priority: 2 }, title: 'Post 2' },
|
|
98
|
+
{ data: { priority: 1 }, title: 'Post 3' }
|
|
99
|
+
];
|
|
100
|
+
|
|
101
|
+
const result = filterFn(collection, 'priority', 1);
|
|
102
|
+
assert.strictEqual(result.length, 2);
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
|
package/src/fragments.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* fragment shortcode - Include content from fragments
|
|
6
|
+
*
|
|
7
|
+
* This shortcode reads a file from the _fragments directory and includes
|
|
8
|
+
* its content. The content will be processed by the template engine.
|
|
9
|
+
*
|
|
10
|
+
* @param {Object} eleventyConfig - The Eleventy configuration object
|
|
11
|
+
*/
|
|
12
|
+
export function fragments(eleventyConfig) {
|
|
13
|
+
eleventyConfig.addShortcode("fragment", function(path) {
|
|
14
|
+
// Get the input directory from Eleventy's context
|
|
15
|
+
const inputDir = this.page?.inputPath
|
|
16
|
+
? join(process.cwd(), eleventyConfig.dir?.input || ".")
|
|
17
|
+
: process.cwd();
|
|
18
|
+
|
|
19
|
+
// Construct the full path to the fragment file
|
|
20
|
+
const fragmentPath = join(inputDir, "_fragments", path);
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
// Read the fragment file
|
|
24
|
+
const content = readFileSync(fragmentPath, "utf8");
|
|
25
|
+
|
|
26
|
+
// Return content to be processed by the template engine
|
|
27
|
+
return content;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
console.error(`Error reading fragment at ${fragmentPath}:`, error.message);
|
|
30
|
+
return `<!-- Fragment not found: ${path} -->`;
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
|
package/src/index.cjs
CHANGED
|
@@ -9,12 +9,18 @@ module.exports = async function eleventyBricksPlugin(eleventyConfig, options) {
|
|
|
9
9
|
return plugin(eleventyConfig, options);
|
|
10
10
|
};
|
|
11
11
|
|
|
12
|
-
// Export individual helpers
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
12
|
+
// Export individual helpers for granular usage
|
|
13
|
+
['bricks', 'mdAutoRawTags', 'mdAutoNl2br', 'fragments', 'setAttrFilter', 'byAttrFilter'].forEach(name => {
|
|
14
|
+
module.exports[name] = async (eleventyConfig) => {
|
|
15
|
+
const module = await import('./index.js');
|
|
16
|
+
return module[name](eleventyConfig);
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
// Export transform functions for advanced usage
|
|
21
|
+
['transformAutoRaw', 'transformNl2br'].forEach(name => {
|
|
22
|
+
module.exports[name] = async (content) => {
|
|
23
|
+
const module = await import('./index.js');
|
|
24
|
+
return module[name](content);
|
|
25
|
+
};
|
|
26
|
+
});
|
package/src/index.js
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { bricks } from "./bricks.js";
|
|
2
|
+
import { mdAutoRawTags, mdAutoNl2br, transformAutoRaw, transformNl2br } from "./markdown.js";
|
|
3
|
+
import { fragments } from "./fragments.js";
|
|
4
|
+
import { setAttrFilter } from "./setAttrFilter.js";
|
|
5
|
+
import { byAttrFilter } from "./byAttrFilter.js";
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
8
|
* 11ty Bricks Plugin
|
|
@@ -9,18 +12,20 @@ import { autoRaw } from "./autoRaw.js";
|
|
|
9
12
|
*
|
|
10
13
|
* @param {Object} eleventyConfig - The Eleventy configuration object
|
|
11
14
|
* @param {Object} options - Plugin options
|
|
12
|
-
* @param {boolean} options.
|
|
13
|
-
* @param {boolean} options.
|
|
15
|
+
* @param {boolean} options.bricks - Enable bricks system with dependencies injection (default: false)
|
|
16
|
+
* @param {boolean} options.mdAutoRawTags - Enable mdAutoRawTags preprocessor (default: false)
|
|
17
|
+
* @param {boolean} options.mdAutoNl2br - Enable mdAutoNl2br for \n to <br> conversion (default: false)
|
|
18
|
+
* @param {boolean} options.fragments - Enable fragment shortcode (default: false)
|
|
19
|
+
* @param {boolean} options.setAttrFilter - Enable setAttr filter (default: false)
|
|
20
|
+
* @param {boolean} options.byAttrFilter - Enable byAttr filter (default: false)
|
|
14
21
|
*/
|
|
15
22
|
export default function eleventyBricksPlugin(eleventyConfig, options = {}) {
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
19
|
-
if (options.autoRaw) {
|
|
20
|
-
autoRaw(eleventyConfig);
|
|
21
|
-
}
|
|
23
|
+
const plugins = { bricks, mdAutoRawTags, mdAutoNl2br, fragments, setAttrFilter, byAttrFilter };
|
|
24
|
+
Object.entries(options).forEach(([key, enabled]) => enabled && plugins[key]?.(eleventyConfig));
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
// Export individual helpers for granular usage
|
|
25
|
-
export {
|
|
26
|
-
|
|
28
|
+
export { bricks, mdAutoRawTags, mdAutoNl2br, fragments, setAttrFilter, byAttrFilter };
|
|
29
|
+
|
|
30
|
+
// Export transform functions for advanced usage
|
|
31
|
+
export { transformAutoRaw, transformNl2br };
|
package/src/markdown.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform Nunjucks syntax in content by wrapping it with raw tags
|
|
3
|
+
*
|
|
4
|
+
* This function wraps Nunjucks syntax ({{, }}, {%, %}) with {% raw %} tags
|
|
5
|
+
* to prevent them from being processed by the template engine.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} content - The content to transform
|
|
8
|
+
* @returns {string} The transformed content with Nunjucks syntax wrapped
|
|
9
|
+
*/
|
|
10
|
+
export function transformAutoRaw(content) {
|
|
11
|
+
// This regex looks for {{, }}, {%, or %} individually and wraps them
|
|
12
|
+
return content.replace(/({{|}}|{%|%})/g, "{% raw %}$1{% endraw %}");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* mdAutoRawTags - Forbid Nunjucks processing in Markdown files
|
|
17
|
+
*
|
|
18
|
+
* This preprocessor wraps Nunjucks syntax ({{, }}, {%, %}) with {% raw %} tags
|
|
19
|
+
* to prevent them from being processed by the template engine in Markdown files.
|
|
20
|
+
*
|
|
21
|
+
* @param {Object} eleventyConfig - The Eleventy configuration object
|
|
22
|
+
*/
|
|
23
|
+
export function mdAutoRawTags(eleventyConfig) {
|
|
24
|
+
eleventyConfig.addPreprocessor("mdAutoRawTags", "md", (data, content) => {
|
|
25
|
+
return transformAutoRaw(content);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Transform \n sequences to <br> tags
|
|
31
|
+
*
|
|
32
|
+
* This function converts literal \n sequences (double backslash + n) to HTML <br> tags.
|
|
33
|
+
* It handles both double \n\n and single \n sequences, processing double ones first.
|
|
34
|
+
*
|
|
35
|
+
* @param {string} content - The content to transform
|
|
36
|
+
* @returns {string} The transformed content with \n converted to <br>
|
|
37
|
+
*/
|
|
38
|
+
export function transformNl2br(content) {
|
|
39
|
+
// Replace double \n\n first, then single \n to avoid double conversion
|
|
40
|
+
return content.replace(/\\n\\n/g, '<br>').replace(/\\n/g, '<br>');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* mdAutoNl2br - Auto convert \n to <br> in markdown (especially tables)
|
|
45
|
+
*
|
|
46
|
+
* This function amends the markdown library to automatically convert \n
|
|
47
|
+
* to <br> tags in text content, which is particularly useful for line breaks
|
|
48
|
+
* inside markdown tables where standard newlines don't work.
|
|
49
|
+
*
|
|
50
|
+
* @param {Object} eleventyConfig - The Eleventy configuration object
|
|
51
|
+
*/
|
|
52
|
+
export function mdAutoNl2br(eleventyConfig) {
|
|
53
|
+
eleventyConfig.amendLibrary("md", mdLib => {
|
|
54
|
+
mdLib.renderer.rules.text = (tokens, idx) => {
|
|
55
|
+
return transformNl2br(tokens[idx].content);
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it } from "node:test";
|
|
2
2
|
import assert from "node:assert/strict";
|
|
3
|
-
import { transformAutoRaw } from "./
|
|
3
|
+
import { transformAutoRaw, transformNl2br } from "./markdown.js";
|
|
4
4
|
|
|
5
5
|
describe("transformAutoRaw", () => {
|
|
6
6
|
it("should wrap opening double curly braces with raw tags", () => {
|
|
@@ -85,3 +85,68 @@ Some text
|
|
|
85
85
|
});
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
+
describe("transformNl2br", () => {
|
|
89
|
+
it("should convert single \\n to <br>", () => {
|
|
90
|
+
const input = "Line 1\\nLine 2";
|
|
91
|
+
const expected = "Line 1<br>Line 2";
|
|
92
|
+
assert.equal(transformNl2br(input), expected);
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
it("should convert double \\n\\n to <br>", () => {
|
|
96
|
+
const input = "Line 1\\n\\nLine 2";
|
|
97
|
+
const expected = "Line 1<br>Line 2";
|
|
98
|
+
assert.equal(transformNl2br(input), expected);
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
it("should convert multiple \\n sequences", () => {
|
|
102
|
+
const input = "Line 1\\nLine 2\\nLine 3";
|
|
103
|
+
const expected = "Line 1<br>Line 2<br>Line 3";
|
|
104
|
+
assert.equal(transformNl2br(input), expected);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it("should handle mixed single and double \\n", () => {
|
|
108
|
+
const input = "Line 1\\n\\nLine 2\\nLine 3";
|
|
109
|
+
const expected = "Line 1<br>Line 2<br>Line 3";
|
|
110
|
+
assert.equal(transformNl2br(input), expected);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it("should handle text without \\n", () => {
|
|
114
|
+
const input = "Just plain text";
|
|
115
|
+
assert.equal(transformNl2br(input), input);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
it("should handle empty content", () => {
|
|
119
|
+
assert.equal(transformNl2br(""), "");
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
it("should handle content with only \\n", () => {
|
|
123
|
+
const input = "\\n\\n\\n";
|
|
124
|
+
const expected = "<br><br>";
|
|
125
|
+
assert.equal(transformNl2br(input), expected);
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("should handle markdown table cell content with \\n", () => {
|
|
129
|
+
const input = "Cell 1\\nCell 1 Line 2\\n\\nCell 1 Line 3";
|
|
130
|
+
const expected = "Cell 1<br>Cell 1 Line 2<br>Cell 1 Line 3";
|
|
131
|
+
assert.equal(transformNl2br(input), expected);
|
|
132
|
+
});
|
|
133
|
+
|
|
134
|
+
it("should handle multiple consecutive double \\n\\n", () => {
|
|
135
|
+
const input = "Line 1\\n\\n\\n\\nLine 2";
|
|
136
|
+
const expected = "Line 1<br><br>Line 2";
|
|
137
|
+
assert.equal(transformNl2br(input), expected);
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
it("should preserve actual newlines (not literal \\n)", () => {
|
|
141
|
+
const input = "Line 1\nLine 2";
|
|
142
|
+
const expected = "Line 1\nLine 2";
|
|
143
|
+
assert.equal(transformNl2br(input), expected);
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
it("should only convert literal backslash-n sequences", () => {
|
|
147
|
+
const input = "Text with\\nbackslash-n and\nreal newline";
|
|
148
|
+
const expected = "Text with<br>backslash-n and\nreal newline";
|
|
149
|
+
assert.equal(transformNl2br(input), expected);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* setAttr filter - Override an attribute and return the object
|
|
3
|
+
*
|
|
4
|
+
* This filter takes an object, a key, and a value, and returns a new object
|
|
5
|
+
* with the specified attribute set to the given value.
|
|
6
|
+
*
|
|
7
|
+
* @param {Object} eleventyConfig - The Eleventy configuration object
|
|
8
|
+
*/
|
|
9
|
+
export function setAttrFilter(eleventyConfig) {
|
|
10
|
+
eleventyConfig.addFilter("setAttr", function(obj, key, value) {
|
|
11
|
+
return {
|
|
12
|
+
...obj,
|
|
13
|
+
[key]: value
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
|
package/src/autoRaw.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transform Nunjucks syntax in content by wrapping it with raw tags
|
|
3
|
-
*
|
|
4
|
-
* This function wraps Nunjucks syntax ({{, }}, {%, %}) with {% raw %} tags
|
|
5
|
-
* to prevent them from being processed by the template engine.
|
|
6
|
-
*
|
|
7
|
-
* @param {string} content - The content to transform
|
|
8
|
-
* @returns {string} The transformed content with Nunjucks syntax wrapped
|
|
9
|
-
*/
|
|
10
|
-
export function transformAutoRaw(content) {
|
|
11
|
-
// This regex looks for {{, }}, {%, or %} individually and wraps them
|
|
12
|
-
return content.replace(/({{|}}|{%|%})/g, "{% raw %}$1{% endraw %}");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* autoRaw - Forbid Nunjucks processing in Markdown files
|
|
17
|
-
*
|
|
18
|
-
* This preprocessor wraps Nunjucks syntax ({{, }}, {%, %}) with {% raw %} tags
|
|
19
|
-
* to prevent them from being processed by the template engine in Markdown files.
|
|
20
|
-
*
|
|
21
|
-
* @param {Object} eleventyConfig - The Eleventy configuration object
|
|
22
|
-
*/
|
|
23
|
-
export function autoRaw(eleventyConfig) {
|
|
24
|
-
eleventyConfig.addPreprocessor("autoRaw", "md", (data, content) => {
|
|
25
|
-
return transformAutoRaw(content);
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
|
package/src/bricks/_gtm.njk
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{% macro renderHead(gtmId) %}
|
|
2
|
-
<!-- Google Tag Manager -->
|
|
3
|
-
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
|
|
4
|
-
new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
|
|
5
|
-
j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|
6
|
-
'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
|
|
7
|
-
})(window,document,'script','dataLayer','{{ gtmId }}');</script>
|
|
8
|
-
<!-- End Google Tag Manager -->
|
|
9
|
-
{% endmacro %}
|
|
10
|
-
|
|
11
|
-
{% macro renderBody(gtmId) %}
|
|
12
|
-
<!-- Google Tag Manager (noscript) -->
|
|
13
|
-
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id={{ gtmId }}"
|
|
14
|
-
height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
|
|
15
|
-
<!-- End Google Tag Manager (noscript) -->
|
|
16
|
-
{% endmacro %}
|
package/src/bricks/_nav.njk
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
{% macro render(navPages, curPage) %}
|
|
2
|
-
{# https://www.11ty.dev/docs/plugins/navigation/#bring-your-own-html-render-the-menu-items-manually #}
|
|
3
|
-
<nav>
|
|
4
|
-
{%- for entry in navPages %}
|
|
5
|
-
<a href="{{ entry.url }}" {{ 'aria-current="page"' | safe if entry.url == curPage.url }}>
|
|
6
|
-
{{- entry.title -}}
|
|
7
|
-
</a>
|
|
8
|
-
{%- endfor %}
|
|
9
|
-
</nav>
|
|
10
|
-
{% endmacro %}
|