Personal tools
You are here: Home Documentation How-Tos Understanding viewlets

Understanding viewlets

This How-to applies to: Any version.
This How-to is intended for: Any audience.

Viewlets is a flexible way to compound html snippets. Learn what they are and how they work.


A viewlet is a component that represents an HTML snippet. It has basically the same purpose as a macro, but is more clean, powerful and flexible. Viewlets in Grok are synonymous to viewlets in Zope 3. It's only how to create and register them that is different, but they work exactly the same way.

Viewlets are typically used for the layout of the web site. Often all the pages of the site has the same layout with header, one or two columns, the main content area and a footer.

Viewlets are grouped by adding them to viewlet managers. Viewlets can have a certain order within a group. The viewlet manager has a name and that is what you refer to in a page template when you want to use viewlets. When you ask the viewlet manager to be rendered or inserted into your page template, what will happen is that update() of each viewlet is called. After that render() of each viewlet will be called and the return values of each render() is added to the output. You can provide your own render() method if you want or you can provide a template and that will be called.


This is an example of how you can use viewlets. Two viewlets (Fred and Wilma) are ordered in a viewlet manager. To try this out, create a new project with "grokproject viewlettest" and add these three files.

import grok

class Counter(grok.Model):
    def __init__(self):
        self.count = 0

class GrokExample(grok.Application, grok.Container):
    def __init__(self):
        self.fred = Counter()
        self.wilma = Counter()

class Index(grok.View):

class CountersManager(grok.ViewletManager):'counters')

class Fred(grok.Viewlet):

    def update(self):
        self.context.fred.count += 1
        self.counter = self.context.fred.count

class Wilma(grok.Viewlet):

    def update(self):
        self.context.wilma.count += 1

    def render(self):
        return """<div style='float: left; width:200px; height:200px'>
                  <div style='font-size:200%%'>
                  </div>""" % self.context.wilma.count


<div style="float: left; width:200px; height:200px">
    <div style="font-size: 200%;" tal:content="view/counter" />


  <h1>Grok viewlets</h1>

  <div style="width: 400px" tal:content="structure provider:counters" />

What happens when you visit http://localhost:8080/exampleapp/

  1. The 'index' view of the application is automatically used when nothing is specified and it will render the template.
  2. The template says it wants to insert whatever is returned by the viewlet manager called 'counters'.
  3. 'counters' is a group of two viewlets and the Wilma viewlet has lower order than Fred so the 'counters' viewlet manager process Wilma first.
  4. The viewlet manager will call update() on the Wilma viewlet first and update Wilma's counter. The manager will then call update() on the Fred viewlet which will cause an increment of Fred's counter.

Typo in

Posted by at Dec 16, 2008 04:09 PM

Gidday I couldn't get this demo to work until I changed the word view in to viewlet


It was a guess and it worked! George

Re: Typo in fred_template

Posted by at Dec 17, 2008 01:56 AM

I pasted in the html code and it got interpreted so my message was hard to read. Change this: tal:content="view/counter" to this: tal:content="viewlet/counter"