Local commands:
==============

PasteScript supports the notion of local commands. These are commands
that can be executed from within a project. See the ``localcommands``
directory in ZopeSkel for more information.


Plone
-----

Check that the `addcontent` command is not globaly available::

    >>> help_text = read_sh('paster help')
    >>> help_text.find('addcontent') == -1
    True

`addcontent` is active for all ZopeSkel templates that have ``use_local_commands``
attribute set to true.

Let's for example take the plone template::

    >>> paster('create -t plone plone.example --no-interactive')
    paster create -t plone plone.example --no-interactive
    ...
    >>> cd('plone.example')
    >>> paster('help')
    paster help
    ...
    <BLANKLINE>
    ZopeSkel local commands:
      addcontent   Adds plone content types to your project
    <BLANKLINE>
    <BLANKLINE>
    
What sub-templates are available for a plone based project ?::

    >>> paster('addcontent --list')
    paster addcontent --list
    Available templates:
        browserlayer:  A Plone browserlayer
        form:          A form skeleton
        formfield:     Schema field for a form
        i18nlocale:    An i18n locale directory structure
        portlet:       A Plone 3 portlet
        view:          A browser view skeleton
        zcmlmeta:      A ZCML meta directive skeleton
    

Now we can add a portlet to our project::

    >>> paster('addcontent --no-interactive portlet')
    paster addcontent --no-interactive portlet
    Inserting from __init__.py_insert into ...
    Inserting from configure.zcml_insert into ...
    Recursing into portlets
    ...

Test if we have the new files::

    >>> ls('plone', 'example', 'portlets')
    __init__.py
    configure.zcml
    exampleportlet.pt
    exampleportlet.py
    >>> ls('plone', 'example', 'tests')
    __init__.py
    base_exampleportlet.py
    test_exampleportlet.py

Check that the existing files like profile/portlets are updated::

    >>> cat('plone', 'example', 'profiles', 'default', 'portlets.xml')
    <?xml version="1.0"?>
    ...
       <portlet
         addview="plone.example.portlets.ExamplePortlet"
         title="Example portlet"
         description=""
         i18n:attributes="title; description"
       />
    ...
    
Adding a portlet via localcommand should update __init__.py to include 
MessageFactory as well as defining a message factory for this project:

    >>> cat('plone', 'example', '__init__.py')
      # -*- extra stuff goes here -*- 
    from zope.i18nmessageid import MessageFactory
    <BLANKLINE>
    exampleMessageFactory = MessageFactory('plone.example')
    ...
    
The portlet localcommand should also update the root-level configure.zcml to insert an include package directive.  Make sure it has:

    >>> cat('plone', 'example', 'configure.zcml')
    <configure
    ...
    <BLANKLINE>
      <include package=".portlets" />
    <BLANKLINE>
    ...


Now add a new i18n locales directory structure to the project::

    >>> paster('addcontent --no-interactive i18nlocale')
    paster addcontent --no-interactive i18nlocale
    Inserting from configure.zcml_insert into ...
    Recursing into locales
    ...

Test if we have the new files::

    >>> ls('plone', 'example', 'locales')
    nl
    
The i18nlocale localcommand should also update the root-level configure.zcml to register the locales directory translations.  Make sure it has:

    >>> cat('plone', 'example', 'configure.zcml')
    <configure
    ...
    <BLANKLINE>
      <i18n:registerTranslations directory="locales" />
    <BLANKLINE>
    ...

Let's try to add a form to our project::

    >>> paster('addcontent --no-interactive form')
    paster addcontent --no-interactive form
    Inserting from __init__.py_insert into ...
    ...
    Recursing into browser
    ...

Test if we have the new files::

    >>> ls('plone', 'example', 'browser')
    __init__.py
    configure.zcml
    exampleform.py
    
The form localcommand should also update the root-level configure.zcml to insert an include package directive.  Make sure it has:

    >>> cat('plone', 'example', 'configure.zcml')
    <configure
    ...
    <BLANKLINE>
      <include package=".browser" />
    <BLANKLINE>
    ...


Let's try to add a browserlayer to our project::
    >>> paster('addcontent --no-interactive browserlayer')
    paster addcontent --no-interactive browserlayer
    A BrowserLayer is generally used in packages to be installed in a Plone Site.
    If you didn't choose Register Profile option when creating this package
    you should probably add a <genericsetup:registerProfile /> directive in
    the main configure.zcml.
    <BLANKLINE>
      Recursing into browser 
      ...
        Inserting from configure.zcml_insert into ...
      Recursing into interfaces
      ...
      Recursing into profiles
        Recursing into default
      ...

Test if we have the new files::
    >> ls('plone', 'example', 'browser')
    __init__.py
    configure.zcml

    >> ls('plone', 'example', 'interfaces')
    __init__.py
    ploneexample.py

Check that the existing files like profile/browserlayer are updated::
    >>> cat('plone', 'example', 'profiles', 'default', 'browserlayer.xml')
    <?xml version="1.0"?>
    ...
        <layer name="PloneExample"
            interface="plone.example.interfaces.ploneexamplelayer.IPloneExampleLayer" />
    ...

    >>> cat('plone', 'example', 'browser', 'configure.zcml')
    <configure
    ...
      <include package="plone.browserlayer" />
    ...

    >> cat('plone', 'example', 'interfaces', 'packagenamelayer.py')
    ...
    class IPloneExampleLayer(Interface):
    ...

Go back to the top level directory to have a more or less clean slate
for the following tests.
    >>> cd('..')

Archetype
---------

An archetype based project has other localcommands available::

    >>> paster('create -t archetype archetype.example --no-interactive')
    paster create -t archetype archetype.example --no-interactive
    ...
    >>> cd('archetype.example')
    >>> paster('help')
    paster help
    ...
    <BLANKLINE>
    ZopeSkel local commands:
      addcontent   Adds plone content types to your project
    <BLANKLINE>
    <BLANKLINE>

What sub-templates are available for an archetype based project ?::

    >>> paster('addcontent --list')
    paster addcontent --list
    Available templates:
        atschema:      A handy AT schema builder
        browserlayer:  A Plone browserlayer
        contenttype:   A content type skeleton
        form:          A form skeleton
        formfield:     Schema field for a form
        i18nlocale:    An i18n locale directory structure
        portlet:       A Plone 3 portlet
        view:          A browser view skeleton
        zcmlmeta:      A ZCML meta directive skeleton
