-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy path.eleventy.js
761 lines (659 loc) · 26 KB
/
.eleventy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
const { DateTime } = require('luxon');
const fs = require('fs');
const pluginNavigation = require('@11ty/eleventy-navigation');
const markdownIt = require('markdown-it');
const markdownItAnchor = require('markdown-it-anchor');
const {decode} = require('html-entities');
const util = require('util');
const { exit } = require('process');
module.exports = function(eleventyConfig) {
function getCharCodes(s){
let charCodeArr = [];
for(let i = 0; i < s.length; i++){
let code = s.charCodeAt(i);
charCodeArr.push(code);
}
return charCodeArr;
}
function parseItems(items, conjunction)
{
if (!Array.isArray(items)) {
return '';
}
let mappedItems = items.map((item) => {
return '`' + item + '`';
});
let lastItem = mappedItems.pop();
if (mappedItems.length > 0) {
return mappedItems.join(', ') + ' ' + conjunction + ' ' + lastItem;
}
return lastItem;
}
function sumDigits(n) {
return (n - 1) % 9 + 1;
}
function calcSumDigitsOfString(s) {
let ascii = getCharCodes(s);
let sum = ascii.reduce(function (a, b) {
return a + b;
}, 0);
return sumDigits(sum);
}
eleventyConfig.addFilter('dumper', obj => {
return util.inspect(obj)
});
// Add plugins
eleventyConfig.addPlugin(pluginNavigation);
// https://www.11ty.dev/docs/data-deep-merge/
eleventyConfig.setDataDeepMerge(true);
// Alias `layout: post` to `layout: layouts/post.njk`
// eleventyConfig.addLayoutAlias('example', 'layouts/example.html');
// see https://rob.cogit8.org/posts/2020-10-28-simple-11ty-cache-busting/
eleventyConfig.addFilter('bust', (url) => {
const [urlPart, paramPart] = url.split('?');
const params = new URLSearchParams(paramPart || '');
params.set('v', DateTime.local().toFormat('X'));
return `${urlPart}?${params}`;
});
eleventyConfig.addFilter('stringify', (csvString) => {
if (!Array.isArray(csvString)) {
return '[]';
}
return JSON.stringify(csvString);
});
eleventyConfig.addShortcode('toc', (content, version, flemsFiles, flemsLinks) => {
const regex = /<h2 id=".*?" tabindex=".*?">.+?<\/h2>/ig
let matches = content.match(regex);
if (!Array.isArray(matches)) {
matches = []
}
let toc = []
const noFlems = Array.isArray(flemsFiles)
&& (flemsFiles.length === 0)
&& Array.isArray(flemsLinks)
&& (flemsLinks.length === 0)
if (version && !noFlems) {
toc.push(['live-example', 'Live Example'])
toc.push(['dependencies', 'Dependencies'])
}
matches.map(function(val){
const match = val.match(/<h2 id="(.+)" tabindex=".+">(.+)<a.*>*<\/a><\/h2>/i)
toc.push([match[1], match[2].trim()])
})
if (toc.length === 0) {
return ''
}
toc.push(['contribute', 'Contribute'])
let list = '';
toc.map((f) => {
list += `<li class="toc__item"><a clas="toc__link" href="#${f[0]}">${f[1]}</a></li>`
});
return `<div class="toc">
<h2 class="toc__heading">Contents</h2>
<ol class="toc__list">${list}</ol>
</div>`
});
eleventyConfig.addShortcode('textifyTop', (title, date, tags, level, version, author, authorUrl, link, authorMap) => {
// some nice procedural programming ;-)
let textVariantNumber = calcSumDigitsOfString(title) % 3;
let authorExampleCount = 1;
authorMap.forEach((data) => {
if (author === data[0]) {
authorExampleCount = data[1].count;
return;
}
});
let apiMethods = (tags || []).filter(function (tag) {
return tag.includes('m.');
});
let lifecycleMethods = (tags || []).filter(function (tag) {
const methods = ['onbeforeupdate', 'onremove', 'onbeforeremove', 'onupdate', 'oncreate', 'oninit'];
return methods.indexOf(tag) >= 0;
});
let text = [];
if (version.length > 0) {
text.push ("\n");
if (version === 'latest') {
text.push([
'The snippet is using the most current version of Mithril.js framework.',
'The snippet requires the latest version of Mithril.js framework.',
'As a prerequisite for this snippet, the latest version of Mithril.js framework is required.'
][textVariantNumber]);
} else {
text.push([
'The snippet is using version ' + version + ' of Mithril.js framework.',
'The snippet requires version ' + version + ' of Mithril.js framework.',
'As a prerequisite for this snippet, version ' + version + ' of Mithril.js framework is required.'
][textVariantNumber]);
}
}
if (level.length > 0) {
switch(level) {
case 'beginner':
text.push([
'It is aimed at beginners and shows some basic recipes.',
'It is ideal for beginners showing some basic recipes.',
'Beginners should have no problems following this example, that simply shows some basic recipies.'
][textVariantNumber]);
break;
case 'advanced':
text.push([
'It is aimed at more advanced users and shows some things, that are not easy to achieve.',
'More advanced users should be able to follow this example, however it contains some first difficulties.',
'Advanced users belong to the target group of this example, meaning some framework knowledge should be there.'
][textVariantNumber]);
break;
case 'intermediate':
text.push([
'It is aimed at intermediate users who are familiar with most of the aspects of the framework.',
'You should be familiar with most aspects of the framework. So the example is aimed at advanced users.',
'The example targets intermediate users, that are familiar with with most aspects of the framework.'
][textVariantNumber]);
break;
case 'expert':
text.push([
'It is aimed at expert users who are familiar with all of the aspects of the framework and JavaScript itself.',
'As an expert user, who is familiar with all the aspects of Mithril.js and JavaScript itself, you are able the follow the example easily.',
'The example really targets users on expert level, that are familiar with all aspects of Mithril.js and JavaScript itself.'
][textVariantNumber]);
break;
}
}
if ((apiMethods.length > 0) || (lifecycleMethods.length > 0) || (tags.indexOf('vnode') > 0)) {
text.push('');
}
if (apiMethods.length > 1) {
text.push([
'Besides Mithril.js\' hyperscript function m() we can see different [Mithril.js API methods](/api-methods/) like ' + parseItems(apiMethods, 'or') + '.',
'In this example we can see some [Mithril.js API methods](/api-methods/) like ' + parseItems(apiMethods, 'or') + ', besides Mithril.js\' basic m() hyperscript function.',
'Here we can see use cases of different [Mithril.js API methods](/api-methods/) like ' + parseItems(apiMethods, 'or') + ', besides the centrepiece m() hyperscript function.'
][textVariantNumber]);
} else if (apiMethods.length === 1) {
text.push([
'In addition to the Mithril.js hyperscript function m(), here we can see an example of Mithril.js\' ' + parseItems(apiMethods, 'or') + ' [API method](/api-methods/).',
'In this example we can see an example of Mithril.js\' ' + parseItems(apiMethods, 'or') + ' [API method](/api-methods/), besides it core m() hyperscript function.',
'In this code sample Mithril.js\' ' + parseItems(apiMethods, 'or') + ' [API method](/api-methods/) is use, besides the basic hyperscript function m().'
][textVariantNumber]);
}
if (lifecycleMethods.length > 1) {
text.push([
'It also shows, how Mithril.js\' hooks (called [lifecycle methods](/lifecycle-methods/)) like ' + parseItems(lifecycleMethods, 'and') + ' can be used.',
'It also demonstrates, how Mithril.js\' [lifecycle methods](/lifecycle-methods/) (aka hooks) like ' + parseItems(lifecycleMethods, 'and') + ' can be used.',
'Moreover, it can also be seen how [lifecycle methods](/lifecycle-methods/) (as known as hooks) like ' + parseItems(lifecycleMethods, 'and') + ' can be used.'
][textVariantNumber]);
} else if (lifecycleMethods.length === 1) {
text.push([
'It also shows, how Mithril.js\' [lifecycle methods](/lifecycle-methods/) can be used. This can be seen here by using the ' + parseItems(lifecycleMethods, 'and') + ' hook.',
'It is also showing the ' + parseItems(lifecycleMethods, 'and') + ' hook, which is one of several Mithril.js\' [lifecycle methods](/lifecycle-methods/).',
'Moreover, it shows how the [lifecycle method](/lifecycle-methods/) ' + parseItems(lifecycleMethods, 'and') + ' can be used (better known as hook).'
][textVariantNumber]);
}
if (tags.indexOf('vnode') > 0) {
text.push([
'In this example we can also see the usecase of Vnodes (virtual DOM nodes) which is a JavaScript data structure that describes a DOM tree.',
'We can also see the usecase of virtual DOM nodes (Vnodes) that is a JavaScript data structure describing a DOM tree.',
'Also covered in this example is the use of Vnodes or virtual DOM nodes, a JavaScript data structure that describes a DOM tree.'
][textVariantNumber]);
}
if (link && (link.length > 0)) {
text.push('');
text.push([
'You can find [more information](' + link + ') here.',
'More information about this example [can be found here](' + link + ').',
'[Click here](' + link + '), if you need more information on that.',
][textVariantNumber]);
}
if (author.length > 0) {
text.push ("\n");
text.push([
'The example was contributed by ' + author + ' and last modified on ' + date + '.',
'The code sample was authored by ' + author + '. It was last modified on ' + date + '.',
'The example was written by ' + author + ', last edits were made on ' + date + '.',
][textVariantNumber]);
if (authorExampleCount > 2) {
text.push([
'[Click here](' + authorUrl + ') to see more examples contributed by the author.',
'Want to see more examples written by ' + author + '? Then [Click here](' + authorUrl + ').',
'The author has contributed some more snippets. [Click here](' + authorUrl + ') to see them all.'
][textVariantNumber]);
} else if(authorExampleCount === 2) {
text.push([
'[Click here](' + authorUrl + ') to see another example contributed by the author.',
'Do you want to see another one written by ' + author + '? Then [Click here](' + authorUrl + ').',
'The author has written one more snippet. [Click here](' + authorUrl + ') to see it.'
][textVariantNumber]);
}
}
if (text.length > 0) {
return markdownLibrary.render(text.join("\n"));
}
return '';
});
eleventyConfig.addShortcode('textifyBottom', (title, date, tags, level, version) => {
// some nice procedural programming ;-)
let textVariantNumber = calcSumDigitsOfString(title) % 3;
let text = [];
if (version.length > 0) {
text.push ("\n");
text.push ("## Contribute");
if (version === 'latest') {
text.push([
'If anyone has some improvements, that should be addressed, let me know by [opening an issue](https://github.com/tbreuss/mithril-by-examples/issues).',
'Do you see some improvements, that could be addressed here? Then let me know by [opening an issue](https://github.com/tbreuss/mithril-by-examples/issues).',
'Did you note a typo or something else? So let me know by [opening an issue](https://github.com/tbreuss/mithril-by-examples/issues).',
][textVariantNumber]);
} else {
text.push([
'🤫 Shh! If anyone want\'s to bring this code snippet up to the current version, or has other improvements, that should be addressed, let me know by [opening an issue](https://github.com/tbreuss/mithril-by-examples/issues).',
'❓ Hey! Do you want to bring this code sample up to the latest version? Or do you see a bug or other improvements for this snippet? Then let me know by [opening an issue](https://github.com/tbreuss/mithril-by-examples/issues).',
'💪 This snippet uses an older Mithril.js version. Let me know by [opening an issue](https://github.com/tbreuss/mithril-by-examples/issues) if you want to improve this example or update it to the latest Mithril.js version.'
][textVariantNumber]);
}
text.push([
'Or simply fork the repository on GitHub, push your commits and send a pull request.',
'As an alternative, you can fork the repository on GitHub, push your commits and send a pull request.',
'Or much better: just fork the repository on GitHub, push your commits and send a pull request.'
][textVariantNumber]);
text.push([
'For starting your work, you can click the edit link below. Thanks for contributing.',
'To start your work, click on the edit link below. Thank you for contributing to this repo.',
'Ready to start your work? Then click on the edit link below. Thanks in advance!'
][textVariantNumber]);
}
if (text.length > 0) {
return markdownLibrary.render(text.join("\n"));
}
return '';
});
function flemsButton(content, title, flemsSelected, flemsFiles, flemsLinks, version) {
// some nice procedural programming ;-)
if (!flemsSelected || flemsSelected === '') {
flemsSelected = '.js';
}
if (!Array.isArray(flemsFiles)) {
flemsFiles = ['.html', '.css', '.ts', '.js'];
}
let flemsLinksArray = [];
if (!Array.isArray(flemsLinks)) {
flemsLinks = [];
}
flemsLinksArray.push({
name: 'mithril@' + version,
type: 'script',
url: 'https://unpkg.com/mithril@' + version
});
for (let link of flemsLinks) {
if (typeof link === 'object') {
flemsLinksArray.push({
name: link.name,
type: link.type,
url: link.url
})
} else {
flemsLinksArray.push({
name: link,
type: 'script',
url: 'https://unpkg.com/' + link
})
}
}
const languages = [
{
type: 'html',
name: '.html',
openTag: '<code class="language-html">',
closeTag: '</code>',
filenameRegex: /<!-- (.+?\.html) -->/s
},
{
type: 'css',
name: '.css',
openTag: '<code class="language-css">',
closeTag: '</code>',
filenameRegex: /\/\* (.+?\.css) \*\//s
},
{
type: 'ts',
name: '.ts',
openTag: '<code class="language-ts">',
closeTag: '</code>',
filenameRegex: /\/\/ (.+?\.ts)/s
},
{
type: 'js',
name: '.js',
openTag: '<code class="language-js">',
closeTag: '</code>',
filenameRegex: /\/\/ (.+?\.js)/s
},
]
const matches = content.match(/<code class="language-(.+?)">(.*?)<\/code>/sg);
if (!Array.isArray(matches)) {
return '';
}
let flemsFilesArray = [];
let fileNames = [];
for (let match of matches) {
for (let language of languages) {
let openTagLength = language.openTag.length;
if (match.substr(0, openTagLength) !== language.openTag) {
continue;
}
if (fileNames.includes(language.name)) {
continue;
}
let flemsName = language.name;
let flemsCompiler = '';
let flemsContent = decode(match.substr(openTagLength, match.length - openTagLength - language.closeTag.length));
let firstLine = flemsContent.split('\n')[0];
let nameMatch = firstLine.match(language.filenameRegex);
if (nameMatch && nameMatch[1]) {
flemsName = nameMatch[1];
}
let found = false;
for (let tmpFile of flemsFiles) {
if (typeof tmpFile === 'object') {
if (tmpFile.name === flemsName) {
if (tmpFile.compiler) {
flemsCompiler = tmpFile.compiler;
}
found = true;
break;
}
} else {
if (tmpFile === flemsName) {
found = true;
break;
}
}
}
if (!found) {
continue;
}
if (flemsCompiler !== '') {
flemsFilesArray.push({
name: flemsName,
compiler: flemsCompiler,
content: flemsContent
});
} else {
flemsFilesArray.push({
name: flemsName,
content: flemsContent
});
}
fileNames.push(flemsName);
}
}
if (flemsFilesArray.length === 0 && flemsLinksArray.length === 0) {
return '';
}
const jsonFlemsFiles = JSON.stringify(flemsFilesArray);
const jsonFlemsLinks = JSON.stringify(flemsLinksArray);
let html = `
<h2 id="live-example">Live Example <a class="direct-link" href="#live-example" aria-hidden="true">#</a></h2>
<div id="flems"></div>
<script>
Flems(document.getElementById("flems"), {
middle: 0,
resizable: false,
editable: true,
toolbar: true,
autoHeight: false,
selected: '${flemsSelected}',
files: ${jsonFlemsFiles},
links: ${jsonFlemsLinks}
});
</script>
`;
const htmlDepsRows = flemsLinksArray.map((v) => {
return `<tr><td class="capitalize">${v.type}</td><td>${v.name}</td><td>${v.url}</td></tr>`;
}).join();
if (htmlDepsRows.length > 0) {
html += `
<div class="dependencies">
<h2 id="dependencies" class="dependencies__heading" tabindex="-1">Dependencies <a class="direct-link" href="#dependencies" aria-hidden="true">#</a></h2>
<div class="dependencies__tableWrap">
<table class="dependencies__table dependencies__table--${flemsLinksArray.length}">
<thead>
<tr>
<th>Type</th>
<th>Name</th>
<th>URL</th>
</tr>
</thead>
<tbody>
${htmlDepsRows}
</tbody>
</table>
</div>
</div>
`;
}
return html;
};
eleventyConfig.addFilter('readableDate', dateObj => {
return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('dd LLLL yyyy');
});
// https://html.spec.whatwg.org/multipage/common-microsyntaxes.html#valid-date-string
eleventyConfig.addFilter('htmlDateString', (dateObj) => {
return DateTime.fromJSDate(dateObj, {zone: 'utc'}).toFormat('yyyy-LL-dd');
});
// Get the first `n` elements of a collection.
eleventyConfig.addFilter('head', (array, n) => {
if(!Array.isArray(array) || array.length === 0) {
return [];
}
if( n < 0 ) {
return array.slice(n);
}
return array.slice(0, n);
});
// Return the smallest number argument
eleventyConfig.addFilter('min', (...numbers) => {
return Math.min.apply(null, numbers);
});
function filterTagList(tags) {
return (tags || []).filter(tag => ['all', 'nav', 'post', 'posts'].indexOf(tag) === -1);
}
eleventyConfig.addFilter('filterTagList', filterTagList)
eleventyConfig.addFilter('filterByAuthor', function(collection, author) {
if (!author) return collection;
return collection.filter(item => item.data.author === author)
});
eleventyConfig.addFilter('filterByLevel', function(collection, level) {
if (!level) return collection;
return collection.filter(item => item.data.level === level)
});
eleventyConfig.addFilter('filterByTag', function(collection, tag) {
if (!tag) return collection;
return collection.filter(item => item.data.tags.indexOf(tag) !== -1)
});
eleventyConfig.addFilter('flems', (content, title, flemsSelected, flemsFiles, flemsLinks, version) => {
const flems = flemsButton(content, title, flemsSelected, flemsFiles, flemsLinks, version)
const firstHeadingPosition = content.indexOf('<h2')
if (firstHeadingPosition == -1) {
return flems + content
}
return content.substring(0, firstHeadingPosition)
+ flems
+ content.substring(firstHeadingPosition)
});
eleventyConfig.addCollection('levelMap', function(collection) {
let map = new Map();
collection.getFilteredByGlob('./examples/*.*').forEach(item => {
let key = item.data.level
if (!key || key.length <= 0) {
return
}
key = key.toLowerCase()
let level = {
name: item.data.level,
count: 1
}
if (map.has(key)) {
let count = map.get(key).count
level.count = count + 1
}
map.set(key, level)
}
);
return [...map.entries()];
});
eleventyConfig.addCollection('levelList', function(collection) {
let levelSet = new Set();
collection.getFilteredByGlob('./examples/*.*').forEach(item => {
if (item.data.level && item.data.level.length > 0) {
levelSet.add(item.data.level)
}
});
return [...levelSet];
});
eleventyConfig.addCollection('authorMap', function(collection) {
let map = new Map();
collection.getFilteredByGlob('./examples/*.*').forEach(item => {
let key = item.data.author
if (!key || key.length <= 0) {
return
}
key = key.toLowerCase()
let author = {
name: item.data.author,
count: 1
}
if (map.has(key)) {
let count = map.get(key).count
author.count = count + 1
}
map.set(key, author)
}
);
return [...map.entries()];
});
eleventyConfig.addCollection('authorList', function(collection) {
let authorSet = new Set();
collection.getFilteredByGlob('./examples/*.*').forEach(item => {
if (item.data.author && item.data.author.length > 0) {
authorSet.add(item.data.author)
}
});
return [...authorSet];
});
eleventyConfig.addCollection('tagMap', function(collection) {
let map = new Map();
collection.getFilteredByGlob('./examples/*.*').forEach(item => {
(item.data.tags || []).forEach(tag => {
let key = tag
if (!key || key.length <= 0) {
return
}
key = key.toLowerCase()
let tagObj = {
name: tag,
count: 1
}
if (map.has(key)) {
let count = map.get(key).count
tagObj.count = count + 1
}
map.set(key, tagObj)
});
});
return [...map.entries()];
});
// Create an array of all tags
eleventyConfig.addCollection('tagList', function(collection) {
let tagSet = new Set();
collection.getFilteredByGlob('./examples/*.*').forEach(item => {
(item.data.tags || []).forEach(tag => tagSet.add(tag));
});
return filterTagList([...tagSet]);
});
eleventyConfig.addCollection('examplesLatest', collection => {
return collection.getFilteredByGlob('./examples/*.md').sort(function(a, b) {
if (a.data.date > b.data.date) return -1;
else if (a.data.date < b.data.date) return 1;
else return 0;
});
});
eleventyConfig.addCollection('examples', collection => {
return collection.getFilteredByGlob('./examples/*.md').sort(function(a, b) {
let nameA = a.data.title.toUpperCase();
let nameB = b.data.title.toUpperCase();
if (nameA < nameB) return -1;
else if (nameA > nameB) return 1;
else return 0;
});
});
// Copy the `img` and `css` folders to the output
eleventyConfig.addPassthroughCopy('img');
eleventyConfig.addPassthroughCopy('css');
eleventyConfig.addPassthroughCopy('js');
eleventyConfig.addPassthroughCopy('.htaccess');
eleventyConfig.addPassthroughCopy('robots.txt');
eleventyConfig.addPassthroughCopy('CNAME');
// Customize Markdown library and settings:
let markdownLibrary = markdownIt({
html: true,
breaks: false,
linkify: true
}).use(markdownItAnchor, {
permalink: markdownItAnchor.permalink.ariaHidden({
placement: 'after',
class: 'direct-link',
symbol: '#',
level: [1,2,3,4],
}),
slugify: eleventyConfig.getFilter('slug')
});
eleventyConfig.setLibrary('md', markdownLibrary);
// Override Browsersync defaults (used only with --serve)
eleventyConfig.setBrowserSyncConfig({
callbacks: {
ready: function(err, browserSync) {
const content_404 = fs.readFileSync('_site/404.html');
browserSync.addMiddleware('*', (req, res) => {
// Provides the 404 content without redirect.
res.writeHead(404, {'Content-Type': 'text/html; charset=UTF-8'});
res.write(content_404);
res.end();
});
},
},
ui: false,
ghostMode: false
});
return {
// Control which files Eleventy will process
// e.g.: *.md, *.njk, *.html, *.liquid
templateFormats: [
'md',
'njk',
'html',
'liquid'
],
// -----------------------------------------------------------------
// If your site deploys to a subdirectory, change `pathPrefix`.
// Don’t worry about leading and trailing slashes, we normalize these.
// If you don’t have a subdirectory, use "" or "/" (they do the same thing)
// This is only used for link URLs (it does not affect your file structure)
// Best paired with the `url` filter: https://www.11ty.dev/docs/filters/url/
// You can also pass this in on the command line using `--pathprefix`
// Optional (default is shown)
pathPrefix: '/',
// -----------------------------------------------------------------
// Pre-process *.md files with: (default: `liquid`)
markdownTemplateEngine: 'njk',
// Pre-process *.html files with: (default: `liquid`)
htmlTemplateEngine: 'njk',
// Opt-out of pre-processing global data JSON files: (default: `liquid`)
dataTemplateEngine: false,
// These are all optional (defaults are shown):
dir: {
input: '.',
includes: '_includes',
data: '_data',
output: '_site'
}
};
};