I'm currently in the process of rebuilding my main app using ClearSilver,
and it's really slick. In a nutshell, it's a presentation layer (view)
for an MVC-style application. Your controller (the 'C') uses the
model/backend (the 'M') to create a dataset that it passes to
ClearSilver (the 'V') to render the actual page.
This is a good idea for several reasons, the main one being that it
forces a complete separation between your view and your
controller. It also allows you to hand off your view to some
non-programmers to build using ClearSilver. They needn't learn
CF, or anything about your application. All they need is to
understand how to access data from the dataset using a couple very
simple tags. ClearSilver is also entirely platform neutral.
It's written as a native C library, with bindings for Java, Ruby,
Python, Perl, C#, and CGI, so you can seamlessly move templates between
any of those environments without needing any changes. Finally,
it's a good way to allow users of an application to have a very high
level of control over page formatting, without exposing the app to
malicious CF code. Since ClearSilver templates can only recall
data out of the dataset, the wost they can possibly do is create a
template that is time consuming to process.
In my particular case, it's the last point that really
differentiated it from it's competitors (such as Velocity). Our
app includes a web CMS as part of it's functionality, and exposing
complete control over the site layout makes for better integration with
existing infrastructure for our clients, without mandating a
significant amount of custom development work.
But enough of that, how does it work?
<cfsavecontent variable="data">
page.title = "My Title"
page.content << EOM
<h1>Hello, World!</h1>
<p>here's a paragraph
</p>
EOM
</cfsavecontent>
<cfsavecontent variable="template">
<html>
<head>
<title><?cs var:page.title ?></title>
</head>
<body>
<?cs var:page.content ?>
</body>
</html>
</cfsavecontent>
<cfset hdf = createObject("java", "org.clearsilver.HDF").init() />
<cfset hdf.readString(data) />
<cfset cs = createObject("java", "org.clearsilver.CS").init(hdf) />
<cfset cs.parseString(template) />
<cfoutput>#cs.render()#</cfoutput>
Of course, your data sets get a lot more complex than that, as do
your templates. You can load data sets from files, create them
from strings (as I did above), or build them a field at a time using hdf.setValue(path, value)
.
Templates are usually stored on the filesystem (so they can include one
another), and you define a template path (like your $PATH at the
shell), which makes customization a snap. Provide default
templates, and allow people to add custom templates to a directory
that's earlier in the path.
All in all, ClearSilver is a very
functional presentation engine. Some of the syntax is a bit
obtuse because of all the extra "<?cs" and "?>" bits in there,
but it's very easy to work with. And best of all, it's
ludicriously fast. Even with the overhead of having to convert
native CF datatypes (structs, arrays, queries) into HDF, using
ClearSilver instead of CF templates to generate the HTML is still
faster.
If that sounds interesting, I highly recommend checking
it out. The Java API is somewhat lacking compared to the Python
and C interfaces, but after I implemented a couple of the missing bits,
the guy who wrote it said that he'd put in a bunch of missing stuff
into the next release. So it should be even more capable when
that rolls out. Of course, if you don't mind getting your hands a
little dirty, the API is simple to augment on your own.