Skip to content. | Skip to navigation

Notes on Rolling Your Own Product

Case 1.

Case 2.

Solution.

 

Case 1. You have a perfectly lovely site, but you want to make a policy change.

Example A. Adding a Group Action

We expect our clients will want to upload large batches of files, like images into an album.  The conventional approach is to upload one at a time.  But what if you want multi-file upload? There are some nifty ways to do this with some fancy javascript.  There is an add-on product for Plone (collective.uploadify) which utilizes Uploadify.  But the product doesn't come with the interface wired into the Plone theme.

See semetricmedia.uploadifyaction

To add this group action, it is necessary to modify "actions.xml". But where is "profiles/default/actions.xml"? What does this mean? The instructions go on to describe how you make the same configuration change through-the-web (TTW) using the Zope Management Interface (ZMI), but that's not what we are interested in, expedient though it may be.

Aspelli's oft-cited Professional Plone Development is a good resource.  There are several other Plone books.  But none seem to narrowly describe this case.

 

CASE 2. You have a perfectly lovely site, but you want to add a view to the display menu for collections.

Maybe you want to redesign the search results you get from a collection. Plone comes with several stock views, but maybe you need to create a new one from scratch or based on a stock view.

Similar to the case above, you can do this by making TTW modifications in the ZMI.  But this doesn't scale well if you want to repeat the modifications to multiple sites, store the changes in source code management, or bundle it for distribution.

Solution

Paster

Paster gets you halfway there in two different ways.

Paster (aka Paste Script) is a utility for creating product skeletons. It will typically ask a series of configuration questions and spit out the directories and essential configuration files or a Zope/Plone product.

from Practical Plone Development, page 358

 

To make creating this boilerplate easier, you can use ZopeSkel, a set of PasteScript templates for the paster command that generates common Plone boilerplate.

Plone 3.2+ installations give you ZopeSkel and paster by default. To install ZopeSkel in the older versions of 3.x, you first need to have easy_install installed on your system. If you don't have it already, download and then run ez_setup.py, for example:

$ wget peak.telecommunity.com/dist/ez_setup.py
$ python ez_setup.py

(where "python" is the version of you are using

with Plone, e.g. python2.4)

Then, to install the ZopeSkel egg and its dependencies (including PasteScript), run:

$ easy_install -U ZopeSkel

This will install the paster command in the place where your Python binaries go. Keep an eye on the output of easy_install, in case you can't find it afterwards. If it's not in your $PATH, you may want to symlink it in there.

For now, create a filesystem product using one of the standard paster recipes

such as:

$ paster create -t plone
$ paster create -t plone_app

or

$ paster create -t plone3_theme

There are a number of other recipes available. To see the available options, you

can run:

$ paster create --list-templates

 

In our experience, the "Plone" template for Paster is adequate if your requirements are strictly limited to making policy changes via GenericSetup.  On the other extreme, the "Plone3_theme" solution is a good starting point if you are making a complete theme which is based on the Plone Default theme but then includes style sheet, image and javascript replacements.

We have found that a better place to start for anything less than a complete Theme is  the "Plone3_theme" template and then strip out some of the items rather than trying to manually add boilerplate ZCML and XML to the "Plone" template.

Here are the steps we use:

In the zinstance/src/ directory, run paster as follows

$ paster create -t plone3_theme

You can accept the default options for each question with the following exceptions

Enter namespace_package (Namespace package (like plonetheme)) ['plonetheme']: mycompany

Enter package (The package contained namespace package (like example)) ['example']: myproduct

Enter skinname (The skin selection to be added to 'portal_skins' (like 'My Theme')) ['']: Example Product

Enter description (One-line description of the package) ['An installable theme for Plone 3']: A product based on plone3_theme. 

 

A full transcript of the paster run.

 

Resulting Directory Structure

Picture 312.jpg

Modify the Product

