Exploring Software: Getting a Hang of Zope’s Grok

0
38
I Grok!

I Grok!

According to Wikipedia, “to grok” is to share the same reality or line of thinking with another physical or conceptual entity. For example, to say that you “know” LISP is simply to assert that you can code in it if necessary — but to say you “grok LISP” is to claim that you have deeply imbibed the world-view and spirit of the language, with the implication that it has transformed your view of programming.

Getting started with Django, or for that matter, Rails, typically involves creating a model. This is likely to be just a relational table. The framework creates a form with the option to insert, edit and delete records. And you have a working application in a matter of minutes.

The Grok tutorial comes as a surprise; it starts with views and templates instead. Persistence of data “magically” happens behind the scenes, using ZODB. The tutorial exposes you to the basic usage of Zope Page Templates and its relationship to the Python code. You will get a flavour of Grok quickly, though building a working application takes more effort.

Comparing it with the MVC paradigm, one can relate to the idea of models and views — but controllers seem to be missing (refer to the Grok Developer’s Notes). The URLs point to model objects in the Grok application views. This brings up an interesting issue when trying different frameworks: while it may take just a few lines of code to implement some concept, it can be hard, in the beginning, to find what those lines are, or where they go! So, the chances are that the first framework you learn will feel much easier and more “natural” than the rest!

While Grok makes it easier to build Zope3 applications, an understanding of the Zope concepts is necessary. Zope is sufficiently different, so you won’t be surprised to come across a page like this documentation, which says, “ZopeInAnger is meant to help you develop Zope programs without necessarily understanding the full API (as if that were possible for mere mortals)…” The geeky humour ensured that I did not give up.

While Grok’s tutorial was fine, several user-contributed example applications had issues with current versions. The issues were minor, but can be intimidating when one is just getting started.

Persistence

The main aspect of Grok that is conceptually different from other major frameworks is the persistence mechanism of Grok/Zope3, which can be thought of as a database consisting of containers and persistent objects. A container can be thought of as a Python dictionary with key-value pairs, much like gdbm or Berkeley DB. The value in this case is any Python object that can be pickled. The key is used to navigate through the objects. While Zope applications normally use ZODB, it is possible to replace ZODB with a relational database and an object-relational mapper, like SQLAlchemy.

A persistent object is defined by a class that inherits from grok.Model. Consider a simple example like an “LFY” application that stores articles. A code fragment may look like what’s shown below:

class LFY(grok.Application, grok.Container):
    def add_object(self, name, article):
         self[name] = article

class Article(grok.Model):
    title = ''
    content = ''

If you want to dynamically create a form for the model, you need to make more of an effort. To define the object in a Zope interface, with the specification of the schema data types, let’s first implement the interface in the model. The code fragment for the interface should be as follows:

class IArticle(interface.Interface): 
    title = schema.TextLine(title=u"Title") 
    content = schema.TextLine(title=u"Content")

The model will now be:

class Article(grok.Model):
    interface.Implements(IArticle)
    title = ''
    content = ''

Let’s suppose that each article can have comments. You can model the comments as a Python dictionary. However, if the number of comments is very large,  you can use a container for storing comment objects.

In case the data needs to be stored in a relational database and ZODB is not an option, Grok provides an option to use an object relational mapper, like SQLAlchemy.

For completeness, it is worth noting that it is possible to use ZODB with Django!

Views

As expected, it is easy to create the add and edit forms. The code and the visual elements are well separated, thanks to Zope Page Templates (ZPT), which encourage clean separation of content, graphics design, and program code. ZPT standards are TAL (Template Attribute Language), TALES (TAL Expression Syntax) and METAL (Macro Expansion TAL). Given below is an example illustrating the display of all articles, with each row being clickable:

<p>Available Articles:</p> 
       <li tal:repeat="key python:context.keys()">
           <a tal:attributes="href python:view.url(key)" tal:content="python:key">Article Name</a> 
       </li>

You can guess that the name of the article, which is the key for storing articles in the container, is displayed on each line. The key replaces the sample text “Article Name” in the template. Clicking on a name would call a URL that’s determined by calling a Python method.

The syntax is pure XML, and fits well into HTML. This is in contrast to some template engines, which tend to use some special characters like curly brackets, for example, to differentiate template code from HTML code.

Whether using XML in a template engine makes it easier, is questionable, since the template language and HTML have to be in the same file. However, if both HTML and the template engine were replaced by something like YAML, it would definitely be a step forward to simplify coding and understanding.

To learn more about Grok, I would recommend exploring the this tutorial, but only after going through the official Grok tutorial mentioned in the beginning of this article.

It is worth learning alternate frameworks like Grok even if you do not use them, simply because it can help you grok the framework that you use!

Feature image courtesy: groks. Reused under terms of CC-BY-SA 2.0 License.

LEAVE A REPLY

Please enter your comment!
Please enter your name here