2.1 The View
When writing a Lift app, it’s often best to start off with the user interface... build what the user will see and then add behavior to the HTML page. So, let’s look at the Lift template that will make up our chat application.
index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><title>Home</title></head>
<body class="lift:content_id=main">
<div id="main" class="lift:surround?with=default;at=content">
<!-- the behavior of the div -->
<div class="lift:comet?type=Chat">
Some chat messages
<ul>
<li>A message</li>
<li class="clearable">Another message</li>
<li class="clearable">A third message</li>
</ul>
</div>
<div>
<form class="lift:form.ajax">
<input class="lift:ChatIn" id="chat_in"/>
<input type="submit" value="Say Something"/>
</form>
</div>
</div>
</body>
</html>
It’s a valid HTML page, but there are some hinky looking class attributes. The first one is <body class="lift:content_id=main">. The class in this case says “the actual page content is contained by the element with id=’main’.” This allows you to have valid HTML pages for each of your templates, but dynamically add “chrome” around the content based on one or more chrome templates.
Let’s look at the
<div id="main">. It’s got a funky class as well:
lift:surround?with=default;at=content. This class invokes a snippet which surrounds the
<div> with the default template and inserts the
<div> and its children at the element with id “content” in the default template. Or, it wraps the default chrome around the
<div>. For more on snippets, see
7.1 on page 1↓.
Next, we define how we associate dynamic behavior with the list of chat elements: <div class="lift:comet?type=Chat">. The “comet” snippet looks for a class named Chat that extends CometActor and enables the mechanics of pushing content from the CometActor to the browser when the state of the CometActor changes.
(C) 2012 David Pollak