3.
"Worst Practices", Or Things To Avoid
Up one level
At Plone Conference 2006, Stefan Holek ("lurker") presented a well-received talk called "Top Twenty Plone Pitfalls." You can read his entire presentation or watch it online.
A number of his pitfalls were especially revelant to developers of add-on products, and we've adapted them here as a set of "Worst Practices" or things to avoid.
Do not develop your application logic in TALES.
Templates are for presentation, and for presentation only. You should put all of your application logic into Python code (scripts, tools). If you find yourself trying to create complex conditional statements in your templates, take a moment and think about how you can push your logic down into a Python script. Don't start writing increasingly complex TALES python: expressions -- they will make your application hard to maintain, hard to debug and hard for others to understand.
Stefan humorously-but-seriously suggests that you make a small donation to the Plone Foundation every time you use “python:” in a Page Template. ;-)
Do not impose a relational data model on an object database.
Do not expect the ZODB to work like MySQL. It won’t. The ZODB is an object database, not a relational database. Think about how to design your application in an object oriented way, rather than as rows of data in a table. Conversely, there is nothing wrong with using an RDBMS with Plone, if your data calls for it. The most common way to do this is to use a database connector and ZSQL methods to read/write data from your RDBMS.
Useful resources on how to do this include:
- http://www.plope.com/Books/2_7Edition/RelationalDatabases.stx
- http://plone.org/documentation/how-to/add-file-system-zsql-method
- http://plone.org/documentation/how-to/mysql-connectivity-in-zope-plone
Do not check for roles, only check for permissions.
- That’s because objects and methods are protected by permissions, not roles
- Use portal_membership.checkPermission.
Do not use REQUEST.AUTHENTICATED_USER.
- AUTHENTICATED_USER is unsafe and was deprecated many winters ago.\
- Use portal_membership.getAuthenticatedUser
Do not use the Authenticated role to model your site’s security.
- Authenticated is a system-owned role.
- Add your own custom role(s).
Do not use proxy roles.
- Proxy roles are similar to SUID scripts in *nix.
- Be very careful about what your proxied scripts do; you are poking holes into your site’s security.
Do not forget to add security declarations to your methods, the default is public (!).
- That’s because Item, which is the base class for most Zope2 objects, allows access to unprotected attributes.
- Be extra careful with tools. Methods may need to be public and perform their own security checks.
Do not call getObject on catalog results.
- getObject uses restrictedTraverse internally.
- Add everything you need as catalog metadata.
Do not use contentValues nor objectValues.
- contentValues/objectValues “wake up” subobjects, i.e. load them from disk into memory.
- objectIds is OK, incidentally, but not contentIds.
Do not return objects from scripts, return (lists of) dictionaries.
- Objects cannot be RAM-cached.
- Objects will be security checked.
- Python scripts are prime targets for RAM-caching.
Do not compute values at display time.
- Compute values at edit time and store them.
Do not “touch” objects at display time.
- Viewing an object must not cause a database write.
- Easy to accidentally cause a modification; watch the Undo tab.