Programming languages as web template languages
Web templating languages!!. Don’t we love em.
Every one has their favourite but a common denominator among them all is that they make our work as web developers easier by giving us separation of concerns between data and content as well as lots of other advantages. A fancy term for web templating languages is a web template system.
From Wikipedia a Web template system is defined as
A web template system uses a template processor to combine web templates to form finished web pages, possibly using some data source to customize the pages or present a large amount of content on similar-looking pages
a simple JavaScript example using mustach is seen below
var view = {
title: “Joe”,
calc: function () {
return 2 + 4;
}
};
> var output = Mustache.render(“{{title}} spends {{calc}}”, view);
> console.log(output)
> Joe spends 6
However today we are having a different take on templating i.e. libraries,frameworks which generate content without mixing html with the template system.
These frameworks,libraries rather have helper functions which are used for generating various dom elements without mixing in html with template logic .
var output = Mustache.render(“{{title}} spends {{calc}}”, view);
We will be giving basic examples from the following three languages,frameworks.
- yaws ehtml
- elm views
- mitril.js components
yaws ehtml
Yaws is a high performance web server written using the erlang programming language.It has a handy way of generating html using erlang called ehtml .
Using ehtml, erlang terms can be used directly to represent html code which will be sent to the browser.An example below
out(A) ->
{ehtml,
{table, [{bgcolor, grey}],
[
{tr, [],
[
{td, [], “1”},
{td, [], “2”},
{td, [], “3”}
]
},
{tr, [],
[
{td,[{colspan, “3”}], “444”}
]
}
]
}
}.
This will expand into the html below
<table bgcolor="grey">
<tr>
<td> 1 </td>
<td> 2 </td>
<td> 3 </td>
</tr>
<tr>
<td colspan="3"> 444 </td>
</tr>
</table>
out(A) ->
H = yaws_api:reformat_header(A#arg.headers),%%list containing headers
{ehtml,
[
{h4,[], “The headers passed to us were:“},
{hr},
{ol, [],lists:map(fun(S) -> {li,[], {p,[],S}} end,H)}
]}.
The list:map(a,b) stuff in there is like a loop going through all the headers and generating li elements out of the header sent in the request.
The above code will expand into the html below
<h4>The headers passed to us were:</h4><hr />
<ol>
<li>
<p>Connection: keep-alive</p></li>
<li>
<p>Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8</p></li>
<li>
<p>Host: localhost:8004</p></li>
<li>
<p>User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Ubuntu Chromium/53.0.2785.143 Chrome/53.0.2785.143 Safari/537.36</p></li>
<li>
<p>Cookie: AZY65UYNYALKSDJ=nonode@nohost-101318251358486025453327098776478182566; __utma=111872281.971381288.1489266346.1489266346.1489266346.1; __utmz=111872281.1489266346.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)</p></li>
<li>
<p>Accept-Language: en-US,en;q=0.8</p></li>
<li>
<p>Accept-Encoding: gzip, deflate, sdch</p></li>
<li>
<p>Upgrade-Insecure-Requests: 1</p></li>
<li>
<p>Cache-Control: max-age=0</p></li></ol>
elm views
Elm is a functional language that compiles to javascript .You can do some really cool front end stuff with elm but for the purposes of this post we will concentrate on how a view (html output) is created in elm. An example below of code for creating html output in elm is given below
view : Model -> Html Msg
view model =
div []
[
input [ type_ “text”, placeholder “Name”] []
, button [ onClick Decrement ] [ text “-” ]
, div [] [ text (toString model) ]
, button [ onClick Increment ] [ text “+” ]
, div [] [ text “” ]
, button [ onClick Reset ] [ text “0” ]
]
Notice how the data is completely separate from the view functions (no mixing of html with data).
In this case also the div,button,onClick,text are all functions which accept parameters.
The general pattern is that the functions(dom elements) accept as the first parameter a list of attributes and
then a list of child nodes or inner html value as the second parameter.
So the first div above has no attributes but has child nodes. the first input element has a list representing attributes(i.e. the type=text and placeholder=Name). the text function can be used for putting values into the tags and is the innerhtml in the parent div tag . The value of model which contains the state of the application in this case is 0.
the text function accepts only strings as a parameter so 0 has to converted to “0” else there will be an error thrown. (toString model) just means turn 0 into a string and give us the result of that computation. Elm is statically typed so does type checking at compile time. one nice thing it also has is type inference which basically means it can infer types without type annotations. Elm generated html also does does some virtual dom stuff internally before content is redrawn on screen. This results in very fast rendering speeds :).
At the end the above elm view code will turn into the html below
<div>
<input type="text" placeholder="Name">
<button>-</button>
<div>0</div>
<button>+</button>
<div></div>
<button>0</button>
</div>
mithril.js components
Mithril is a modern client-side Javascript framework for building Single Page Applications . you can also do some cool stuff with it too but we will be concentrating on the way components are created using javascript in this case . An example below of code for creating a component is given below
var Hello = {
view: function() {
return m(“main”, [
m(“h1”, {class: “title”}, “My first app”),
m(“button”, “A button”),
])
}
};
m.mount(root, Hello);//to activate the content
A Mithril component is just an object with a view function.
As usual the code is a variant of a function accepting a list of attributes and a list of childnodes or an inner html value.
The m(a,b) is a function for which the first parameter is a list of attributes , the second parameter being a list of child nodes or an inner html value.
mithril.js also does some virtual dom diffing under the hood so it renders html quite quickly also.
you can do some really fancy stuff in there especially if you combine it with libraries like rambda for component creation.
this is a very simple example but it does have all the advantages like ease of testing,separation of data from content,power of js to create components.
This will expand into the html below
<main>
<h1 class="title">My first app</h1>
<button>A button</button>
</main>
Summing up
Programming languages which are used as template languages are in a lot of ways very powerful and they enhance templating by
- making available all the power of a programming language to be used in generating templates
- reduced learning curve since no special syntax has to be learnt to create templates
- its easier to debug and find errors when creating components/html because html/components are all functions the compiler/debugger of the language is also at your disposal.elm is super at this :)
- separation of data from view is very easy .the data mostly become input to the component generation functions
- rapid and more flexible development due to familiarity with language (this however depends on the capability of the language in question)
- standards compliance made easier.no more looking for that div hidden somewhere which is breaking all the html code :)
- not constrained by how the template engine does stuff.logic-less,logic,small template library functions etc…