1 | const nunjucks = require('nunjucks');
|
2 |
|
3 | const isEmpty = (l1, l2) => {
|
4 | const s1 = new Set(l1.filter(_ => _ !== ''));
|
5 | const s2 = new Set(l2.filter(_ => _ !== ''));
|
6 | const r = new Set([...s1].filter(_ => s2.has(_)));
|
7 |
|
8 | return r.size === 0;
|
9 | };
|
10 |
|
11 | class LinkExt {
|
12 | constructor() {
|
13 | this.tags = ['link'];
|
14 | }
|
15 |
|
16 | parse(parser, nodes, lexer) {
|
17 | const tok = parser.nextToken();
|
18 | const args = parser.parseSignature(null, true);
|
19 |
|
20 | parser.advanceAfterBlockEnd(tok.value);
|
21 |
|
22 | return new nodes.CallExtension(this, 'run', args);
|
23 | }
|
24 |
|
25 | run(context, ...args) {
|
26 | const [path, name, rest = { class: '', __exact: true }] = args;
|
27 | const currentPath = `/${context.ctx.page.path}`;
|
28 |
|
29 | const isExact = rest.__exact;
|
30 |
|
31 | if (isExact && path === currentPath) rest.class = `active ${rest.class}`;
|
32 | if (!isExact && !isEmpty(path.split('/'), currentPath.split('/')))
|
33 | rest.class = `active ${rest.class}`;
|
34 |
|
35 | const attrs = Object.keys(rest)
|
36 | .filter(_ => !_.startsWith('__'))
|
37 | .map(key => `${key}="${rest[key]}"`)
|
38 | .join(' ');
|
39 |
|
40 | return new nunjucks.runtime.SafeString(
|
41 | `<a href="${path}" ${attrs}>${name}</a>`
|
42 | );
|
43 | }
|
44 | }
|
45 |
|
46 | module.exports = LinkExt;
|