Commits

Anonymous committed 17be3df

chapter07 final

  • Participants
  • Parent commits c804773

Comments (0)

Files changed (133)

File chapter07/pox.buildout/README.txt

+=======================
+Using a custom buildout
+=======================
+
+Note: If you are using Windows, if you do not have PIL installed, or you are
+not using Python 2.4 as your main system Python, please see the relevant
+sections below.
+
+You probably got here by running something like:
+
+ $ paster create -t plone3_buildout
+
+Now, you need to run:
+
+ $ python bootstrap.py
+
+This will install zc.buildout for you.
+
+To create an instance immediately, run:
+
+ $ bin/buildout
+
+This will download Plone's eggs and products for you, as well as other
+dependencies, create a new Zope 2 installation (unless you specified
+an existing one when you ran "paster create"), and create a new Zope instance
+configured with these products.
+
+You can start your Zope instance by running:
+
+ $ bin/instance start
+
+or, to run in foreground mode:
+
+ $ bin/instance fg
+
+To run unit tests, you can use:
+
+ $ bin/instance test -s my.package
+
+Installing PIL
+--------------
+
+To use Plone, you need PIL, the Python Imaging Library. If you don't already
+have this, download and install it from http://www.pythonware.com/products/pil.
+
+Using a different Python installation
+--------------------------------------
+
+Buildout will use your system Python installation by default. However, Zope
+2.10 (and by extension, Plone) will only work with Python 2.4. You can verify
+which version of Python you have, by running:
+
+ $ python -V
+
+If that is not a 2.4 version, you need to install Python 2.4 from
+http://python.org. If you wish to keep another version as your main system
+Python, edit buildout.cfg and add an 'executable' option to the "[buildout]"
+section, pointing to a python interpreter binary:
+
+ [buildout]
+ ...
+ executable = /path/to/python
+
+Working with buildout.cfg
+-------------------------
+
+You can change any option in buildout.cfg and re-run bin/buildout to reflect
+the changes. This may delete things inside the 'parts' directory, but should
+keep your Data.fs and source files intact.
+
+To save time, you can run buildout in "offline" (-o) and non-updating (-N)
+mode, which will prevent it from downloading things and checking for new
+versions online:
+
+ $ bin/buildout -Nov
+
+Creating new eggs
+-----------------
+
+New packages you are working on (but which are not yet released as eggs and
+uploaded to the Python Package Index, aka PYPI) should be placed in src. You can do:
+
+ $ cd src/
+ $ paster create -t plone my.package
+
+Use "paster create --list-templates" to see all available templates. Answer
+the questions and you will get a new egg. Then tell buildout about your egg
+by editing buildout.cfg and adding your source directory to 'develop':
+
+ [buildout]
+ ...
+ develop =
+    src/my.package
+
+You can list multiple packages here, separated by whitespace or indented
+newlines.
+
+You probably also want the Zope instance to know about the package. Add its
+package name to the list of eggs in the "[instance]" section, or under the
+main "[buildout]" section:
+
+ [instance]
+ ...
+ eggs =
+    ${buildout:eggs}
+    ${plone:eggs}
+    my.package
+
+Leave the ${buildout:eggs} part in place - it tells the instance to use the
+eggs that buildout will have downloaded from the Python Package Index
+previously.
+
+If you also require a ZCML slug for your package, buildout can create one
+automatically. Just add the package to the 'zcml' option:
+
+ [instance]
+ ...
+ zcml =
+    my.package
+
+When you are finished, re-run buildout. Offline, non-updating mode should
+suffice:
+
+ $ bin/buildout -Nov
+
+Developing old-style products
+-----------------------------
+
+If you are developing old-style Zope 2 products (not eggs) then you can do so
+by placing the product code in the top-level 'products' directory. This is
+analogous to the 'Products/' directory inside a normal Zope 2 instance and is
+scanned on start-up for new products.
+
+Depending on a new egg
+----------------------
+
+If you want to use a new egg that is in the Python Package Index, all you need
+to do is to add it to the "eggs" option under the main "[buildout]" section:
+
+ [buildout]
+ ...
+ eggs =
+    my.package
+
+If it's listed somewhere else than the Python Package Index, you can add a link
+telling buildout where to find it in the 'find-links' option:
+
+ [buildout]
+ ...
+ find-links =
+    http://dist.plone.org
+    http://download.zope.org/distribution/
+    http://effbot.org/downloads
+    http://some.host.com/packages
+
+Using existing old-style products
+---------------------------------
+
+If you are using an old-style (non-egg) product, you can either add it as an
+automatically downloaded archive or put it in the top-level "products" folder.
+The former is probably better, because it means you can redistribute your
+buildout.cfg more easily:
+
+ [productdistros]
+ recipe = plone.recipe.distros
+ urls =
+    http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz
+
+If someproduct-1.3.tar.gz extracts into several products inside a top-level
+directory, e.g. SomeProduct-1.3/PartOne and SomeProduct-1.3/PartTwo, then
+add it as a "nested package":
+
+ [productdistros]
+ recipe = plone.recipe.distros
+ urls =
+    http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz
+ nested-packages =
+    someproduct-1.3.tar.gz
+
+Alternatively, if it extracts to a directory which contains the version
+number, add it as a "version suffix package":
+
+ [productdistros]
+ recipe = plone.recipe.distros
+ urls =
+    http://plone.org/products/someproduct/releases/1.3/someproduct-1.3.tar.gz
+ version-suffix-packages =
+    someproduct-1.3.tar.gz
+
+You can also track products by adding a new bundle checkout part. It
+doesn't strictly have to be an svn bundle at all, any svn location will do,
+and cvs is also supported:
+
+ [buildout]
+ ...
+ parts =
+    plone
+    zope2
+    productdistros
+    myproduct
+    instance
+    zopepy
+
+Note that "myproduct" comes before the "instance" part. You then
+need to add a new section to buildout.cfg:
+
+ [myproduct]
+ recipe = plone.recipe.bundlecheckout
+ url = http://svn.plone.org/svn/collective/myproduct/trunk
+
+Finally, you need to tell Zope to find this new checkout and add it to its
+list of directories that are scanned for products:
+
+ [instance]
+ ...
+ products =
+    ${buildout:directory}/products
+    ${productdistros:location}
+    ${plonebundle:location}
+    ${myproduct:location}
+
+Without this last step, the "myproduct" part is simply managing an svn
+checkout and could potentially be used for something else instead.
+
+=============
+Using Windows
+=============
+
+To use buildout on Windows, you will need to install a few dependencies which
+other platforms manage on their own.
+
+Here are the steps you need to follow (thanks to Hanno Schlichting for these):
+
+Python (http://python.org)
+--------------------------
+
+  - Download and install Python 2.4.4 using the Windows installer from
+    http://www.python.org/ftp/python/2.4.4/python-2.4.4.msi
+    Select 'Install for all users' and it will put Python into the
+    "C:\Python24" folder by default.
+
+  - You also want the pywin32 extensions available from
+    http://downloads.sourceforge.net/pywin32/pywin32-210.win32-py2.4.exe?modtime=1159009237&big_mirror=0
+
+  - And as a last step you want to download the Python imaging library available
+    from http://effbot.org/downloads/PIL-1.1.6.win32-py2.4.exe
+
+  - If you develop Zope based applications you will usually only need Python 2.4
+    at the moment, so it's easiest to put the Python binary on the systems PATH,
+    so you don't need to specify its location manually each time you call it.
+
+    Thus, put "C:\Python24" and "C:\Python24\Scripts" onto the PATH. You can
+    find the PATH definition in the control panel under system preferences on
+    the advanced tab at the bottom. The button is called environment variables.
+    You want to add it at the end of the already existing PATH in the system
+    section. Paths are separated by a semicolons.
+
+  - You can test if this was successful by opening a new shell (cmd) and type
+    in 'python -V'. It should report version 2.4.4 (or whichever version you
+    installed).
+
+    Opening a new shell can be done quickly by using the key combination
+    'Windows-r' or if you are using Parallels on a Mac 'Apple-r'. Type in 'cmd'
+    into the popup box that opens up and hit enter.
+
+
+Subversion (http://subversion.tigris.org)
+-----------------------------------------
+
+  - Download the nice installer from
+    http://subversion.tigris.org/files/documents/15/35379/svn-1.4.2-setup.exe
+
+  - Run the installer. It defaults to installing into
+    "C:\Program Files\Subversion".
+
+  - Now put the install locations bin subfolder (for example
+    "C:\Program Files\Subversion\bin") on your system PATH in the same way you
+    put Python on it.
+
+  - Open a new shell again and type in: 'svn --version' it should report
+    version 1.4.2 or newer.
+
+
+MinGW (http://www.mingw.org/)
+-----------------------------
+
+  This is a native port of the gcc compiler and its dependencies for Windows.
+  There are other approaches enabling you to compile Python C extensions on
+  Windows including Cygwin and using the official Microsoft C compiler, but this
+  is a lightweight approach that uses only freely available tools. As
+  it's used by a lot of people chances are high it will work for you and there's
+  plenty of documentation out there to help you in troubleshooting problems.
+
+  - Download the MinGW installer from
+    http://downloads.sourceforge.net/mingw/MinGW-5.1.3.exe?modtime=1168794334&big_mirror=1
+
+  - The installer will ask you which options you would like to install. Choose
+    base and make here. It will install into "C:\MinGW" by default. The install
+    might take some time as it's getting files from sourceforge.net and you
+    might need to hit 'retry' a couple of times.
+
+  - Now put the install location's bin subfolder (for example "C:\MinGW\bin") on
+    your system PATH in the same way you put Python on it.
+
+  - Test this again by typing in: 'gcc --version' on a newly opened shell and
+    it should report version 3.4.2 or newer.
+
+
+Configure Distutils to use MinGW
+--------------------------------
+
+  Some general information are available from
+  http://www.mingw.org/MinGWiki/index.php/Python%20extensions for example but
+  you don't need to read them all.
+
+  - Create a file called 'distutils.cfg' in "C:\Python24\Lib\distutils". Open it
+    with a text editor ('notepad distutils.cfg') and fill in the following lines:
+
+    [build]
+    compiler=mingw32
+
+    This will tell distutils to use MinGW as the default compiler, so you don't
+    need to specify it manually using "--compiler=mingw32" while calling a
+    package's setup.py with a command that involves building C extensions. This
+    is extremely useful if the build command is written down in a buildout
+    recipe where you cannot change the options without hacking the recipe
+    itself. The z2c.recipe.zope2install used in ploneout is one such example.

File chapter07/pox.buildout/bootstrap.py

+##############################################################################
+#
+# Copyright (c) 2006 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Bootstrap a buildout-based project
+
+Simply run this script in a directory containing a buildout.cfg.
+The script accepts buildout command-line options, so you can
+use the -c option to specify an alternate configuration file.
+
+$Id: bootstrap.py 85041 2008-03-31 15:57:30Z andreasjung $
+"""
+
+import os, shutil, sys, tempfile, urllib2
+
+tmpeggs = tempfile.mkdtemp()
+
+try:
+    import pkg_resources
+except ImportError:
+    ez = {}
+    exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py'
+                         ).read() in ez
+    ez['use_setuptools'](to_dir=tmpeggs, download_delay=0)
+
+    import pkg_resources
+
+if sys.platform == 'win32':
+    def quote(c):
+        if ' ' in c:
+            return '"%s"' % c # work around spawn lamosity on windows
+        else:
+            return c
+else:
+    def quote (c):
+        return c
+
+cmd = 'from setuptools.command.easy_install import main; main()'
+ws  = pkg_resources.working_set
+assert os.spawnle(
+    os.P_WAIT, sys.executable, quote (sys.executable),
+    '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout',
+    dict(os.environ,
+         PYTHONPATH=
+         ws.find(pkg_resources.Requirement.parse('setuptools')).location
+         ),
+    ) == 0
+
+ws.add_entry(tmpeggs)
+ws.require('zc.buildout')
+import zc.buildout.buildout
+zc.buildout.buildout.main(sys.argv[1:] + ['bootstrap'])
+shutil.rmtree(tmpeggs)

File chapter07/pox.buildout/buildout.cfg

+[buildout]
+parts =
+    zope2
+    productdistros
+    instance
+    zopepy
+    ipzope
+    seleniumenv
+    omelette
+
+unzip = true
+# Change the number here to change the version of Plone being used
+extends = 
+    http://dist.plone.org/release/3.3.5/versions.cfg
+    http://good-py.appspot.com/release/dexterity/1.0a2
+    versions.cfg
+versions = versions
+
+# Add additional egg download sources here. dist.plone.org contains archives
+# of Plone packages.
+index = http://plone.intranet.rcom.com.ar/pypi/
+find-links =
+    http://dist.plone.org/release/3.3.5
+    http://download.zope.org/ppix/
+    http://download.zope.org/distribution/
+    http://effbot.org/downloads
+
+# Add additional eggs here
+eggs =
+    PILwoTk
+    Products.DocFinderTab
+    Products.Clouseau
+    plone.reload
+    zope.testrecorder
+    pox.policy
+    pox.banner
+    pox.video
+    Products.poxContentTypes
+
+# Reference any eggs you are developing here, one per line
+# e.g.: develop = src/my.package
+develop =
+    src/pox.policy
+    src/pox.banner
+    src/pox.video
+    src/Products.poxContentTypes
+
+[zope2]
+# For more information on this step and configuration options see:
+# http://pypi.python.org/pypi/plone.recipe.zope2install
+recipe = plone.recipe.zope2install
+fake-zope-eggs = true
+skip-fake-eggs =
+    zope.i18n
+    docutils
+additional-fake-eggs = 
+    ZODB3
+    Testing
+url = ${versions:zope2-url}
+
+# Use this section to download additional old-style products.
+# List any number of URLs for product tarballs under URLs (separate
+# with whitespace, or break over several lines, with subsequent lines
+# indented). If any archives contain several products inside a top-level
+# directory, list the archive file name (i.e. the last part of the URL,
+# normally with a .tar.gz suffix or similar) under 'nested-packages'.
+# If any archives extract to a product directory with a version suffix, list
+# the archive name under 'version-suffix-packages'.
+[productdistros]
+# For more information on this step and configuration options see:
+# http://pypi.python.org/pypi/plone.recipe.distros
+recipe = plone.recipe.distros
+urls =
+nested-packages =
+version-suffix-packages =
+
+[instance]
+# For more information on this step and configuration options see:
+# http://pypi.python.org/pypi/plone.recipe.zope2instance
+recipe = plone.recipe.zope2instance
+zope2-location = ${zope2:location}
+user = admin:admin
+http-address = 8080
+debug-mode = on
+verbose-security = on
+
+# If you want Zope to know about any additional eggs, list them here.
+# This should include any development eggs you listed in develop-eggs above,
+# e.g. eggs = Plone my.package
+eggs =
+    Plone
+    ${buildout:eggs}
+
+# If you want to register ZCML slugs for any packages, list them here.
+# e.g. zcml = my.package my.other.package
+zcml =
+    five.grok
+    zope.testrecorder
+    pox.video
+
+products =
+    ${buildout:directory}/products
+    ${productdistros:location}
+
+[zopepy]
+# For more information on this step and configuration options see:
+# http://pypi.python.org/pypi/zc.recipe.egg
+recipe = zc.recipe.egg
+eggs = ${instance:eggs}
+interpreter = zopepy
+extra-paths = ${zope2:location}/lib/python
+scripts = zopepy
+
+[plonesite]
+recipe = collective.recipe.plonesite
+site-id = plone
+instance = instance
+products =
+    Clouseau
+
+[ipzope]
+# a IPython Shell for interactive use with zope running. you also need to put
+# https://svn.plone.org/svn/collective/dotipython/trunk/ipy_profile_zope.py
+# to your $HOME/.ipython directory for the following to work.
+recipe = zc.recipe.egg:scripts
+eggs =
+    ipython
+    ${instance:eggs}
+initialization =
+    import sys, os
+    os.environ["SOFTWARE_HOME"] = "${zope2:location}/lib/python"
+    os.environ["INSTANCE_HOME"] = "${instance:location}"
+    sys.argv[1:1] = "-p zope".split()
+entry-points = ipython=IPython.ipapi:launch_new_instance
+extra-paths = ${zope2:location}/lib/python
+scripts = ipython=ipzope
+
+[seleniumenv]
+recipe = rcom.recipe.seleniumenv
+seleniumversion = 1.0.1
+eggs = ${instance:eggs}
+
+[omelette]
+recipe = collective.recipe.omelette
+eggs = 
+    ${instance:eggs}
+products =
+    ${instance:products}
+packages = 
+    ${zope2:location}/lib/python ./
+

File chapter07/pox.buildout/coreloadtests.cfg

+[buildout]
+extends = 
+    funkload.cfg
+parts +=
+    coreloadtests_site
+eggs +=
+    collective.coreloadtests
+
+auto-checkout +=
+    collective.coreloadtests
+
+[sources]
+collective.coreloadtests = svn https://svn.plone.org/svn/collective/collective.coreloadtests/trunk
+
+[collective.funkload]
+eggs += collective.coreloadtests
+
+[fl-run-bench]
+eggs += collective.coreloadtests
+
+[coreloadtests_site]
+recipe = collective.recipe.plonesite >= 0.6
+site-id = coreloadtests
+site-replace = True

File chapter07/pox.buildout/etc/monitor.conf

+# default configuration file for the monitor server
+# note that %(FLOAD_HOME)s is accessible
+#
+# $Id: credential.conf 22780 2005-06-06 09:43:52Z bdelbosc $
+
+# ------------------------------------------------------------
+[server]
+# configuration used by monitord
+host = localhost
+port = 8008
+
+# sleeptime between monitoring in second
+# note that load average is updated by the system only every 5s
+interval = .5
+
+# network interface to monitor lo, eth0
+interface = lo
+
+# ------------------------------------------------------------
+[client]
+# configuration used by monitorctl
+host = localhost
+port = 8008

File chapter07/pox.buildout/funkload.cfg

+[buildout]
+extends = 
+    buildout.cfg
+
+parts +=
+    tcpwatch-source
+    tcpwatch-install
+    funkload
+    fl-tests
+    site-pox.banner.tests
+        
+[tcpwatch-source]
+recipe = hexagonit.recipe.download
+url = http://hathawaymix.org/Software/TCPWatch/tcpwatch-1.3.tar.gz
+
+[tcpwatch-install]
+recipe = z3c.recipe.egg:setup
+setup = ${tcpwatch-source:location}/tcpwatch
+args = install_scripts --install-dir=${tcpwatch-source:location}/bin
+
+[funkload]
+recipe = zc.recipe.egg:scripts
+eggs = 
+    docutils
+    funkload
+    ${instance:eggs}
+extra-paths=${zope2:location}/lib/python
+#scripts = 
+#    fl-monitor-ctl
+#    fl-recorder
+initialization =
+    import os
+    os.environ['PATH'] = (
+        '${tcpwatch-source:location}/bin:'+os.environ['PATH'])
+
+[fl-tests]
+recipe = collective.recipe.funkload
+eggs = 
+    ${instance:eggs}
+zope2-location = ${zope2:location}
+url = http://localhost:8080
+
+[instance]
+eggs +=
+    collective.funkload
+    Products.CacheSetup
+    
+[site-pox.banner.tests]
+recipe = collective.recipe.plonesite
+site-id = pox.banner.tests
+instance = instance
+site-replace = True
+products =
+    pox.banner
+    pox.video
+
+[site-pox.banner.tests.withcache]
+recipe = collective.recipe.plonesite
+site-id = pox.banner.tests
+instance = instance
+site-replace = True
+products =
+    CacheSetup
+    pox.banner
+    pox.video
+

File chapter07/pox.buildout/models/poxContentTypes.zargo

Binary file added.

File chapter07/pox.buildout/products/README.txt

+Old-style Zope products you are developing can be added here

File chapter07/pox.buildout/sources.cfg

+[buildout]
+
+sources = sources
+auto-checkout =
+    Plone
+    Products.Archetypes
+    Products.ATContentTypes
+    Products.CMFActionIcons
+    Products.CMFCalendar
+    Products.CMFCore
+    Products.CMFDefault
+    Products.CMFDiffTool
+    Products.CMFDynamicViewFTI
+    Products.CMFEditions
+    Products.CMFFormController
+    Products.CMFPlacefulWorkflow
+    Products.CMFQuickInstallerTool
+    Products.CMFTestCase
+    Products.CMFTopic
+    Products.CMFUid
+    Products.DCWorkflow
+    Products.ExtendedPathIndex
+    Products.ExternalEditor
+    Products.GenericSetup
+    Products.kupu
+    Products.Marshall
+    Products.MimetypesRegistry
+    Products.PasswordResetTool
+    Products.PlacelessTranslationService
+    Products.PluggableAuthService
+    Products.PortalTransforms
+    Products.PlonePAS
+    Products.PluginRegistry
+    Products.ResourceRegistries
+    Products.validation
+    Products.ZopeVersionControl
+    borg.localrole
+    five.customerize
+    kss.core
+    plone.app.content
+    plone.app.contentrules
+    plone.app.controlpanel
+    plone.app.customerize
+    plone.app.form
+    plone.app.kss
+    plone.app.layout
+    plone.app.portlets
+    plone.app.upgrade
+    plone.app.viewletmanager
+    plone.app.vocabularies
+    plone.memoize
+    plone.protect
+    plone.recipe.zope2instance
+    plone.session
+    wicked
+
+[sources]
+Zope2                               = svn http://svn.zope.org/repos/main/Zope/branches/2.12
+Plone                               = svn https://svn.plone.org/svn/plone/Plone/branches/4.0
+archetypes.kss                      = svn https://svn.plone.org/svn/archetypes/archetypes.kss/branches/1.4
+borg.localrole                      = svn https://svn.plone.org/svn/collective/borg/components/borg.localrole/trunk
+five.customerize                    = svn http://svn.zope.org/repos/main/five.customerize/trunk
+five.localsitemanager               = svn http://svn.zope.org/repos/main/five.localsitemanager/trunk
+kss.core                            = svn https://codespeak.net/svn/kukit/kss.core/trunk
+plone.browserlayer                  = svn https://svn.plone.org/svn/plone/plone.browserlayer/trunk
+plone.contentrules                  = svn https://svn.plone.org/svn/plone/plone.contentrules/trunk
+plone.fieldsets                     = svn https://svn.plone.org/svn/plone/plone.fieldsets/trunk
+plone.i18n                          = svn https://svn.plone.org/svn/plone/plone.i18n/trunk
+plone.indexer                       = svn https://svn.plone.org/svn/plone/plone.indexer/trunk
+plone.intelligenttext               = svn https://svn.plone.org/svn/plone/plone.intelligenttext/trunk
+plone.keyring                       = svn https://svn.plone.org/svn/plone/plone.keyring/branches/1.x
+plone.locking                       = svn https://svn.plone.org/svn/plone/plone.locking/trunk
+plone.memoize                       = svn https://svn.plone.org/svn/plone/plone.memoize/trunk
+plone.openid                        = svn https://svn.plone.org/svn/plone/plone.openid/trunk
+plone.portlets                      = svn https://svn.plone.org/svn/plone/plone.portlets/trunk
+plone.protect                       = svn https://svn.plone.org/svn/plone/plone.protect/trunk
+plone.session                       = svn https://svn.plone.org/svn/plone/plone.session/branches/2.x
+plone.theme                         = svn https://svn.plone.org/svn/plone/plone.theme/branches/1.x
+plone.app.content                   = svn https://svn.plone.org/svn/plone/plone.app.content/branches/2.0
+plone.app.contentmenu               = svn https://svn.plone.org/svn/plone/plone.app.contentmenu/branches/1.x
+plone.app.contentrules              = svn https://svn.plone.org/svn/plone/plone.app.contentrules/branches/2.0
+plone.app.controlpanel              = svn https://svn.plone.org/svn/plone/plone.app.controlpanel/branches/2.0
+plone.app.customerize               = svn https://svn.plone.org/svn/plone/plone.app.customerize/branches/1.2
+plone.app.form                      = svn https://svn.plone.org/svn/plone/plone.app.form/trunk
+plone.app.i18n                      = svn https://svn.plone.org/svn/plone/plone.app.i18n/branches/1.x
+plone.app.iterate                   = svn https://svn.plone.org/svn/plone/plone.app.iterate/branches/1.2
+plone.app.kss                       = svn https://svn.plone.org/svn/plone/plone.app.kss/trunk
+plone.app.layout                    = svn https://svn.plone.org/svn/plone/plone.app.layout/branches/2.0
+plone.app.linkintegrity             = svn https://svn.plone.org/svn/plone/plone.app.linkintegrity/trunk
+plone.app.locales                   = svn https://svn.plone.org/svn/plone/plone.app.locales/trunk
+plone.app.openid                    = svn https://svn.plone.org/svn/plone/plone.app.openid/branches/1.x
+plone.app.portlets                  = svn https://svn.plone.org/svn/plone/plone.app.portlets/branches/2.0
+plone.app.redirector                = svn https://svn.plone.org/svn/plone/plone.app.redirector/branches/1.x
+plone.app.upgrade	                = svn https://svn.plone.org/svn/plone/plone.app.upgrade/branches/1.0
+plone.app.viewletmanager            = svn https://svn.plone.org/svn/plone/plone.app.viewletmanager/trunk
+plone.app.vocabularies              = svn https://svn.plone.org/svn/plone/plone.app.vocabularies/branches/2.0
+plone.app.workflow                  = svn https://svn.plone.org/svn/plone/plone.app.workflow/branches/1.2
+plone.portlet.collection            = svn https://svn.plone.org/svn/plone/plone.portlet.collection/branches/1.1
+plone.portlet.static                = svn https://svn.plone.org/svn/plone/plone.portlet.static/branches/1.2
+plone.recipe.zope2instance          = svn https://svn.plone.org/svn/collective/buildout/plone.recipe.zope2instance/trunk
+txtfilter                           = svn https://svn.plone.org/svn/collective/txtfilter/trunk
+wicked                              = svn https://svn.plone.org/svn/collective/wicked/trunk
+z3c.autoinclude                     = svn http://svn.zope.org/repos/main/z3c.autoinclude/trunk
+
+# Products
+Products.Archetypes                 = svn https://svn.plone.org/svn/archetypes/Products.Archetypes/branches/1.6
+Products.ATContentTypes             = svn https://svn.plone.org/svn/collective/Products.ATContentTypes/branches/2.0
+Products.ATReferenceBrowserWidget   = svn https://svn.plone.org/svn/archetypes/MoreFieldsAndWidgets/ATReferenceBrowserWidget/branches/2.0
+Products.CMFActionIcons             = svn http://svn.zope.org/repos/main/Products.CMFActionIcons/trunk
+Products.CMFCalendar                = svn http://svn.zope.org/repos/main/Products.CMFCalendar/trunk
+Products.CMFCore                    = svn http://svn.zope.org/repos/main/Products.CMFCore/trunk
+Products.CMFDefault                 = svn http://svn.zope.org/repos/main/Products.CMFDefault/trunk
+Products.CMFDiffTool                = svn https://svn.plone.org/svn/collective/Products.CMFDiffTool/trunk
+Products.CMFDynamicViewFTI          = svn https://svn.plone.org/svn/collective/CMFDynamicViewFTI/trunk
+Products.CMFEditions                = svn https://svn.plone.org/svn/collective/Products.CMFEditions/trunk
+Products.CMFFormController          = svn https://svn.plone.org/svn/collective/CMFFormController/trunk
+Products.CMFPlacefulWorkflow        = svn https://svn.plone.org/svn/collective/Products.CMFPlacefulWorkflow/branches/1.4
+Products.CMFQuickInstallerTool      = svn https://svn.plone.org/svn/collective/CMFQuickInstallerTool/trunk
+Products.CMFTestCase                = svn https://svn.plone.org/svn/collective/Products.CMFTestCase/trunk
+Products.CMFTopic                   = svn http://svn.zope.org/repos/main/Products.CMFTopic/trunk
+Products.CMFUid                     = svn http://svn.zope.org/repos/main/Products.CMFUid/trunk
+Products.DCWorkflow                 = svn http://svn.zope.org/repos/main/Products.DCWorkflow/trunk
+Products.ExtendedPathIndex          = svn https://svn.plone.org/svn/plone/Products.ExtendedPathIndex/trunk
+Products.ExternalEditor             = svn http://svn.zope.org/repos/main/Products.ExternalEditor/trunk
+Products.GenericSetup               = svn http://svn.zope.org/repos/main/Products.GenericSetup/trunk
+Products.GroupUserFolder            = svn https://svn.plone.org/svn/collective/Products.GroupUserFolder/trunk
+Products.i18ntestcase               = svn https://svn.plone.org/svn/collective/Products.i18ntestcase/trunk
+Products.kupu                       = svn https://codespeak.net/svn/kupu/trunk/Products.kupu
+Products.Marshall                   = svn https://svn.plone.org/svn/archetypes/Products.Marshall/trunk
+Products.MimetypesRegistry          = svn https://svn.plone.org/svn/archetypes/Products.MimetypesRegistry/trunk
+Products.PasswordResetTool          = svn https://svn.plone.org/svn/collective/Products.PasswordResetTool/trunk
+Products.PlacelessTranslationService= svn https://svn.plone.org/svn/collective/PlacelessTranslationService/trunk
+Products.PloneLanguageTool          = svn https://svn.plone.org/svn/collective/PloneLanguageTool/branches/3.0
+Products.PlonePAS                   = svn https://svn.plone.org/svn/collective/Products.PlonePAS/trunk
+Products.PloneTestCase              = svn https://svn.plone.org/svn/collective/Products.PloneTestCase/trunk
+Products.PluggableAuthService       = svn http://svn.zope.org/repos/main/Products.PluggableAuthService/trunk
+Products.PluginRegistry             = svn http://svn.zope.org/repos/main/Products.PluginRegistry/trunk
+Products.PortalTransforms           = svn https://svn.plone.org/svn/archetypes/Products.PortalTransforms/trunk
+Products.ResourceRegistries         = svn https://svn.plone.org/svn/plone/ResourceRegistries/trunk
+Products.SecureMailHost             = svn https://svn.plone.org/svn/collective/SecureMailHost/branches/1.1
+Products.statusmessages             = svn https://svn.plone.org/svn/collective/statusmessages/trunk
+Products.validation                 = svn https://svn.plone.org/svn/archetypes/Products.validation/trunk
+Products.ZopeVersionControl         = svn http://svn.zope.org/repos/main/Products.ZopeVersionControl/trunk

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/__init__.py

+# See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages
+try:
+    __import__('pkg_resources').declare_namespace(__name__)
+except ImportError:
+    from pkgutil import extend_path
+    __path__ = extend_path(__path__, __name__)

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/INTEGRATION.txt

+    >>> self.loginAsPortalOwner()
+    >>> portal.invokeFactory('XNewsItem', 'dummy')
+    'dummy'
+    >>> portal.dummy
+    <XNewsItem at /plone/dummy>
+
+    >>> portal.dummy.countryVocabulary()
+    (('AQ', 'Antartiqa'), ('AR', 'Argentina'), ('BS', 'Bahamas'), ('BR', 'Brazil'), ('CM', 'Cameroon'), ('CL', 'Chile'))
+
+    >>> from Products.poxContentTypes.tests.tests import ipython
+    >>> # ipython(locals())
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/README.txt

+    >>> from Products.poxContentTypes import config
+    >>> from Products.poxContentTypes.content.XNewsItem import XNewsItem
+
+    >>> xni=XNewsItem('dummy')
+
+    >>> xni
+    <XNewsItem at dummy>
+
+    >>> xni.countryVocabulary()
+    (('AQ', 'Antartiqa'), ('AR', 'Argentina'), ('BS', 'Bahamas'), ('BR', 'Brazil'), ('CM', 'Cameroon'), ('CL', 'Chile'))
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/__init__.py

+# -*- coding: utf-8 -*-
+#
+# File: poxContentTypes.py
+#
+# Copyright (c) 2010 by []
+# Generator: ArchGenXML Version 2.4.1
+#            http://plone.org/products/archgenxml
+#
+# GNU General Public License (GPL)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+__author__ = """JPG & MFR <unknown>"""
+__docformat__ = 'plaintext'
+
+
+# There are three ways to inject custom code here:
+#
+#   - To set global configuration variables, create a file AppConfig.py.
+#       This will be imported in config.py, which in turn is imported in
+#       each generated class and in this file.
+#   - To perform custom initialisation after types have been registered,
+#       use the protected code section at the bottom of initialize().
+
+import logging
+logger = logging.getLogger('poxContentTypes')
+logger.debug('Installing Product')
+
+import os
+import os.path
+from Globals import package_home
+import Products.CMFPlone.interfaces
+from Products.Archetypes import listTypes
+from Products.Archetypes.atapi import *
+from Products.Archetypes.utils import capitalize
+from Products.CMFCore import DirectoryView
+from Products.CMFCore import permissions as cmfpermissions
+from Products.CMFCore import utils as cmfutils
+from Products.CMFPlone.utils import ToolInit
+from config import *
+
+DirectoryView.registerDirectory('skins', product_globals)
+
+
+##code-section custom-init-head #fill in your manual code here
+##/code-section custom-init-head
+
+
+def initialize(context):
+    """initialize product (called by zope)"""
+    ##code-section custom-init-top #fill in your manual code here
+    ##/code-section custom-init-top
+
+    # imports packages and types for registration
+    import content
+
+
+    # Initialize portal content
+    all_content_types, all_constructors, all_ftis = process_types(
+        listTypes(PROJECTNAME),
+        PROJECTNAME)
+
+    cmfutils.ContentInit(
+        PROJECTNAME + ' Content',
+        content_types      = all_content_types,
+        permission         = DEFAULT_ADD_CONTENT_PERMISSION,
+        extra_constructors = all_constructors,
+        fti                = all_ftis,
+        ).initialize(context)
+
+    # Give it some extra permissions to control them on a per class limit
+    for i in range(0,len(all_content_types)):
+        klassname=all_content_types[i].__name__
+        if not klassname in ADD_CONTENT_PERMISSIONS:
+            continue
+
+        context.registerClass(meta_type   = all_ftis[i]['meta_type'],
+                              constructors= (all_constructors[i],),
+                              permission  = ADD_CONTENT_PERMISSIONS[klassname])
+
+    ##code-section custom-init-bottom #fill in your manual code here
+    ##/code-section custom-init-bottom
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/browser.txt

+    >>> from Products.Five.testbrowser import Browser
+    >>> from Products.PloneTestCase.setup import portal_owner, default_password
+
+    >>> browser = Browser()
+    >>> portal_url = self.portal.absolute_url()
+
+    >>> browser.open(portal_url)
+    >>> browser.getLink('Log in').click()
+    >>> browser.getControl('Login Name').value = portal_owner
+    >>> browser.getControl('Password').value = default_password
+    >>> browser.getControl('Log in').click()
+
+    >>> browser.open(portal_url + '/createObject?type_name=XNewsItem')
+    >>> browser.getControl('Title').value = 'This is an XNewsItem title'
+    >>> browser.getControl('Lead').value = 'Lead field is required'
+    >>> browser.getControl('Country').value = ('AR',)
+    >>> browser.getControl('Save').click()
+    >>> 'Changes saved.' in browser.contents
+    True
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/config.py

+# -*- coding: utf-8 -*-
+#
+# File: poxContentTypes.py
+#
+# Copyright (c) 2010 by []
+# Generator: ArchGenXML Version 2.4.1
+#            http://plone.org/products/archgenxml
+#
+# GNU General Public License (GPL)
+#
+
+__author__ = """JPG & MFR <unknown>"""
+__docformat__ = 'plaintext'
+
+
+# Product configuration.
+#
+# The contents of this module will be imported into __init__.py, the
+# workflow configuration and every content type module.
+#
+# If you wish to perform custom configuration, you may put a file
+# AppConfig.py in your product's root directory. The items in there
+# will be included (by importing) in this file if found.
+
+from Products.CMFCore.permissions import setDefaultRoles
+##code-section config-head #fill in your manual code here
+##/code-section config-head
+
+
+PROJECTNAME = "poxContentTypes"
+
+# Permissions
+DEFAULT_ADD_CONTENT_PERMISSION = "Add portal content"
+setDefaultRoles(DEFAULT_ADD_CONTENT_PERMISSION, ('Manager', 'Owner', 'Contributor'))
+ADD_CONTENT_PERMISSIONS = {
+    'XNewsItem': 'poxContentTypes: Add XNewsItem',
+}
+
+setDefaultRoles('poxContentTypes: Add XNewsItem', ('Manager','Owner'))
+
+product_globals = globals()
+
+# Dependencies of Products to be installed by quick-installer
+# override in custom configuration
+DEPENDENCIES = []
+
+# Dependend products - not quick-installed - used in testcase
+# override in custom configuration
+PRODUCT_DEPENDENCIES = []
+
+##code-section config-bottom #fill in your manual code here
+##/code-section config-bottom
+
+
+# Load custom configuration not managed by archgenxml
+try:
+    from Products.poxContentTypes.AppConfig import *
+except ImportError:
+    pass

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/configure.zcml

+<configure xmlns="http://namespaces.zope.org/zope" 
+           xmlns:browser="http://namespaces.zope.org/browser" 
+           xmlns:five="http://namespaces.zope.org/five"
+           xmlns:i18n="http://namespaces.zope.org/i18n"
+           i18n_domain="poxContentTypes">
+  
+  <i18n:registerTranslations directory="locales" />
+
+  <include file="profiles.zcml" />
+
+
+
+  <!-- ##code-section configure.zcml -->
+  <!-- ##/code-section configure.zcml -->
+
+</configure>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/content/XNewsItem.py

+# -*- coding: utf-8 -*-
+#
+# File: XNewsItem.py
+#
+# Copyright (c) 2010 by []
+# Generator: ArchGenXML Version 2.4.1
+#            http://plone.org/products/archgenxml
+#
+# GNU General Public License (GPL)
+#
+
+__author__ = """JPG & MFR <unknown>"""
+__docformat__ = 'plaintext'
+
+from AccessControl import ClassSecurityInfo
+from Products.Archetypes.atapi import *
+from zope.interface import implements
+import interfaces
+
+from Products.CMFDynamicViewFTI.browserdefault import BrowserDefaultMixin
+
+from Products.ATContentTypes.content.newsitem import ATNewsItem
+from Products.ATContentTypes.content.newsitem import ATNewsItemSchema
+from Products.poxContentTypes.config import *
+
+##code-section module-header #fill in your manual code here
+##/code-section module-header
+
+copied_fields = {}
+copied_fields['relatedItems'] = ATNewsItemSchema['relatedItems'].copy()
+copied_fields['relatedItems'].schemata = "default"
+schema = Schema((
+
+    StringField(
+        name='lead',
+        widget=StringField._properties['widget'](
+            label="Lead",
+            label_msgid='poxContentTypes_label_lead',
+            i18n_domain='poxContentTypes',
+        ),
+        required=True,
+    ),
+    StringField(
+        name='country',
+        widget=SelectionWidget(
+            label="Country",
+            label_msgid='poxContentTypes_label_country',
+            i18n_domain='poxContentTypes',
+        ),
+        enforceVocabulary=True,
+        vocabulary="countryVocabulary",
+    ),
+    copied_fields['relatedItems'],
+
+
+),
+)
+
+##code-section after-local-schema #fill in your manual code here
+##/code-section after-local-schema
+
+XNewsItem_schema = ATNewsItemSchema.copy() + \
+    schema.copy()
+
+##code-section after-schema #fill in your manual code here
+XNewsItem_schema.moveField('lead', after='title')
+XNewsItem_schema.moveField('country', before='text')
+XNewsItem_schema.moveField('relatedItems', pos='bottom')
+##/code-section after-schema
+
+class XNewsItem(ATNewsItem):
+    """
+    """
+    security = ClassSecurityInfo()
+
+    implements(interfaces.IXNewsItem)
+
+    meta_type = 'XNewsItem'
+    _at_rename_after_creation = True
+
+    schema = XNewsItem_schema
+
+    ##code-section class-header #fill in your manual code here
+    ##/code-section class-header
+
+    # Methods
+
+    # Manually created methods
+
+    security.declarePublic('locationVocabulary')
+    def countryVocabulary(self):
+        """
+        Returns a list of country codes and their names for the
+        "country" field
+
+        >>> from Products.poxContentTypes import config
+        >>> from Products.poxContentTypes.content.XNewsItem import XNewsItem
+
+        >>> xni=XNewsItem('dummy')
+
+        >>> xni
+        <XNewsItem at dummy>
+
+        >>> xni.countryVocabulary()
+        (('AQ', 'Antartiqa'), ('AR', 'Argentina'), ('BS', 'Bahamas'), ('BR', 'Brazil'), ('CM', 'Cameroon'), ('CL', 'Chile'))
+        """
+
+        return (\
+                ('AQ', 'Antartiqa'),\
+                ('AR', 'Argentina'),\
+                ('BS', 'Bahamas'),\
+                ('BR', 'Brazil'),\
+                ('CM', 'Cameroon'),\
+                ('CL', 'Chile')\
+                )
+
+
+registerType(XNewsItem, PROJECTNAME)
+# end of class XNewsItem
+
+##code-section module-footer #fill in your manual code here
+##/code-section module-footer
+
+
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/content/__init__.py

+# -*- coding: utf-8 -*-
+#
+# File: content.py
+#
+# Copyright (c) 2010 by []
+# Generator: ArchGenXML Version 2.4.1
+#            http://plone.org/products/archgenxml
+#
+# GNU General Public License (GPL)
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+# 02110-1301, USA.
+#
+
+__author__ = """JPG & MFR <unknown>"""
+__docformat__ = 'plaintext'
+
+
+##code-section init-module-header #fill in your manual code here
+##/code-section init-module-header
+
+
+# Subpackages
+# Additional
+
+# Classes
+import XNewsItem
+
+##code-section init-module-footer #fill in your manual code here
+##/code-section init-module-footer
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/content/interfaces.py

+# -*- coding: utf-8 -*-
+
+from zope.interface import Interface
+
+##code-section HEAD
+##/code-section HEAD
+
+class IXNewsItem(Interface):
+    """Marker interface for .XNewsItem.XNewsItem
+    """
+
+##code-section FOOT
+##/code-section FOOT

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/i18n/generated.pot

+# archgenxml generated POT File
+# JPG & MFR <unknown>, 2009.
+msgid ""
+msgstr ""
+"Project-Id-Version: poxContentTypes\n"
+"POT-Creation-Date: Fri Aug 14 16:47:52 2009\n"
+"PO-Revision-Date: Fri Aug 14 16:47:52 2009\n"
+"Last-Translator: JPG & MFR <unknown>\n"
+"Language-Team: JPG & MFR <unknown>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+"Language-Code: en\n"
+"Language-Name: English\n"
+"Preferred-Encodings: latin1 utf-8\n"
+"Domain: poxContentTypes\n"
+
+#. Default: "Lead"
+#: content/XNewsItem.py
+msgid "poxContentTypes_label_lead"
+msgstr ""
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles.zcml

+<configure
+    xmlns="http://namespaces.zope.org/zope"
+    xmlns:genericsetup="http://namespaces.zope.org/genericsetup"
+    i18n_domain="poxContentTypes">
+
+  <include package="Products.GenericSetup" file="meta.zcml" />
+
+  <!-- ##code-section profiles.zcml-top #fill in your manual code here -->
+  <!-- ##/code-section profiles.zcml-top -->
+
+  <genericsetup:registerProfile
+      name="default"
+      title="poxContentTypes"
+      directory="profiles/default"
+      description="Extension profile for poxContentTypes."
+      provides="Products.GenericSetup.interfaces.EXTENSION"
+      />
+  
+  <!-- ##code-section profiles.zcml-bottom #fill in your manual code here -->
+  <!-- ##/code-section profiles.zcml-bottom -->
+
+</configure>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/cssregistry.xml

+<?xml version="1.0"?>
+<object name="portal_css" meta_type="Stylesheets Registry">
+ <!-- EXAMPLE DEFINITION
+ <stylesheet title=""
+             cacheable="True"
+             compression="safe"
+             cookable="True"
+             enabled="1"
+             expression=""
+             id="myfancystyle.css"
+             media="all"
+             rel="stylesheet"
+             rendering="import"/>
+ -->
+
+ <!-- ##code-section cssregistry.xml -->
+ <!-- ##/code-section cssregistry.xml -->
+</object>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/factorytool.xml

+<?xml version="1.0"?>
+<object name="portal_factory" meta_type="Plone Factory Tool">
+ <factorytypes>
+  <type portal_type="XNewsItem"/>
+ </factorytypes>
+</object>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/import_steps.xml

+<?xml version="1.0"?>
+<import-steps>
+
+ 
+
+
+ <import-step 
+    id="poxContentTypes-Update-RoleMappings" 
+    handler="Products.poxContentTypes.setuphandlers.updateRoleMappings"
+    title="Update Workflow role mappings for poxContentTypes"
+    version="2010-05-02T20:54:20.254336">
+   <dependency step="poxContentTypes-QI-dependencies"/>
+   updates the workflow role mappings for poxContentTypes
+ </import-step>
+
+ <import-step 
+    id="poxContentTypes-postInstall" 
+    handler="Products.poxContentTypes.setuphandlers.postInstall"
+    title="manual coded post-install for poxContentTypes"
+    version="2010-05-02T20:54:20.254336">
+   <dependency step="poxContentTypes-QI-dependencies"/>
+   manual coded post-install for poxContentTypes
+ </import-step>
+
+<!-- ##code-section ADDITIONALSTEPS -->
+<!-- ##/code-section ADDITIONALSTEPS -->
+
+</import-steps>
+ 

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/jsregistry.xml

+<?xml version="1.0"?>
+<object name="portal_javascripts" meta_type="JavaScripts Registry">
+ <!-- EXAMPLE DEFINITION
+ <javascript cacheable="True"
+             compression="safe"
+             cookable="True"
+             enabled="True"
+             expression=""
+             id="myfancyscript.js"
+             inline="False"/>
+ -->
+
+ <!-- ##code-section jsregistry.xml -->
+ <!-- ##/code-section jsregistry.xml -->
+
+</object>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/metadata.xml

+<?xml version="1.0"?>
+<metadata>
+  <version>1.0.12</version>
+  <!-- ##code-section METADATA -->
+  <!-- ##/code-section METADATA -->
+</metadata>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/poxContentTypes_marker.txt

+This is a marker for the products GenericSetup import steps.
+
+With this marker file present the steps in setuphandlers.py are executed only
+in context of this specific profile.

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/skins.xml

+<?xml version="1.0"?>
+
+<object name="portal_skins"
+        meta_type="Plone Skins Tool"
+        allow_any="False"
+        cookie_persistence="False"
+        request_varname="plone_skin">
+
+ <object name="poxcontenttypes_images"
+         meta_type="Filesystem Directory View"
+         directory="poxContentTypes/skins/poxcontenttypes_images"/>
+ <object name="poxcontenttypes_styles"
+         meta_type="Filesystem Directory View"
+         directory="poxContentTypes/skins/poxcontenttypes_styles"/>
+ <object name="poxcontenttypes_templates"
+         meta_type="Filesystem Directory View"
+         directory="poxContentTypes/skins/poxcontenttypes_templates"/>
+ 
+ <skin-path name="*">
+  <layer insert-after="custom" 
+         name="poxcontenttypes_images"/>
+  <layer insert-after="custom" 
+         name="poxcontenttypes_styles"/>
+  <layer insert-after="custom" 
+         name="poxcontenttypes_templates"/>
+ </skin-path>
+
+</object>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/types.xml

+<?xml version="1.0"?>
+<object name="portal_types"
+        meta_type="Plone Types Tool">
+ <object name="XNewsItem"
+         meta_type="Factory-based Type Information with dynamic views"/>
+ <!-- ##code-section TYPES -->
+ <!-- ##/code-section TYPES -->
+</object>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/profiles/default/types/XNewsItem.xml

+<?xml version="1.0"?>
+<object name="XNewsItem"
+        meta_type="Factory-based Type Information with dynamic views"
+        xmlns:i18n="http://xml.zope.org/namespaces/i18n"
+        i18n:domain="plone">
+   
+ <property name="title" i18n:translate="">XNewsItem</property>
+ <property name="description" i18n:translate=""></property>
+ <property name="content_icon">XNewsItem.gif</property>
+ <property name="content_meta_type">XNewsItem</property>
+ <property name="product">poxContentTypes</property>
+ <property name="factory">addXNewsItem</property>
+ <property name="immediate_view">base_view</property>
+ <property name="global_allow">True</property>
+ <property name="filter_content_types">False</property>
+ <property name="allowed_content_types">
+ </property>
+ <property name="allow_discussion">False</property>
+ <property name="default_view">base_view</property>
+ <property name="view_methods">
+  <element value="base_view"/>
+ </property>
+ <property name="default_view_fallback">False</property>
+ <alias from="(Default)" to="(dynamic view)"/>
+ <alias from="index.html" to="(dynamic view)"/>
+ <alias from="view" to="(selected layout)"/>
+ <alias from="edit" to="base_edit"/>
+ <action title="View" 
+         action_id="view"
+         category="object" 
+         condition_expr=""
+         url_expr="string:${object_url}/view" 
+         visible="True">
+  <permission value="View"/>
+ </action>
+ <action title="Edit" 
+         action_id="edit"
+         category="object" 
+         condition_expr="not:object/@@plone_lock_info/is_locked_for_current_user"
+         url_expr="string:${object_url}/edit" 
+         visible="True">
+  <permission value="Modify portal content"/>
+ </action>
+</object>

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/refresh.txt

Empty file added.

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/setuphandlers.py

+# -*- coding: utf-8 -*-
+#
+# File: setuphandlers.py
+#
+# Copyright (c) 2010 by []
+# Generator: ArchGenXML Version 2.4.1
+#            http://plone.org/products/archgenxml
+#
+# GNU General Public License (GPL)
+#
+
+__author__ = """JPG & MFR <unknown>"""
+__docformat__ = 'plaintext'
+
+
+import logging
+logger = logging.getLogger('poxContentTypes: setuphandlers')
+from Products.poxContentTypes.config import PROJECTNAME
+from Products.poxContentTypes.config import DEPENDENCIES
+import os
+from Products.CMFCore.utils import getToolByName
+import transaction
+##code-section HEAD
+##/code-section HEAD
+
+def isNotpoxContentTypesProfile(context):
+    return context.readDataFile("poxContentTypes_marker.txt") is None
+
+
+
+def updateRoleMappings(context):
+    """after workflow changed update the roles mapping. this is like pressing
+    the button 'Update Security Setting' and portal_workflow"""
+    if isNotpoxContentTypesProfile(context): return 
+    wft = getToolByName(context.getSite(), 'portal_workflow')
+    wft.updateRoleMappings()
+
+def postInstall(context):
+    """Called as at the end of the setup process. """
+    # the right place for your custom code
+    if isNotpoxContentTypesProfile(context): return
+    site = context.getSite()
+
+
+
+##code-section FOOT
+##/code-section FOOT

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/skins/poxcontenttypes_images/XNewsItem.gif

Added
New image

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/tests/__init__.py

Empty file added.

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/tests/seleniumtests/__init__.py

+import testXNewsItem

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/tests/seleniumtests/testXNewsItem.py

+from selenium import selenium
+import unittest, time, re
+
+class testXNewsItem(unittest.TestCase):
+    def setUp(self):
+        self.verificationErrors = []
+        # self.selenium = selenium("localhost", 4444, "*chrome", "http://localhost:8080/plone")
+        self.selenium = selenium("localhost", port, browser, url)
+        self.selenium.start()
+
+    def test_test_x_news_item(self):
+        sel = self.selenium
+        sel.open("/plone")
+        sel.wait_for_page_to_load("30000")
+        sel.click("link=Log in")
+        sel.wait_for_page_to_load("30000")
+        sel.type("__ac_name", "admin")
+        sel.type("__ac_password", "admin")
+        sel.click("submit")
+        sel.wait_for_page_to_load("30000")
+        sel.click("//dl[@id='plone-contentmenu-factories']/dt/a/span[1]")
+        sel.click("//a[@id='xnewsitem']/span")
+        sel.wait_for_page_to_load("30000")
+        sel.type("title", "This is another XNewsItem title")
+        sel.type("lead", "Lead field is still required")
+        sel.select("country", "label=Argentina")
+        sel.click("form.button.save")
+        sel.wait_for_page_to_load("30000")
+        try:
+            self.failUnless(sel.is_text_present("Changes saved."))
+        except AssertionError, e: 
+            self.verificationErrors.append(str(e))
+
+    def tearDown(self):
+        self.selenium.stop()
+        self.assertEqual([], self.verificationErrors)
+
+if __name__ == "__main__":
+    unittest.main()
+

File chapter07/pox.buildout/src/Products.poxContentTypes/Products/poxContentTypes/tests/tests.py