TurboStan 0.8.7
Filed under: turbostanHere's the latest release of TurboStan. It includes arbitrarily deep inheritance, code and content caching, and lots of little fixes.Here's a brief overview of what's new:
- Arbitrarily deep levels of inheritance. Earlier versions only supported inheriting from a single master template. Now templates can inherit from templates which in turn inherit from other templates.
- Code caching. Templates are precompiled and stored in memory. This gives an enormous performance boost.
- Fragment caching. Slots can be cached as static HTML via an argument to the override tag. Further, arbitrary cache expiration schemes can be employed via a callback. Also allows for custom cache identifiers if needed.
- Absolute paths to templates. The relative path scheme employed before was a mess. Now you can set stan.templates = 'path/to/templates' in your TurboGears config file and that becomes the root for all template paths.
- Passing an arbitrary namespace to included fragments. You can now add locals = dict ( myvar = 'foo' ) and pack the dictionary with variables you want the included fragment to see.
Here's a short example showing how you might implement a time-based caching scheme (i.e. expire the cache at midnight):
controllers.py:
from calendar import weekday, day_name
from time import time, localtime
class Root ( controllers.RootController ):
@turbogears.expose ( template = 'stan:.public' )
def index ( self, *args, **kwargs ):
def render_content ( self ):
now = tuple ( localtime ( time ( ) ) [ :3 ] )
today = day_name [ weekday ( *now ) ]
return ( ''
This could be pulled from a database or some other source.
I explain why this is a callback below.
And to help make the time-based cache expiration make
a little sense, we'll print what day it is:
Today is %s.
'' % today )
def cache_valid ( self ):
''
Function should return True if the cache content is valid, False if it should
be flushed and render_content ( ) asked to regenerate the data.
''
return not isMidnight ( )
return dict (
render_content = render_content,
cache_valid = cache_valid
)
The reason I'm using a callback to generate the content rather than just passing the content back in the return value of the controller is because I don't want to regenerate the content if it's already in the cache. Remember that the controller method is called on every page access prior to rendering the template and prior to checking the cache. This means that if we were to say, pull the content from the database, this database call would be made regardless of whether we later used the cache or not. By implementing this as a callback, we can guarantee that no extraneous functions are called when the cache is used.
Now our index.stan template:
html [
head [
title [ 'TurboStan Example' ]
],
html [
h1 [ 'Welcome to TurboStan!' ],
div ( id = 'main-content' ) [
slot ( 'content' )
]
]
]
And finally, our public.stan template. Note that this is the template referenced in the controller. Index.stan is referenced via inheritance:
inherits ( 'index' ) [
override ( 'content', cached = vars.cache_valid ) [
xml ( vars.render_content ( ) )
]
]
You can download TurboStan 0.8.7 `here`_.
Feel free to contact me with bug reports, feature requests, etc...
here: http://www.develix.com/downloads/TurboStan/TurboStan-0.8.7.tgz






