A few things you may not know about portlets in Plone 3
Sort of unexpectedly, the thing about Plone that seems to be getting people the most upset, is the new portlets engine. Since I was largely responsible for that, I feel a few responses are in order.
First of all, the idea that portlet is a template acquired from the context and referenced in a property is certainly simple, but it makes it woefully hard to make anything complex. In Plone 2.5, we had a kind of strange hybrid where we stuffed some information into views that didn't render anything, but which were looked up in the portlets templates. (These were still in a global namespace and needed to have uniqified names.) We did that because most portlets are not just static content - they require processing. The other three options (used prior to 2.1) were either to use really complex python: expressions in TAL (the most common kind, also the most difficult to maintain and poorly scalable solution); to use a pyscript in a skin layer (which are all in a flat namespace, and which are painful to work with because they're so context-less and subject to Restricted Python); or to create or abuse a tool (witness the bloat of the plone_utils tool).
The engine we have in plone.portlets and plone.app.portlets now is an evolution of PlonePortlets, a package for Plone 2.x by Plone Solutions, which has seen a lot of real-world testing. It had a few goals:
- Provide a natural place to put portlet-related logic - much like a view class does for templates.
- Give enough metadata about portlets so that a more user-friendly UI could be built (Going to manage_main and the Properties tab is not an impressive proposition for non-technical users).
- Make it possible to assign portlets to a group or a content type, not just a context.
I completely understand that this can seem scary, but it's not meant to be. I know a lot of people who find the new way of working more robust and, yes, easier. But it depends on what you want to do, of course.
In the past, people have created page templates for more or less anything. Want a bit of static text in the column? Create a template (or use a pretty hacky acquisition trick). Want to render a listing? Create a template that calls portal_catalog. Want something specific and content-type-dependent, create a template, and add a left_slots or right_slots property (or worse, a class variable) to your content type.
The intention of the new portlets engine is that we can write more re-usable, easier to re-distribute and ultimately more powerful portlets. In fact, we wanted to ship Plone 3.0 with more such portlets that let administrators and users do many of the tasks that previously required programmers writing TAL. Unfortunately, we didn't have time to do that, except for with the RSS and Search portlets. Subsequently to the release, though, we've produced a few:
- plone.portlet.static allows you to write static text. At the moment, it doesn't use Kupu due to the lack of a widget, but this has been written (on a branch of plone.app.form) and will be in Plone 3.1 (I could be persuaded to release it as an add-on package for 3.0 instead if necessary).
- plone.portlet.collection allows you to point a portlet at a Smart Folder to get any type of listing. It's not 100% done yet, so it doesn't have a release, but it's nearly there.
- collective.portlet.tal allows you to write ZPT code straight in the browser (sound familiar?) and render it inside a portlet. This is a bit of an "escape route", of course.
Other products, such as Quills, also distribute their own portlet types.
For programmers, I genuinely don't think that writing a new-style portlet is very hard. There is definitely some more overhead if you just want a dead-simple, template-only portlet (but then you could just use a Classic Portlet, which still works just fine with old templates, or a TAL portlet if you want TTW). There is a whole lot less overhead if you want to write any sort of portlet where your users have the ability to configure it on a per-instance basis. If you look at how portlets are used in other systems, this type of end-user configurability is taken for granted.
The packages above demonstrate minimal, portlet-only packages. I completely agree that we could benefit from convention-over-configuration patterns here, and the portlets packages are one of the first things I'd like to trial when we come to introduce Grok-like patterns in Plone (hopefully quite soon). The ZCML directive should go, but it's hardly complex - it just has to reference a few things. Similarly, the add and edit forms have to be defined, but will be boilerplate in most cases.
Now for the good news: If you want to create a portlet-only package, you can get started using a template from ZopeSkel. Just install ZopeSkel and run:
$ paster create -t plone3_portlet my.portlet
...and follow the instructions. In fact, Must@p has demonstrated how this can work in a more natural way, adding the boilerplate for any number of portlets inside an existing content types-focused package.
I do agree that we need more documentation on this. Geir gave a talk on portlets at the Plone Conference. I'd hoped that could turn into a tutorial, but we'll probably need someone to write one. I do, of course, cover them in my book, if you have that.
However, I'd encourage you to not just throw your arms up and close your editor at a new-style portlet. You may find it's not as complex as you think, and you may find that the tools at your disposal allow you to create better, faster (the built-in portlets use very powerful caching) and more flexible portlets that give your users more control over how their site works.