@rhinostone/swig 2.5.0 → 2.5.2
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/HISTORY.md +24 -0
- package/README.md +12 -5
- package/ROADMAP.md +14 -2
- package/dist/swig.js +33 -4
- package/dist/swig.min.js +11 -2
- package/dist/swig.min.js.map +1 -1
- package/eslint.config.js +32 -0
- package/lib/parser.js +3 -0
- package/lib/swig.js +177 -1
- package/lib/tags/extends.js +25 -0
- package/lib/tags/set.js +5 -5
- package/package.json +8 -20
- package/.eslintrc.json +0 -24
package/lib/swig.js
CHANGED
|
@@ -14,7 +14,7 @@ var utils = require('./utils'),
|
|
|
14
14
|
*
|
|
15
15
|
* @type {String}
|
|
16
16
|
*/
|
|
17
|
-
exports.version = "2.5.
|
|
17
|
+
exports.version = "2.5.2";
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Swig Options Object. This object can be passed to many of the API-level Swig methods to control various aspects of the engine. All keys are optional.
|
|
@@ -336,17 +336,193 @@ exports.Swig = function (opts) {
|
|
|
336
336
|
* Export methods publicly
|
|
337
337
|
*/
|
|
338
338
|
defaultInstance = new exports.Swig();
|
|
339
|
+
/**
|
|
340
|
+
* Add a custom filter for swig variables.
|
|
341
|
+
*
|
|
342
|
+
* @example
|
|
343
|
+
* function replaceMs(input) { return input.replace(/m/g, 'f'); }
|
|
344
|
+
* swig.setFilter('replaceMs', replaceMs);
|
|
345
|
+
* // => {{ "onomatopoeia"|replaceMs }}
|
|
346
|
+
* // => onofatopeia
|
|
347
|
+
*
|
|
348
|
+
* @param {string} name Name of filter, used in templates. <strong>Will</strong> overwrite previously defined filters, if using the same name.
|
|
349
|
+
* @param {function} method Function that acts against the input. See <a href="/docs/filters/#custom">Custom Filters</a> for more information.
|
|
350
|
+
* @return {undefined}
|
|
351
|
+
*/
|
|
339
352
|
exports.setFilter = defaultInstance.setFilter;
|
|
353
|
+
/**
|
|
354
|
+
* Add a custom tag. To expose your own extensions to compiled template code, see <code data-language="js">swig.setExtension</code>.
|
|
355
|
+
*
|
|
356
|
+
* For a more in-depth explanation of writing custom tags, see <a href="../extending/#tags">Custom Tags</a>.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* var tacotag = require('./tacotag');
|
|
360
|
+
* swig.setTag('tacos', tacotag.parse, tacotag.compile, tacotag.ends, tacotag.blockLevel);
|
|
361
|
+
* // => {% tacos %}Make this be tacos.{% endtacos %}
|
|
362
|
+
* // => Tacos tacos tacos tacos.
|
|
363
|
+
*
|
|
364
|
+
* @param {string} name Tag name.
|
|
365
|
+
* @param {function} parse Method for parsing tokens.
|
|
366
|
+
* @param {function} compile Method for compiling renderable output.
|
|
367
|
+
* @param {boolean} [ends=false] Whether or not this tag requires an <i>end</i> tag.
|
|
368
|
+
* @param {boolean} [blockLevel=false] If false, this tag will not be compiled outside of <code>block</code> tags when extending a parent template.
|
|
369
|
+
* @return {undefined}
|
|
370
|
+
*/
|
|
340
371
|
exports.setTag = defaultInstance.setTag;
|
|
372
|
+
/**
|
|
373
|
+
* Add extensions for custom tags. This allows any custom tag to access a globally available methods via a special globally available object, <var>_ext</var>, in templates.
|
|
374
|
+
*
|
|
375
|
+
* @example
|
|
376
|
+
* swig.setExtension('trans', function (v) { return translate(v); });
|
|
377
|
+
* function compileTrans(compiler, args, content, parent, options) {
|
|
378
|
+
* return '_output += _ext.trans(' + args[0] + ');'
|
|
379
|
+
* };
|
|
380
|
+
* swig.setTag('trans', parseTrans, compileTrans, true);
|
|
381
|
+
*
|
|
382
|
+
* @param {string} name Key name of the extension. Accessed via <code data-language="js">_ext[name]</code>.
|
|
383
|
+
* @param {*} object The method, value, or object that should be available via the given name.
|
|
384
|
+
* @return {undefined}
|
|
385
|
+
*/
|
|
341
386
|
exports.setExtension = defaultInstance.setExtension;
|
|
387
|
+
/**
|
|
388
|
+
* Parse a given file into tokens.
|
|
389
|
+
* @param {string} pathname Full path to file to parse.
|
|
390
|
+
* @param {SwigOpts} [options={}] Swig options object.
|
|
391
|
+
* @return {object} parsed Template tokens object.
|
|
392
|
+
* @private
|
|
393
|
+
*/
|
|
342
394
|
exports.parseFile = defaultInstance.parseFile;
|
|
395
|
+
/**
|
|
396
|
+
* Pre-compile a source string into a cache-able template function.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* swig.precompile('{{ tacos }}');
|
|
400
|
+
* // => {
|
|
401
|
+
* // tpl: function (_swig, _locals, _filters, _utils, _fn) { ... },
|
|
402
|
+
* // tokens: {
|
|
403
|
+
* // name: undefined,
|
|
404
|
+
* // parent: null,
|
|
405
|
+
* // tokens: [...],
|
|
406
|
+
* // blocks: {}
|
|
407
|
+
* // }
|
|
408
|
+
* // }
|
|
409
|
+
*
|
|
410
|
+
* In order to render a pre-compiled template, you must have access to filters and utils from Swig. <var>efn</var> is simply an empty function that does nothing.
|
|
411
|
+
*
|
|
412
|
+
* @param {string} source Swig template source string.
|
|
413
|
+
* @param {SwigOpts} [options={}] Swig options object.
|
|
414
|
+
* @return {object} Renderable function and tokens object.
|
|
415
|
+
*/
|
|
343
416
|
exports.precompile = defaultInstance.precompile;
|
|
417
|
+
/**
|
|
418
|
+
* Compile string source into a renderable template function.
|
|
419
|
+
*
|
|
420
|
+
* @example
|
|
421
|
+
* var tpl = swig.compile('{{ tacos }}');
|
|
422
|
+
* // => {
|
|
423
|
+
* // [Function: compiled]
|
|
424
|
+
* // parent: null,
|
|
425
|
+
* // tokens: [{ compile: [Function] }],
|
|
426
|
+
* // blocks: {}
|
|
427
|
+
* // }
|
|
428
|
+
* tpl({ tacos: 'Tacos!!!!' });
|
|
429
|
+
* // => Tacos!!!!
|
|
430
|
+
*
|
|
431
|
+
* When compiling a source string, a file path should be specified in the options object in order for <var>extends</var>, <var>include</var>, and <var>import</var> to work properly. Do this by adding <code data-language="js">{ filename: '/absolute/path/to/mytpl.html' }</code> to the options argument.
|
|
432
|
+
*
|
|
433
|
+
* @param {string} source Swig template source string.
|
|
434
|
+
* @param {SwigOpts} [options={}] Swig options object.
|
|
435
|
+
* @return {function} Renderable function with keys for parent, blocks, and tokens.
|
|
436
|
+
*/
|
|
344
437
|
exports.compile = defaultInstance.compile;
|
|
438
|
+
/**
|
|
439
|
+
* Compile a source file into a renderable template function.
|
|
440
|
+
*
|
|
441
|
+
* @example
|
|
442
|
+
* var tpl = swig.compileFile('./mytpl.html');
|
|
443
|
+
* // => {
|
|
444
|
+
* // [Function: compiled]
|
|
445
|
+
* // parent: null,
|
|
446
|
+
* // tokens: [{ compile: [Function] }],
|
|
447
|
+
* // blocks: {}
|
|
448
|
+
* // }
|
|
449
|
+
* tpl({ tacos: 'Tacos!!!!' });
|
|
450
|
+
* // => Tacos!!!!
|
|
451
|
+
*
|
|
452
|
+
* @example
|
|
453
|
+
* swig.compileFile('/myfile.txt', { varControls: ['<%=', '=%>'], tagControls: ['<%', '%>']});
|
|
454
|
+
* // => will compile 'myfile.txt' using the var and tag controls as specified.
|
|
455
|
+
*
|
|
456
|
+
* @param {string} pathname File location.
|
|
457
|
+
* @param {SwigOpts} [options={}] Swig options object.
|
|
458
|
+
* @param {Function} [cb] Asynchronous callback function. If not provided, <var>compileFile</var> will run synchronously.
|
|
459
|
+
* @return {function} Renderable function with keys for parent, blocks, and tokens.
|
|
460
|
+
*/
|
|
345
461
|
exports.compileFile = defaultInstance.compileFile;
|
|
346
462
|
exports.compileFileAsync = defaultInstance.compileFileAsync;
|
|
463
|
+
/**
|
|
464
|
+
* Compile and render a template string for final output.
|
|
465
|
+
*
|
|
466
|
+
* When rendering a source string, a file path should be specified in the options object in order for <var>extends</var>, <var>include</var>, and <var>import</var> to work properly. Do this by adding <code data-language="js">{ filename: '/absolute/path/to/mytpl.html' }</code> to the options argument.
|
|
467
|
+
*
|
|
468
|
+
* @example
|
|
469
|
+
* swig.render('{{ tacos }}', { locals: { tacos: 'Tacos!!!!' }});
|
|
470
|
+
* // => Tacos!!!!
|
|
471
|
+
*
|
|
472
|
+
* @param {string} source Swig template source string.
|
|
473
|
+
* @param {SwigOpts} [options={}] Swig options object.
|
|
474
|
+
* @return {string} Rendered output.
|
|
475
|
+
*/
|
|
347
476
|
exports.render = defaultInstance.render;
|
|
477
|
+
/**
|
|
478
|
+
* Compile and render a template file for final output. This is most useful for libraries like Express.js.
|
|
479
|
+
*
|
|
480
|
+
* When the active loader sets <code>loader.async === true</code> and a callback is provided, this method routes to the async-codegen dispatch path (added in v2.2.0) which supports dynamic <var>include</var> paths the sync path cannot. Otherwise it runs synchronously.
|
|
481
|
+
*
|
|
482
|
+
* @example
|
|
483
|
+
* swig.renderFile('./template.html', {}, function (err, output) {
|
|
484
|
+
* if (err) {
|
|
485
|
+
* throw err;
|
|
486
|
+
* }
|
|
487
|
+
* console.log(output);
|
|
488
|
+
* });
|
|
489
|
+
*
|
|
490
|
+
* @example
|
|
491
|
+
* swig.renderFile('./template.html', {});
|
|
492
|
+
* // => output
|
|
493
|
+
*
|
|
494
|
+
* @param {string} pathName File location.
|
|
495
|
+
* @param {object} [locals={}] Template variable context.
|
|
496
|
+
* @param {Function} [cb] Asynchronous callback function. If not provided, <var>renderFile</var> will run synchronously.
|
|
497
|
+
* @return {string} Rendered output.
|
|
498
|
+
*/
|
|
348
499
|
exports.renderFile = defaultInstance.renderFile;
|
|
349
500
|
exports.renderFileAsync = defaultInstance.renderFileAsync;
|
|
501
|
+
/**
|
|
502
|
+
* Run a pre-compiled template function. This is most useful in the browser when you've pre-compiled your templates with the Swig command-line tool.
|
|
503
|
+
*
|
|
504
|
+
* @example
|
|
505
|
+
* $ swig compile ./mytpl.html --wrap-start="var mytpl = " > mytpl.js
|
|
506
|
+
* @example
|
|
507
|
+
* <script src="mytpl.js"></script>
|
|
508
|
+
* <script>
|
|
509
|
+
* swig.run(mytpl, {});
|
|
510
|
+
* // => "rendered template..."
|
|
511
|
+
* </script>
|
|
512
|
+
*
|
|
513
|
+
* @param {function} tpl Pre-compiled Swig template function. Use the Swig CLI to compile your templates.
|
|
514
|
+
* @param {object} [locals={}] Template variable context.
|
|
515
|
+
* @param {string} [filepath] Filename used for caching the template.
|
|
516
|
+
* @return {string} Rendered output.
|
|
517
|
+
*/
|
|
350
518
|
exports.run = defaultInstance.run;
|
|
519
|
+
/**
|
|
520
|
+
* Clears the in-memory template cache.
|
|
521
|
+
*
|
|
522
|
+
* @example
|
|
523
|
+
* swig.invalidateCache();
|
|
524
|
+
*
|
|
525
|
+
* @return {undefined}
|
|
526
|
+
*/
|
|
351
527
|
exports.invalidateCache = defaultInstance.invalidateCache;
|
|
352
528
|
exports.loaders = loaders;
|
package/lib/tags/extends.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
var _t = require('@rhinostone/swig-core/lib/tokentypes');
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
4
|
* Makes the current template extend a parent template. This tag must be the first item in your template.
|
|
3
5
|
*
|
|
@@ -24,4 +26,27 @@ exports.parse = function () {
|
|
|
24
26
|
return true;
|
|
25
27
|
};
|
|
26
28
|
|
|
29
|
+
/*!
|
|
30
|
+
* Lower a dynamic parent-path to IR so `{% extends layout_var %}`
|
|
31
|
+
* resolves at render time on the async codegen path. A lone
|
|
32
|
+
* string-literal path (`{% extends "x.html" %}`) returns undefined, so
|
|
33
|
+
* the engine keeps its existing tokens.parent string + ir.literal path
|
|
34
|
+
* unchanged; only a dynamic path is lowered. Mirrors include.js. The
|
|
35
|
+
* resulting IRExpr is read back as token.irExpr.file by the parser
|
|
36
|
+
* splitter and stashed on the sibling tokens.parentExpr slot.
|
|
37
|
+
*/
|
|
38
|
+
exports.lowerExpr = function (parser, tokens) {
|
|
39
|
+
var i, tk, pathTokens = [];
|
|
40
|
+
for (i = 0; i < tokens.length; i += 1) {
|
|
41
|
+
tk = tokens[i];
|
|
42
|
+
if (tk.type === _t.WHITESPACE) { continue; }
|
|
43
|
+
pathTokens.push(tk);
|
|
44
|
+
}
|
|
45
|
+
if (!pathTokens.length) { return undefined; }
|
|
46
|
+
if (pathTokens.length === 1 && pathTokens[0].type === _t.STRING) {
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
return { file: parser.parseExpr(tokens) };
|
|
50
|
+
};
|
|
51
|
+
|
|
27
52
|
exports.ends = false;
|
package/lib/tags/set.js
CHANGED
|
@@ -36,9 +36,9 @@ var ir = require('@rhinostone/swig-core/lib/ir'),
|
|
|
36
36
|
|
|
37
37
|
// Pure-dot LHS shape: `_ctx.foo` or `_ctx.foo.bar.baz`. Bracket-touched
|
|
38
38
|
// targets (`_ctx.foo["bar"]`, `_ctx.foo[bar]`, mixed dot+bracket) fail
|
|
39
|
-
// this match and stay on the transitional string fallback
|
|
40
|
-
//
|
|
41
|
-
//
|
|
39
|
+
// this match and stay on the transitional string fallback. The
|
|
40
|
+
// bracket-lvalue contract is a cross-flavor design call and is deferred
|
|
41
|
+
// to a dedicated session.
|
|
42
42
|
var _pureDotTarget = /^_ctx\.([a-zA-Z_$][\w$]*)((?:\.[a-zA-Z_$][\w$]*)*)$/;
|
|
43
43
|
|
|
44
44
|
exports.compile = function (compiler, args, content, parents, options, blockName, token) {
|
|
@@ -70,8 +70,8 @@ exports.lowerExpr = function (parser, tokens) {
|
|
|
70
70
|
// assignment operator; lowerExpr only concerns itself with the RHS.
|
|
71
71
|
// Locate the first ASSIGNMENT, slice the tail, and hand it to parseExpr.
|
|
72
72
|
// Fall back (return undefined) if the tail contains FILTER / FILTEREMPTY
|
|
73
|
-
// (filter pipes are not part of the expression grammar
|
|
74
|
-
//
|
|
73
|
+
// (filter pipes are not yet part of the expression grammar — pending
|
|
74
|
+
// output-site lowering) or a nested ASSIGNMENT (parseExpr does not
|
|
75
75
|
// lower assignments, and bracket-write-as-assignment on the RHS would
|
|
76
76
|
// misparse silently).
|
|
77
77
|
var assignIdx = -1, i;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rhinostone/swig",
|
|
3
|
-
"version": "2.5.
|
|
3
|
+
"version": "2.5.2",
|
|
4
4
|
"description": "A simple, powerful, and extendable templating engine for node.js and browsers, similar to Django, Jinja2, and Twig.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"template",
|
|
@@ -21,21 +21,17 @@
|
|
|
21
21
|
"Rhinostone <contact@gina.io>"
|
|
22
22
|
],
|
|
23
23
|
"dependencies": {
|
|
24
|
-
"@rhinostone/swig-core": "2.5.
|
|
24
|
+
"@rhinostone/swig-core": "2.5.2"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
|
-
"blanket": "~1.1",
|
|
28
27
|
"esbuild": "^0.28.0",
|
|
29
|
-
"eslint": "^
|
|
28
|
+
"eslint": "^9",
|
|
30
29
|
"expect.js": "~0.2",
|
|
31
|
-
"express": "
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"mocha-phantomjs": "~3.1",
|
|
30
|
+
"express": "^4",
|
|
31
|
+
"globals": "^16",
|
|
32
|
+
"lodash": "^4",
|
|
35
33
|
"path-browserify": "^1.0.1",
|
|
36
|
-
"
|
|
37
|
-
"terser": "^5.46.1",
|
|
38
|
-
"travis-cov": "~0.2"
|
|
34
|
+
"terser": "^5.46.1"
|
|
39
35
|
},
|
|
40
36
|
"license": "MIT",
|
|
41
37
|
"main": "index",
|
|
@@ -50,15 +46,7 @@
|
|
|
50
46
|
},
|
|
51
47
|
"scripts": {
|
|
52
48
|
"prepublish": "npm prune && make build",
|
|
53
|
-
"test": "make lint && make test reporter=spec && make
|
|
54
|
-
"travis-cov": {
|
|
55
|
-
"threshold": 95
|
|
56
|
-
}
|
|
57
|
-
},
|
|
58
|
-
"config": {
|
|
59
|
-
"blanket": {
|
|
60
|
-
"pattern": "swig/lib"
|
|
61
|
-
}
|
|
49
|
+
"test": "make lint && make test reporter=spec && make coverage"
|
|
62
50
|
},
|
|
63
51
|
"publishConfig": {
|
|
64
52
|
"access": "public"
|
package/.eslintrc.json
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"env": {
|
|
3
|
-
"node": true,
|
|
4
|
-
"mocha": true,
|
|
5
|
-
"es2017": true
|
|
6
|
-
},
|
|
7
|
-
"parserOptions": {
|
|
8
|
-
"ecmaVersion": 2017
|
|
9
|
-
},
|
|
10
|
-
"globals": {
|
|
11
|
-
"Promise": "readonly"
|
|
12
|
-
},
|
|
13
|
-
"rules": {
|
|
14
|
-
"max-len": ["error", { "code": 600 }],
|
|
15
|
-
"semi": ["error", "always"],
|
|
16
|
-
"no-eval": "off",
|
|
17
|
-
"no-new-func": "off",
|
|
18
|
-
"strict": "off",
|
|
19
|
-
"eqeqeq": "off",
|
|
20
|
-
"no-trailing-spaces": "error",
|
|
21
|
-
"no-undef": "error",
|
|
22
|
-
"no-redeclare": "error"
|
|
23
|
-
}
|
|
24
|
-
}
|