@rhinostone/swig-jinja2 2.5.1 → 2.5.3
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/lib/parser.js +3 -0
- package/lib/tags/extends.js +44 -26
- package/package.json +2 -2
package/lib/parser.js
CHANGED
|
@@ -548,6 +548,7 @@ exports.parse = function (swig, source, opts, tags, filters) {
|
|
|
548
548
|
var line = 1;
|
|
549
549
|
var stack = [];
|
|
550
550
|
var parent = null;
|
|
551
|
+
var parentExpr = null;
|
|
551
552
|
var tokens = [];
|
|
552
553
|
var blocks = {};
|
|
553
554
|
var inRaw = false;
|
|
@@ -698,6 +699,7 @@ exports.parse = function (swig, source, opts, tags, filters) {
|
|
|
698
699
|
if (token) {
|
|
699
700
|
if (token.name === 'extends') {
|
|
700
701
|
parent = token.args.length ? String(token.args[0]) : null;
|
|
702
|
+
parentExpr = token.irExpr && token.irExpr.file;
|
|
701
703
|
} else if (token.block && !stack.length) {
|
|
702
704
|
blocks[token.args.join('')] = token;
|
|
703
705
|
}
|
|
@@ -757,6 +759,7 @@ exports.parse = function (swig, source, opts, tags, filters) {
|
|
|
757
759
|
return {
|
|
758
760
|
name: opts.filename,
|
|
759
761
|
parent: parent,
|
|
762
|
+
parentExpr: parentExpr,
|
|
760
763
|
tokens: tokens,
|
|
761
764
|
blocks: blocks
|
|
762
765
|
};
|
package/lib/tags/extends.js
CHANGED
|
@@ -3,21 +3,27 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Declares a parent template for inheritance:
|
|
5
5
|
*
|
|
6
|
-
* {% extends "layout.html" %}
|
|
6
|
+
* {% extends "layout.html" %} (static — compile-time)
|
|
7
|
+
* {% extends parent_var %} (dynamic — render-time)
|
|
8
|
+
* {% extends full if cond else partial %} (dynamic)
|
|
7
9
|
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* parent-chain resolution (`engine.getParents` + `remapBlocks` +
|
|
11
|
-
* `importNonBlocks`) walks the chain statically at compile time
|
|
12
|
-
* runtime-valued parent cannot be resolved on the sync path. Dynamic
|
|
13
|
-
* extends is the async-codegen path's concern, tracked separately.
|
|
10
|
+
* A static string-literal path is pushed as the single `token.args`
|
|
11
|
+
* element; the parser's splitter lifts it onto `template.parent`, and the
|
|
12
|
+
* engine's parent-chain resolution (`engine.getParents` + `remapBlocks` +
|
|
13
|
+
* `importNonBlocks`) walks the chain statically at compile time.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
* `
|
|
17
|
-
* `
|
|
15
|
+
* A dynamic path is lowered through `parser.parseExpr` into an IRExpr and
|
|
16
|
+
* stashed on `token.irExpr.file`; the splitter lifts it onto the sibling
|
|
17
|
+
* `template.parentExpr` slot, which the async codegen path
|
|
18
|
+
* (`buildExtendsDeferred`) prefers over the string literal and resolves at
|
|
19
|
+
* render time via `_swig.getTemplate`. Dynamic extends therefore requires
|
|
20
|
+
* an async loader (`renderFile` with a callback); on the synchronous
|
|
21
|
+
* render path a runtime-valued parent is unresolvable. Mirrors the
|
|
22
|
+
* dynamic-path lowering in `include.js`.
|
|
18
23
|
*
|
|
19
24
|
* Compile emits nothing — `extends` is a parse-time declaration carried via
|
|
20
|
-
* `template.parent` metadata; no runtime code is
|
|
25
|
+
* `template.parent` / `template.parentExpr` metadata; no runtime code is
|
|
26
|
+
* generated for the tag.
|
|
21
27
|
*/
|
|
22
28
|
|
|
23
29
|
var utils = require('@rhinostone/swig-core/lib/utils');
|
|
@@ -28,20 +34,26 @@ exports.ends = false;
|
|
|
28
34
|
exports.block = true;
|
|
29
35
|
|
|
30
36
|
/**
|
|
31
|
-
* Parse the `{% extends %}` tag body.
|
|
32
|
-
*
|
|
33
|
-
*
|
|
37
|
+
* Parse the `{% extends %}` tag body.
|
|
38
|
+
*
|
|
39
|
+
* A single STRING literal is stashed (quotes stripped) as `token.args[0]`
|
|
40
|
+
* for the splitter to lift onto `template.parent`. Any other expression
|
|
41
|
+
* (VAR, member access, inline-if, ...) is a dynamic path: it is lowered
|
|
42
|
+
* through `parser.parseExpr` into an IRExpr on `token.irExpr.file` (the
|
|
43
|
+
* splitter lifts it onto `template.parentExpr`) and the raw source text is
|
|
44
|
+
* kept on `token.args[0]` so the sync `template.parent` string stays
|
|
45
|
+
* truthy. Mirrors `include.js`.
|
|
34
46
|
*
|
|
35
47
|
* @param {string} str Tag body.
|
|
36
48
|
* @param {number} line Source line of the opening `{%`.
|
|
37
|
-
* @param {object} parser The Jinja2 parser module (
|
|
38
|
-
* bare string literal).
|
|
49
|
+
* @param {object} parser The Jinja2 parser module (exposes `parseExpr`).
|
|
39
50
|
* @param {object} types Jinja2 lexer token-type enum.
|
|
40
51
|
* @param {Array} stack Open-tag stack (unused — extends has no body).
|
|
41
52
|
* @param {object} opts Per-call options (honors `opts.filename`).
|
|
42
53
|
* @param {object} swig Swig instance (unused).
|
|
43
|
-
* @param {object} token In-progress TagToken. `token.args`
|
|
44
|
-
* unquoted
|
|
54
|
+
* @param {object} token In-progress TagToken. Gets `token.args` (raw or
|
|
55
|
+
* unquoted path) and, for a dynamic path,
|
|
56
|
+
* `token.irExpr.file` (the lowered IRExpr).
|
|
45
57
|
* @return {boolean} Always `true` on success. Throws otherwise.
|
|
46
58
|
*/
|
|
47
59
|
exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
@@ -53,17 +65,23 @@ exports.parse = function (str, line, parser, types, stack, opts, swig, token) {
|
|
|
53
65
|
if (!pathTok) {
|
|
54
66
|
utils.throwError('Expected parent template path in "extends" tag', line, opts.filename);
|
|
55
67
|
}
|
|
56
|
-
if (pathTok.type !== types.STRING) {
|
|
57
|
-
utils.throwError('Dynamic "extends" is not supported — parent path must be a string literal', line, opts.filename);
|
|
58
|
-
}
|
|
59
68
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
69
|
+
if (pathTok.type === types.STRING) {
|
|
70
|
+
pos += 1;
|
|
71
|
+
while (pos < tokens.length && tokens[pos].type === types.WHITESPACE) { pos += 1; }
|
|
72
|
+
if (pos < tokens.length) {
|
|
73
|
+
utils.throwError('Unexpected token "' + tokens[pos].match + '" after parent path in "extends" tag', line, opts.filename);
|
|
74
|
+
}
|
|
75
|
+
token.args = [pathTok.match.replace(/^['"]|['"]$/g, '')];
|
|
76
|
+
return true;
|
|
64
77
|
}
|
|
65
78
|
|
|
66
|
-
|
|
79
|
+
// Dynamic path: lower to an IRExpr so it resolves at render time on the
|
|
80
|
+
// async codegen path. The raw source is kept on token.args[0] so the
|
|
81
|
+
// sync template.parent string stays truthy (the async dispatch guard
|
|
82
|
+
// keys on it); buildExtendsDeferred prefers template.parentExpr.
|
|
83
|
+
token.irExpr = { file: parser.parseExpr(tokens) };
|
|
84
|
+
token.args = [utils.strip(str)];
|
|
67
85
|
return true;
|
|
68
86
|
};
|
|
69
87
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rhinostone/swig-jinja2",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.3",
|
|
4
4
|
"description": "Jinja2-syntax frontend for the @rhinostone/swig-core template engine. Part of the @rhinostone/swig multi-flavor family.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"template",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"node": ">=12"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
|
-
"@rhinostone/swig-core": "2.5.
|
|
26
|
+
"@rhinostone/swig-core": "2.5.3"
|
|
27
27
|
},
|
|
28
28
|
"publishConfig": {
|
|
29
29
|
"access": "public"
|