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

grok.Model

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

grok.Container

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.

grok.Application

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

Layout

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/app.py. You should see something like this

import grok

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

class Index(grok.View):
pass


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

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

class MyDocument(grok.Model):
pass


Done.

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 app.py, Index class need to be modified a bit.

class Index(grok.View):
grok.context(MyProject)


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):
grok.implements(IMyFolder)


Afterward, lets create a form

class MyFolderAddForm(grok.AddForm):
grok.context(MyProject)

form_fields = grok.AutoFields(IMyFolder)

@grok.action(u'Add MyFolder')
def add(self,**data):
mf = MyFolder()
self.applyData(mf,**data)
name = data['name']
self.context[name] = mf
self.redirect(self.url(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/index.pt and replace the template with this:


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


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): 
grok.context(MyFolder)
grok.name('index')


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

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


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 : http://grok.zope.org/doc/current/tutorial.html

Zope TAL Spec : http://wiki.zope.org/ZPT/TALSpecification14

Zope Component Architecture : http://www.muthukadan.net/docs/zca.html

Grok/Zope Forms : http://grok.zope.org/documentation/phc_topic_area?topic=Forms

Have fun
Post a Comment
Locations of visitors to this page