[Another in a series of posts about moving from Django to Plone. I’m a Plone/Zope newbie writing about my bafflements and enlightenments as they happen.
Some of my opinions are certainly wrong. I’m writing this in the expectation that the history of my meandering learning path may be useful, or at least entertaining, to future Plone newbies. If I sound wordy today, it may be because I just watched Good Night, and Good Luck. on my Blu-ray player. (The difference between Edward R. Murrow, and the regurgitating talking heads of today’s television, is a sad thing to contemplate.)]
I spent only half of this week on Plone/Zope. Here’s some of what I bumped into.
Portlets, Viewlets, and Content Managers
I’ve been puzzled about the big conceptual difference between portlets and viewlets. Not until I read page 234 of Professional Plone Development did I understand that it was in their invocation model! A viewlet will generate page content anywhere in the page when a viewlet manager deliberately invokes it. A portlet may generate content in the left or right column, automatically.
Although an interesting distinction, I still don’t see a good reason for portlets’ existence. Instead of a “portlets” entity, why not instead give viewlets a hook to indicate they’re an automatically-invoked-left-or-right-column object? It could be something as simple as the existence of an
automatic_render() method in a viewlet object. If that method is defined, it signifies the object as a candidate for automatic rendering in the left or right column.
Because this is an obvious point, and the Plone/Zope community contains so many smart developers, I’ve got to be missing some other difference. And so I am very likely an ignoramus. These aren’t the droids you’re looking for, move along…
Portlets don’t exist in Django, but they’re easier in Django
I guess you’d make Django “portlets” by putting a loop in a left or right column’s
<div>. The loop would call all of the portlets’ functions or methods. Each one would decide whether to return HTML, based on business logic. You’d iterate over a set or list of portlets, with each function checking its display criteria. So, the View (template) would call the Controller (“portlet”) code, which decides whether to display HTML. And you’d have to code this up manually.
In Plone, the relationship (unless I’m wrong about this…) is flipped. The Controller (portlet object) decides (apparently…UIWAT) whether to be displayed within the View (page template’s columns) without being deliberately called.
Although Django doesn’t have this functionality built-in, any halfway-decent Python developer could create a Django portlet system in no time.
Zcatalog, Holy Crap
ZCatalog is powerful, but I’m missing how it’s hooked up to search forms.
It seems like a ZCatalog is used if an
name=xxxx attribute matches an index; and a report form is used if it references a ZCatalog by name. But that’s too fragile a relationship definition to be viable in a large application. The linkage must be defined in some XML or interface file, but I’m too dense to see it right now.
Zope 3 interfaces: Gaaaa!
Zope 3 Interfaces leave me cold. They smell like a traditional language’s way of protecting the programmer from herself. It’s a layer of Java-esque crap static typing layered over Python code.
When I consider using a preexisting code package, I don’t just close my eyes and copy it over blind. First, I’ll read the documentation, and search for published reviews. I’ll then evaluate its support and license. Then, I’ll look for example or demo code. Only after all that will I decide whether to use it, and if so, do the necessary coding. Since I’m doing all that anyway, of what value is an interface definition?
Maybe I’ll rue these words in two months, but I think separate interface definitions are syntactic sludge. I’m hoping for an experienced Zope developer will show me that I’m dead wrong.
Aspect-Oriented Programming: Gaaaaaaaaaaaaaaaaaaa!
I appreciate the problem definition. Briefly: Some code (like logging code, or user authentication) can be scattered throughout an application. This makes it hard to share OOP source code, and increases maintenance costs. AOP tries to mitigate this problem by defining cross-cutting code as aspects, and providing ways to declare when such aspects should be invoked.
I have two complaints with this.
First, the problems aren’t as painful as they’re made out to be, in my experience. I’ve never seen a project get hung up by changes to its logging code; in fact, logging calls are the most painless code in a project. Authentication code can be problematic, but hassles with it are usually due to poor design decisions within the authentication package, and not in having to add authentication calls around other code.
But let’s forget all that. And, let’s pretend like the problem, as described, is a big deal. Now I get to my second problem, which is this: When I read through what AOP makes you do to solve this problem, I want to gouge my eyes out with a yogurt spoon. Join points, pointcuts, advice, adapters, interfaces, adapter factories…man, you’ve got to be kidding me! All of that is better than giving code you’re thinking of using a once-over?!? I don’t think so.