Sunday, July 31, 2005

Bye bye, Cheetah

Well, over the last week I finally took the plunge and wrote my own templating system. It's semantically pretty similar to Cheetah, but using PHP-like <% %> syntax. It's working title is simply Blocks.

Basic features:
  • All the functionality from Cheetah is present.
  • Many of the useful tags from Django's template system are included.
  • Instead of Cheetah's compilation system Blocks uses in-memory partial compilation.
  • Each page and defined block within it each specify their own caching properties.
  • Cache parameters can include aging and dependencies on Python objects.
  • Caching works with inheritance and is fully hierarchical.
Okay, time for a simple example:
<% def blogEntry(entry) %>
<% depends entry.lastModified %>
<%? entry.contents %>
<% end def %>

<% for entry in entries %>
<div class="entry">
<span class="entry_title"><%? entry.title %></span>
<span class="entry_content"><% block blogEntry(entry) %></span>
<% end for %>

As you can see, pretty similar to Cheetah. The syntax is better in many ways - particularly as many HTML editors will happily ignore it as PHP code. The distinction between a tag and an evaluation has been made a'la Cheetah, although slightly more verbosely.

The cacheing system is the most important part of Blocks. The output of each page and 'def' block is stored by default and re-used for the next render. This can be controlled by the use of 4 tags within the block itself. No-cache speaks for itself, as does MaxAge. The age parameter for MaxAge however, is evaulated dynamically as so could change per render if necessary. The Depends tag allows cache invalidation based on either the output an evaluated expression or its lastModified property. Multiple caches may be present using the Varies tag, for instance to cache stats per user by varying on user ID.

I haven't implemented Django's filter system yet, mainly because I believe that most of it it just horrible syntax for calling a function. However, I can see a use for filtering the contents of a block - so that will be implemented pretty soon. It fits easily within the current design of Blocks.

My only disadvantage now is that I can't think of any reason to still be using Subway...

If anyone wants a copy or more info, let me know. I'll open if up if there's any interest.

4 comments:

  1. Anonymous08:27

    Of course there's interest. Please post it on the CherryPy mailing list.

    ReplyDelete
  2. Anonymous18:49

    Mr P., did you ever publish Blocks? It looks very interesting.

    ReplyDelete
  3. Anonymous21:17

    Cheetah's cache has been greatly improved since 0.9.18 .. I advise you to give it another chance

    ReplyDelete
  4. Apologies to all, but the project I was developing Blocks for has been put on the back-burner for a while. Blocks itself is probably ready for use by others, I just have not had the time to package it up ready.

    I've just taken a look at Cheetah's new cache features. Although they probably help in some circumstances, they still do not address the core problem I wanted to address - cache dependancies. In Blocks, when you include another block in your current context you add that block to the cache's dependancy list, ensuring that relevant parts of a page are updated correctly when their sub-blocks change.

    I'll make the effort to make Blocks available, then you can see for yourself.

    ReplyDelete