Skip to content

Commit 3d27112

Browse files
committed
Initial release
1 parent 2ee49cf commit 3d27112

17 files changed

+818
-2
lines changed

.editorconfig

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
charset = utf-8
6+
trim_trailing_whitespace = true
7+
insert_final_newline = true
8+
visual_wrap = true
9+
max_line_length = 120
10+
11+
[*]
12+
indent_style = tab
13+
indent_size = 2
14+
15+
[**.yaml]
16+
indent_style = space
17+
indent_size = 2
18+
19+
[**.yml]
20+
indent_style = space
21+
indent_size = 2
22+
23+
[**.md]
24+
indent_style = space
25+
indent_size = 2

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules/**
2+

.npmignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
examples/**
2+
.editorconfig
3+

README.md

Lines changed: 159 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,159 @@
1-
# yate
2-
Yet Another Template Engine
1+
YATE
2+
======
3+
4+
YATE is tool for using html templates as JS files with DOM rendered elements and special helper to manipulate real time data updates.
5+
6+
## Installing
7+
To install YATE you have to just run npm in your project dir:
8+
9+
```bash
10+
npm install yate ---save-dev
11+
```
12+
13+
## Usage
14+
### Sample usage with bin tool
15+
You have test.html example template. To build it just use yate bin tool:
16+
17+
```bash
18+
./bin/yate.js examples/simple.yat > templates.js
19+
```
20+
21+
Now merge yate.js lib with generated template
22+
23+
```bash
24+
cat ./yate.js templates.js > bundle.js
25+
```
26+
27+
Well you can do same as above with one command:
28+
29+
```bash
30+
./bin/yate.js examples/simple.yat -b > bundle.js
31+
```
32+
33+
Finally require in browser just created the bundle.js file.
34+
You got yate variable defined with template pool manipulation helpers and templates variable with your template.
35+
36+
Now just get rendered DOM and append to any element. The key of template same as file name without extension.
37+
38+
```javascript
39+
var t = templates.get('simple');
40+
document.body.appendChild(t.dom());
41+
```
42+
43+
Wanna update some parameters? Easy:
44+
45+
```javascript
46+
t.update({welcome_text: 'YATE works!'});
47+
```
48+
49+
Now you can see rendered test template on your screen.
50+
51+
### Usage with webpack or whatever
52+
First install loader for webpack. Instruction read here: (https://www.npmjs.com/package/yate-loader).
53+
54+
Install stuff:
55+
56+
```bash
57+
npm install yate
58+
npm install yate-loader
59+
```
60+
61+
Somewhere in your code write to render
62+
63+
```javascript
64+
# First require dependencies
65+
var yate = require('yate');
66+
var simple_tpl = require('examples/simple.yat');
67+
68+
# Make pool of templates, really only one now
69+
var pool = yate.pool(simple_tpl);
70+
71+
# Fetch template and render
72+
var t = pool.get('simple')
73+
document.body.appendChild(t.dom());
74+
t.update({welcome_text: 'YATE works!'});
75+
```
76+
77+
Build your project and enjoy!
78+
79+
## Template markup
80+
You can use only simple constructs in your html template.
81+
82+
### Variables
83+
Just use {{ var_name }} in attribute or inside element to make it works.
84+
```html
85+
<div title="{{ title }}">{{ body }}</div>
86+
```
87+
88+
### Iteration
89+
When making iteration inside template YATE switching context inside iterated object. So only possible to access object variables of current iterated item.
90+
91+
```json
92+
{
93+
"rows": [
94+
{"value": 1},
95+
{"value": 2}
96+
]
97+
}
98+
```
99+
100+
```html
101+
<div for="rows">
102+
The value is: {{ value }}
103+
</div>
104+
```
105+
106+
You know what will be as result? :)
107+
108+
### Condition
109+
Condition switches context as iteration. Its same easy to use.
110+
111+
```json
112+
{
113+
"first": false,
114+
"second": {
115+
"value": 2
116+
}
117+
}
118+
```
119+
120+
```html
121+
{first}
122+
<div>
123+
First block wont appear here
124+
</div>
125+
{/first}
126+
{second}
127+
<div>
128+
In context of second condition: {value}
129+
</div>
130+
{/second}
131+
```
132+
133+
## Template pool methods
134+
### get(template, data)
135+
Return template object from pool of available templates using the template key.
136+
137+
- *template* - name of template. If your template name as mytemplate.yat it must be mytemplate (without extension).
138+
- *data* - optional. Pass data to render your template as object.
139+
140+
### release(template, instance)
141+
It releases generate template from DOM tree
142+
143+
- *template* - name of template.
144+
- *instance* - generated Node of this template.
145+
146+
## Template object methods
147+
When you get template from created pool, it has several methods to manipulate it.
148+
149+
### dom()
150+
The method returns generated DOM tree for current template as DocumentFragment (see document.createDocumentFragment).
151+
152+
### update(data)
153+
- *data* - object to update and rerender current loaded template's DOM.
154+
155+
### remove()
156+
This method removes rendered element from DOM tree.
157+
158+
## Loaders for YATE
159+
Webpack: (https://www.npmjs.com/package/yate-loader).

bin/yate

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env node
2+
import fs from 'fs';
3+
import { fileURLToPath } from 'url';
4+
import { dirname, resolve } from 'path';
5+
import build from './../build.js';
6+
7+
const args = process.argv.slice(2);
8+
const files = [];
9+
10+
let asModule = false;
11+
let asBundle = false;
12+
13+
const __filename = fileURLToPath(import.meta.url);
14+
const __dirname = dirname(__filename);
15+
16+
for (const arg of args) {
17+
switch (arg) {
18+
case '-m':
19+
case '--module':
20+
asModule = true;
21+
break;
22+
23+
case '-b':
24+
case '--bundle':
25+
asBundle = true;
26+
break;
27+
28+
default:
29+
files.push(arg);
30+
}
31+
}
32+
33+
if (files.length > 0) {
34+
if (asBundle) {
35+
const scriptPath = resolve(__dirname, '..', 'yate.js');
36+
37+
try {
38+
const content = fs.readFileSync(scriptPath, { encoding: 'utf8' });
39+
console.log(content);
40+
} catch (error) {
41+
console.error(`Error reading file: ${error.message}`);
42+
process.exit(1);
43+
}
44+
}
45+
46+
new Promise((resolve, reject) => {
47+
build(files, asModule)
48+
.then(result => {
49+
console.log(result);
50+
resolve(result);
51+
})
52+
.catch(error => {
53+
console.error('Error during build:', error);
54+
reject(error);
55+
});
56+
});
57+
} else {
58+
console.log("Usage: yate file1.yat [...file2.yat] [options]");
59+
console.log(" yate file1.yat -m");
60+
console.log("Options:");
61+
console.log(" -m, --module build as module");
62+
console.log(" -b, --bundle generate bundle code with injected yate.js");
63+
console.log("Error: No input files provided.");
64+
console.log("Please provide at least one .yate file to process.");
65+
}
66+

bin/yate.js

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/usr/bin/env node
2+
import fs from 'fs';
3+
import { fileURLToPath } from 'url';
4+
import { dirname, resolve } from 'path';
5+
import build from './../build.js';
6+
7+
const args = process.argv.slice(2);
8+
const files = [];
9+
10+
let asModule = false;
11+
let asBundle = false;
12+
13+
const __filename = fileURLToPath(import.meta.url);
14+
const __dirname = dirname(__filename);
15+
16+
for (const arg of args) {
17+
switch (arg) {
18+
case '-m':
19+
case '--module':
20+
asModule = true;
21+
break;
22+
23+
case '-b':
24+
case '--bundle':
25+
asBundle = true;
26+
break;
27+
28+
default:
29+
files.push(arg);
30+
}
31+
}
32+
33+
if (files.length > 0) {
34+
if (asBundle) {
35+
const scriptPath = resolve(__dirname, '..', 'yate.js');
36+
37+
try {
38+
const content = fs.readFileSync(scriptPath, { encoding: 'utf8' });
39+
console.log(content);
40+
} catch (error) {
41+
console.error(`Error reading file: ${error.message}`);
42+
process.exit(1);
43+
}
44+
}
45+
46+
new Promise((resolve, reject) => {
47+
build(files, asModule)
48+
.then(result => {
49+
console.log(result);
50+
resolve(result);
51+
})
52+
.catch(error => {
53+
console.error('Error during build:', error);
54+
reject(error);
55+
});
56+
});
57+
} else {
58+
console.log("Usage: yate file1.yat [...file2.yat] [options]");
59+
console.log(" yate file1.yat -m");
60+
console.log("Options:");
61+
console.log(" -m, --module build as module");
62+
console.log(" -b, --bundle generate bundle code with injected yate.js");
63+
console.log("Error: No input files provided.");
64+
console.log("Please provide at least one .yat file to process.");
65+
}
66+

build.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import { DOMParser } from 'xmldom';
2+
import Compile from './compile.js';
3+
import { promises as fs } from 'fs';
4+
5+
const parser = new DOMParser();
6+
7+
const processFiles = async (files, asModule) => {
8+
const fileArray = Array.isArray(files) ? files : [files];
9+
10+
const pool = {};
11+
await Promise.all(fileArray.map(async (file) => {
12+
const content = await fs.readFile(file, 'utf8');
13+
const parsed = parser.parseFromString(content);
14+
const fileName = file.split('/').pop().split('.')[0];
15+
await new Compile(parsed, pool).build(fileName);
16+
}));
17+
18+
const poolCode = Object.entries(pool)
19+
.map(([template, code]) => `"${template}":${code}`)
20+
.join(',');
21+
22+
const moduleCode = `
23+
const yate = require("yate");
24+
module.exports = {${poolCode}};
25+
`;
26+
27+
const windowCode = `
28+
const templateList = {${poolCode}};
29+
window.templates = yate.pool(templateList);
30+
`;
31+
32+
return asModule ? moduleCode : windowCode;
33+
};
34+
35+
export default async function (files, asModule) {
36+
return processFiles(files, asModule);
37+
}
38+

0 commit comments

Comments
 (0)