template engine [ was: Re: Implementing tables - advice wanted ]

Gaspar Chilingarov <>
Wed Jun 14 13:48:24 CEST 2006


Joe Armstrong (AL/EAB) wrote:
> I see no reason why a template engine should offer any other than
> full access to all Erlang functions, not some ad-hock subset.
> 
> 
> My template engine is described here:
> 
> http://www.erlang.org/ml-archive/erlang-questions/200602/msg00326.html 
> 
> I've edited some comments into Gaspar's mail at the end of this post.
> 
> 	<? map
> Since this posting I have done one or two experiments - all failed
> so I stand by the original design.
> 
> I also came up with a small (and useful) "mini template".
> 
> Since it is instructive, I can relate what happened when I tried to
> improve upon the original design.
> 
> - I made two attempts to "improve" my design
> 	1) make a restricted template language (like velocity)
> 	2) make something A lot like PHP
> 
> What happened?
> 
> 1)
> 
> I did something like velocity - but I very soon missed
> the power of a full programming language - doing easy thing was,
> well .. uuug easy - doing other things was complex and doing
> difficult things was ... impossible.
> 
> Embedding ajax calls using higher order functions - forget it ...
> 
> I junked this experiment
> 
> 2) I thought "this (ie my template engine) is pretty much like PHP
> let's make it even more like PHP to attract users who know PHP.
> 
> To do this I added an out(String) primitive and changed the semantics of
> my 
> template language.
> 
> < aside >
> I have to briefly explain the semantics of my original template
> language:
> 
>    <h1>hello</h1>
>    <? N = 10, "" ?>
>    <p>Factorial <? N ?> is <? fac(N) ?>
> 
> This means "create a string"
> 
> 	"<h1>hello</h1> ++ "" ++ "<p>factorial N is" ++
> coerce_to_string(N) ++ " is " ++ ...
> 
> is the LAST value is a <? .. ?> is coerced into a string and the value
> is
> pasted into the document. Bindings created *within* <? ... ?> get
> carried to the
> next <? ... ?> context.
> </aside>
> 
> My new language (inspired by PHP) was more like this:
> 
>     <h1>hello</h1>
>     <? N = 10 ?>
>     <p>factorial <? out(N) ?> is <? out(fac(N)) ?>
> 
> Which was transformed into:
> 
> 	out("<h1>hello</h1>"),
> 	N = 10,
> 	out("<p>factorial ");
> 	out(N),
> 	out(" is "),	
> 	out(fac(N))
> 
> At the time I rather liked this - all I had to do was enclose
> top level bits of HTML in an out(...) wrapper.
> 
> Then my subroutines could also call out(...) - like PHP
> 
> This resulted in a soggy mess. Why? - evaluation order now matters.
> I/O is an imperative side effect, scattering out(X) statements at random
> 
> in subroutines implies that somehow and somewhere you have an idea as to
> 
> in which order these subroutines will be called.
> 
> Pure functional programming is far easier - in the earlier model
> each function returns a string (if that's what you want) and the caller
> assembles the
> return values into new strings. The order of calling the routines is
> irrelevant,
> since you will always get the same result.
> 
> I/O by side effects (using out(X) in a subroutines) made writing all 
> other than simple code a mess.
> 
> I junked this experiment.
> 
> To recap - If I had distributed experiment 1 (the velocity approach) I
> would
> have committed a venial sin, resulting in "temporary loss of grace" from
> the
> Erlang Users. But distributing something with a PHP like syntax would be
> a mortal
> sin requiring a valid confession in articolo mortis - and what would
> happen if
> I met an untimely end, like in a car crash, so that I couldn't confess
> ...
> 
> So we're back to my original design.
> 
> In passing I did make a little mini-mini-template language.
> 
> This is simply HTML with a few ${Var} variables in it - like this:
> 
> Put this in a file foo.template
> 
> 	<title>${title}</title>
> 	<h1>hello ${person} how are you?
> 
> 
> Then expand with:
> 
> 	expand:file("foo.template", [{"title", "my web page"},
> 	                             {"person", "joe"}]).
> 
> Or make an xml template instance (say in the file bar)
> 
> 	<title>my web page</title>
> 	<person>joe</person>
> 
> and expand with:
> 
> 	expand_xml("bar!", "foo.template")	
> 	
> This mini-mini-template language which is laughably simple, 
> is *very useful*.
> 	
>  
> /Joe
> 
> 
>  
> 
> 
>> -----Original Message-----
>> From:  
>> [mailto:] On Behalf Of 
>> Gaspar Chilingarov
>> Sent: den 13 juni 2006 23:23
>> To: Erlang Users' List; ke han
>> Subject: RFC: template engine [ was: Re: Implementing tables 
>> - advice wanted ]
>>
>> Hello all!
>>
>> Post directed mainly to ke han, but all other list members are welcome
>> -- You have mentioned html template engine for erlang - what 
>> kind of features do you like in there ?
>>
>> For current moment I got some simple engine which provides 
>> following templating commands -
>>
>> <%TRANSLATE atom%>  - generate string, calling some 
>> translation function (to make multilangual sites)
>>
> 
>      <? translate(atom) ?>
> 
>> <%FOREACH keyname%> - <%/FOREACH%> - take element keyname 
>> from proplist (which should have list value) and iterate 
>> inner part of FOREACH loop for each element in that list.
> 
>      <? map(fun foo/1, L) ?>  with an external function, or
> 
> 	<? map(fun(I) ->
> 	         ["<h1> ...", I , ... ]
> 	       end, L) ?>
> 
> 
>> <%WITH keyname%> <%/WITH%>- just go one level deeper - fetch 
>> one element from proplist and execute inner template with it
> 
>     I don't understand - possibly
> 
> 	<? someFunc(dict:lookup(keyname, D)) ?>
> 
> 
>> <%PUT keyname%> - just put element of proplist into current position.
> 
>     <? D1 = dict:store(keyname, Val, D), "" ?> (note the extra "" :-)
> 
>> <%PUTVALUE%> - if we are in a leaf node - put it's value into 
>> current position - ether string or integer.
> 
>     ??????
> 
>> so
>> if you have template
>> <%FOREACH args%><%PUTVALUE%> <%/FOREACH%>
>>
>> and we feed templating function with
>> {struct, [
>> 	{args, {array, ["Hello", "world", "!"]} } ]} data we 
>> will receive "Hello world ! " string.
>>
>> this approach - added with if/ifdef/else commands allows 
>> create templates which are totally separate from programming 
>> language and are driven only by data which is fed to template 
>> interpreted.
>>
>> it somehow resembles XSLT, but much more simple to allow HTML 
>> designers easily use it and put into pages without disturbing 
>> programmer too much.
>>
>> second idea with such markup is that there is translator from 
>> such markup to JSON notation, and there is JS template 
>> renderer, which could be run on client machine - thus 
>> allowing passing from server not rendered template, but 
>> parsed template and data -- JS copes well even on slow 
>> machines with datasets about up to 1000 elements  - like 
>> 10x100 table - which is practically enough for most tasks.
>>
>>
>> solution, which you would like to see - even too fantastic or 
>> futuristic -- because it's always possible to find something 
>> reasonable and practical there.
>>
>  
> 
>> Looking forward for answers :)
>>
>> --
>> Gaspar Chilingarov
>>
>> System Administrator,
>> Network security consulting
>>
>> t +37493 419763 (mob)
>> i 63174784
>> e 
>>
> 


-- 
Gaspar Chilingarov

System Administrator,
Network security consulting

t +37493 419763 (mob)
i 63174784
e 



More information about the erlang-questions mailing list