/microjungle

:factory: HTML templating with JS. The Right Way.

Primary LanguageJavaScript

microjungle

npm bower travis coverage climate gratipay

HTML templating with JS. The Right Way.

Install

$ npm i -S microjungle
$ bower i -S microjungle

Usage

Browser

<script src="microjungle/dist/dom.min.js"></script>
<script>
    (function() {
        var documentFragment = microjungle([ ... ]);
    })();
</script>

or just use it as AMD/CommonJS module.

Non-browser JS environment

Such as Nodejs, but it should work almost anywhere:

var microjungle = require('microjungle');
var plainHTML = microjungle([ ... ]);

Syntax

It's all about JS:

// just an element
microjungle([
    ['div'],
]);
// <div></div>

// two elements
microjungle([
    ['div'],
    ['div']
]);
// <div></div><div></div>

// textnode as content
microjungle([
    ['div', 'text content']
]);
// <div>text content</div>

// multiple contents
microjungle([
    ['div', 'text content', 123, 'and another one']
]);
// <div>text content123and another one</div>

// attributes
microjungle([
    ['div', {'class': 'wrapper'}]
]);
// <div class="wrapper"></div>

// something more complex in browser environment
microjungle([
    ['div', {'class': 'wrapper'},
        ['p', 'inner paragraph',
            document.createElement('span'),
            document.createDocumentFragment().appendChild(
                document.createElement('i')
            ),
            false,
            undefined,
            0,
            []
        ]
    ]
]);
// <div class="wrapper"><p>inner paragraph<span></span><i></i>0</p></div>

Templating

// index.js

var data = require('./data');
var template = require('./template');
var html = template(data);
// data.json

{
  "title": {
    "url": "#",
    "text": "some pretty title"
  },
  "paragraphs": [
    "some pretty paragraph",
    "another one"
  ],
  "list": [
    {"text": "item1"},
    {"text": "item2", "active": true},
    {"text": "item3", "url": "#"}
  ],
  "footer": {
    "input": {
        "type": "text",
        "value": "some pretty input"
    },
    "button": {
        "type": "button",
        "value": "push"
    },
    "copyright": "all rights reserved, copyright 2011."
  }
}
// template.js

var microjungle = require('microjungle');

module.exports = function(data) {
    return microjungle([
        ['div', {'class': 'header'},
            ['h1',
                ['a', {'href': data.title.url}, data.title.text]
            ],
            'some pretty text line 1', ['br'],
            'some pretty text line 2'
        ],
        ['div', {'class': 'content'},
            data.paragraphs.map(function(text) {
                return ['p', text]
            }),
            ['ul', {'class': 'pretty-list'},
                data.list.map(function(item) {
                    return ['li', item.active && {'class': 'active'},
                        item.url ?
                            ['a', {'href': item.url}, item.text] :
                            item.text
                    ]
                })
            ]
        ],
        ['div', {'class': 'footer'},
            ['form', {'action': '/'},
                ['input', data.footer.input],
                ['input', data.footer.button]
            ],
            data.footer.copyright
        ]
    ]);
};

You can even use YAML for static templates and any kind of preprocessors like CoffeeScript.

Test

$ npm run lint
$ npm run unit
$ npm run unit:dom
$ npm run unit:plain

Build

$ npm run build
$ npm run build:dom
$ npm run build:plain

Notes

As it turned out later after writing the very first version in 2011, the idea is indentical to JsonML, but I hope it still makes sense in another implementation like microjungle :)

License

WTFPL