Latest Version: 0.9.6.2
  Dashboard > Pylons Cookbook > ... > Extending Pylons > Creating Templates For The paster create Command
  Pylons Cookbook Log In | Sign Up   View a printable version of the current page.  
  Creating Templates For The paster create Command
Added by James Gardner, last edited by Junya HAYASHI on Dec 08, 2007  (view change)
Labels: 

Name Space Page Section Version Status Reviewed Author(s)
Creating Templates For The paster create Command Pylons CookBook Creating Templates For The paster create Command Home 1.0 Draft False James Gardner

Introduction

Paste is an extremely powerful package that isn't just about WSGI middleware. A few weeks ago I demonstrated how to use entry_points to create simple plugins. In this article I'm going to show you how to write just such a plugin for use Paste's project template creation facility and how to add a command to Paste's paster script.

We are going to create a template for an imaginary content management system. The template we create is going to produce a project directory structure for a Python package so we need to be able to specify a package name.

Creating The Directory Structure and Templates

The directory structure for the new project needs to look like this:

- default_project
        - +package+
            - __init__.py
            - static
                - layout
                - region
                - renderer
            - service
                - layout
                    - __init__.py
                - region
                    - __init__.py
                - renderer
                    - __init__.py
        - setup.py_tmpl
        - setup.cfg_tmpl
        - development.ini_tmpl
        - README.txt_tmpl
        - ez_setup.py

Of course, your project's directory structure might look very different. In fact the paster create command can even be used to generate directory structures which aren't project templates although this wasn't what it was designed for.

When the paster create command is run, any directories with +package+ in their name will have that portion replaced by a simplified package name and likewise any directories with +egg+ in their name will have that portion replaced by the name of the egg directory, although we don't make use of that feature in this example.

All of the files with _tmpl at the end of their filenames are treated as templates and will have the variables they contain replaced automatically. All other files will remain unchanged.

The small templating language which can be used with paster create in files ending in _tmpl is defined at http://pythonpaste.org/module-paste.util.template.html

When your users specify a package name it can include capitalisation and _ characters but bear in mind the actual name of the package will be the lowercase package name with the _ characters removed. If the package name contains an _ the egg name will contain a _ character so occasionally the +egg+ name is different to the +package+ name.

To save yourself difficulty you should always recommend to your users that they stick with package names that contain no _ character and are still unique when made lowercase.

Implementing the Code

Now that we have defined our directory structure we need to implement the commands that will convert this to a ready-to-run project. The template creation commands are implemented by a class derived from paste.script.templates.Template. Here's how ours look:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
from paste.script.templates import Template, var

    vars = [
        var('version', 'Version (like 0.1)'),
        var('description', 'One-line description of the package'),
        var('long_description', 'Multi-line description (in reST)'),
        var('keywords', 'Space-separated keywords/tags'),
        var('author', 'Author name'),
        var('author_email', 'Author email'),
        var('url', 'URL of homepage'),
        var('license_name', 'License name'),
        var('zip_safe', 'True/False: if the package can be distributed as a .zip file',
            default=False),
    ]
        
    class ArtProjectTemplate(Template):
        _template_dir = 'templates/default_project'
        summary = 'Art project template'
        vars = vars

The vars arguments can all be set at run time and will be available to be used as Cheetah template variables in the files which end _tmpl. For example our the setup.py_tmpl file for the default_project might looks like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
from setuptools import setup, find_packages

    version = ${repr(version)|"0.0"}

    setup(name=${repr(project)},
        version=version,
        description="${description|nothing}",
        long_description="""\
    ${long_description|nothing}""",
        classifiers=[], # Get strings from http://www.python.org/pypi?%3Aaction=list_classifiers
        keywords=${repr(keywords)|empty},
        author=${repr(author)|empty},
        author_email=${repr(author_email)|empty},
        url=${repr(url)|empty},
        license=${repr(license_name)|empty},
        packages=find_packages(exclude=['ez_setup']),
        include_package_data=True,
        zip_safe=${repr(bool(zip_safe))|False},
        install_requires=[
          # -*- Extra requirements: -*-
        ],
        entry_points="""
            [paste.app_factory]
            main=${package}:make_app
        """,
    )

You can see how the variables specified in vars earlier are used to generate the actual setup.py file.

The final thing we need to do in order to use our new templates is to wire them up to the paster create command by means of an entry point. In the setup.py file of the project in which the project template we have created is going to be stored we need to add the following:

1
2
3
4
entry_points="""
        [paste.paster_create_template]
        art_project=art.entry.template:ArtProjectTemplate
    """,

We also need to add PasteScript>=1.3 to the install_requires line.

install_requires=["PasteScript>=1.3"],

We just need to install the entry points now by running:

python setup.py develop

We should now be able to see a list of available templates with this command:

paster create --list-templates

Windows users will need to add their Python scripts directory to their path or enter the full version of the command, similar to this:

C:\Python24\Scripts\paster.exe create --list-templates

You should see the following:

Available templates:
    art_project:              Art project template
    basic_package:            A basic setuptools-enabled package

There may be other projects too.

Troubleshooting

If the Art entries don't show up you should check that you can import the template.py file we created because any errors are simply ignored by the paster create command rather than printing a warning.

If you are sure your code is correct it might be that the entry points data hasn't been updated. Have a look in your Python site-packages directory and delete and the Art.egg-link files, any Art*.egg files or directories and remove any entries for art from easy_install.pth (replacing Art with whatever the name you chose for your project of course). Then re-run python setup.py develop to install the correct information again.

If you are sill having problems you might want to run this code to print out a list of all entry points. It might help you track the problem down:

1
2
3
import pkg_resources
        for x in pkg_resources.iter_group_name(None, None):
            print x

Using Our Template

Now that our entry point is working we can create a new project:

paster create --template=art TestProject

You will be asked lots of questions based on the variables you setup in vars earlier. If you just push return the default will be used. What you end up with is a nice project template ready for you to start coding with!

Implementing Pylons Templates

If you regularly create lots of Pylons projects with a slightly different setup from the Pylons defaults you might want to consider creating your own Pylons template to generate the projects. You can do this in exactly the way described in this document.

First setup a new Python package, perhaps called something like CustomPylons (you obviously can't use the Pylons name because Pylons itself is already using it). Then checkout the Pylons source code and copy the pylons/templates/default_project directory into your project as a starting point. You will then have to add your custom vars and Template class and setup your entry points in the CustomPylons setup.py file.

After you have finished you should be able to create your own template, based on the Pylons one, using your CustomPylons package.

Site running on a free Atlassian Confluence Open Source Project License granted to Pylons. Evaluate Confluence today.
Powered by Atlassian Confluence, the Enterprise Wiki. (Version: 2.3.3 Build:#645 Feb 13, 2007) - Bug/feature request - Contact Administrators
Top