Custom configuration starts with src/mycompany.myproduct/mycompany/myproduct/configure.zcml. This file includes several other ZCML files. Together they begin the process of registering resources with Zope.

At the top of configure.zcml, several namespaces are declared. I like to expand this so that all the namespaces we might need are available.

replace

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:five="http://namespaces.zope.org/five"
    xmlns:cmf="http://namespaces.zope.org/cmf"
    i18n_domain="mycompany.myproduct">

 

with

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:five="http://namespaces.zope.org/five"
    xmlns:cmf="http://namespaces.zope.org/cmf"
    xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
    xmlns:browser="http://namespaces.zope.org/browser"

    i18n_domain="mycompany.myproduct">

 

As is, the product is a Theme and will register itself with the portal_skins tool as a theme.  In this article, we are trying to augment the existing themes.  This means adding the skin layers right after the "custom" layer in all of the existing themes.

To do this, we need to modify as follows

in src/mycompany.myproduct/myproduct/mycompany/myproduct/profiles/default/skins.xml

replace

<object name="portal_skins" allow_any="False" cookie_persistence="False"
   default_skin="Example SkinName">

with

<object name="portal_skins">

AND

replace

 <skin-path name="Example SkinName" based-on="Plone Default">

with

 <skin-path name="*">

Rename or Delete Files

The ZopeSkel template for plone3_theme assumes you will override the standard Plone Default styles.  Let's not do that here, so rename or delete the following files so they are not found through acquisition.

within src/mycompany.myproduct/myproduct/mycompany/myproduct/

browser/stylesheets/main.css

skins/mycompany_myproduct_styles/base_properties.props

skins/mycompany_myproduct_styles//base.css.dtml

skins/mycompany_myproduct_styles/portlets.css.dtml

skins/mycompany_myproduct_styles/public.css.dtml

We also do not want to register main.css at this time, so modify cssregistry.xml and comment out the stylesheet registration.

 

Buildout.cfg

No that the directory structure and boilerplate is in place, modify the buildout.cfg file to include the new product in your Plone instance. Modify as follows:

eggs =
...
    mycompany.myproduct
zcml =
...
    mycompany.myproduct
develop =
...
    src/mycompany.myproduct

Re-run buildout on offline mode, it's faster and we haven't added any new dependencies that require downloading any packages.

./bin/buildout -o

 

Load the Product

Start Plone and load the product through portal_quickinstaller or the Plone Site Setup web interface. It will be named "Example Product" as specified in the paster answer to the question [].

Three new layers are now defined in the portal_skins tool. These are Filesystem Directory views.  Each corresponds to a directory in src/mycompany.myproduct/mycompany/myproduct/skins/

mycompany_myproduct_custom_images

mycompany_myproduct_custom_templates

mycompany_myproduct_custom_styles

Files in these folders can only be modified in the filesystem. Any modifications made through the web result in bew entries in the custom layer.

The properties tab of the portal_skins tool shows these three layers added to the existing themes.  They have been placed immediately after "custom" which puts them very high in precedence for acquisition.

 

Additional Modifications to Meet our Requirements

 Note: Changes to the product will always require stopping Plone, re-running buildout, and restarting Plone. Depending on the type of change, you may need to uninstall and reinstall the product so that GenericSetup process any new profile modifications.

 

Adding a Group Action for Uploadify

This is now as simple as creating a file and inserting the XML supplied by the collective.uploadify homepage.

file name and location: src/mycompany.myproduct/mycomapny/myproduct/profiles/default/actions.xml

 

Adding a Template for a new View

 

Create the template file using the Plone templating language. Place the file in src/mycompany.myproduct/mycompany/myproduct/skins/mycompany_myproduct_custom_templates

 

Register the View with a Content Type

 

This requires a GenericSetup profile change similar to creating the Group Action for Uploadify. See more at Using the Portal Setup tool to reverse Engineer a profile change.

Document Actions