cybertools/composer
helmutm 8c9326149e fix bugs on schema field display
git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2948 fd906abe-77d9-0310-91a1-e0d9ade77398
2008-10-27 14:20:42 +00:00
..
layout clean up layout code 2008-10-22 13:07:09 +00:00
message service management bug fixes 2007-12-14 15:13:33 +00:00
rule more on checkout rule handling, including browser redirect 2007-11-20 10:54:17 +00:00
schema fix bugs on schema field display 2008-10-27 14:20:42 +00:00
__init__.py starting with organize.service; new package cybertools.composer 2007-05-14 20:31:15 +00:00
base.py extending composer and organize.schema to provide basis for tumsm 2007-07-29 13:28:50 +00:00
instance.py extending composer and organize.schema to provide basis for tumsm 2007-07-29 13:28:50 +00:00
interfaces.py work in progress: layout management 2008-07-31 11:18:28 +00:00
README.txt renamed client to instance; re-build schema/README.txt 2007-05-18 10:17:01 +00:00
tests.py starting with organize.service; new package cybertools.composer 2007-05-14 20:31:15 +00:00

================================================================
Composer - Building Complex Structures with Templates or Schemas
================================================================

  ($Id$)

  >>> from cybertools.composer.base import Element, Compound, Template
  >>> from cybertools.composer.instance import Instance

We set up a very simple demonstration system using a PC configurator.
We start with two classes denoting a configuration and a simple
component within this configuration.

  >>> class Configuration(Template):
  ...     def __init__(self, name):
  ...         self.name = name
  ...         super(Configuration, self).__init__()

  >>> class BasicComponent(Element):
  ...     def __init__(self, name):
  ...         self.name = name
  ...     def __repr__(self):
  ...         return self.name

  >>> desktop = Configuration('Desktop')
  >>> desktop.components.append(BasicComponent('case'))
  >>> desktop.components.append(BasicComponent('mainboard'))
  >>> desktop.components.append(BasicComponent('cpu'))
  >>> desktop.components.append(BasicComponent('harddisk'))

Now somebody wants to configure a desktop PC using this configuration.
We need another class denoting the product that will be created.

  >>> class Product(object):
  ...     def __init__(self, productId):
  ...         self.productId = productId
  ...         self.parts = {}
  ...     def __repr__(self):
  ...         return self.productId

  >>> c001 = Product('c001')

The real stuff will be done by an instance adpater that connects the product
with the template.

  >>> class ConfigurationAdapter(Instance):
  ...     def applyTemplate(self):
  ...         for c in self.template.components:
  ...             print c, self.context.parts.get(c.name, '-')

  >>> inst = ConfigurationAdapter(c001)
  >>> inst.template = desktop
  >>> inst.applyTemplate()
  case -
  mainboard -
  cpu -
  harddisk -

If we have configured a CPU for our configuration this will be listed.

  >>> c001.parts['cpu'] = Product('z80')
  >>> inst.applyTemplate()
  case -
  mainboard -
  cpu z80
  harddisk -

Note that the ConfigurationInstance's applyTemplate() method is fairly
primitive. In a real-world application there usually are a lot more methods
that do more stuff. In our PC configurator application there might be
methods that just list components (e.g. to provide a user interface),
retrieve candidate products (e.g. CPUs) to use in the
configuration and store the user's selection in the context object.