Back to index

plone3  3.1.7
widget.py
Go to the documentation of this file.
00001 from AccessControl import ClassSecurityInfo
00002 from AccessControl.unauthorized import Unauthorized
00003 from Acquisition import aq_inner
00004 from Globals import InitializeClass
00005 
00006 # BBB, this can be removed once we do not support PTS anymore
00007 from Products.PageTemplates.GlobalTranslationService \
00008      import getGlobalTranslationService as getGTS
00009 
00010 from zope.i18nmessageid import Message
00011 
00012 class iwidget:
00013     def __call__(instance, context=None):
00014         """Returns a rendered fragment that can be included in a larger
00015         context when called by a renderer.
00016 
00017         instance - the instance this widget is called for
00018         context  - should implement dict behavior
00019         """
00020 
00021     def getContext(mode, instance):
00022         """Returns a prepared context or an empty {}."""
00023 
00024     def Label(instance):
00025         """Returns the label, possibly translated."""
00026 
00027     def Description(instance):
00028         """Returns the description, possibly translated."""
00029 
00030 class widget:
00031     """Base class for widgets.
00032 
00033     A dynamic widget with a reference to a macro that can be used to
00034     render it.
00035 
00036     description -- tooltip
00037     label       -- textual label
00038     visible     -- visible[default] | invisible | hidden
00039     condition   -- TALES expression to control the widget display
00040     """
00041 
00042     __implements__ = (iwidget,)
00043 
00044     security  = ClassSecurityInfo()
00045     security.declareObjectPublic()
00046     security.setDefaultAccess('allow')
00047 
00048     _properties = {
00049         'description' : '',
00050         'label' : '',
00051         'visible' : {'edit':'visible', 'view':'visible'},
00052         'condition': '',
00053     }
00054 
00055     def __init__(self, **kwargs):
00056         self._process_args(**kwargs)
00057 
00058     def _process_args(self, **kwargs):
00059         self.__dict__.update(self._properties)
00060         self.__dict__.update(kwargs)
00061 
00062     def __call__(self, mode, instance, context=None):
00063         """Not implemented."""
00064         return ''
00065 
00066     def getContext(self, instance):
00067         """Returns a prepared context or an empty {}."""
00068         return {}
00069 
00070     def _translate_attribute(self, instance, name):
00071         value = getattr(self, name, '')
00072         msgid = getattr(self, name+'_msgid', None) or value
00073 
00074         if not value and not msgid:
00075             return ''
00076 
00077         if isinstance(value, Message):
00078             return value
00079 
00080         domain = (getattr(self, 'i18n_domain', None) or
00081                   getattr(instance, 'i18n_domain', None))
00082 
00083         if domain is None:
00084             return value
00085 
00086         return getGTS().translate(domain, msgid, mapping=instance.REQUEST,
00087                                   context=instance, default=value)
00088 
00089     def Label(self, instance, **kwargs):
00090         """Returns the label, possibly translated."""
00091         value = getattr(self, 'label_method', None)
00092         method = value and getattr(aq_inner(instance), value, None)
00093         if method and callable(method):
00094             # Label methods can be called with kwargs and should
00095             # return the i18n version of the description
00096             value = method(**kwargs)
00097             return value
00098         return self._translate_attribute(instance, 'label')
00099 
00100     def Description(self, instance, **kwargs):
00101         """Returns the description, possibly translated."""
00102         value = self.description
00103         method = value and getattr(aq_inner(instance), value, None)
00104         if method and callable(method):
00105             # Description methods can be called with kwargs and should
00106             # return the i18n version of the description
00107             value = method(**kwargs)
00108             return value
00109         target_language = kwargs.get('target_language', None)
00110         return self._translate_attribute(instance, 'description')
00111 
00112 
00113 class macrowidget(widget):
00114     """Macro is the file containing the macros, the mode/view is the
00115     name of the macro in that file.
00116     """
00117 
00118     _properties = widget._properties.copy()
00119     _properties.update({
00120         'macro' : None,
00121     })
00122 
00123     def bootstrap(self, instance):
00124         # Do initialization-like thingies that need the instance
00125         pass
00126 
00127     def __call__(self, mode, instance, context=None):
00128         self.bootstrap(instance)
00129         # If an attribute called macro_<mode> exists resolve that
00130         # before the generic macro, this lets other projects
00131         # create more partial widgets
00132         macro = getattr(self, 'macro_%s' % mode, self.macro)
00133         # Now split the macro into optional parts using '|'
00134         # if the first part doesn't exist, the search continues
00135         paths = macro.split('|')
00136         if len(paths) == 1 and macro == self.macro:
00137             # Prepend the default (optional) customization element
00138             paths.insert(0, 'at_widget_%s' % self.macro.split('/')[-1])
00139         for path in paths:
00140             try:
00141                 template = instance.restrictedTraverse(path = path)
00142                 if template:
00143                     return template.macros[mode]
00144             except (Unauthorized, AttributeError, KeyError):
00145                 # This means we didn't have access or it doesn't exist
00146                 pass
00147         raise AttributeError("Macro %s does not exist for %s" %(macro,
00148                                                                 instance))
00149 
00150 InitializeClass(widget)