Skip to main content

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

Popular posts from this blog

Consolidated community site infrastructure on Plone

In Inigo, we believe in helping out local FOSS communities and help them grow. We help out in community events where we can, present FOSS talks, and provide some platforms for local communities to grow. One of such platform is our consolidated community site infrastructure on Plone.

The system/infra and its components was originally developed for the Fedora Malaysia website, while keeping in mind to keep it generic enough so that other communities could use the same components for their own community sites. The infra is already at a usable state, and we can add new sites easily with just a few clicks.

Features in this consolidated infra are:
Document/Content management (Plone built-in)Calendar system (powered by solgema.fullcalendar addon)Conference/BarCamp system (powered by collective.conference addon, which was developed for FUDCon Kuala Lumpur 2012)Blog (powered by Products.Scrawl)Simple yet powerful theming engine (powered by plone.app.theming/ Diazo) - Check out Diazo, you'l…

HOWTO: Mirroring Yum repositories using Yum-Utils

As promised before in one of my previous post, a Howto on how to mirror and manage yum repositories using some of the utilities in yum-utils.

The first step is, well, of course, is to get yum-utils from fedora repository
yum install yum-utils

Reposync
Reposync is a utility for mirroring and synchronizing local copy of a yum/rpmmetadata repository.

This utility is very useful if you wanted to make a yum repository mirror. Before this, I used "wget -R -np -N" but this method is a little bit tedious and it doesnt work with repos that didn't use directory listing. Plus, it also download together additional site stuff that I don't need/want and it doesn't verify checksum of the downloaded packages.

Mirroring a repo using this utility is easy, just execute this command
reposync -r <repoid> -a <arch> -n
and the repo will be mirrored in a folder with the same name of the repoid in the directory you executed the command. Eg: you executed the command in /mnt/storage/mi…

Adding simple popup to Plone frontpage

Here is a little guide for those who want to add a simple popup to the Plone frontpage for some purpose (eg: announcements, advertisements, etc).

Create a basic html file containing the content you want to appear in the popup. Upload it into $PLONE_SITE/portal_skins/custom (as Page Template) and for the sake of this example, name it popup.html

Afterward, create a Javascript file with your Pop-Up loader script. For example , this script:


function popup(mylink, windowname)
{
if (! window.focus)return true;
var href;
if (typeof(mylink) == 'string')
href=mylink;
else
href=mylink.href;
window.open(href, windowname, 'width=220,height=400,scrollbars=no');
return false;
};

popup('popup.html', 'My Popup');


Also upload this file into $PLONE_SITE/portal_skins/custom (as Page Template too). For this example, name it as popup.js

Afterward, in $PLONE_SITE/portal_javascripts , add popup.js as a new script into portal_javascripts…