Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/davidjamesstone/hyperviews

Template language that produces `h` output
https://github.com/davidjamesstone/hyperviews

html hyperapp hyperscript template-language

Last synced: 4 days ago
JSON representation

Template language that produces `h` output

Awesome Lists containing this project

README

        

# hyperviews

`hyperviews` is a template language that transforms to hyperscript.

Use it as a build tool with any `h(tag, props, children)` compliant framework e.g. React, preact or hyperapp.

```js
const hv = require('hyperviews')

hv("

{state.name}
")
// => h('div', { id: 'foo' }, (state.name))
```

### Installation

`npm i hyperviews`

### API

`hyperviews(tmpl, mode, name, argstr)`

- `tmpl` (required) - The template string.
- `mode` - The output format. Can be one of [`raw`, `esm`, `cjs`, `browser`], or if any other value is passed the function is exported as a variable with that name. The default is `raw`.
- `name` - The default output function name. The default is `view`.
- `args` - The default function arguments. The default is `props state`.

### CLI

Reads the template from stdin,

`cat examples/test.html | hyperviews --mode esm --name foo --args bar > examples/test.js`

See [more CLI examples](./test/cli.js)

## Template language

### Interpolation

Use curly braces in attributes and text.

```html



My name is {state.name} my age is {state.age} and I live at {state.address}

```

See [more interpolation examples](./test/interpolation.js)

### Conditionals

There are two forms of conditional.

Using an `if` attribute.

```html
Show Me!
```

Or using tags ``, `` and ``

```html



1

2

bar is neither 1 or 2, it's {state.bar}!


```

`if` tags can be [nested](./test/conditionals.js#L84).

See [more conditional examples](./test/conditionals.js)

### Iteration

The `each` attribute can be used to repeat over items in an Array.
Three additional variables are available during each iteration: `$value`, `$index` and `$target`.

It supports keyed elements as shown here.

```html



  • {post.title} {$index}


```

produces

```js
h('ul', {}, (state.posts || []).map(function ($value, $index, $target) {
const post = $value
return h('li', { key: (post.id) }, h('span', {}, (post.title) + ' ' + ($index)))
}, this))
```

See [more iteration examples](./test/iteration.js)

### Events

```html
{state.foo}
```

produces this output

```js
h('a', { href: 'http://example.com', onclick: this.onClick, (state.foo))
```

See [more event examples](./test/events.js)

### Style

The `style` attribute expects an object

```html


```

produces this output

```js
h('p', { style: { color: state.color, fontSize: '12px' } })
```

### Literal

The `script` tag literally outputs it's contents.

```html

import { h, Component } from 'preact'
import MyComponent from './component.js'

```

This is also useful for recursive nodes, e.g. a tree

```html


{state.name}


  • view(props, child)


{state.name}

```

produces this output

```js
function view (props, state) {
return (function () {
if (state.children) {
return h('div', {}, [
h('a', { href: '#' + (state.path) }, (state.name)),
h('ul', {}, (state.children || []).map(function ($value, $index, $target) {
var child = $value
return h('li', {}, view(props, child))
}))
])
} else {
return h('a', { href: '#' + (state.path) }, (state.name))
}
})()
}
```

See [more literal examples](./test/literal.js)

### Function

The `function` tag outputs a function, returning it's contents.
Supports `name` and `args` attributes.

```html

{x}

```

produces this output

```js
function MyComponent (x, y, z) {
return h('div', null, (x))
}
```

### Components

Components are declared with if the tag starts with a capital letter.

```html




```

produces this output

```js
h('div', null, h(MyComponent, { foo: 'bar' }))
```

### Module example

How you structure your app is down to you.
I like to keep js and html in separate files so a component might look like this:

- MyComponent
- view.html (The template file e.g. `

{state.name}
`)
- view.html.js (The transformed `h` output of the file above)
- index.js (Imports the transformed view and exports the component)

but if you want you could build entire modules in a html file like this:

```html

import { h, Component } from 'preact'

export default class MyComponent extends Component {
constructor (props) {
super(props)
this.render = view

this.onSubmit = e => {
e.preventDefault()
// ...
}
}
}






```

Compiles to

```js
import { h, Component } from 'preact'

export default class MyComponent extends Component {
constructor (props) {
super(props)
this.render = view

this.onSubmit = e => {
e.preventDefault()
// ...
}
}
}

function view (props, state) {
return h('section', null, h('form', { onsubmit: this.onSubmit }, [
h('input', { type: 'text', name: 'text', value: (state.text) }),
h('input', { type: 'text', name: 'description', value: (state.description) })
]))
}
```

More examples [here](https://github.com/davidjamesstone/hyperviews/tree/master/examples)

Using `browserify`?
Then install the `hyperviewify` transform so you can simply require templates.

`const view = require('./my-view.html')`

`npm i hyperviewify`