|
Templating is way to generate dynamic pages. In tales Html stays html and you use a jquery like api to put dynamic data into it
Html templating
A html page that is displayed will at minimum have two file associate with it
Let's start with an example, create a new tales app. The home page that you see is generated using
<div talesId="name">Test</div>Open Index.fan and add this code in main() method: html := Html("template/Index.html")
html.tag("text").text("Jhon")
response.writeTag(html)
Refresh the browser. The generated html will look like this
<div>Jhon</div>
Things to note:
Let's look at a deeper example
Imagine you wanted to display a text that greets the user. You could write something like
username := "Kaushik"
html.tag("talesid").text("Hello, welcome <b>$username</b>")
A better way to do it would be to move all markups to html. You can write something like this:
<div>Hello, welcome <b talesId="name">Something</b></div>and in markup username := "kaushik"
html.tag("name").text(username)
Changing other attributes
You can manipulate other attributes using the ".attr()" method
html:
<div talesId="name">Something</div>fan: html.tag("name").text("Kaushik").attr("style", "color:red")
will result in html
<div style="color:red">Kaushik</div>
Another example:
Html: <a href="#" talesId="myLink">Click here</a>Fan: html.tag("myLink").attr("href","/user/id/1")
Will result in:
<a href="/user/id/1">Click here<a>
Adding and removing classes and styles
The "Tag" class provides convenient shortcuts for adding and removing classes
html: <div talesId="name">Something</div>fan: html.tag("name").addClass("active").addCss("color", "red")
will result in html:
<div style="color:red" class="active">Kaushik</div>
Nested and duplicate markups
talesids need not be unique.
Html: <div talesId = "name" style="color:red"></div> <div talesId = "name" style="color:blue"></div>Fan: html.tag("name").text("Jhon")
Will result in html:
<div talesId = "name" style="color:red">Jhon</div> <div talesId = "name" style="color:blue">Jhon</div>
talesIds can be nested. For eg.
<div talesId="two"></div> <div talesId = "one"> <div talesId = "two" ></div> </div>A fantom code like this html.tag("two").text("Hello")
Will affect nested and non-nested tags like this
<div>Hello</div> <div> <div>Hello</div> </div>However you can choose to affect only nested tags like this oneTag := html.tag("one")
oneTag.tag("two").text("Hello")
The output will be
<div>/div> <div talesId = "one"> <div>Hello</div> </div>
Repeaters
You might want to repeat a tag multiple times
Html:
<div talesId="numbers"></div>Fan: vals := ["One", "Two", "Three"]
html.tag("numbers").repeating
vals.each{
tag := html.tag("numbers").addRow
tag.text("$it")
}
gives an output:
<div>One</div> <div>Two</div> <div>Three</div>Repeating-tags themselves can have nested talesIds: <ul>
<li talesId="number">
<span talesId="val"></span>
</li>
</ul>
Fan:
vals := ["One", "Two", "Three"]
html.tag("numbers").repeating
vals.each{
numberRow := html.tag("numbers").addRow
numberRow.tag("val").text("$it")
}
gives an output:
<ul>
<li>
<span>One</span>
</li>
<li>
<span>Two</span>
</li>
<li>
<span>Three</span>
</li>
</ul>
Instead of calling ".repeating()" method you can call ".repeat(num)" if you know the number of times of repetition ahead of time. For eg.
<span talesId="name">Test</span>and Fan: tags := html.tag("name").repeat(10)
tags.each|Tag tag, Int index|{
tag.text("$index")
}
will result in html
<span>1</span><span>2</span><span>3</span>
Panels and Layouts
There is no separate concept of panels and layouts but you can arbitrarily nest tags with file names for eg., Consider this panel
<div>Hello, I am a panel</div>
and another page
<div> I am a parent panel <div talesId="child"></div></div>
You can include the panel in page like this
page := Html("template/page.html")
panel := Html("template/panel.html")
page.tag("child", panel)
response.writeTag(page)
Apply method and "Cut and Send"
On any Html tag you can call the apply method to get the html
for eg., Html: <span talesId="name"></span>and fan: html := Html("template/page.html")
html.tag("name").text("Jhon")
Str result := html.apply
echo(result)
will print <span >Jhon</span> to the output.
You can only ask for portions of html instead of complete html. For eg.
Html: <span>Title</span> Some other html <span talesId="age"></span>and fan ageTag := Html("template/page.html").cutAt("age")
ageTag.text("20")
result := ageTag.apply
echo(result)
will print <span >20</span> to the output (only html corresponding to tag with talesId="age").
|
