An amazing directive template engine for JavaScript.
- 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
npm install --save sodajs
- 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.node.min.js
- https://unpkg.com/sodajs@0.4.10/dist/soda.node.js
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
- script tag
<script src="https://unpkg.com/sodajs@0.4.10/dist/soda.min.js"></script>
- with webpack
import soda from "sodajs"
let soda = require('sodajs/node');
or use dist version for older node
let soda = require('sodajs/dist/soda.node')
var tpl = '<div>{{name}}</div>';
document.body.innerHTML = soda(tpl,{ name : 'soda' })
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"
var data = {}
soda("{{1 + 2}}", data);
// result => 2
soda("{{true ? 'soda' : 'foo'}}", data)
// result => "soda"
soda("{{1 < 3 && 'soda'}}", data)
// result => "soda"
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)
// result => '<>aa</h1>'
var data = { name : 'soda',show: true };
soda(` <div soda-if="show">Hello, {{name}}</div>
<div soda-if="!show">I\'m hidden!</div>`,
data
)
// result => <div>Hello, soda</div>
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);
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!'}
] })
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>' })
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>' })
div will be replaced with given html
include template
soda-include="tmplateName:arg1:arg2:..." with soda.discribe, we can include sub templates
var data = {
name: "soda"
};
// define sub template named tmpl1
soda.discribe('tmpl1', `<h1>{{name}}</h1>`);
// use template tmpl1 by soda-include
soda(`<span soda-include="tmpl1">1</span>`, data);
// result => <h1>dorsy</h1>
// set compile false not to compile sub template
soda.discribe('tmpl1', `<h1>{{name}}</h1>`, {
compile: false
});
// show origin template
soda(`<span soda-include="tmpl1">1</span>`, data);
// result => <h1>{{name}}</h1>
soda.discribe('tmpl2', function(path){
return `<h1>{{name}}_${path}</h1>`;
});
soda(`<span soda-include="list3:sub{{'path' + 1}}">1</span>`, data);
// result => <h1>soda_subpath1</h1>
// In node env
soda.discribe('tmplNode', function(path){
return fs.readFileSync(path, 'utf-8');
});
soda(`<span soda-include="tmplNode:view.html">1</span>`, data);
// result => view.html Tmplate
soda-class="currItem === 'list1' ? 'active' : ''"
soda-src="hello{{index}}.png"
soda-style="style"
data example:
var data = { style : { width : '100px', height : '100px' } };
soda-rx="{{rx}}%"
soda-checked="{{false}}"
if the value is false or "", the attribute will be removed
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);
Custom your directive
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
getValue({a: {b: 1}}, "a.b"); // ===> 1
- parseSodaExpression: parse soda expressions
parseSodaExpression('{{1 + 2 + a}}', {a: 1}); // ===> 4
- compileNode: compile new nodes
- document: using document rather than window.document to run in node env;
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'
});
// result ==> <div>add one tips: tips</div>
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);
// ... run
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
soda uses mocha to run test
test unit is in test dir.
npm run test
QQ Tribes(兴趣部落), QQ Group(群) and other projects
Copyright (c) 2015-present, AlloyTeam