Overview // MarkoImprove this page
Marko is an eBay open source HTML-based templating engine that can be used to render templates on the server (Node.js) or in the web browser. It is extremely fast and lightweight (~3.75KB gzipped) while also supporting streaming and asynchronous rendering. Developers can extend the HTML grammar with custom tags and custom attributes to introduce new and reusable building blocks. The Marko compiler produces Node.js-compatible JavaScript modules that are easy to read, understand and debug. In contrast to other templating engines, Marko avoids evil global variables and global helpers.
Marko was founded on the philosophy that an HTML-based templating language is more natural and intuitive for generating HTML. Because the Marko compiler understands the structure of the HTML document, the directives in template files are less obtrusive and more powerful. Marko also retains the full power and flexibility of JavaScript by allowing JavaScript expressions inside templates.
Marko supports progressive HTML rendering by writing directly to an output stream so that HTML can be sent over the wire sooner. Marko automatically flushes around asynchronous parts of the template so that the HTML is delivered in the optimized number of chunks. Because Marko is an asynchronous templating language, additional data can be asynchronously fetched even after rendering has begun. These characteristics make Marko an excellent choice for creating high performance websites.
For building rich UI components with client-side behavior please check out the marko-widgets project.
Syntax
Marko supports both a familiar HTML syntax, as well as a more concise indentation-based syntax. Both syntaxes are equally supported. Regardless of which syntax you choose, the compiled code will be exactly the same.
Syntax highlighting is available in the following editors and IDEs:
- Atom: language-marko
- Sublime Text: marko-sublime
- WebStorm: marko.tmbundle (See: Importing TextMate Bundles)
- TextMate: marko.tmbundle
HTML syntax
<html lang="en"><head><title>Marko Templating Engine</title></head><body><h1>Hello !</h1><ul ifdata.colors.length><li forcolor in data.colors></li></ul><div else>No colors!</div></body></html>
Concise syntax
The following concise template is equivalent to the previous template:
html lang="en"headtitle - Marko Templating Enginebodyh1 - Hello !ul ifdata.colors.lengthli forcolor in data.colorsdiv else- No colors!
Mixed syntax
You can even mix and match the concise syntax with the HTML syntax within the same document. The following template is equivalent to the previous templates:
html lang="en"headtitle - Marko Templating Enginebody<h1>Hello !</h1>ul ifdata.colors.lengthli forcolor in data.colorsdiv else- No colors!
Sample Code
A basic template with text replacement, looping and conditionals is shown below:
hello-world.marko:
<h2>Hello !</h2><ul ifdata.colors.length><li style="color: " forcolor in data.colors></li></ul><div else>No colors!</div>
The template can then be rendered as shown in the following sample code:
;var template = ;template;
The output of running the above program will be the following (formatted for readability):
Hello World!redgreenblue
For comparison, given the following data consisting of an empty array of colors:
name: 'World'colors:
The output would be the following:
<h2>Hello World!</h2><div>No colors!</div>
The streaming API can be used to stream the output to an HTTP response stream or any other writable stream. For example, with Express:
var template = ;app;
Another Templating Language?
Most front-end developers are familiar with, and comfortable with, templating languages such as Handlebars, Dust or Mustache so why was Marko introduced?
What makes Marko different is that it is an HTML-based templating language that allows javascript expressions as attribute values. Any HTML file is a valid Marko template. Because Marko understands the HTML structure of the templates, it can support powerful functionality that would not be possible in text-based templating languages such as Handlerbars, Dust or Mustache. Marko allows developers to extend the HTML language by introducing custom HTML elements and attributes. On top of that, utilizing the HTML structure for applying templating directives makes templates more readable and allows data templates to more closely resemble the final HTML structure.
Let's compare Marko with Handlebars (a text-based templating language):
Handlebars:
<h2>Hello {{name}}!</h2>{{#if colors}}<ul>{{#each colors}}<li class="color">{{this}}</li>{{/each}}</ul>{{else}}<div>No colors!</div>{{/if}}
Marko:
<h2>Hello !</h2><ul ifdata.colors.length><li class="color" forcolor in data.colors></li></ul><div else>No colors!</div>
A few things to note for the Marko template:
- Less lines of code
- Less lines are "touched" to make the template dynamic
- Only opening tags are modified for conditionals and looping
Beyond Marko being an HTML-based templating language, it was also designed with extreme performance and extensibility in mind. The Marko compiler gives developers full control over how templates are compiled to JavaScript and the runtime was designed to be as efficient as possible. Marko fully embraces the JavaScript language for better performance and flexibility (e.g. favoring JavaScript expressions over a custom expression language).
Finally, another distinguishing feature of Marko is that it supports asynchronous template rendering. This powerful feature allows portions of the template to be rendered asynchronously. Instead of waiting for all data to come back from remote services before beginning to render the template, you can now immediately start rendering the template and the portions of the template that depend on asynchronous data will render as soon as the asynchronous data becomes available. The Marko rendering engine ensures that the final HTML will be streamed out in the correct order.
Design Philosophy
- Readable: Templates should be as close to the output HTML as possible to keep templates readable. Cryptic syntax and symbols should be avoided.
- Simple: The number of new concepts should be minimized and complexity should be avoided.
- Extensible: The template engine should be easily extensible at both compile-time and runtime.
- High Performance: Runtime and compiled output should be optimized for low CPU and memory usage and have a small footprint. All expressions should be native JavaScript to avoid runtime interpretation.
- Not Restrictive: Whether or not to go less logic or more logic in templates is up to the developer.
- Asynchronous and Streaming Output: It should be possible to render HTML out-of-order, but the output HTML should be streamed out in the correct order. This minimizes idle time and reduces the time to first byte.
- Intuitive: The templating engine should introduce as few surprises as possible.
- Browser and Server Compatibility: Templates should compile down to JavaScript that can be executed on both the server and the client.
- Debuggable: Compiled JavaScript should be debuggable and readable.
- Compile-Time Checks: Syntax, custom tags and custom attributes should be validated at compile-time.
- Tools Support: Tools should be enabled to offer auto-completion and validation for improved productivity and safety.
- Modular: Runtime and compiled templates should be based on CommonJS modules for improved dependency management. Template dependencies (such as custom tags) should be resolved based on a template's file system path instead of relying on a global registry.