@itrocks/template 0.0.27 → 0.0.29
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 +12 -6
- package/cjs/template.js +27 -20
- package/esm/template.js +24 -14
- package/package.json +1 -1
package/README.md
CHANGED
@@ -330,13 +330,13 @@ Result:
|
|
330
330
|
|
331
331
|
### Climbing Back Up the Data Structure
|
332
332
|
|
333
|
-
|
333
|
+
Begin with a dot (`.`) to navigate up one level in the data context:
|
334
334
|
```ts
|
335
335
|
new Template({ name: 'Eddie', data: { age: 30, status: 'well' } })
|
336
336
|
.parseBuffer(`
|
337
337
|
<!--data-->
|
338
338
|
<ol>
|
339
|
-
<li>name: {
|
339
|
+
<li>name: {.name}</li>
|
340
340
|
<li>age: {age}</li>
|
341
341
|
<li>status: {status}</li>
|
342
342
|
</ol>
|
@@ -349,6 +349,13 @@ Result:
|
|
349
349
|
<ol><li>name: Eddie</li><li>age: 30</li><li>status: well</li></ol>
|
350
350
|
```
|
351
351
|
|
352
|
+
- To climb multiple levels up, add more dots (`.`).
|
353
|
+
Example: `{...name}` moves up three levels before retrieving `name`.
|
354
|
+
- dots (`.`) used alone indicate how many levels to move up:
|
355
|
+
- `{.}` refers to the current context (does not move up).
|
356
|
+
- `{..}` moves up one level (parent context).
|
357
|
+
- `{...}` moves up two levels.
|
358
|
+
|
352
359
|
### Simple Literals
|
353
360
|
|
354
361
|
Values in quotes inside `{}` are treated as literals:
|
@@ -390,13 +397,12 @@ You can pass parent or sub-data to your included template as an alternative cont
|
|
390
397
|
```html
|
391
398
|
<div>
|
392
399
|
<!--subData-->
|
393
|
-
{./another-template.html
|
394
|
-
{./another-template.html(-)}
|
400
|
+
{./another-template.html(..)}
|
395
401
|
<!--end-->
|
396
402
|
{./another-template.html(subData)}
|
397
403
|
</div>
|
398
404
|
```
|
399
|
-
In this example,
|
405
|
+
In this example, `..` refers to the parent context. Parentheses are optional in this specific case.
|
400
406
|
|
401
407
|
#### Delimiting Rendered Content in an Included Template
|
402
408
|
|
@@ -551,7 +557,7 @@ When the template encounters something like {@userId}, it will call myParser to
|
|
551
557
|
|
552
558
|
#### doExpression (boolean)
|
553
559
|
|
554
|
-
By default, the template engine attempts to interpret `{
|
560
|
+
By default, the template engine attempts to interpret `{foo}` and `<!--bar-->` blocks as expressions or directives.
|
555
561
|
If you disable `doExpression`, the engine will treat them as literal text and not attempt to parse them.
|
556
562
|
|
557
563
|
- Set `template.doExpression = false` if you only want to read the template as-is without any dynamic substitution.
|
package/cjs/template.js
CHANGED
@@ -1,11 +1,8 @@
|
|
1
1
|
"use strict";
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
4
|
-
};
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
6
3
|
exports.Template = exports.frontScripts = void 0;
|
7
|
-
const
|
8
|
-
const
|
4
|
+
const app_dir_1 = require("@itrocks/app-dir");
|
5
|
+
const rename_1 = require("@itrocks/rename");
|
9
6
|
const sorted_array_1 = require("@itrocks/sorted-array");
|
10
7
|
const promises_1 = require("node:fs/promises");
|
11
8
|
const node_path_1 = require("node:path");
|
@@ -366,6 +363,21 @@ class Template {
|
|
366
363
|
}
|
367
364
|
return this.include(expression, data);
|
368
365
|
}
|
366
|
+
let onlyDots = true;
|
367
|
+
for (const c of expression) {
|
368
|
+
if (c === '.')
|
369
|
+
continue;
|
370
|
+
onlyDots = false;
|
371
|
+
break;
|
372
|
+
}
|
373
|
+
if (onlyDots) {
|
374
|
+
if (expression.length <= 1) {
|
375
|
+
return (((typeof data)[0] === 'f') && ((data + '')[0] !== 'c'))
|
376
|
+
? data.call()
|
377
|
+
: data;
|
378
|
+
}
|
379
|
+
expression = expression.slice(2);
|
380
|
+
}
|
369
381
|
this.blockBack = 0;
|
370
382
|
for (const variable of expression.split('.')) {
|
371
383
|
data = await this.parseVariable(variable, data);
|
@@ -374,9 +386,12 @@ class Template {
|
|
374
386
|
}
|
375
387
|
async parseVariable(variable, data) {
|
376
388
|
if (variable === '') {
|
377
|
-
|
378
|
-
|
379
|
-
|
389
|
+
let dataBack;
|
390
|
+
do {
|
391
|
+
this.blockBack++;
|
392
|
+
dataBack = this.blockStack[this.blockStack.length - this.blockBack];
|
393
|
+
} while (dataBack.condition);
|
394
|
+
return dataBack.data;
|
380
395
|
}
|
381
396
|
if (variable === '*') {
|
382
397
|
return (typeof data === 'object') ? Object.values(data) : data;
|
@@ -389,21 +404,13 @@ class Template {
|
|
389
404
|
|| ((firstChar === "'") && (variable[variable.length - 1] === "'"))) {
|
390
405
|
return variable.substring(1, variable.length - 1);
|
391
406
|
}
|
392
|
-
if (firstChar === '-') {
|
393
|
-
let dataBack;
|
394
|
-
do {
|
395
|
-
this.blockBack++;
|
396
|
-
dataBack = this.blockStack[this.blockStack.length - this.blockBack];
|
397
|
-
} while (dataBack.condition);
|
398
|
-
return dataBack.data;
|
399
|
-
}
|
400
407
|
for (const [prefix, callback] of this.parsers) {
|
401
408
|
if (firstChar === prefix) {
|
402
409
|
return callback(variable, data);
|
403
410
|
}
|
404
411
|
}
|
405
412
|
if (data[variable] === undefined) {
|
406
|
-
data = new rename_1.
|
413
|
+
data = new rename_1.Str(data);
|
407
414
|
}
|
408
415
|
let value = data[variable];
|
409
416
|
return (((typeof value)[0] === 'f') && ((value + '')[0] !== 'c'))
|
@@ -659,7 +666,7 @@ class Template {
|
|
659
666
|
}
|
660
667
|
if (inLinkHRef && attributeValue.endsWith('.css')) {
|
661
668
|
let frontStyle = (0, node_path_1.normalize)(this.filePath + node_path_1.sep + this.source.substring(this.start, this.index))
|
662
|
-
.substring(app_dir_1.
|
669
|
+
.substring(app_dir_1.appDir.length);
|
663
670
|
if (node_path_1.sep !== '/') {
|
664
671
|
frontStyle = frontStyle.replaceAll(node_path_1.sep, '/');
|
665
672
|
}
|
@@ -668,7 +675,7 @@ class Template {
|
|
668
675
|
}
|
669
676
|
if (inScriptSrc && attributeValue.endsWith('.js')) {
|
670
677
|
let frontScript = (0, node_path_1.normalize)(this.filePath + node_path_1.sep + this.source.substring(this.start, this.index))
|
671
|
-
.substring(app_dir_1.
|
678
|
+
.substring(app_dir_1.appDir.length);
|
672
679
|
if (node_path_1.sep !== '/') {
|
673
680
|
frontScript = frontScript.replaceAll(node_path_1.sep, '/');
|
674
681
|
}
|
@@ -810,7 +817,7 @@ class Template {
|
|
810
817
|
this.start = this.index;
|
811
818
|
}
|
812
819
|
startsExpression(char, open = '{', close = '}') {
|
813
|
-
return RegExp('[a-z0-9"*.?\'' + open + close + this.prefixes + '
|
820
|
+
return RegExp('[a-z0-9"*.?\'' + open + close + this.prefixes + ']', 'i').test(char);
|
814
821
|
}
|
815
822
|
trimEndLine(string) {
|
816
823
|
let index = string.length;
|
package/esm/template.js
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
import
|
2
|
-
import
|
1
|
+
import { appDir } from '@itrocks/app-dir';
|
2
|
+
import { Str } from '@itrocks/rename';
|
3
3
|
import { SortedArray } from '@itrocks/sorted-array';
|
4
4
|
import { readFile } from 'node:fs/promises';
|
5
5
|
import { normalize, sep } from 'node:path';
|
@@ -361,6 +361,21 @@ export default class Template {
|
|
361
361
|
}
|
362
362
|
return this.include(expression, data);
|
363
363
|
}
|
364
|
+
let onlyDots = true;
|
365
|
+
for (const c of expression) {
|
366
|
+
if (c === '.')
|
367
|
+
continue;
|
368
|
+
onlyDots = false;
|
369
|
+
break;
|
370
|
+
}
|
371
|
+
if (onlyDots) {
|
372
|
+
if (expression.length <= 1) {
|
373
|
+
return (((typeof data)[0] === 'f') && ((data + '')[0] !== 'c'))
|
374
|
+
? data.call()
|
375
|
+
: data;
|
376
|
+
}
|
377
|
+
expression = expression.slice(2);
|
378
|
+
}
|
364
379
|
this.blockBack = 0;
|
365
380
|
for (const variable of expression.split('.')) {
|
366
381
|
data = await this.parseVariable(variable, data);
|
@@ -369,9 +384,12 @@ export default class Template {
|
|
369
384
|
}
|
370
385
|
async parseVariable(variable, data) {
|
371
386
|
if (variable === '') {
|
372
|
-
|
373
|
-
|
374
|
-
|
387
|
+
let dataBack;
|
388
|
+
do {
|
389
|
+
this.blockBack++;
|
390
|
+
dataBack = this.blockStack[this.blockStack.length - this.blockBack];
|
391
|
+
} while (dataBack.condition);
|
392
|
+
return dataBack.data;
|
375
393
|
}
|
376
394
|
if (variable === '*') {
|
377
395
|
return (typeof data === 'object') ? Object.values(data) : data;
|
@@ -384,14 +402,6 @@ export default class Template {
|
|
384
402
|
|| ((firstChar === "'") && (variable[variable.length - 1] === "'"))) {
|
385
403
|
return variable.substring(1, variable.length - 1);
|
386
404
|
}
|
387
|
-
if (firstChar === '-') {
|
388
|
-
let dataBack;
|
389
|
-
do {
|
390
|
-
this.blockBack++;
|
391
|
-
dataBack = this.blockStack[this.blockStack.length - this.blockBack];
|
392
|
-
} while (dataBack.condition);
|
393
|
-
return dataBack.data;
|
394
|
-
}
|
395
405
|
for (const [prefix, callback] of this.parsers) {
|
396
406
|
if (firstChar === prefix) {
|
397
407
|
return callback(variable, data);
|
@@ -805,7 +815,7 @@ export default class Template {
|
|
805
815
|
this.start = this.index;
|
806
816
|
}
|
807
817
|
startsExpression(char, open = '{', close = '}') {
|
808
|
-
return RegExp('[a-z0-9"*.?\'' + open + close + this.prefixes + '
|
818
|
+
return RegExp('[a-z0-9"*.?\'' + open + close + this.prefixes + ']', 'i').test(char);
|
809
819
|
}
|
810
820
|
trimEndLine(string) {
|
811
821
|
let index = string.length;
|
package/package.json
CHANGED