Skip to content
laverdet edited this page Apr 29, 2012 · 3 revisions

What is js-xml-literal?

js-xml-literal adds XML literals to JavaScript via automatic code rewriting. Having XML literals means that markup becomes first-class citizens in your application, and it becomes much easier to generate HTML pages or other XML documents.

In any language, a literal value is something recognized directly by the language parser as a value. For instance, false, 12.5, and "hello world" are all literal values. With js-xml-literal, <span>Hello</span> also becomes a literal.

This is a very similar idea to the mostly abandoned and ill-conceived E4X standard. For the author's perspective on why js-xml-literal is a good thing and E4X is a bad thing, check out Differences from E4X.

What does it look like?

var uri = 'https://github.com/laverdet/js-xml-literal/';
var anchor = <a href={uri}>Check out js-xml-literal on GitHub!</a>;
console.log(anchor.toString()); // '<a href="https://github.com/laverdet/js-xml-literal/">Check out js-xml-literal on GitHub!</a>'

Functional decomposition is possible, and will feel very similar to working with the DOM you're already familiar with in browsers.

var anchor = <a />;
anchor.href = uri;
anchor.appendChild(<span>Hello</span>);
console.log(anchor.toString()); // '<a><span>Hello</span></a>'

Why is this useful?

js-xml-literal makes generating HTML or XHTML documents extremely simple. Since HTML context is maintained in the grammar of the language, you are protected from XSS attacks in most cases. The resulting document or document fragment can be mutated as much as you need with a familiar API before serving it to a user.

You may say "but what about my MVC?!". XML literals have nothing to do with what display paradigm you want to enforce in your application. You can still adhere to an MVC structure with js-xml-literal, what you do with the technology is up to you. You should also keep in mind that MVC is not the only way to develop an application, and many very large teams are building great applications without strict MVC.

How does it work?

js-xml-literal finds all the XML literals in your applications and rewrites them with plain JavaScript function calls and object literals. This means you can use js-xml-literal today in any browser or JavaScript engine.*

How do I try this out?

Install js-xml-literal with npm: npm install xml-literals. After that you need to bootstrap the XML environment a little for your application. The first step to get XML literals working in your Node project is to register which file extensions should be transformed. If you want to allow XML literals in any Javascript file you would do this:

require('xml-literals').register('js');

This tells NodeJS to preprocess all *.js files with the XML literals transformation.

Unfortunately you won't be able to use XML literals in the file where you invoked the registration, so this kind of thing won't work:

init.js:

require('xml-literals').register('js');
// WON'T WORK!!
var test = <span>Hello</span>;

After registering a file extension you must setup the XMLEnvironment. If you want to use the included simple-html-dom (recommended) you would do this:

var SimpleHTMLDOMXMLEnvironment = require('xml-literals/simple-html-dom');
XMLEnvironment.set(new SimpleHTMLDOMXMLEnvironment);

Then just require() your main script and it will have XML literals enabled. simple-html-dom works just like the DOM in your browser, however it's simplified. Only basic DOM manipulation and querying functions are available. If you are looking for a more full-featured server-side DOM I recommend taking a look at jsdom, however you will incur a large performance penalty here. simple-html-dom does include a toString() method, so you can convert your DOM to string to send to the browser easily.

A quick example is included. Hello World.

What all can I do with this?

On the server you can work with a simple DOM API that can be converted to a string and sent to the user's browser via simple-html-dom.

In the browser you can use XML literals to directly create DOM elements with dom-environment.