Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/charmander/razorleaf
A template engine for HTML in Node.js JavaScript
https://github.com/charmander/razorleaf
nodejs template-engine
Last synced: 3 months ago
JSON representation
A template engine for HTML in Node.js JavaScript
- Host: GitHub
- URL: https://github.com/charmander/razorleaf
- Owner: charmander
- License: isc
- Created: 2013-03-08T23:41:38.000Z (almost 12 years ago)
- Default Branch: main
- Last Pushed: 2023-02-04T23:16:32.000Z (almost 2 years ago)
- Last Synced: 2024-10-10T10:26:42.841Z (3 months ago)
- Topics: nodejs, template-engine
- Language: JavaScript
- Homepage: https://charmander.me/razorleaf/
- Size: 850 KB
- Stars: 12
- Watchers: 4
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[![Build status][ci image]][ci]
Razor Leaf is an HTML template engine for Node.js.
## Features
- automatic escaping
- template inheritance
- recursive macros
- conditional attributes and classes
- explicit whitespace only to make it clear when it affects the content
- no dependencies\*
- unrestricted JavaScript expressions and inline code; no sandboxes to work around
\* This might change.
## Example
`example.rl`:
```
doctype html
head
meta charset: "utf-8"
meta name: "viewport" content: "initial-scale=1"title "Example"
body
h1 "Hello, world!"do const { left, right } = data;
p "#{left} × #{right} = #{left * right}"
````example.js`:
```javascript
const DirectoryLoader = require('razorleaf/directory-loader');const templateLoader = new DirectoryLoader(__dirname);
const template = templateLoader.load('example');console.log(
template({
left: 9,
right: 12,
})
);
```Output:
> # Hello, world!
>
> 9 × 12 = 108## Syntax
### Elements
Elements are defined by their names only; no other special character is
necessary.```
p
``````html
```Void elements are recognized automatically.
```
meta
``````html
```
### Strings
Strings are double-quoted and escaped for use in HTML as needed. Backslash
escape codes can be used as in JavaScript. No whitespace is added
around strings.```
"--> A string <--\n" "A string containing \"double-quotes\""
``````html
--> A string <--
A string containing "double-quotes"
```Strings can also contain interpolated sections, delimited by `#{` and `}`.
`#{` can be escaped with a leading backslash; `}` doesn’t require escaping.```
"#{6 * 7}"
``````html
42
```If an exclamation mark precedes the string, it and any of its interpolated
sections will not be escaped.```
!""
``````html
```
### Attributes
Attributes are marked up using the syntax
name: "value"
, where"value"
is a string as described above. Use an empty string for boolean attributes.```
meta charset: "utf-8"
``````html
```
If a boolean attribute is conditional, it can be written in shorthand:
```
input
name: "#{field.name}"
disabled: if field.disabled
```equivalent to:
```
input
name: "#{field.name}"if field.disabled
disabled: ""
```### Classes
Classes are marked up with a leading period, as in
.class
.```
fieldset .upload-meta
input.required
``````html
```
### Hierarchy
Hierarchy in Razor Leaf is defined using indentation. For example:
```
doctypehtml
head
meta charset: "utf-8"title "Example"
link
rel: "stylesheet"
type: "text/css"
href: "stylesheets/example.css"body
p id: "introduction"
"This template is a brief example of hierarchy."
``````html
ExampleThis template is a brief example of hierarchy.
```Content found after an element on the same line will also be considered that
element’s content.### Comments
Comments begin with `#` and continue to the end of the line. They do not affect
the rendered HTML.### Code
**Code blocks** begin with `do` and treats all of their content as JavaScript.
```
do
const compareKeys = (a, b) =>
a.key < b.key ? -1 :
a.key > b.key ? 1 :
0;const sorted = (array, by) =>
array
.map(value => ({key: by(value), value}))
.sort(compareKeys)
.map(({value}) => value);let characterCount = 0;
for post of sorted(posts, post => post.title)
post-detail(post)
do characterCount += post.content.length;
```### Special blocks
Some names define special blocks. These are:
- **`doctype`**: Inserts ``.
- **`if (condition)`**: Includes its content only if *`condition`* is met.
- **`elif (condition)`**: Can immediately follow an `if` or an `elif`.
- **`else`**: Can immediately follow an `if` or an `elif`.
- **`for (identifier) of (collection)`**: Includes its content for each element of the array or array-like object *`collection`*.
- **`for (identifier), (index) of (collection)`**: Allows the index variable in a `for` loop to be named.
- **`include (name)`**: Loads and includes another template.
- **`extends (name)`**: Loads another template and replaces its blocks. A template that extends another template cannot have any content outside of block actions.
- **`block (name)`**: Defines a replaceable block.
- **`replace (name)`**: Replaces a block.
- **`append (name)`**: Appends to a block.
- **`do`**: See [**Code**](#code).## API
### `new razorleaf.DirectoryLoader(root, [options])`
Creates a loader that maps template names to files with the `.rl` extension
in the directory located at *`root`*.#### `razorleaf.DirectoryLoader.prototype.load(name, [options])`
Returns a template object loaded from the root directory.
### `razorleaf.compile(template, [options])`
Compiles a template string into a function. The compiled function takes
one argument, `data`, which can be used (under that name) in the template.### Options
- **`load(name)`**: A function that returns a parsed template represented by `name`. This is filled automatically by most loaders.
- **`globals`**: An object representing the global variables that should be made available to the template.[ci]: https://travis-ci.org/charmander/razorleaf
[ci image]: https://api.travis-ci.org/charmander/razorleaf.svg?branch=master