https://github.com/sgolub/atat
š Fast and simple JavaScript template engine
https://github.com/sgolub/atat
express html javascript nodejs templating templating-engine typescript
Last synced: about 2 months ago
JSON representation
š Fast and simple JavaScript template engine
- Host: GitHub
- URL: https://github.com/sgolub/atat
- Owner: sgolub
- License: mit
- Created: 2017-03-17T20:17:36.000Z (about 9 years ago)
- Default Branch: master
- Last Pushed: 2023-03-04T05:01:59.000Z (about 3 years ago)
- Last Synced: 2025-10-23T02:16:04.778Z (6 months ago)
- Topics: express, html, javascript, nodejs, templating, templating-engine, typescript
- Language: TypeScript
- Homepage: https://sgolub.github.io/atat/
- Size: 1.47 MB
- Stars: 0
- Watchers: 0
- Forks: 1
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# αtαt
Fast and simple asynchronous JavaScript template engine without dependencies and for any environment (:
[](https://github.com/sgolub/atat/actions)
## But why?
I wanted to create something simple for what you don't need to spend hours to read the documentation, something that you can start to use in a few minutes. The main idea is using pure JavaScript with pure HTML. You don't need to learn new syntax, just do everything like in JavaScript.
## Features
- Embedded JavaScript code
- Browser support
- Complies with Express
- Layouts, partials and sections
- No dependencies and very small size
- TypeScript support
- Easy to use
## Installation
Using yarn or npm:
```bash
$ yarn add atat
$ npm install --save atat
```
## Tests
Using yarn or npm:
```bash
$ yarn test
$ npm test
```
## Usage
```js
import { config, parse, loadAndRender, render, loadAndParse } from 'atat';
var atat = require('atat');
```
`atat` object has the following methods
- `config` to setup global configuration for all templates
- `parse` to parse a template, returns a render function
- `loadAndParse` the same with `parse` but allows a path to a template as the first argument
- `render` to parse and render a template, returns the result string
- `loadAndRender` the same with `render` but allows a path to a template as the first argument
```js
import { parse, loadAndRender, render, loadAndParse } from 'atat';
const render = await parse(templateString, options);
container.innerHTML = render(model);
container.innerHTML = await render(templateString, model, options);
const render = await loadAndParse(pathToTemplate, options);
container.innerHTML = render(model);
container.innerHTML = await loadAndRender(pathToTemplate, model, options);
```
If your environment doesn't support `async/await` sytax, use `Promise`
```js
render(templateString, options).then((err, result) => {
container.innerHTML = result;
});
```
### Options
- `it` models variable name, default `"it"`
- `$` helpers variable name, default `"$"`
- `helpers` extra helpers
- `loader` templates provider
```js
import { parse, render, config, DEFAULT_LOADER } from 'atat';
const options = {
it: "it",
$: "$",
helpers: { },
loader: DEFAULT_LOADER
};
// global config will be applied to all templates
config(options);
// also you can pass options to the parse and render methods
const tmpl = await parse(templateString, options);
const html = await render(templateString, { /* model */ }, options);
```
### Loaders
Loaders allow you to load templates asynchronously. There are two default loaders available right from the library:
- `DEFAULT_LOADER` - for Node.js, default loader, uses `fs` module
- `FETCH_LOADER` - for a browser, loads templates through `fetch` method
```js
import { loadAndRender, loadAndParse, config, FETCH_LOADER, DEFAULT_LOADER } from 'atat';
const html = await loadAndRender(
path.resolve(__dirname, './views/main.html'),
{ /* model */ },
{ loader: DEFAULT_LOADER },
);
// in a browser you must specify loader, at least FETCH_LOADER
const html = await loadAndRender(
'http://localhost:3000/views/main.html',
{ /* model */ },
{ loader: FETCH_LOADER },
);
// custom loader
config({
loader: async (path) => {
const template = await loadTemplate(path);
return template;
}
});
```
### Syntax
Encoded output
```html
@(it.user.firstName)@
```
Raw html output
```html
@!(it.rawHTML)@
```
Embedded JavaScript code
```html
@{
// Any JavaScript code is acceptable in this block
var firstName = it.user.firstName;
var secondName = it.user.secondName;
}@
@(firstName)@ @(secondName)@
```
**@if**
```html
@if (it.user != null) {
@(it.user.firstName)@
@(it.user.secondName)@
}@
```
**@if...else if...else**
```html
@if(it.user && it.user.firstName && it.user.secondName){
@(it.user.firstName)@
@(it.user.secondName)@
} else if (it.user && it.user.firstName) {
@(it.user.firstName)@
} else {
User is not defined
}@
```
**@for**
```html
- @(it.users[i].firstName)@ @(it.users[i].secondName)@
@for(var i = 0, l = it.users.length; i < l; i++){
}@
```
**@while**
```html
- @(i++)@
@{ var i = 0, j = 5; }@
@while (i < j) {
}@
```
### Helpers
#### Custom helper
`@()@`
- `name` the valid name
- `args...` whatever you want
```js
const options = {
$: '$',
helpers: {
l10n: (lang, key) => resources[lang][key];
}
};
const result = await atat.render(template, { lang: 'en' }, options);
```
```html
@l10n(it.lang, "title")@
@('My Website - ' + $.l10n(it.lang, "title"))@
```
#### Default helpers
- `@json()@` returns a result of JSON stringify
- `@encode()@` the same as `@()@`
- `@join(, )@` joins the array with the separator (optional)
- `@upper()@` simple uppercase
- `@lower()@` simple lowercase
### Layout
`@layout()@`
- `path` the path to the layout file
**index.atat**
```html
@layout('/views/_layout.atat')@
Home page!
```
**/views/\_layout.atat**
```html
@!(body)@
```
Output:
```html
Home page!
```
### Patrial
Patrials allow you to reuse useful pieces of code in different places
`@partial(, )@`
- `path` path to partial a view file
- `model` model for a partial view (optional)
**views/\_menu.atat**
```html
```
**views/\_layout.atat**
```html
@{ const { $route } = it; }@
@partial('/views/_menu.atat', $route)@
@!(body)@
```
Output:
```html
```
### Section
Section allows you to pass HTML markup from a view to a layout level
Use the following syntax to specify a new section
```html
@section script {
document.addEventListener('DOMContentLoaded', function() {
// your code is here
});
}@
```
and another one to output the result anywhere
`@section()@`
- `name` sections name
**index.atat**
```html
@layout('/views/_layout.atat')@
Home page!
@section script {
document.addEventListener('DOMContentLoaded', function() {
// your code is here
});
}@
```
**/views/\_layout.atat**
```html
@!(body)@
@section('script')@
```
Output:
```html
Home page!
document.addEventListener('DOMContentLoaded', function() {
// your code is here
});
```
### ExpressJS Integration
Just set `'view engine'` value to `atat`
```js
const express = require('express');
const app = express();
app.set('views', './views');
app.set('view engine', 'atat');
```
Example available [here](https://github.com/sgolub/atat/tree/master/example)
### Demo
[Live demo](https://sgolub.github.io/atat)
## License
The JavaScript Templates script is released under the [MIT license](https://opensource.org/licenses/MIT).