Thoughts on my new template language/HTML generator?
- by Ralph
I guess I should have pre-faced this with: Yes, I know there is no need for a new templating language, but I want to make a new one anyway, because I'm a fool. That aside, how can I improve my language:
Let's start with an example:
using "html5"
using "extratags"
html {
head {
title "Ordering Notice"
jsinclude "jquery.js"
}
body {
h1 "Ordering Notice"
p "Dear @name,"
p "Thanks for placing your order with @company. It's scheduled to ship on {@ship_date|dateformat}."
p "Here are the items you've ordered:"
table {
tr {
th "name"
th "price"
}
for(@item in @item_list) {
tr {
td @item.name
td @item.price
}
}
}
if(@ordered_warranty)
p "Your warranty information will be included in the packaging."
p(class="footer") {
"Sincerely," br @company
}
}
}
The "using" keyword indicates which tags to use. "html5" might include all the html5 standard tags, but your tags names wouldn't have to be based on their HTML counter-parts at all if you didn't want to.
The "extratags" library for example might add an extra tag, called "jsinclude" which gets replaced with something like <script type="text/javascript" src="@content"></script>
Tags can be optionally be followed by an opening brace. They will automatically be closed at the closing brace. If no brace is used, they will be closed after taking one element.
Variables are prefixed with the @ symbol. They may be used inside double-quoted strings. I think I'll use single-quotes to indicate "no variable substitution" like PHP does.
Filter functions can be applied to variables like @variable|filter. Arguments can be passed to the filter @variable|filter:@arg1,arg2="y"
Attributes can be passed to tags by including them in (), like p(class="classname").
You will also be able to include partial templates like:
for(@item in @item_list)
include("item_partial", item=@item)
Something like that I'm thinking. The first argument will be the name of the template file, and subsequent ones will be named arguments where @item gets the variable name "item" inside that template. I also want to have a collection version like RoR has, so you don't even have to write the loop. Thoughts on this and exact syntax would be helpful :)
Some questions:
Which symbol should I use to prefix variables? @ (like Razor), $ (like PHP), or something else?
Should the @ symbol be necessary in "for" and "if" statements? It's kind of implied that those are variables.
Tags and controls (like if,for) presently have the exact same syntax. Should I do something to differentiate the two? If so, what?
This would make it more clear that the "tag" isn't behaving like just a normal tag that will get replaced with content, but controls the flow. Also, it would allow name-reuse.
Do you like the attribute syntax? (round brackets)
How should I do template inheritance/layouts?
In Django, the first line of the file has to include the layout file, and then you delimit blocks of code which get stuffed into that layout.
In CakePHP, it's kind of backwards, you specify the layout in the controller.view function, the layout gets a special $content_for_layout variable, and then the entire template gets stuffed into that, and you don't need to delimit any blocks of code.
I guess Django's is a little more powerful because you can have multiple code blocks, but it makes your templates more verbose... trying to decide what approach to take
Filtered variables inside quotes:
"xxx {@var|filter} yyy"
"xxx @{var|filter} yyy"
"xxx @var|filter yyy"
i.e, @ inside, @ outside, or no braces at all. I think no-braces might cause problems, especially when you try adding arguments, like @var|filter:arg="x", then the quotes would get confused. But perhaps a braceless version could work for when there are no quotes...? Still, which option for braces, first or second? I think the first one might be better because then we're consistent... the @ is always nudged up against the variable.
I'll add more questions in a few minutes, once I get some feedback.