0.2.3 • Published 3 years ago

hexel-view v0.2.3

Weekly downloads
64
License
MIT
Repository
github
Last release
3 years ago

Hexel View

A fully featured HTML view renderer for NodeJS.

npm install hexel-view

Features

  • Standard HTML5
  • Embedded JavaScript expressions
  • Enhanced HTML attributes
  • Scope blocks
  • Control flow statements
  • Partials
  • Layouts
  • API

Standard HTML5

Most of the HTML5 specification is supported, with some limitations applied:

  • Non-void elements must always have closing tags.
  • Only the HTML5 doctype is supported.
  • Element attributes must always be quoted using either single or double quotes.

Some additional conveniences have also been added:

  • Any element can use the self-closing element syntax: <element />

Embedded JavaScript expressions

Expression

The expression will be evaluated, but not output to your template, allowing you to perform operations like you would in Javascript. Only a single expression is allowed.

{% expression %}

Print expression

These work just like the normal expression, except they will output the return value of the expression. If the return value is null or undefined, then nothing will be printed.

{%= expression %}

Variable declaration

Variables can be defined in your views like you would do in plain Javascript. You're limited to let declarations though.

{% let value = expression %}

Expression comment

These expression comments allow you to add comments to your views that won't be printed into the rendered result.

{%# Comment text %}

Enhanced HTML attributes

Attribute value interpolation

Element attributes may contain expression statements like any other part of the view.

<element attribute="{%= expression %}">

E.g.
<a href="/items/{%= item.id %}/edit">

Attribute value as expression

You can also bind the value of an attribute to the return value of an expression without needing to use the expression tags in the attribute value.

<element [attribute]="<expression>">

E.g.
<a [href]="showPath">

Append attribute value

This syntax allows you to append a value to an attribute value, based on an expression. If the expression evaluates to a truthy value, then the value after the dot (.) will be appended to the base value of the attribute, separated by a space. The append value may not contain any space characters, to ensure that it complies with value HTML syntax.

<element [attribute.value]="<expression>">

E.g.
<div [class.is-open]="isOpen">

Boolean attribute

By using a boolean attribute expression you can add a boolean attribute to an element if the value of its expression evaluated to a truthy value.

<element [?attribute]="<expression>">

E.g.
<input [?checked]="isChecked">

Scope blocks

Sometimes it is useful to simply scope some variables in Javascript. You can achieve this in Hexel by using a plain js block.

<js>
	...
</js>

Print block

Print blocks are an alternative syntax to be output expression.

<js @print="<expression>" />

These statements also support block content as an argument in your expressions. The $block variable will be injected into your expression as a function which will return the rendered content of the @print block. You can also pass arguments to the $block function, which will be exposed in the view block.

<js @print="method($block)" @block="arg1, arg2">
	...
</js>

The format of the $block function is:

function $block(...args: unknown[]): Promise<string>;

If statement

<js @if="<condition>">
	...
</js>
<js @else-if="<condition>">
	...
</js>
<js @else>
	...
</js>

Switch statement

<js @switch="<expression>">
	<js @case="<expression>">
		...
	</js>
	<js @case="<expression>">
		...
	</js>
	<js @default>
		...
	</js>
</js>

Foreach statement

Array iteration

<js @foreach="<value>[, <index>] in <array>">
	...
</js>

Object iteration

<js @foreach="<key>[, <value>[, <index>]] in <object>">
	...
</js>

While statement

<js @while="<condition>">
	...
</js>

Render statement

You can render partial views in other views using the @render declaration.

<js @render="<partial-view-path>" @context="<expression>" />

Layouts and slots

Hexel supports layouts and content slots, making composing complex templates much easier.

Layouts

To define the layout for a view inline, just add an @layout declaration to the start of your template.

Note: Partial views cannot define a layout to use inline.

<js @layout="<layout-view-path>" />

Now any content you write in your view will be considered part of the "default" content slot, which can be renderer in the layout view.

Render default slot

You can render the content for the default slot in a layout view using the @render-content declaration.

<js @render-content />

Slot content

You can also specify content for a specific named slot in your view.

<js @content-for="<slot-name>">
	...
</js>

Render slot

To render the content for a named slot, simply add an @render-content declaration with the desired slot name. If no content has been rendered for that slot, it won't output anything.

<js @render-content="<slot-name>" />

Example

<js @if="items.length > 0">
    <ul class="list">
        <js @foreach="item, index in items">
            <li>
                <a class="link"
                   href="/items/{{ item.id }}"
                   [data-id]="item.id"
                   [?hidden]="!item.isVisible"
                   [class.is-active]="index === 0">
                    {{ item.name }}
                </a>
            </li>
        </js>
    </ul>
</js>
<js @else>
	<div class="empty">No items</div>
</js>

API

1. Import the Renderer

// ES6 Modules
import { Renderer } from 'hexel-view';

// CommonJS Modules
const { Renderer } = require('hexel-view');

2. Setup the Renderer

// Default options
let renderer = new Renderer();

// With options
let renderer = new Renderer({
	// ...
});

The Renderer supports various options, which are listed below:

interface RendererOptions {
	views?: string = 'views';
	cache?: boolean = true;
	tags?: {
		blockTagName: string = 'js';
		expressionStart: string = '{%';
		expressionEnd: string = '%}';
		printStart: string = '{%=';
		commentStart: string = '{%#';
	};
	layout?: string = null;
	tabSize?: number = 4;
}

3. ExpressJS integration (optional)

Hexel integrates seamlessly with ExpressJS. All you have to do is to call the setup method with your express server instance:

renderer.setupExpress(expressApp, {
	// ...
});

You can configure the integration using the options listed below:

interface ExpressOptions {
	extension?: string = 'html';
	isDefault?: boolean = true;
}