Showing posts with label templateengine. Show all posts
Showing posts with label templateengine. Show all posts

Wednesday, September 30, 2009

Python Cheetah Benchmark

With any web application, no matter what language it may be written in, templates need to be rendered. These are often HTML templates. If there were no templates, just static HTML files, what we would have is a static site as opposed to a web application. The dynamic aspects of the page are filled in by rendering a template. This is the most common approach for several reasons. Chiefly, the user interface is nicely separated from application logic. This, in turn, makes it easier for the user interfaces developers and designers to work without disrupting the logic they aren't concerned with. This also works vice-versa.

The Cheetah template rendering system, written for Python web applications, is a mature one. Cheetah provides a clean, elegant template syntax when compared to other Python template rendering systems. For instance, the syntax constructs are not represented as tags. This provides both flexibility and separation of concerns. Since tags aren't required, Cheetah can be used for templates other than HTML. Also, it is more obvious with Cheetah what is HTML markup and what is template markup.

Below is a very incomplete, sample of how to use Cheetah pragmatically. That is, it is very easy to plug into any potential Python system.
#Example; Timing Cheetah rendering.

#Do imports.
import timeit
from Cheetah.Template import Template

#Rendering test.
def render_cheetah():

#Cheetah template string.
template_str="""<html>
<head>
<title>$title</title>
</head>
<body>$body</body>
</html>"""

#The context supplied to the template; variable substitution.
context={"title":"Cheetah Test", "body":"Cheetah Test"}

#Initialize the Cheetah template object.
template_obj=Template(template_str, searchList=[context])

#Render the template.
str(template_obj)

#Main.
if __name__=="__main__":

#Run the test an print the results.
cheetah_timer=timeit.Timer("render_cheetah()",\
"from __main__ import render_cheetah")
print "Cheetah:",cheetah_timer.timeit(number=1000)

Monday, May 4, 2009

Django Templates and NodeLists

Whether dealing with a complex web application or a simple web site with relatively few pages, using templates is generally a good idea. With complex page structures, this is unavoidable. The alternative would be to implement the page structure manually. Even with simplistic web pages, there is often a dynamic element that is undesirable to manually edit. If the web application is built with a Python web application, developers have several template engines to choose from. TuboGears, for instance, offers support for several third-party template engines. Django, on the other hand, offers their own template rendering system. The Django template engine provides many of the same features as do other Python template engines. The syntax used in Django templates is simplistic and easy to use. Inside the template engine are two closely related classes that represent key template concepts and are illustrated below. These classes are Template and NodeList.



The Template class represents a template in its' entirety. During the construction of Template instances, the template is compiled. Since this process takes place in the Template constructor, the template string is a required constructor parameter. Since any given Template instance is compiled, it may be rendered at any time. The template passed to the constructor is only compiled once since the compilation takes place in the constructor. Template instances support iteration. Each iteration through a particular Template instance yields a node from the NodeList instance that resulted from compiling the template. Invoking Template.render() will in turn invoke NodeList.render(), passing along the specified context.

The NodeList represents a collection of nodes that result from compiling a template string. The majority of these nodes are HTML elements, template variables, or some Python language construct such as an if statement. NodeList instances are also instances of the Python list primitive. This means that each node contained within the list behaves just like a Python list element. The NodeList.render() method will cumulatively invoke render() on each node contained within the list. The end result is the rendered template. This rendering behavior provided by the NodeList.render() method can be considered polymorphic. The method iteratively invokes render() on anonymous instances. All it cares about is the render() interface.