sodajs
An amazing directive template engine for JavaScript.
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
npm install --save sodajs
CDN
Usage
Difference between 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
Browser
<script src="https://unpkg.com/sodajs@0.4.10/dist/soda.min.js"></script>
import soda from "sodajs"
Node
let soda = require('sodajs/node');
or use dist version for older node
let soda = require('sodajs/dist/soda.node')
API
Output
plain
var tpl = '<div>{{name}}</div>';
document.body.innerHTML = soda(tpl,{ name : 'soda' })
➜ plain example
safe propery chain output
var data = {
name: 'soda',
info: {
version: '2.0'
}
}
soda("{{info.version}}", data);
soda("{{info.foo.foo1}}", data)
soda("{{info['name']}}", data)
expression
var data = {}
soda("{{1 + 2}}", data);
soda("{{true ? 'soda' : 'foo'}}", data)
soda("{{1 < 3 && 'soda'}}", data)
➜ expression example
complex expression
var data = {
list: [
{list: [{'title': '<>aa</h1>'}, {'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)
Directives
if
var data = { name : 'soda',show: true };
soda(` <div soda-if="show">Hello, {{name}}</div>
<div soda-if="!show">I\'m hidden!</div>`,
data
)
➜ if example
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
var tpl = '\
<ul>\
<li soda-repeat="item in list" soda-if="item.show">\
{{item.name}}\
{{$index}}\
</li>\
</ul>'
var data = {
list: [
{name: "Hello" ,show: true},
{name: "sodajs" ,show: true},
{name: "AlloyTeam"}
]
};
document.body.innerHTML = soda(tpl, data);
➜ repeat example
filter
soda.filter(String filterName, Function func(input, args...))
{{input|filte1:args1:args2...|filter2:args...}}
example:
soda.filter('shortTitle', function(input, length){
return (input || '').substr(0, length);
});
var tpl = '\
<ul soda-repeat="item in list">\
<li class="title">\
{{item.title|shortTitle:10}}\
</li>\
</ul>'
document.body.innerHTML = soda(tpl,{ list : [
{title:'short'},
{title:'i am too long!'}
] })
➜ filter example
html
output origin html as innerHTML
var tpl = '<div soda-html="html"></div>'
document.body.innerHTML = soda(tpl,{ html : '<span style="color:red;">test soda-html</span>' })
➜ html example
replace
replace this node with html
var tpl = '<div soda-replace="html"></div>'
document.body.innerHTML = soda(tpl,{ html : '<span style="color:red;">test soda-html</span>' })
➜ replace example
div will be replaced with given html
include
include template
soda-include="tmplateName:arg1:arg2:..."
with soda.discribe, we can include sub templates
var data = {
name: "soda"
};
soda.discribe('tmpl1', `<h1>{{name}}</h1>`);
soda(`<span soda-include="tmpl1">1</span>`, data);
soda.discribe('tmpl1', `<h1>{{name}}</h1>`, {
compile: false
});
soda(`<span soda-include="tmpl1">1</span>`, data);
soda.discribe('tmpl2', function(path){
return `<h1>{{name}}_${path}</h1>`;
});
soda(`<span soda-include="list3:sub{{'path' + 1}}">1</span>`, data);
soda.discribe('tmplNode', function(path){
return fs.readFileSync(path, 'utf-8');
});
soda(`<span soda-include="tmplNode:view.html">1</span>`, data);
Others
soda-class
soda-class="currItem === 'list1' ? 'active' : ''"
soda-src
soda-src="hello{{index}}.png"
soda-style
soda-style="style"
data example:
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-"
soda.prefix('v:')
var tpl = '\
<ul>\
<li v:repeat="item in list" v:if="item.show">\
{{item.name}}\
</li>\
</ul>'
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
soda.directive('name', {
priority: 8,
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
getValue({a: {b: 1}}, "a.b");
- parseSodaExpression: parse soda expressions
parseSodaExpression('{{1 + 2 + a}}', {a: 1});
- compileNode: compile new nodes
- document: using document rather than window.document to run in node env;
example
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(`
<div soda-mydirective="add one tips: {{tips}}"></div>
`, {
tips: 'tips'
});
soda.setDocument
custom dom parsor for node running.
soda.node version default document dom parsor is nodeWindow.
var document = require('document');
var soda = require('soda');
soda.setDocument(document);
Contribute
Development
git clone
git clone git://github.com/AlloyTeam/sodajs.git
install dependency
npm install
then run npm start
npm start
publish code to run test
npm run build
Auto-Test
soda uses mocha to run test
test unit is in test dir.
npm run test
online test result
Used projects
QQ Tribes(兴趣部落), QQ Group(群) and other projects
License
MIT
Copyright (c) 2015-present, AlloyTeam