Daniel Nouri's Blog

Sat, 03 Jun 2006

Skeleton for Plone Core packages in ZopeSkel

Thanks to Hanno, ZopeSkel now has a template for starting Plone Core packages. Hanno is using ZopeSkel for the new plone.i18n package.

Get ZopeSkel

ZopeSkel has moved to the Collective. Get the latest and greatest of ZopeSkel via this command:

easy_install http://svn.plone.org/svn/collective/ZopeSkel/trunk#egg=ZopeSkel-dev

Create a package

Remember from last time that Paste Script is useful for creating a consistent directory structure and files for you so that you can get to the actual work quickly. Plus, your projects will be ready for distribution without any additional work.

Now let's say we want to start a plone.form package. What we need to do is invoke paster create, telling it that we want to use the plone_core template. This is done using the -t command-line option. After invoking the command, we're asked for some variables:

$ paster create -t plone_core
Selected and implied templates:
  ZopeSkel#plone_core  A Plone Core project

Enter project name: plone.form
Variables:
  package:  ploneform
  project:  plone.form
Creating template plone_core
Enter namespace_package (Namespace package) ['plone']:
Enter package (The package contained namespace package (like i18n)) ['']: form
Enter version (Version) ['0.1']:
Enter description (One-line description of the package) ['']: Plone compatibility layer for zope.app.schema and zope.formlib
Enter long_description (Multi-line description (in reST)) ['']:
Enter author (Author name) ['Plone Foundation']:
Enter author_email (Author email) ['plone-developers@NOSPAMlists.sourceforge.net']:
Enter keywords (Space-separated keywords/tags) ['']:
Enter url (URL of homepage) ['']:
Enter license_name (License name) ['GPL']:
Enter zip_safe (True/False: if the package can be distributed as a .zip file) [False]:
Creating directory ./plone.form
  Recursing into +namespace_package+
    Creating ./plone.form/plone/
    Recursing into +package+
      Creating ./plone.form/plone/form/
      Copying HISTORY.txt_tmpl to ./plone.form/plone/form/HISTORY.txt
      Copying LICENSE.GPL to ./plone.form/plone/form/LICENSE.GPL
      Copying LICENSE.txt_tmpl to ./plone.form/plone/form/LICENSE.txt
      Copying README.txt_tmpl to ./plone.form/plone/form/README.txt
      Copying __init__.py to ./plone.form/plone/form/__init__.py
      Copying configure.zcml to ./plone.form/plone/form/configure.zcml
      Copying version.txt_tmpl to ./plone.form/plone/form/version.txt
    Copying __init__.py to ./plone.form/plone/__init__.py
  Copying setup.cfg to ./plone.form/setup.cfg
  Copying setup.py_tmpl to ./plone.form/setup.py
Running /usr/bin/python setup.py egg_info

Note that we typed in values for the project, package and descriptions variables only. For the rest we decided that the default was good enough. We're ready to start working on plone.form now.

Non- Plone Core packages

There's no reason why we wouldn't use the plone_core template for our own packages. After all, the name of the namespace package and that of the contained package are variables, and the directory structure might well be useful for your own project.

Updating a ZopeSkel package

Whenever the plone_core template changes, we can simply rerun the paster create command to update our project:

$ paster create -t plone_core
Selected and implied templates:
  ZopeSkel#plone_core  A Plone Core project

Enter project name: plone.form
Variables:
  package:  ploneform
  project:  plone.form
Creating template plone_core
Enter namespace_package (Namespace package) ['plone']:
Enter package (The package contained namespace package (like i18n)) ['']: form

[...]

  Recursing into +namespace_package+
    Recursing into +package+
      ./plone.form/plone/form/HISTORY.txt already exists (same content)
      ./plone.form/plone/form/LICENSE.GPL already exists (same content)
      ./plone.form/plone/form/LICENSE.txt already exists (same content)
      ./plone.form/plone/form/README.txt already exists (same content)
      ./plone.form/plone/form/__init__.py already exists (same content)
      ./plone.form/plone/form/configure.zcml already exists (same content)
      ./plone.form/plone/form/version.txt already exists (same content)
    ./plone.form/plone/__init__.py already exists (same content)
  ./plone.form/setup.cfg already exists (same content)
  ./plone.form/setup.py already exists (same content)
Running /usr/bin/python setup.py egg_info

If something had changed, we would have been presented a diff of our version of the file and the new version inside the template.

An inconvenience here is that when running paster create, we're asked for all variables again. Fortunately, there's the --config=CONFIG option that'll store all our variables in a file. Both for initial creation and for updating, our command becomes:

$ paster create -t plone_core --config=plone.form/template_vars.cfg

Extending ZopeSkel

Extending the plone_core package to fit our own needs is really easy. Let's say we want to create a new template called my_package that's based on plone_core. We want our new template to use what's already there in plone_core and add a browser package in there with __init__.py and configure.zcml files.

Inside our SVN checkout of ZopeSkel, we create this directory:

$ mkdir -p zopeskel/templates/my_package/+namespace_package+/+package+/browser

Then we add our two files:

$ edit zopeskel/templates/my_package/+namespace_package+/+package+/browser/__init__.py_tmpl
$ edit zopeskel/templates/my_package/+namespace_package+/+package+/browser/configure.zcml

Note that we create an __init__.py_tmpl file, with the _tmpl suffix because setuptools would currently not include our .py file in the distribution if the file ended with .py. So although our __init__.py_tmpl file isn't necessarily a template (nothing is substituted), we make it a Paste Script template so that it gets picked up by setuptools.

The next thing we do is wire up the my_package template so that it's available from the command-line. Inside zopeskel/__init__.py we add this:

class MyPackage(PloneCore):
    _template_dir = 'templates/my_package'
    summary = 'A Plone package that has a browser subpackage'
    required_templates = ['plone_core']

Finally, we define an entry point for our template in setup.py:

[...]

entry_points="""
[paste.paster_create_template]
basic_zope = zopeskel:BasicZope
plone_core = zopeskel:PloneCore
my_package = zopeskel:MyPackage
""",

[...]

Note that we only added the my_package entry point here.

After calling setup.py develop we're ready to create a new project with our own template:

$ python setup.py develop
[...]
$ paster create --list-templates
Available templates:
  basic_package:  A basic setuptools-enabled package
  basic_zope:     A Zope project
  my_package:     A Plone package that has a browser subpackage
  paste_deploy:   A web application deployed through paste.deploy
  plone_core:     A Plone Core project

Easy as pie!

posted at: 15:30 | 3 comments | category: /devel/zope rss | permanent link | add to del.icio.us or digg it


< June 2006 >
SuMoTuWeThFrSa
     1 2 3
4 5 6 7 8 910
11121314151617
18192021222324
252627282930 

Feed of all categories: rss rss | atom

Categories: