My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label XML. Show all posts
Showing posts with label XML. Show all posts

Sunday, December 06, 2009

mjst - Micro JavaScript Template Engine

This is the content I've written so far in the official mjst repository. I'd love to know your thoughts about this little experiment, cheers!

What

mjst is a lightweight, about 1Kb minified and gzipped, and performances focused template engine with standards support. There are dozens JavaScript? Template Engines solutions out there but as far as I know this is the only one based on validation for both client and server side programming languages.

How

There is one single function to call:

// via text (e.g. Ajax or innerHTML from a template node)
var transformed = mjst('<?js var hello = "mjst!"; ?><js-hello/>');

// classic template node example
<script id="mytpl" type="text/html">
 
<?js
   
var hello = "mjst!";
 
?>
 
<js-hello/>
</script>
myEl.innerHTML = mjst(document.getElementById("mytpl"));

/
/ via XML (e.g. Ajax or a created document)
// this is a configuration object as second argument example as well
myEl
.innerHTML = mjst(
 
new DOMParser().parseFromString(
   
'<root><js-hello/><br class="${myBrClass}" /></root>',
   
"text/xml"
 
), {
    hello
:"Hi there!",
    myBrClass
:"clear-both"
 
}
);

// Ajax example with an XML template as response
/*
<root>
  <ul>
    <?js
      for(var i = 0; i < collection.length; ++i) {
    ?>
      <li class="li-${i}">Item No: <js-i/> Name: <?js print(collection[i]); ?></li>
    <?js
      }
    ?>
  </ul>
</root>
*/


// transformation ...
myEl
.innerHTML = mjst(xhr.responseXML, {collection:["a", "b", "c"]});

It is possible to write whatever we want inside an mjst template block via print(1, 2, 3, N, func(), whatever) function, the only one injected in the execution scope.

JavaScript? block VS Attributes

To make mjst templates XML compatible I decided to remove JavaScript? block inside attributes. It is still possible to access JavaScript? variables via ${myVar.propName} as showed, as example, in the br node class.

PHP And JavaScript? Template Example

<?php // mjst example
function mjst($name, $value){
    echo
'<?js var ', $name, '=', json_encode($value), ' ?>';
};
header('Content-Type: text/xml');
$a = array(
    'some database result' => array(1, 2, 3),
    'some other value' => 'Hi There'
);
?>
<?xml version="1.0"?>
<root>
   
<?php mjst('result', $a); ?>
   
<?js
   
for(var k in result)
       
print(result[k], "<br />")
   
;
   
?>
</root>

<script type="text/javascript" src="mjst.js"></script>
<script type="text/
javascript">
onload
= function(){
   
with(this.XMLHttpRequest ?
     
new XMLHttpRequest :
     
new ActiveXObject("Microsoft.MSXML")
   
){
      open
("get", "mjst.php", true);
      onreadystatechange
= function(){
       
if(readyState == 4)
          document
.body.innerHTML = mjst(responseXML);
       
;
     
};
      send
(null);
   
};
};
</script>

Why Standards

Apparently every other JavaScript? template engine is implementing a manual, char by char, or RegExp? based, parser, over a syntax that in PHP world has basically defined deprecated ages ago: the classic <%=stuff%> (<?=stuff?> in PHP). The first reason to avoid this kind of syntax is ambiguity. Which program language should consider that block of code? PHP, ASP, JavaScript? ... who else? Moreover, to make things as clear and simple as possible, avoiding ambiguity, PHP community decided to solve the classic <?xml?> problem, caused by short code block, via an explicit <?php ?> which is the suggested, default one. This is also standards safe, in the meaning that a nodeType 7 is defined as a PROCESSING_INSTRUCTION_NODE In few words mjst is compatible with both valid XML and XHTML, which means that its templates can be created via standard DOM API being sure the template will be valid as well. At the same time, using official engines to validate and parse templates blocks mjst could be considered more reliable than other solutions, more robust, and at the same time fast, thanks to core functionality. The good part, at least for me, is that delegating templates parsing operations to the browser core, is more probable that the error is inside a non valid template block, rather than inside this tiny library source code: a welcome side-effect about standards and core validation.

Why Fast

Every transformation could create one or two pre-compiled functions reused every time we would like to transform an already parsed template block. The reason mjst creates up to two functions is that we can arbitrary send a second argument as configuration object. Since this procedure requires the usage of the with statement, avoiding outer scope name conflicts during the execution, and since we do not necessary need to send this second configuration object, the runtime compiled function will consider both cases, only when encountered, making the with free execution 3 to 10 times faster. In other words, if we transform the same template block always without the second argument, the function that will contain the with statement will never be created and vice versa.

Why Robust

The XML core parser and transformer is also another reason to consider mjst both fast and reliable. As example, probably the most famous JavaScript micro templating, from John Resig, is surely lightweight, but it could suffer some problem if the template block is not perfect. For instance, try to use a string like s = "<%" for whatever reason, and you'll be able to break the John micro suggestion, but this is not only about John code. Another well known product is the EJS library, adopted in many different environments and definitively a good piece of code. EJS offers somethng more than mjst but it is still based on manual parsing over a syntax that XML does not like that much. This means that we could have hard life to generate EJS templates via server or directly in our page while mjst delegates template validity to the markup itself.

<?xml version="1.0" ?> 
<script id="mytpl" type="text/html">
 
<!-- msjt accepts valid XML (as XHTML as well) or HTML5 -->
 
<?js
   
var hello = "mjst is here!";
 
?>
 
<js-hello />
</script>

Why ... Generally Speaking

I am a PHP developer, before being a JavaScript? one, and I have always complained about the open close everythere PHP style. This technique does not split presentation and business logic layers and it is generally "slower than a single echo". I have started to appreciate the couple XML and XSL-T years ago but XSL-T sometimes is just a pain in the ass and via server is difficult to cache XSL-T instances. As example, the New York Time had to create their own core library to speed up transformations over common XSL files allowing fast serialization. Brilliant, but still this ad hoc library does not scale for the whole World Wide Web scenario. Different hosts, different PHP versions, but at the end of the day, what could happen if we delegate the transformation to the client side via core JavaScript? features? Nothing bad, actually it's almost a year I am transforming complex layout into html in the fastest way ever even in IE6 and only thanks to XSL-T but, as I have said, the XSL syntax could not sound familiar at all, specially for programmers that would like to have much more power while they generate a layout. This is basically the reason PHP had such great success over these years, so why don't try to emulate XSL bringing there directly JavaScript? rather than XSL syntax, and in a PHP familiar style? This is all about this experiment. It delegates layout render into the client side, the best place imho to do this. It avoids useless server side stress, it could be embed in the page thanks to the fake script with an unknown type, and as side effect, it could speed up client server interactions re-using templates blocks whenever we need and requiring only data, which nowadays, it is just all we need to make Web users happy. So, as pure final evil plan, we could create a view able to produce mjst templates directly via CouchDB resolving some greedy map reduce operation in the db moving partial logic in the client via simple row data sets or generating clear layout directly via Server Side JavaScript? so that all we need is a language, rather than 3 different technologies ... does it sound insane? ;-)

Sunday, November 29, 2009

XML To HTML Snippet

This John Resig post about nodeName demonstrates once again how trustfulness are edge cases in JavaScript.
I must agree 100% with @jdalton: frameworks or selector libraries should not be concerned about these cases.

First of all there is no universal solution so whatever effort able to slow down libraries won't be perfect, then why bother?

Secondly, I cannot even understand why on earth somebody could need to adopt XML nodes in that way.
Agreed that importNode or adoptNode should not be that buggy, but at the same time I have always used XSL(T) to inject XML into HTML and I have never had problems.

Different Worlds

In an XML document a tag is just a tag. It does not matter which name we chose or which JavaScript event we attached, XML is simply a data protocol, or transporter, and nothing else.
A link, a div, an head, the html node itself, does not mean anything different in XML so again: why do we need to import in that way?
In Internet Explorer we have the xml property which is, for HTML represented inside XML docs, the fastest/simplest way to move that node and what it contains inside an element and via innerHTML.
Moreover, namespaces are a problem, we cannot easily represent them into an HTML document so, in any case, we need to be sure about represented data.

A Better Import

Rather than ask every selector library to handle these edge cases we could simply adopt a better import strategy.
This XML to HTML transformer is already a valid alternative, but we can write something a bit better or more suitable for common cases.
As example, a truly common case in these kind of transformations is a CDATA section inside a script node.
With CDATA we can put almost whatever we want inside the node but 99.9% of the time what we need is a JavaScript code, rather than a comment.
Another thing to consider is that if we need to import or adopt an XML node, 99.9% of the time we need to import its full content and not an empty node (otherwise we should ask us why we are representing data like that, no?).
I bet the deep variable will be basically true by default so, here there is my alternative proposal which should be a bit faster, avoiding implicit boolean cast for each attribute or node, and considering what I have said few lines ago:

function XML2HTML(xml){
// WebReflection Suggestion - MIT Style License
for(var
nodeName = xml.nodeName.toUpperCase(),
html = document.createElement(nodeName),
attributes = xml.attributes || [],
i = 0, length = attributes.length,
tmp;
i < length; ++i
)
html.setAttribute((tmp = attributes[i]).name, tmp.value)
;
for(var
childNodes = xml.childNodes,
i = 0, length = childNodes.length;
i < length; ++i
){
switch((tmp = childNodes[i]).nodeType){
case 1:
html.appendChild(XML2HTML(tmp));
break;
case 3:
html.appendChild(document.createTextNode(tmp.nodeValue));
break;
case 4:
case 8:
// assuming .text works in every browser
nodeName === "SCRIPT" ?
html.text = tmp.nodeValue :
html.appendChild(document.createComment(tmp.nodeValue))
;
break;
}
};
return html
};

I have tried to post above snippet into John post as well but for some reason it is still not there (maybe waiting to be approved)
We can test above snippet via this piece of code:

var data = '<section data="123"><script><![CDATA[\nalert(123)\n]]></script><option>value</option></section>';
try{
var xml = new ActiveXObject("Microsoft.XMLDOM");
xml.loadXML(data);
}catch(e){
var xml = new DOMParser().parseFromString(data, "text/xml");
}
var section = xml.getElementsByTagName("section")[0];
onload = function(){
document.body.appendChild(XML2HTML(section));
alert(document.body.innerHTML);
};

We can use latest snippet to test the other function as well and as soon as I can I will try to compare solutions to provide some benchmark.

Monday, May 25, 2009

Template Engine - Why Bother? XML + XSLT

I am not sure I read the entire recent "war" in the PHP general mailing list about the best PHP Template Engine Option but, generally speaking, this argument is truly loads of solutions and controversial opinions. Here I am with mine.

PHP 5 And In Core DOM, XML and XSLT

Apparently, all these "Smarty adorers" did not consider that PHP 5 introduced a lot of core classes to work over DOM, XML, and transform them via XSL files. Nothing to do, they prefer to move an entire template application rather than use the best native, fast, in core, solution. Here a couple of reasons to generally prefer XML and XSL Transformations rather than whatever engine, specially those written in PHP itself, a not that fast interpreted programming language.

Think Portable

Apparently developers like to be stuck forever in a single programming language, something I cannot even try to consider, since Information Technology means Flexibility and Updates. An extremely valid point to choose XML as output, and XSL as Transformer, is the universality of the XML markup language first, and complete separation between data and business logic from its presentation after.
Something PHP developers often look for, discarding without a valid reason what is already there since ages. Even if the entire website or application programming language will change (performances anybody?), rather than simply take care about how to reproduce the same XML via the new language, they prefer to recreate for each sub-part of the website the code to make that completely new and different template engine work. This becomes even more ridiculous when arguments are like:
if I need php in the middle of the presentation layer, I simply put it there ...
... "good thinking", isn't it?

Think Scalable


First of all, XML can be easily cached without even moving a single database connection. Moreover, having zero dependencies from external engines probably based on the same XML + XSLT concept, could simply make our application faster. XML has thousands of implementations, libraries, and fast parsers, for every kind of programming language and latest dabases could even interact directly with stored XML (or retrieve data directly in XML, did you know that?)
An application that as main intermediate layer has XML will have so many long therms advantages hard to imagine, are you still thinking a foreach inside the layout is a good solution?

Think About Your Career


Ok, I use PHP and I want a template engine that will bring me nothing new to learn, except its own PHP exposed API. And tomorrow, when I'll move into another better structured company, everything about XML, XSL(T), and XPath, will be a non-sense, "'cause I know peeaichpee", isn't it?
If you think you know enough about XML and XSLT and you are not using these layers I bet you do not truly know them or real potentials.
I bet you do not know XPath, you do not know how to generate a valid XHTML/HTML layout, and you do not know XSLT strategies to retrieve only info you want to show and nothing else.
Well, think about this, more enterprise ready stuff, rather than just whoevercanuseit programming language (easy to start, hard to use properly, that's PHP) ... is it an extra plus to at least give them a try?

Extreme Performances? A concrete Example


The New York Times website is using these technologies since ages and it implemented its own XSL Cache Extension in order to obtain best performances with xsl documents. At the same time, XSLT is present in every browser, included Internet Explorer 5 so it is even possible to simply delegate transformation to the client, speeding up even more the server. Here a simple example, based on my "old" JXON proposal.

Do you still think there are so many better options?

Saturday, July 26, 2008

JXON - A little update loads of documentation

I have updated my lightweight JXON library right now, lightly improving them, and adding a consistent documentation for each method as well.

At this point, the last thing I could do about JXON, is to talk about what exactly is, and what is not at all.


JXON IS


  • An intermediate, well defined, layer between native JavaScript variables, and a generic page content (their representation inside the layout)

  • A fast and cross-browser JS to XML, and vice-versa, parser

  • A human comprehensive way to represent JavaScript Object Notation via XML using a natural, lightweight, and unambiguous, schema, that will make XSL files creation, manipulation, and maintenance, more clear and natural than ever, working over both XPath, and semantic data types nodes with optional keys for object members

  • A simple and crossbrowser global object, with few methods to transform JavaScript raw data into a valid (x)HTML layout page, or portion

  • An advanced, XSLT based, enterprise ready way to represent data in a generic browser, with possibility to re-use thousands of time the same XSL file, or choose which one should be loaded for that browser (device browser indipendent)





JXON is NOT


  • A JSON parser

  • An Ajax library

  • A template Engine


Indeed, JXON aim is to be easily integrated inside your library, or your own code.
You do not necessary need a JSON parser, but every famous client library has one, so you can still perform client / server interactions using that parser, if necessary, and putting JXON between the evaluated result, and the layout.
The load method principal aim is to assign the public xml property that will be the JXON XML node you need to transform. This means that you have no options to change both its syncronous nature, or to use them to send POST parameters, it is NOT Ajax, but you can use every kind of library or code to perform these tasks putting JXON, again, between these interactions and your automatically updated layout portion.
Finally, thanks to JXON, you could focus entirely about data, instead of data plus its layout representation, delegating latter task to one of the most related languages to do that: XSL, a dedicated markup template engine transformer.

JXON - In line JavaScript to XSLT Example Page

P.S. Above link uses an object instead of a regular layout, and of course, even if when you look at that extremely light page (1.24 kB without gzip), Google and generally every kind of search engine, is able to read those information.