Some minor ranting about Plone 3
First, Plone 3 is a great release, it is pretty much stable since the 3.0 release but:
- customizing stuff like header, footer or so became too complicated. Performing trivial customizations is no longer easily possible - neither for a scripter nor for a developer. By moving stuff from portal_skins to browser views or viewlets we lost a lot of flexibility for making customizations. Some Plone 3 customers already complained about that - good for the solution provider, bad for the customer. Although I appreciate the cleaner architecture, it introduces too much complexity. Example: the recent portlet is only available for logged-in user. If you want to make it available for anonymous users you have to subclass it and override its available() method. Sorry but that's the wrong way.
One of the major German public radio stations is using Plone for its youth radio.
I am pleased to announce that the public radio station Saarländischer Rundfunk will relaunch the website their youth radio Unser Ding on October 1st 2007 on top of a Plone-based CMS solution developed by ZOPYX. The Saarländischer Rundfunk is one of the sixteen federal-state radio stations in Germany. Unser Ding is a radio programme made by young people for young people and broadcasts 7*24h.
Professional and high-quality export of Plone content into office formats
After several months of development SmartPrintNG 1.0.0 has been released today. SmartPrintNG provides the best functionality available for Plone for exporting any kind of Plone content into office formats like PDF, RTF, ODT, WML and DOCX ....enjoy!
Nowadays our SVN checkouts of Plone, Zope 2 and Zope 3 consist of lots of svn:externals. Updating the sandboxes often takes a long time because SVN updates the externals one after the other. I came across this Ruby script that performs updating in parallel...pretty nifty..
Zope's MailHost got a new engine under the hood. The sending and delivery part of MailHost is now based on zope.sendmail. This brings us several advantages:
- integration with the Zope transaction system (no longer dupe emails in case of conflict errors)
- TLS/SSL support (if available (requires Python to be compiled with SSL support))
- optional asynchronous mail delivery using a mail queue and a queue processing thread
TransactionalMailHost is yet another MailHost implementation. It integrates with the transaction system of Zope in order to send out email only in case of a committed transaction. TMH currently supports standard SMTP and SMTP AUTH.
While converting some of my projects README.txt file to restructured text with vim, I came across the VST package for vim which provides reST support. After installing VST you can type
:Vst pdfto generate HTML or PDF from the restructured text document in your current buffer..that's pretty nifty.
With an additional line in your .vimrc configuration file you can configure your own command that converts the buffer to HTML, saves the generates HTML on the filesystem and starts Firefox to preview the file:
:com RP :exec "Vst html" | w! /tmp/test.html | :q | !firefox /tmp/test.html
:com RP :exec "Vst html" | w! /tmp/test.html | :q | !open /tmp/test.html
and you call the conversion pipeline from vim using new 'RP' command (RestPreview):
SQLAlchemyDA - a new unified database adapter for Zope 2
SQLAlchemy would deserve the first price for the best Python package ever if there would be such a price.
SQLAlchemy is cool! Why is it cool? Because it solves all my problems!
Lets look at a real world example. I maintain a legacy system which is a hybrid solution storing binary content within the ZODB while keeping the metadata within a Postgres database. Internally we have to deal with hierarchies which are represented within the databases as self-referential table. A self-referential table allows you to store tree-like structure by having a back-references to the parent node. You can imagine that serializing and de-serializing a tree-like structure into a flat table structure within a RDBMS is big pain in the a**. The old legacy code for doing this consists of about 800 lines of Python code and SQL statements. Writing and maintaining such code is boring and really without fun. Well, such a self-referential is complicated enough but these tree structure also have internal references to other trees within the same table and reference to some other tables. So the complete tables is big forest of connected trees.
Lately I started looking at SQLAlchemy in the hope to get somehow out of the SQL hell. In SQLAlchemy every row of a particular table is represented as an instance of a mapper class. Fortunately SQLAlchemy provides support self-referential tables out-of-the-box. You configure your mapper class as a self-referential mapper, you perform a SELECT on the top node and then you're done. SQLAlchemy knows how to deal with the parent-child relationship (by configuration) and make sthe children nodes of the tree available a Python property of the current node. Children node are loaded on request. That nodes are only loaded from the database if needed.
More advantages of SQLAlchemy: you can modify nodes within the subtree by traversing to them and changing their properties. To save a complete
tree you just have to save the root node only. SQLAlchemy knows how update the rows for the modified nodes of the subtree. SQLAlchemy is doing that automatically for you. You don't have to keep track of changes, you don't have to write a single SQL statement
What are the disadvantages of SQLAlchemy? I don't know any. SQLAlchemy has a very good documentation and a very responsive mailing list.
- SQLAlchemy is a big framework. The basics are easy however you must dig into SQLAlchemy when you face more complex scenarios like integrating SQLAlchemy with (unclean) legacy systems