Plone tips and tricks

Here is a list of things that I have found useful when developing Plone sites:

Use ZEO to help you debug

Zope Enterprise Objects (ZEO) is normally a way to cluster multiple Zope instances to help performance. However, it can also come in mighty handy for development as it allows you to run the site in debug mode at the same time as having it accessible through the web. To convert your Zope instance to use ZEO, follow these steps:

  1. Create a ZEO instance:
    /path/to/zope/installation/bin/mkzeoinstance <dirname>
  2. Shut down your Zope instance
  3. Move your Data.fs over to ZEO:
    mv /path/to/zope/instance/var/Data.fs <dirname>/var/
  4. Edit zope.conf:
    Edit /path/to/zope/instance/etc/zope.conf
    Comment out all lines in the first <zodb_db main> section you find
    Uncomment all lines in the <zodb_db main> section that is given after the words
    # ZEO client storage:
  5. Start ZEO:
    <dirname>/bin/zeoctl start
  6. Start Zope:
    /path/to/zope/instance/bin/zopectl start

You should now be able to see your Zope install through the web as normal. If all's well, you can also fire up a debug instance:

/path/to/zope/instance/bin/zopectl debug

After a while, you'll see a reassuring >>> prompt. You can now debug your Zope site by typing Python commands (the 'app' object is the top level of your Zope site). If you need to re-sync with the ZODB, type:

>>> app._p_jar.sync()

Note that any changes you make via the debug prompt are purely temporary. If you need to make these changes permanently (e.g. you've just patched up or deleted some broken objects) then use the following:

>>> get_transaction().commit()

Verbose Security

To help debug authentication problems, install the VerboseSecurity product (but n.b. to remove it on production sites). Also, to be able to see the errors by preventing redirection to the login page, then temporarily alter the following setting in the ZMI: [portal_root]/cookie_authentication page, set 'Auto-login page ID' to an empty string instead of its default value ('require_login')

Docfinder bookmarklet

Once you have installed the excellent DocFinder Product, then just drag the following bookmarklet to your Firefox/Safari tool bar: DocFinder. Then, once you're viewing a page on your DocFinder-equiped Plone site, all you have to do to see the API of the current object is to click on the bookmarklet.

Find-in-files shell script

A common task is to grep all the Plone source code for a given string. To make this easier, create the following script and call it

if [ ! -n "$1" ]
  echo "Usage: `basename $0` [expression to find] [optional extension]"

if [ -n "$2" ]
echo Searching for $1 in *.$filename
find . -iname "*.$filename" | xargs grep "$1"

Then, just cd to the Products directory of your Zope instance, and run e.g. "def UID" to search *.py files, or e.g. css_slot pt to search in page templates.

Finding bottlenecks with PTProfiler

The best way to profile your site to find slow pages is to install the PTProfiler product in a debug instance of Zope, with the ZPublisher call profiler enabled through use of the publisher-profile-file directive enabled in etc/zope.conf

In the ZMI, at the root level, use the Add Item menu to add a new PTProfiler object.

For each page of the site, load the page in a web browser, then go to the PTProfiler object and clear the results. This ensures that initial ZODB object load overhead is not counted in the performance statistics for page rendering.

Now reload the front-end page in a browser, and examine the results in the PTProfiler. At the top of the list of rendering calls are the TAL expressions that are consuming the most processor time for each page rendering. The most expensive calls are generally those that touch a number of ZODB persistent objects, such as calls to getFolderContents(full_objects=True).

Refactor your templates to avoid the most expensive calls, and re-test. Voila - speedy site.

Dealing with 'cannot paste from Javascript' errors in Kupu

If you get these, create a user.js file in ~/Library/Application Support/Firefox/Profiles/xxxxxxx.default that contains the following lines:

user_pref("capability.policy.policynames", "allowclipboard");
user_pref("capability.policy.allowclipboard.sites", "");
user_pref("capability.policy.allowclipboard.Clipboard.cutcopy", "allAccess");
user_pref("capability.policy.allowclipboard.Clipboard.paste", "allAccess");

Then restart Mozilla. More info here and here.

Back to Tristan's Plone area