Cheetah vs. kid: 1 – 0

I should have spent my Sunday doing a million other things, e.g. trying to clean up muttprint‘s build system. Instead I decided to take a quick look at TurboGears and its parts. The Arch packages for it didn’t quite build so I ended up spending some time with CherryPy, Cheetah and Kid. I’m an utter beginner when it comes to “programming the web”, I’ve just never been very interested in it. It might be changing now though :)

CherryPy is truly impressive. A simple Hello World web service hints at just how easy it is to use. It’s written in Python, and it’s very pythonic indeed. However CherryPy isn’t what I wanted to write about. Another area I’ve not looked at is templating systems, I haven’t found a need for it yet. That’s possibly because I’ve never really understood what they are and what they do. That’s changing too.

TurboGears uses Kid so that’s were I started. I downloaded a simple example consisting of two files. The template:

<html>
  <head>
    <title py:content="title">Title</title>
  </head>
  <body>

    <h1 py:content="title">There should be content</h1>

    <ol py:if="title">
      <li py:for="line in lines">
      <span py:replace="line"></span>
      </li>
    </ol>

    <dl>
      <span py:for="n, line in enumerate(lines)" py:omit="">
        <dt py:content="'Line %s' % n"></dt>
        <dd py:content="line"></dd>
      </span>
    </dl>

    <p py:replace="'End of page'+title"></p>

  </body>
</html>

The second file is the CherryPy modules that combines the template with values:

import cherrypy
import kid

class HomePage:

    @cherrypy.expose
    def index(self):
        test = kid.Template(file='kid_test.kid')
        test.title = "Test Kid Page"
        test.lines = ['qwe','asd','zxc']
        return test.serialize(output='xhtml')


if __name__ == "__main__":
    cherrypy.root = HomePage()
    cherrypy.server.start()

This, I think, is rather cool. Very clean, very nice. Still I thought it’d be interesting to take a look at Cheetah (one main reason was that their homepage mentioned that reddit.com, which is funded by Paul Graham, uses it). It was a good decision, I think.

I wrote a Cheetah template producing the same output as the Kid template I downloaded.

<html>
  <head>
    <title>$title</title>
  </head>

  <body>
    <h1>$title</h1>

    <ol>
      #for $l in $lines:
      <li>$l</li>
      #end for
    </ol>

    <dl>
      <span>
        #for $n, $l in $enumerate($lines):
        <dt>Line $n</dt>
        <dd>$l</dd>
        #end for
      </span>
    </dl>

    <p>End of page $title</p>
  </body>
</html>

The matching CherryPy module is very similar to the one above.

import cherrypy
from Cheetah.Template import Template

class HomePage:

    @cherrypy.expose
    def index(self):
        tmpl = Template(file='cheetah_test.html', \
                searchList=[{'title': 'Test Cheetah Page', \
                    'lines': ['qwe', 'asd', 'zxc'],
                    }])
        return str(tmpl)

if __name__ == '__main__':
    cherrypy.root = HomePage()
    cherrypy.server.start()

Now, what do I think? I guess the title of the post betrays my preference ;-)

I spent very little time reading documentation to do this. I needed some help to write the Cheetah template since I had to do it myself. However, I think that if I’d had a Cheetah example and tried to create a matching template using Kid, I wouldn’t be writing this right now. The Kid syntax just seems more confusing to me. I think I’d have to read more documentation as well as spend more time with Kid to reach the same level of confidence I have with Cheetah already after 30 minutes with it.

Now I just need to find some nice little project to verify that my first impressions are correct, both relating to Cheetah and to CherryPy. Any ideas?

Share

7 Comments

  1. Here’s how it’d look using Django‘s template language. I hope this ends up being formatted correctly… :)

    {{ title }}

    {{ title }}

    <ol>
      {% for line in lines %}
      <li>{{ line }}</li>
      {% endfor %}
    </ol>
    
    <dl>
      <span>
        {% for line in lines %}
        <dt>Line {{ forloop.counter }}</dt>
        <dd>{{ line }}</dd>
        {% endfor %}
      </span>
    </dl>
    
    <p>End of page {{ title }}</p>
    

  2. Yes, point gotten. Very nice actually. Might be worth a look that Django thingie ;)

    How does CherryPy and (the relevant part of) Django compare?

  3. To answer your question, here’s what your example would look like as a Django “view”:

    """ from django.core.extensions import render_to_response def homepage(request): context = {'title': 'Test Page', 'lines': ['qwe', 'asd', 'zxc']} return render_to_response('templatename', context) """

    You’d design your URL(s) in a separate file — a URLconf — which is essentially a “table of contents” of your site’s URL structure.

    Feel free to ask any more questions, or join the django-users mailing list, which is full of helpful people!

  4. Hey, have you tried to use Cheetah with cherrypy session? When i use cheetah with cherrypy session the session doesn’t work correctly. In other words, the cherrypy doesn’t keep the session values when using cheetah templates. Any suggestion?

  5. yguaratã, nope, no suggestions. I haven’t played with cheeta/cherrypy in a long time. Sorry I couldn’t be of any help…

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>