grokkerdam2008
Quick intermediary grokkerdam sprint roundup
- Grok now uses the same list of versions as zope's KGS.
- zc.sourcerelease seems to work now: you can create a tarball from a buildout config file. The tarball contains all the downloaded sub-tarballs and eggs. No more downloads from loads of locations.
- Grokproject can now be run from paster. And it has become smaller.
- Documentation cleanup. Looked at possible grok website improvements (including some mails to the list). A couple of new volunteers for the website!
- five.grok has tests now that demonstrates that it works.
- The
url()method can be passed a dict that results in GET parameters at the end of the URL. With the accompanying documentation in multiple places. - Several how-to's added.
- grok.traversable takes care of a common coding pattern. It allows you to mark
attributes and methods as traversable. So http://myobject/something will
call the
something()method on your object (once you configured it that way with agrok.traversable("something")directive).
- Grok's kss support improved (drag/drop, client actions, etc). And design decisions were made (sprints are great for getting everyone on the same track). Documentation is in a way better shape, as is kss itself.
- Not really grok-related, but Christian Theune finalized some bits and pieces on zeoraid : well-working sync for zeo servers! Sounds great.
- There'll be a zope.sqlalchemy package: that will just include low-level transaction integration. All the policy decisions that are now in all five different sqlalchemy integration packages can/will be build on top of zope.sqlalchemy. Great: unification in that area.
- The docgrok tool (build on top of sphinx) is finally merged.
- grokcore.component 1.0 is released. While writing documentation, Philipp found out a bug in grok which opened up other caves and cans of works. It is all fixed now :-)
- Guido Wesdorp talked a lot for two days :-)
- Permissions and roles work. Especially documentation needs/needed to happen: both the desired situation and the current situation.
- Tests for sql are apparently hard to set up. There's now some test setup with plain sqlalchemy, so without zope stuff in it.
- Buildout and virtualenv. Sometimes the buildout-based setup still fails because of interactions with system packages. Virtualenv might help here. There's work being done to check if it can be remedied.
Philipp von Weitershausen - grok and wsgi
WSGI is a specification for the the communication between the "gateway" (where http requests come in) and the "application" (the real thing that does something, in our case the zope publisher). The gateway outputs a python dict of environment variables plus a file-like object that's the request that's coming in. On the way out, you have the output (as an iterable of lines).
Important point: the web application no longer owns the process: no more "zopectl start". The whole process is handled by wsgi. It looks like standard CGI, but much more pythonic.
"Zopeproject" is an early go at running/configuring zope as a wsgi
process. zope.app.wsgi.getWSGIApplication(/path/to/zope.conf). Zope.conf
refers to the site.zcml, site.zcml loads the rest (for instance a demo grok
application that he showed). You can start the application with "paster
server deploy.ini" (or with apache's mod_wsgi etc). deploy.ini configures
what you want to start via wsgi.
Another advantage is that zc.recipe.egg is enough: you don't actually need buildout and custom recipes to run it. Just zc.recipe.egg, a zope.conf, a site.zcml and a paste.ini.
There was some pushback "the repoze guys are doing it wrong the wrong way", "skeletons should not be used, so paster script is bad" and "that's middleware that's not allowed by wsgi". (I didn't agree with all of that, for the record. Putting the contents of a zcml fine as text in a buildout.cfg: yuck) zope.publisher.paste (mentioned next) removes the need for the most "offensive" generated file, btw.
There's something new out of Jim Fulton's fingers:
zope.publisher.paste.Application(). It lets you configure the publication
in paste.ini by passing parameters like database (zodb or not), the root
object, the zcml file, etc. No more zope.conf, just paste.ini.
We can lower the amount of grok-specific code when we use wsgi. A lot of functionality can be hooked up at standard entry points so that we don't have to hook it up ourselves.
Tags: grokplone
Some presentations at the end of the second grokkerdam sprint day
Christian Theune - Pagelets
Normally, a layout template calls a provider that renders some template inside it. A pagelet is a template that instead "wraps" a layout template around it.
The pagelet is effectively defined (in zcml) as both a view and a content provider. It registeres one template as the "inner" template and another template as the "outer" layout template. The outer layout view on the pagelet looks up itself as a provider again in that layout template. So there's some going around in circles that's hard to get your head around (until you understand it, according to Chrisian).
In plone's context, it would be a different implementation of the "content" macro in the main_template.
Jean-Paul Ladage and Godefroid Chapelle - KSS and grok
Godefroid already did most of the kss-in-grok work. You'll have to add megrok.kss to your buildout to get the kss goodies. Add some KSS stuff to your html header and you're set.
Jean-Paul managed to get KSS working on views instead of only on contexts, something Godefroid was real happy with as he wanted to get that working for quite some time.
Apart from some demo effect breakage, everything is apparently working like a charm (client actions, server interaction, drag/drop, etc.)
Grok, sqlalchemy and traversal
Martijn Faassen showed a grok + sqlalchemy application he's been working on. This got everyone into the spirit and more importantly into the problem domain. Something he used a lot was custom traversal to navigate the relational database model with URLs. With some quick pseudocode:
from zope.location.location import located
class Something(grok.Model):
def traverse(self.name):
item = session.query(...).first() # or .one()
if item == None:
return
return located(item)
Storm is an alternative to sqlalchemy. Storm seems to be oriented more towards the needs of big complex projects. Sqlalchemy seems much more active open source community-wise. Storm is less "friendly" as you have to / can configure everything, just like zope3. Sqlalchemy seems more grok-like in outlook. At least, that's what I extracted from the discussion.
An outcome of the discussion was that grok needs a to make it real easy to
traverse to attributes. Unrelated to, but useful for, relational db
integration. grok.traversable("something") was suggested. So this is in
addition to the normal container traversal which effectively works with
dictionary access (container["subitem_id"]). A shorthand that prevents you
from having to write your own traverse() method in many common cases: so very
grok-like.
A useful warning came up in the discussion. In zope, it is really easy to see everything as folders. In sql, you're making it all relational. Both are not 100% right object-oriented wise. Watch out for brainwashing based on your environment.
We went through the zope api docs for zope.app.container, writing down which sqlalchemy information we ought to use for treating the mapped sqlalchemy results as a container. This helped us to flush out some corner cases.
An essential point is to use sqlalchemy and its ORM mapper for the things that that is good at. As grok we won't do the sqlalchemy work, we'll just provide extra grok-specific functionality like traversal and folderish behaviour. Folderish behaviour means, as an example, in handling a "delete" correctly. Correctness is should be handled on the sqlalchemy level: if you configure your mapper right, the right thing will happen. That might sound dead-pan but it is, actually.
Grok also means: "not invented here: in a positive way". What other people figured out and did right is what we don't have to re-invent. So we won't invent it here.
Something that we'd need to figure out: how and where to define the classes, tables and mappers? Do we want it all easily in one class? Do we need to grok something?
Grok needs the fields for the add and edit forms. We didn't like defining an interface for the fields as that's partially double, partially potentially late-binding, etc. So something simple like:
def form_fields(self):
return grok.Fields(rdb.Schema(OurClass))
There was much more, but this ought to do for a summary. I didn't contribute much myself (especially since I have basically no grok experience!). I did learn a lot by listening, picking up useful concepts and ways of working. Nice sprint till now!





