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

https://github.com/alloyteam/sodajs

Light weight but powerful template engine for JavaScript
https://github.com/alloyteam/sodajs

soda sodajs template template-engine

Last synced: 6 months ago
JSON representation

Light weight but powerful template engine for JavaScript

Awesome Lists containing this project

README

          

# sodajs

An amazing directive template engine for JavaScript.

## [中文说明](https://github.com/AlloyTeam/sodajs/blob/master/readme_zh.md)

## Fetures
* super tiny size (4kb gzipped)
* dom directives support
* good compatibility (IE8 +, node)
* prevents XSS holes out of your template file
* high-performance DOM parser
* directive Api compatibile with AngularJS
* custom directive and prefix

## Install
### npm
``` js
npm install --save sodajs
```

### CDN
* [https://unpkg.com/sodajs@0.4.10/dist/soda.min.js](https://unpkg.com/sodajs@0.4.10/dist/soda.min.js)
* [https://unpkg.com/sodajs@0.4.10/dist/soda.js](https://unpkg.com/sodajs@0.4.10/dist/soda.js)
* [https://unpkg.com/sodajs@0.4.10/dist/soda.node.min.js](https://unpkg.com/sodajs@0.4.10/dist/soda.node.min.js)
* [https://unpkg.com/sodajs@0.4.10/dist/soda.node.js](https://unpkg.com/sodajs@0.4.10/dist/soda.node.js)

## Usage
### Difference between soda & soda.node
| version | soda | soda.node |
| ------------ | ------------ | ------------ |
| Mordern Browsers | ✓| ✓|
| Mobile Browsers | ✓ | ✓ |
| ie | ≥8 | ≥9|
| node | ✗ | ✓|
| DOM Parsor| Native | Self |

warning: ie 8 needs es5-shim or es5-sham and console-polyfill

check ie 8 test below
* [ie8 browser test](http://alloyteam.github.io/sodajs/test/soda-browser.html)

### Browser
* script tag

```html

```
* with webpack

```javascript
import soda from "sodajs"
```

### Node
```js
let soda = require('sodajs/node');
```
or use dist version for older node
```js
let soda = require('sodajs/dist/soda.node')
```
## API
### Output

#### plain

```js
var tpl = '

{{name}}
';

document.body.innerHTML = soda(tpl,{ name : 'soda' })

```
➜ [plain example](http://alloyteam.github.io/sodajs/pg/rd.html?type=simple)

#### safe propery chain output
```js
var data = {
name: 'soda',
info: {
version: '2.0'
}
}

soda("{{info.version}}", data);
// result => "2.0"

soda("{{info.foo.foo1}}", data)
// result => "" without errors

soda("{{info['name']}}", data)
// result => "2.0"

```

#### expression

```js
var data = {}

soda("{{1 + 2}}", data);
// result => 2

soda("{{true ? 'soda' : 'foo'}}", data)
// result => "soda"

soda("{{1 < 3 && 'soda'}}", data)
// result => "soda"

```
➜ [expression example](http://alloyteam.github.io/sodajs/pg/rd.html?type=expression)

#### complex expression
```js
var data = {
list: [
{list: [{'title': '<>aa'}, {'title': 'bb'}], name: 0, show: 1},
{list: [{'title': 0 }, {'title': 'bb'}], name: 'b'}
]

};

soda('{{list[list[0].show === 1 ? list[0].name : 1].list[0].title}}', data)
// result => '<>aa'
```

### Directives

#### if

``` js
var data = { name : 'soda',show: true };
soda(`

Hello, {{name}}

I\'m hidden!
`,
data
)
// result =>
Hello, soda

```

➜ [if example](http://alloyteam.github.io/sodajs/pg/rd.html?type=if)

### repeat

> soda-repeat="item in array"

> soda-repeat="item in object"

> soda-repeat="item in array by index"

> soda-repeat="item in object by key"

> soda-repeat="(index, value) in array"

> soda-repeat="(key, value) in object"

default index or key is $index

``` js
var tpl = '\

    \
  • \
    {{item.name}}\
    {{$index}}\
  • \
'

var data = {
list: [
{name: "Hello" ,show: true},
{name: "sodajs" ,show: true},
{name: "AlloyTeam"}
]
};

document.body.innerHTML = soda(tpl, data);
```

➜ [repeat example](http://alloyteam.github.io/sodajs/pg/rd.html?type=repeat)

### filter

> soda.filter(String filterName, Function func(input, args...))
> {{input|filte1:args1:args2...|filter2:args...}}

example:

``` js
soda.filter('shortTitle', function(input, length){
return (input || '').substr(0, length);
});

var tpl = '\

    \
  • \
    {{item.title|shortTitle:10}}\
  • \
'

document.body.innerHTML = soda(tpl,{ list : [
{title:'short'},
{title:'i am too long!'}
] })
```

➜ [filter example](http://alloyteam.github.io/sodajs/pg/rd.html?type=filter)

### html
output origin html as innerHTML
```js
var tpl = '

'
document.body.innerHTML = soda(tpl,{ html : 'test soda-html' })
```

➜ [html example](http://alloyteam.github.io/sodajs/pg/rd.html?type=html)

### replace
replace this node with html

```js
var tpl = '

'
document.body.innerHTML = soda(tpl,{ html : 'test soda-html' })
```

➜ [replace example](http://alloyteam.github.io/sodajs/pg/rd.html?type=replace)

div will be replaced with given html

#### include
include template

soda-include="tmplateName:arg1:arg2:..."
with soda.discribe, we can include sub templates

```js
var data = {
name: "soda"
};

// define sub template named tmpl1
soda.discribe('tmpl1', `

{{name}}

`);


// use template tmpl1 by soda-include
soda(`1`, data);
// result =>

dorsy



// set compile false not to compile sub template
soda.discribe('tmpl1', `

{{name}}

`, {
compile: false
});

// show origin template
soda(`1`, data);
// result =>

{{name}}

soda.discribe('tmpl2', function(path){
return `

{{name}}_${path}

`;
});

soda(`1`, data);
// result =>

soda_subpath1


// In node env
soda.discribe('tmplNode', function(path){
return fs.readFileSync(path, 'utf-8');
});

soda(`1`, data);
// result => view.html Tmplate

```

### Others

#### soda-class
> soda-class="currItem === 'list1' ? 'active' : ''"

#### soda-src
> soda-src="hello{{index}}.png"

#### soda-style
> soda-style="style"

data example:

```js
var data = { style : { width : '100px', height : '100px' } };
```

#### soda-*
> soda-rx="{{rx}}%"

> soda-checked="{{false}}"

if the value is false or "", the attribute will be removed

## Custom

### soda.prefix

change prefix as you like, the default prefix is "soda-"

``` js
soda.prefix('v:')

var tpl = '\

    \
  • \
    {{item.name}}\
  • \
'

var data = {
list: [
{name: "Hello" ,show: true},
{name: "sodajs" ,show: true},
{name: "AlloyTeam"}
]
};

document.body.innerHTML = soda(tpl, data);
```
### soda.directive
Custom your directive
#### es 2015
```js
soda.directive('name', {
priority: 8,

// how to compile el
link({ scope, el, parseSodaExpression, expression, getValue, compileNode, document }) {

}
});
```
* scope: current scope data
* el: current node elment
* expression: directive string value
* getValue: get value from data
```js
getValue({a: {b: 1}}, "a.b"); // ===> 1
```
* parseSodaExpression: parse soda expressions
```js
parseSodaExpression('{{1 + 2 + a}}', {a: 1}); // ===> 4
```
* compileNode: compile new nodes
* document: using document rather than window.document to run in node env;

#### example
```js
soda.directive('mydirective', {
priority: 8,

link({ scope, el, parseSodaExpression, expression, getValue, compileNode, document }) {
var value = parseSodaExpression(expression);
if(value){
var textNode = document.createTextNode(value);
el.appendChild(textNode);
}
}
}

soda(`


`, {
tips: 'tips'
});

// result ==>

add one tips: tips

```

### soda.setDocument
custom dom parsor for node running.

soda.node version default document dom parsor is nodeWindow.

```js
var document = require('document');
var soda = require('soda');

soda.setDocument(document);

// ... run

```

## Contribute
### Development

git clone
``` shell
git clone git://github.com/AlloyTeam/sodajs.git
```
install dependency

``` shell
npm install
```

then run npm start

``` shell
npm start
```
publish code to run test

``` shell
npm run build
```
### Auto-Test
soda uses mocha to run test

test unit is in test dir.
``` shell
npm run test
```

#### online test result
* [soda-mocha](http://alloyteam.github.io/sodajs/test/soda-mocha.html)
* [soda.node-mocha](http://alloyteam.github.io/sodajs/test/soda.node-mocha.html)
* [ie8 browser test](http://alloyteam.github.io/sodajs/test/soda-browser.html)

## Used projects
QQ Tribes(兴趣部落), QQ Group(群) and other projects

## License

[MIT](http://opensource.org/licenses/MIT)

Copyright (c) 2015-present, AlloyTeam