You can even do weird things with host blocks: ##{py## def block_init(data,value,**kw): data['variable']='VARIABLE' data['list']=[1,2,3] data['dictvar']={'subdict':{'item':'NESTED ITEM'}} #### ##{js## function block_init(data) { data['variable']='VARIABLE'; data['list']=[1,2,3]; data['dictvar']={'subdict':{'item':'NESTED ITEM'}}; } #### ##>init## Substition: ##variable## If block: ##@variable## only show when true #### If..else: ##@variable## only show when true ##*## only show when false #### If not block: ##!variable## only show when false #### If not else: ##!variable## only show when false ##*## only show when true #### Choice: ##one?variable## only show when variable is "one" ##two?## - note, no variable specified only show when variable is "two" ##*## show when variable is something else #### Blocks: ##blockvar=blockname## This block is called with ##blockvar## #### Block call: ##variable>blockname## For..in: ##item:list## ##item## #### Nested data: ##dictvar.subdict.item## Literal #: ###hexcolor## is not what you want (it's beard, then #hexcolor, then beard). ##\####variable## will produce something like #ffffff. Host language blocks: ##{py## def block_custom(data,value,output,getvalue,compare): """ data is a dictionary with template variables value is a value of variable passed with block call output(x) converts x into string and writes it into template getvalue(x) will get value of x template variable compare(x,y) is cross-language comparison function """ output(len(data)) #### Roughly the same in JavaScript: ##{js## function block_custom(data,value,output,getvalue,compare) { // the very same as above var n=0; for(var i in data) n++; output(n); } #### And now call it as ordinary block: ##variable>custom## Yes, that's all in a single template file