Monday, September 14, 2009

Grokking Grok - II

Grok, like Plone uses the Zope way of storing data - Persistence, somewhat like 'pickling' in Python.

All instance of objects are treated not as tables like in frameworks such as TurboGears, but as normal runtime class instance objects. There are no need to think of SQL, neither designing a database. Just dump the objects into the ZODB.

Base Model Stereotype

The are 3 main model stereotype in Grok, grok.Model , grok.Container , grok.Application


This is the stereotype for a persistence class. Classes that inherits this stereotype are addable and can store persistent data.


This stereotype give a class a folder-like ability to store children. Inherit from this class if you want to create objects which can store another object.


This is the stereotype of a persistence class which can be added at the root of the Zope3 site.


Siteroot may contain Applications, Applications may contain both Containers and Models, Containers may contain both Containers and Models.

Defining a simple Grok Model

Assumes you've created a project called MyProject. Edit $buildout/src/myproject/ You should see something like this

import grok

class MyProject(grok.Application, grok.Container):

class Index(grok.View):

Lets create a simple grok.Container model which called MyFolder and a normal model called MyDocument. Add these into

class MyFolder(grok.Container,grok.Model):

class MyDocument(grok.Model):


Writing a simple AddForm for adding objects

Grok provides some handy classes for automatically generating forms which based on zope.forms. So you can quickly generate a form using it. Lets create a form to add MyFolder into MyProject.

First, as we are going to have multiple Zope Views (forms are considered as views) in this, Index class need to be modified a bit.

class Index(grok.View):

By default, The context will be acquired from the only Model available in the .py file. But as this example have multiple models in the .py file, that need to be defined.

Next, define the fields which we want MyFolder to have (note: put this code above MyFolder class definition).

from zope.interface import Interface
from zope import schema

class IMyFolder(Interface):
name = schema.TextLine(title=u'Object Name')
title = schema.TextLine(title=u'Title')

As you can see, instead of adding the attributes into the MyFolder class, we created an Interface. Next, make MyFolder implement the Interface

class MyFolder(grok.Container,grok.Model):

Afterward, lets create a form

class MyFolderAddForm(grok.AddForm):

form_fields = grok.AutoFields(IMyFolder)

@grok.action(u'Add MyFolder')
def add(self,**data):
mf = MyFolder()
name = data['name']
self.context[name] = mf

Done. Up to this point, you now have an application called MyProject, and an addable model called MyFolder. Now to adjust the templates.

Edit $buildout/src/myproject/app_templates/ and replace the template with this:

<h1>Welcome to My Application</h1>
<a href="myfolderaddform">Add MyFolder</a>

Creating a View for a Model

MyFolder at the moment does not have a default view template. So lets create one. Create a View by adding this:

class MyFolderView(grok.View): 

Then edit $buildout/src/myproject/app_templates/, and put this as the template:

This is a new MyFolder object called <tal:name replace="context/name"/>
with title '<tal:name replace="context/title"/>'

Done. You should now be able to add an application called MyProject, and add a MyFolder in it.

Running you application

Start Zope3

$buildout/bin/zopectl fg

Open http://localhost:8080/.

Add a MyProject, name it as testapp and open it.

Click the "Add MyFolder" link.

Add a new MyFolder object, name it as testfolder, afterward you should see this

Thats it for now. Try to add an AddForm for MyDocument by yourself.

More details?

Read the official tutorial here :

Zope TAL Spec :

Zope Component Architecture :

Grok/Zope Forms :

Have fun
Post a Comment
Locations of visitors to this page