oml
Note that oml is still a just-for-fun beta project
About
oml (oli markup language) is a tiny template engine built on top of the Oli language which runs in node and the browser. It's powered by oli.js and htgen
You can try it online here
Overview Example
url = 'https://github.com/h2non/oml#syntax-reference' doctypehtml: head: include: includes/head &title: This is oml! script:> if (foo) { bar(2 ^ 2) } end end body: # use a reference that points to 'title' h1.head: *title # use the shortcuts for class and id attributes definition .container@main (title: 'Main container'): p.text: | A template engine built on top of the Oli language a (href: *url): Oml reference textarea:- Lorem ipsum ad his scripta blandit partiendo, eum fastidii accumsan euripidis in, eum liber hendrerit an. Qui ut wisi vocibus suscipiantur end end endend
Take a look to the syntax reference for more details and supported features
Features
- Elegant, simple and minimalist syntax
- Built-in support for mixins and file includes
- Tag definition shortcuts and attributes autocompletion
- Built-in support for data references
- Generates pretty well-indended code
- Runs over node and browsers
- Self-contained, no third party dependencies (in browser environments)
- Based in the Oli language (so you can use all of the native language features)
Upcoming features
- Include/require support in the browser
- Layout blocks (Jade-like)
- HTML entities decoding
Installation
Node.js
$ npm install omljs
For CLI usage only, it's recommented you install it as global package
$ npm install -g omljs
Browser
$ bower install oml --save
Or load the script remotely (just for testing or development)
Then you can create script tags with text/oli
MIME type
It will automatically fetch and parse the oli sources and make it available from oli.scripts
.
To disable the automatic parsing, just add data-ignore
attribute in the script tag
Environments
- Node.js >= 0.8.0
- Chrome
- Firefox
- Safari 5
- Opera >= 11.6
- IE >= 9
CLI
Usage: oml [options] <path/to/file.oli>
Options:
-h, --help output usage information
-V, --version output the version number
-o, --output <file> write output into a file instead of stdout
-i, --in-line parse in-line argument as string
-p, --pretty generate well-indented pretty output
-d, --indent <size> JSON output indent size. Default to 2
-t, --tabs use tabs instead of spaces to indent
-s, --stdin read source from stdin
Usage examples:
$ oml file.oli > file.html
$ oml file.oli -o file.html
$ oml -i "div: p: Hello"
$ oml -s < file.oli
$ oml --indent 4 file.oli
$ oml --tabs file.oli
API
Example
var oml = var code = 'h1.title: Hello oml!'try oml catch e console
render(code, options)
Parse, compile and render the given. It will throw an exception if a parsing, compilation or rendering error happens
Engine(data, options)
Expose the template engine constructor
oli
Expose the oli.js API
htgen
Expose the htgen API
options
Render supported options:
- locals: Local context to pass to the compiler. Default to
null
- basePath: Base path to use for includes. Default to the current working directory
- pretty: Generate a well-indented code. Default to
false
- size: Initial indent size. Default to
0
- indent: Indent spaces. Default to
2
- tabs: Use tabs instead of spaces to indent. Default to
false
Syntax Reference
This reference only points to the specific syntax use cases related to oml
Please, take into account that oml syntax is completely based on the Oli language, so you can use any feature that is natively supported by Oli, like data references or block inheritance
For more information about the oli syntax, you could visit the language site or read the specification
Doctype
The document can use any of the following doctypes alias:
html => <!DOCTYPE html>
xml => <?xml version="1.0" encoding="utf-8" ?>
transitional => <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
strict => <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
frameset => <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
1.1 => <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
basic => <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">
mobile => <!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">
Example
doctype html # => <!DOCTYPE html>
Tags
p: this is a text # => <p>this is a text</p>
ul: li: Apple li: Banana li: Cocoend
Self-closed tags
img! # => <img/>
img(src: 'image.png') # => <img src="image.png"/>
Literal shortcuts
Class
a.button # => <a class="button"></a>
.content # => <div class="content"></div>
ID
a@link # => <a id="link"></a>
@content # => <div id="content"></div>
Attributes
a (href:'google.com'): Google # => <a href="http://google.com"></a> a (class: 'link', href: 'oli-lang.org'): Oli # => <a class="link" href="http://oli-lang.org">Oli</a>
Blocks
Folded
div: p:- This will be parsed as a raw text endend
Unfolded
div: p:= This will be parsed as a raw text endend
You also can use interpolated HTML tags
div: p:- This is a plain <strong>text</strong>end
Using pipe block expression
div: | p: This is a plain <strong>text</strong>
Plain text
script (type: text/javascript):> if (foo) { bar(1 + 5) }end
Includes
Load and include content from a file in the document
include: path/to/file.oli
Requires
require
is like include
, the unique significant difference between both are that require
load and render the file in an isolated sandbox context, so that means you cannot
share variables or mixins between documents
require: path/to/file.oli
Mixins
Mixin declaration
mixin title: h1: Hello Omlend+title
Passing arguments:
mixin sample(title, text): h1: Hello $name p: $textend+sample ('oml', 'This is a paragraph')
Default arguments:
mixin sample(title, text: 'default value'): h1: Hello $name p: $textend+sample ('oml')
Comments
Line comments
# this is # a comment
Block comments
## This is a block comment##
Contributing
Wanna help? Cool! It will be really apreciated :)
You must add new test cases for any new feature or refactor you do, always following the same design/code patterns that already exist
oml is completely written in LiveScript language. Take a look to the language documentation if you are new with it. You should follow the LiveScript language conventions defined in the coding style guide
Development
Only node.js and Grunt are required for development
Clone/fork this repository
$ git clone https://github.com/h2non/oml.git && cd oml
Install package dependencies
$ npm install
Run tests
$ npm test
Coding zen mode
$ grunt zen [--force]
Bundle browser sources
$ grunt build
Release a new patch version
$ grunt release
License
Copyright (c) Tomas Aparicio
Released under the MIT license