Where's the source, Luke? : How to find and debug the code behind Plone


Published on

Plone, being a python based CMS written as a project for the Zope application server, consist almost entirely of python modules and a number of configuration files. Python source code is loved by many in the community for its explicit readablity; however, for many experienced software developers, coming over to the Plone technology stack can be a haunting experience. It seems everything is hidden away as pickled object in the ZODB, and that layers of magic prevent one from understanding how it works and how to affect change. This presentation will explain to the novice: - how to track down the python source behind Plone - how to take advantage of rich open source tools like ctags and pdb - best practices for getting started with file system product development

Published in: Business, Technology
  • Be the first to comment

  • Be the first to like this

No Downloads
Total views
On SlideShare
From Embeds
Number of Embeds
Embeds 0
No embeds

No notes for slide
  • Where's the source, Luke? : How to find and debug the code behind Plone

    1. 1. Where's the source, Luke? How to find and debug the code behind Plone Paul Bugni < pbugni > University of Washington < u.washington.edu >
    2. 2. Introduction and Audience <ul><li>Designed for software developers new to Plone </li></ul><ul><li>Best practices </li></ul><ul><li>System structure </li></ul><ul><li>Debugging </li></ul><ul><li>Tools and tips </li></ul>
    3. 3. Getting Started <ul><li>Looking for a CMS? </li></ul><ul><li>Plone looks to have the features </li></ul><ul><li>And, it’s written in Python! </li></ul><ul><li>Python is so legible - this will be easy… </li></ul><ul><li>But after a quick install and some playing </li></ul><ul><li>around, you find it difficult to locate the </li></ul><ul><li>implementation code. Where is it? </li></ul>
    4. 4. [1] http://www.zope.org/zopearchitecture.gif Copyright (c) 2007 Zope Corporation - Reprinted with permission.
    5. 5. Buildouts: A Better Approach <ul><li>Binary installers are great for quick evaluation </li></ul><ul><li>‘ Unified Installer’ solves the distro woes </li></ul><ul><li>Software projects require </li></ul><ul><ul><li>Repeatable process </li></ul></ul><ul><ul><li>Source code repository </li></ul></ul><ul><ul><li>Inclusion of third party Products, packages, eggs </li></ul></ul><ul><li>zc.buildout[1] to the rescue! </li></ul><ul><ul><li>Check out Martin Aspeli’s great tutorial[2] </li></ul></ul>[1] http://pypi.python.org/pypi/zc.buildout [2] http://plone.org/documentation/tutorial/buildout
    6. 6. Buildout a New Project <ul><li>Use the plone3_buildout template: > paster create -t plone3_buildout myproject </li></ul><ul><li>Bootstrap > cd myproject > python bootstrap.py </li></ul><ul><li>Execute buildout as per rules in buildout.cfg > ./bin/buildout </li></ul><ul><li>Running tests, debugging, starting the instance now simply > ./bin/instance [options] </li></ul>
    7. 7. Directory Structure <ul><li>Highlighting several directories of special interest (installer approach defines directory structure; using the buildout paths): </li></ul><ul><ul><li>myproject/var/filestorage/ The contained ‘Data.fs’ file is the FileStorage representation of the ZODB[1] </li></ul></ul><ul><ul><li>myproject/eggs All the downloaded eggs[2], including the portions of Plone now distributed as namespace packages </li></ul></ul><ul><ul><li>myproject/parts/instance The Zope ‘instance’ directory, analogous to what ‘mkzopeinstance.py’ creates. A.K.A. $INSTANCEHOME </li></ul></ul><ul><ul><li>myproduct/parts/zope2 Zope code, previously known as $SOFTWARE_HOME </li></ul></ul><ul><ul><li>myproject/parts/plone All the Zope 2 style Products used in Plone </li></ul></ul><ul><li>[1] http://wiki.zope.org/ZODB/FileStorageBackup </li></ul><ul><li>[2] http://peak.telecommunity.com/DevCenter/PythonEggs </li></ul>
    8. 8. Dig In! <ul><li>Start up the buildout instance, and add a Plone Site: </li></ul><ul><li>> myproject/bin/instance fg </li></ul><ul><li>WebBrowser -> http://localhost:8080/manage_main </li></ul><ul><li>(using same user / pass provided during ` paster create... ` step above) </li></ul><ul><li>Select 'Plone Site' (Add) </li></ul><ul><li>Id: Plone </li></ul><ul><li>Title: Site </li></ul><ul><li>[Add Plone Site] </li></ul>
    9. 9. Find in the ZMI <ul><li>Before we interact directly with the ZODB, try the [Find] tab in the ZMI first: http://localhost:8080/manage_findForm </li></ul><ul><ul><li>It is case sensitive </li></ul></ul><ul><ul><li>No wildcards available </li></ul></ul><ul><ul><li>Scope is controlled by location </li></ul></ul><ul><li>But it's still very fast and useful! A great place to start. </li></ul>
    10. 10. Direct Access to the ZODB <ul><li>ZODB represents persisted objects, not tabled relational data. </li></ul><ul><li>To interact with the live objects: > myproject/bin/instance debug </li></ul><ul><li>Enable readline for tab completion (very helpful for discovery): >>> import readline, rlcompleter >>> readline.parse_and_bind('tab: complete') </li></ul><ul><li>Purely transactional! Commits required: >>> import transaction >>> transaction.commit() </li></ul><ul><li>Mount the ZODB as a read only file system[1] </li></ul><ul><li>Many additional great tips for interacting with the ZODB[2] </li></ul>[1] http://wiki.zope.org/zope2/HowToMountZODBAsVirtualFilesystem [2] http://docs.neuroinf.de/programming-plone/debug#1-6
    11. 11. Browser Tools <ul><li>Web Developer[1] </li></ul><ul><li>Firebug[2] </li></ul><ul><li>Selenium[3] </li></ul><ul><li>Clouseau[4] </li></ul>[1] http://chrispederick.com/work/web-developer/ [2] http://www.getfirebug.com/ [3] http://www.openqa.org/selenium/ [4] http://plone.org/products/clouseau
    12. 12. Exuberant CTAGS[1] <ul><li>Index tables for other tools to use; available for cygwin[2], TextMate[3], and the old standards: vi & emacs. </li></ul><ul><li>Create anywhere, using defaults or selectively feed files of interest (limiting scope makes quicker, increasing scope expands coverage): > ctags -Re A few emacs keybindings for flavor: M-. <tag> Takes you to tag definition M-0 M-. Go to next definition </li></ul><ul><li>For invocations of a tag: M-x tags-search <regex> M-, Go to the next match </li></ul>[1] http://ctags.sourceforge.net/ [2] http://tulrich.com/geekstuff/emacs.html [3] http://gerd.knops.org/?p=7
    13. 13. PDB Entry <ul><li>Simplest way to get to the debugger, add this line in any source file in the execution path: import pdb; pdb.set_trace() </li></ul><ul><li>Re-launch in foreground, and trigger execution: > myproject/bin/instance fg Browse to trigger </li></ul><ul><li>This is not however easy to do within python scripts and page templates[1]. The best solution is to move code into file system packages. This will also allow unit testing! > myproject/bin/instance test -m plone.portlets </li></ul>[1] http://plone.org/documentation/how-to/debug-script-python-with-pdb
    14. 14. PDB Usage <ul><li>The pdb interface is designed to be fast and easy to work with. A complete list of commands is available here[1]. A few important navigation commands: </li></ul><ul><ul><li>n Next - executes the line and moves to the next </li></ul></ul><ul><ul><li>s Step - steps into the execution </li></ul></ul><ul><ul><li>r Return - resume to end of the current function </li></ul></ul><ul><ul><li>c Continue - resume program execution </li></ul></ul><ul><ul><li>w Where - display the call stack </li></ul></ul><ul><ul><li>u Up - move one frame up the call stack </li></ul></ul><ul><ul><li>d Down - move one frame down the call stack </li></ul></ul><ul><ul><li>p expr Print - print expression </li></ul></ul><ul><li>Check out conditional breakpoints! </li></ul>[1] http://docs.python.org/lib/debugger-commands.html
    15. 15. Logging <ul><li>Logging from most anywhere can be quite useful. </li></ul><ul><ul><li>Within Zope Page Templates (ZPT) : <span tal:content='python: context.plone_log(&quot;details to log: %s&quot; % details)' /> </li></ul></ul><ul><ul><li>Within a python script: context.plone_log(&quot;more details: %s&quot; % more_details) </li></ul></ul><ul><ul><li>In any python file on the filesystem: import logging logger = logging.getLogger(&quot;Plone&quot;) logger.info(&quot;Code being executed here...'&quot;) </li></ul></ul><ul><li>The log file for the example buildout is located in myproject/var/log/instance.log </li></ul><ul><li>If running in 'fg' mode, the logged data will also be written to standard out. </li></ul>
    16. 16. IDEs <ul><li>A number of other IDEs (Integraded Development Environments) exist (some free, some commercial) and promise simple integration and debugging: </li></ul><ul><ul><li>Wing IDE Professional[1] </li></ul></ul><ul><ul><li>Eclipse with Pydev[2] </li></ul></ul><ul><ul><li>PIDA[3] </li></ul></ul><ul><ul><li>BoaConstructor[4] </li></ul></ul><ul><ul><li>Komodo[4] </li></ul></ul>[1] http://wingware.com/doc/howtos/zope [2] http://pydev.sourceforge.net/ [3] http://plone.org/documentation/tutorial/ debugging-plone-products-with-pida/debugging-with-pida [4] http://boa-constructor.sourceforge.net/ [5] http://www.activestate.com/Products/komodo_ide/
    17. 17. Conclusion <ul><li>This isn’t a replacement for the ever improving available documentation[1]. </li></ul><ul><li>Consider file system development (and don’t cheat the tests!) </li></ul><ul><li>Take advantage of the many great tools out there. </li></ul><ul><li>Thanks to the open source community! </li></ul>[1] http://plone.org/documentation/how-to/read-documentation