Author: jmorliaguet Date: Wed Jun 28 17:24:03 2006 New Revision: 3541 Added: cpsskins/branches/paris-sprint-2006/ftests/test_location.py (contents, props changed) cpsskins/branches/paris-sprint-2006/locations/sources.txt (contents, props changed) Modified: cpsskins/branches/paris-sprint-2006/locations/configure.zcml cpsskins/branches/paris-sprint-2006/locations/interfaces.py
Log: - added a context binder for data sources (not 100% done) Added: cpsskins/branches/paris-sprint-2006/ftests/test_location.py ============================================================================== --- (empty file) +++ cpsskins/branches/paris-sprint-2006/ftests/test_location.py Wed Jun 28 17:24:03 2006 @@ -0,0 +1,32 @@ +############################################################################## +# +# Copyright (c) 2005-2006 Nuxeo 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. +# +############################################################################## +"""Location tests + +$Id$ +""" +__docformat__ = "reStructuredText" + +import unittest + +from zope.app.testing.functional import FunctionalDocFileSuite + +from cpsskins.tests.setup import setUp + +def test_suite(): + return unittest.TestSuite(( + FunctionalDocFileSuite('../locations/sources.txt', setUp=setUp), + )) + +if __name__ == '__main__': + unittest.main(defaultTest='test_suite') Modified: cpsskins/branches/paris-sprint-2006/locations/configure.zcml ============================================================================== --- cpsskins/branches/paris-sprint-2006/locations/configure.zcml (original) +++ cpsskins/branches/paris-sprint-2006/locations/configure.zcml Wed Jun 28 17:24:03 2006 @@ -25,16 +25,10 @@ <utility provides="zope.schema.interfaces.IVocabularyFactory" - component=".interfaces.ScopesVocabulary" + component=".interfaces.scopesVocabulary" name="location scopes" /> - <utility - provides="zope.schema.interfaces.IVocabularyFactory" - component=".interfaces.DataVocabulary" - name="location data" - /> - <!-- Typing --> <interface interface=".interfaces.ILocation" Modified: cpsskins/branches/paris-sprint-2006/locations/interfaces.py ============================================================================== --- cpsskins/branches/paris-sprint-2006/locations/interfaces.py (original) +++ cpsskins/branches/paris-sprint-2006/locations/interfaces.py Wed Jun 28 17:24:03 2006 @@ -17,10 +17,12 @@ """ __docformat__ = "reStructuredText" -from zope.interface import Interface, alsoProvides, Attribute +from zope.interface import Interface, alsoProvides, Attribute, implements from zope.i18nmessageid import MessageFactory from zope.schema import TextLine, Tuple, Choice, Int -from zope.schema.interfaces import IVocabularyFactory +from zope.schema.interfaces import ISource +from zope.schema.interfaces import IVocabularyFactory, IContextSourceBinder +from zope.schema.interfaces import IBaseVocabulary, IContextSourceBinder from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm from cpsskins.utils import getThemeManager @@ -28,6 +30,62 @@ _ = MessageFactory("cpsskins") +def scopesVocabulary(context): + """A vocabulary that contains a list of scopes + """ + return SimpleVocabulary( + [SimpleTerm(value, token, title) for value, token, title in ( + ((0, 0), u'0-0', _(u"there and in all sub-folders")), + ((0, 1), u'0-1', _(u"only there")), + ((1, 0), u'1-0', _(u"in all sub-folders")), + )]) + +alsoProvides(scopesVocabulary, IVocabularyFactory) + +class DataSource(object): + """Source for the 'data' field + """ + implements(ISource) + + def __init__(self): + self.context = None + + def __iter__(self): + context = self.context + if context is None: + return iter([]) + tmutil = getThemeManager(context) + root = context.root + choices = {} + + if root == u'pages': + for theme in tmutil.getThemes(): + theme_name = theme.name + for page in theme.getPages(): + page_id = u'%s:%s' % (theme_name, page.name) + choices[page_id] = u'%s / %s' % (theme.title, page.title) + + elif root == u'perspectives': + for perspective in tmutil.listPerspectives(): + choices[perspective.name] = perspective.title + + elif root == u'engines': + # FIXME + choices[u'default'] = u'default' + + return iter( + [SimpleTerm(value=k, title=v) for k, v in choices.items()]) + +def data_source_binder(context): + source = DataSource() + if not ILocation.providedBy(context): + raise ValueError("The data source must be bound with a location as a " + "context.") + source.context = context + return source + +alsoProvides(data_source_binder, IContextSourceBinder) + class ILocation(Interface): """Location""" @@ -48,7 +106,7 @@ data = Choice( title=u"Data", - vocabulary="location data", + source=data_source_binder, ) def __call__(): @@ -57,42 +115,3 @@ def __str__(): """Return the location's path""" -def ScopesVocabulary(context): - """A vocabulary that contains a list of scopes - """ - return SimpleVocabulary( - [SimpleTerm(value, token, title) for value, token, title in ( - ((0, 0), u'0-0', _(u"there and in all sub-folders")), - ((0, 1), u'0-1', _(u"only there")), - ((1, 0), u'1-0', _(u"in all sub-folders")), - )]) - -alsoProvides(ScopesVocabulary, IVocabularyFactory) - -def DataVocabulary(context): - """A vocabulary for the 'data' field - """ - location = context - tmutil = getThemeManager(context) - root = location.root - choices = {} - - if root == u'pages': - for theme in tmutil.getThemes(): - theme_name = theme.name - for page in theme.getPages(): - page_id = u'%s:%s' % (theme_name, page.name) - choices[page_id] = u'%s / %s' % (theme.title, page.title) - - elif root == u'perspectives': - for perspective in tmutil.listPerspectives(): - choices[perspective.name] = perspective.title - - elif root == u'engines': - # FIXME - choices[u'default'] = u'default' - - return SimpleVocabulary( - [SimpleTerm(value=k, title=v) for k, v in choices.items()]) - -alsoProvides(DataVocabulary, IVocabularyFactory) Added: cpsskins/branches/paris-sprint-2006/locations/sources.txt ============================================================================== --- (empty file) +++ cpsskins/branches/paris-sprint-2006/locations/sources.txt Wed Jun 28 17:24:03 2006 @@ -0,0 +1,55 @@ + +======= +SOURCES +======= + +The 'data' field of the Location object gets it information from the context: + + >>> root = getRootFolder() + + >>> from cpsskins.tests.setup import addThemeManager + >>> from cpsskins.tests.setup import makeSite + >>> tmutil = addThemeManager(root, makeSite(root)) + + >>> from zope.schema import Choice + >>> from cpsskins.locations.interfaces import DataSource + >>> data_choice = Choice( + ... title=u"Data", + ... source=DataSource(), + ... ) + +if the field is not bound to a context, no choices will be made available: + >>> print list(data_choice.source) + [] + +let us create a source binder and bind the field to the context: + + >>> from cpsskins.locations.interfaces import data_source_binder + + >>> data_choice_in_context = Choice( + ... title=u"Data", + ... source=data_source_binder, + ... ) + + +if we try to bind the field with an object which does not provide ILocation, +we get an error: + + >>> data_choice_in_context = data_choice_in_context.bind(root) + Traceback (most recent call last): + ... + ValueError: The data source must be bound with a location as a context. + +we create a location: + + >>> from cpsskins.locations import Location + >>> l = Location(root=u'pages') + >>> root[u'location'] = l + + >>> data_choice_in_context = data_choice_in_context.bind(l) + >>> print list(data_choice_in_context.source) + + +clean up: + + >>> del root[u'location'] -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins