def update(self): """See z3c.form.interfaces.IActions.""" # Create a unique prefix. prefix = util.expandPrefix(self.form.prefix) prefix += util.expandPrefix(self.form.buttons.prefix) # Walk through each field, making an action out of it. uniqueOrderedKeys = [] for name, button in self.form.buttons.items(): # Step 1: Only create an action for the button, if the condition is # fulfilled. if button.condition is not None and not button.condition( self.form): # Step 1.1: If the action already existed, but now the # condition became false, remove the old action. if name in self._data: del self._data[name] continue # Step 2: Get the action for the given button. newButton = True if name in self._data: buttonAction = self._data[name] newButton = False elif button.actionFactory is not None: buttonAction = button.actionFactory(self.request, button) else: buttonAction = zope.component.getMultiAdapter( (self.request, button), interfaces.IButtonAction) # Step 3: Set the name on the button buttonAction.name = prefix + name # Step 4: Set any custom attribute values. title = zope.component.queryMultiAdapter( (self.form, self.request, self.content, button, self), interfaces.IValue, name='title') if title is not None: buttonAction.title = title.get() # Step 5: Set the form buttonAction.form = self.form if not interfaces.IFormAware.providedBy(buttonAction): zope.interface.alsoProvides(buttonAction, interfaces.IFormAware) # Step 6: Update the new action buttonAction.update() zope.event.notify(AfterWidgetUpdateEvent(buttonAction)) # Step 7: Add the widget to the manager uniqueOrderedKeys.append(name) if newButton: self._data[name] = buttonAction zope.location.locate(buttonAction, self, name) # always ensure that we add all keys and keep the order given from # button items self._data_keys = uniqueOrderedKeys self._data_values = [self._data[name] for name in uniqueOrderedKeys]
def update(self): """See interfaces.IWidgets""" # Create a unique prefix. prefix = util.expandPrefix(self.form.prefix) prefix += util.expandPrefix(self.prefix) # Walk through each field, making a widget out of it. for field in self.form.fields.values(): # Step 1: Determine the mode of the widget. mode = self.mode if field.mode is not None: mode = field.mode elif field.field.readonly and not self.ignoreReadonly: mode = interfaces.DISPLAY_MODE elif not self.ignoreContext and self.content is not None: # If we do not have enough permissions to write to the # attribute, then switch to display mode. dm = zope.component.getMultiAdapter( (self.content, field.field), interfaces.IDataManager) if not dm.canWrite(): mode = interfaces.DISPLAY_MODE # Step 2: Get the widget for the given field. factory = field.widgetFactory.get(mode) if factory is not None: widget = factory(field.field, self.request) else: widget = zope.component.getMultiAdapter( (field.field, self.request), interfaces.IFieldWidget) # Step 3: Set the prefix for the widget shortName = field.__name__ widget.name = prefix + shortName widget.id = (prefix + shortName).replace('.', '-') # Step 4: Set the context widget.context = self.content zope.interface.alsoProvides(widget, interfaces.IContextAware) # Step 5: Set the form widget.form = self.form zope.interface.alsoProvides(widget, interfaces.IFormAware) # Step 6: Set some variables widget.ignoreContext = self.ignoreContext widget.ignoreRequest = self.ignoreRequest # Step 7: Set the mode of the widget widget.mode = mode # Step 8: Update the widget widget.update() zope.event.notify(AfterWidgetUpdateEvent(widget)) # Step 9: Add the widget to the manager self._data_keys.append(shortName) self._data_values.append(widget) self._data[shortName] = widget zope.location.locate(widget, self, shortName)
def update(self): """See z3c.form.interfaces.IActions.""" # Create a unique prefix. prefix = util.expandPrefix(self.form.prefix) prefix += util.expandPrefix(self.form.buttons.prefix) # Walk through each field, making an action out of it. uniqueOrderedKeys = [] for name, button in self.form.buttons.items(): # Step 1: Only create an action for the button, if the condition is # fulfilled. if button.condition is not None and not button.condition(self.form): # Step 1.1: If the action already existed, but now the # condition became false, remove the old action. if name in self._data: del self._data[name] continue # Step 2: Get the action for the given button. newButton = True if name in self._data: buttonAction = self._data[name] newButton = False elif button.actionFactory is not None: buttonAction = button.actionFactory(self.request, button) else: buttonAction = zope.component.getMultiAdapter( (self.request, button), interfaces.IButtonAction) # Step 3: Set the name on the button buttonAction.name = prefix + name # Step 4: Set any custom attribute values. title = zope.component.queryMultiAdapter( (self.form, self.request, self.content, button, self), interfaces.IValue, name='title') if title is not None: buttonAction.title = title.get() # Step 5: Set the form buttonAction.form = self.form if not interfaces.IFormAware.providedBy(buttonAction): zope.interface.alsoProvides(buttonAction, interfaces.IFormAware) # Step 6: Update the new action buttonAction.update() zope.event.notify(AfterWidgetUpdateEvent(buttonAction)) # Step 7: Add the widget to the manager uniqueOrderedKeys.append(name) if newButton: self._data[name] = buttonAction zope.location.locate(buttonAction, self, name) # always ensure that we add all keys and keep the order given from # button items self._data_keys = uniqueOrderedKeys self._data_values = [self._data[name] for name in uniqueOrderedKeys]
def _process_prefixed_name(prefix, fieldName): """Give prefixed fieldname if applicable """ if prefix: return expandPrefix(prefix) + fieldName else: return fieldName
def processFieldMoves(form, schema, prefix=''): """Process all field moves stored under ORDER_KEY in the schema tagged value. This should be run after all schemata have been processed with processFields(). """ # (name, 'before'/'after', other name) order = mergedTaggedValueList(schema, ORDER_KEY) for field_name, direction, relative_to in order: # Handle shortcut: leading . means 'in this schema'. May be useful # if you want to move a field relative to one in the current # schema or (more likely) a base schema of the current schema, without # having to repeat the full prefix of this schema. if relative_to.startswith('.'): relative_to = relative_to[1:] if prefix: relative_to = expandPrefix(prefix) + relative_to try: if direction == 'before': move(form, field_name, before=relative_to, prefix=prefix) elif direction == 'after': move(form, field_name, after=relative_to, prefix=prefix) except KeyError: # The relative_to field doesn't exist pass
def __init__(self, field, name=None, prefix='', mode=None, interface=None): self.field = field if name is None: name = field.__name__ assert name self.__name__ = util.expandPrefix(prefix) + name self.prefix = prefix self.mode = mode if interface is None: interface = field.interface self.interface = interface
def omit(self, *names, **kwargs): """See interfaces.IFields""" prefix = kwargs.pop('prefix', None) interface = kwargs.pop('interface', None) assert len(kwargs) == 0 if prefix: names = [util.expandPrefix(prefix) + name for name in names] return self.__class__( *[field for name, field in self.items() if not ((name in names and interface is None) or (field.field.interface is interface and field.field.__name__ in names)) ])
def update(self): """See z3c.form.interfaces.IActions.""" # Create a unique prefix. prefix = util.expandPrefix(self.form.prefix) prefix += util.expandPrefix(self.form.buttons.prefix) # Walk through each field, making an action out of it. for name, button in self.form.buttons.items(): # Step 1: Only create an action for the button, if the condition is # fulfilled. if button.condition is not None and not button.condition( self.form): continue # Step 2: Get the action for the given button. if button.actionFactory is not None: buttonAction = button.actionFactory(self.request, button) else: buttonAction = zope.component.getMultiAdapter( (self.request, button), interfaces.IButtonAction) # Step 3: Set the name on the button fullName = prefix + name buttonAction.name = fullName # Step 4: Set any custom attribute values. title = zope.component.queryMultiAdapter( (self.form, self.request, self.content, button, self), interfaces.IValue, name='title') if title is not None: buttonAction.title = title.get() # Step 5: Set the form buttonAction.form = self.form zope.interface.alsoProvides(buttonAction, interfaces.IFormAware) # Step 6: Update the new action buttonAction.update() zope.event.notify(AfterWidgetUpdateEvent(buttonAction)) # Step 7: Add the widget to the manager self._data_keys.append(name) self._data_values.append(buttonAction) self._data[name] = buttonAction zope.location.locate(buttonAction, self, name)
def __init__(self, field, name=None, prefix='', mode=None, interface=None, ignoreContext=None): self.field = field if name is None: name = field.__name__ assert name self.__name__ = util.expandPrefix(prefix) + name self.prefix = prefix self.mode = mode if interface is None: interface = field.interface self.interface = interface self.ignoreContext = ignoreContext
def select(self, *names, **kwargs): """See interfaces.IFields""" prefix = kwargs.pop('prefix', None) interface = kwargs.pop('interface', None) assert len(kwargs) == 0 if prefix: names = [util.expandPrefix(prefix) + name for name in names] mapping = self if interface is not None: mapping = dict([(field.field.__name__, field) for field in self.values() if field.field.interface is interface]) return self.__class__(*[mapping[name] for name in names])
def _prepare_names(self, source, target, prefix): # calculate prefixed fieldname if prefix: source = '{0}.{1}'.format(prefix, source) # Handle shortcut: leading . means "in this form". May be useful # if you want to move a field relative to one in the current # schema or (more likely) a base schema of the current schema, # without having to repeat the full prefix of this schema. if target.startswith('.'): target = target[1:] if prefix: target = expandPrefix(prefix) + target return source, target
def remove(form, field_name, prefix=None): """Get rid of a field. The omitted field will be returned. """ if prefix: field_name = expandPrefix(prefix) + field_name if field_name in form.fields: field = form.fields[field_name] form.fields = form.fields.omit(field_name) return field else: for group in form.groups: if field_name in group.fields: field = group.fields[field_name] group.fields = group.fields.omit(field_name) return field
def update(self): """See interfaces.IWidgets""" # Create a unique prefix. prefix = util.expandPrefix(self.form.prefix) prefix += util.expandPrefix(self.prefix) # Walk through each field, making a widget out of it. uniqueOrderedKeys = [] for field in self.form.fields.values(): # Step 0. Determine whether the context should be ignored. ignoreContext = self.ignoreContext if field.ignoreContext is not None: ignoreContext = field.ignoreContext # Step 1: Determine the mode of the widget. mode = self.mode if field.mode is not None: mode = field.mode elif field.field.readonly and not self.ignoreReadonly: mode = interfaces.DISPLAY_MODE elif not ignoreContext: # If we do not have enough permissions to write to the # attribute, then switch to display mode. dm = zope.component.getMultiAdapter( (self.content, field.field), interfaces.IDataManager) if not dm.canWrite(): mode = interfaces.DISPLAY_MODE # Step 2: Get the widget for the given field. shortName = field.__name__ newWidget = True if shortName in self._data: # reuse existing widget widget = self._data[shortName] newWidget = False elif field.widgetFactory.get(mode) is not None: factory = field.widgetFactory.get(mode) widget = factory(field.field, self.request) else: widget = zope.component.getMultiAdapter( (field.field, self.request), interfaces.IFieldWidget) # Step 3: Set the prefix for the widget widget.name = prefix + shortName widget.id = (prefix + shortName).replace('.', '-') # Step 4: Set the context widget.context = self.content # Step 5: Set the form widget.form = self.form # Optimization: Set both interfaces here, rather in step 4 and 5: # ``alsoProvides`` is quite slow zope.interface.alsoProvides( widget, interfaces.IContextAware, interfaces.IFormAware) # Step 6: Set some variables widget.ignoreContext = ignoreContext widget.ignoreRequest = self.ignoreRequest # Step 7: Set the mode of the widget widget.mode = mode # Step 8: Update the widget widget.update() zope.event.notify(AfterWidgetUpdateEvent(widget)) # Step 9: Add the widget to the manager if widget.required: self.hasRequiredFields = True uniqueOrderedKeys.append(shortName) if newWidget: self._data_values.append(widget) self._data[shortName] = widget zope.location.locate(widget, self, shortName) # allways ensure that we add all keys and keep the order given from # button items self._data_keys = uniqueOrderedKeys
def move(form, field_name, before=None, after=None, prefix=None, relative_prefix=None): """Move the field with the given name before or after another field. """ if prefix: field_name = expandPrefix(prefix) + field_name if before and after: raise ValueError(u"Only one of 'before' or 'after' is allowed") offset = 0 if after: offset = 1 relative = orig_relative = before or after if relative_prefix: relative = expandPrefix(relative_prefix) + relative if field_name not in form.fields: found = False for group in getattr(form, 'groups', []): if field_name in group.fields: found = True break if not found: raise KeyError("Field %s not found" % field_name) if relative != '*' and relative not in form.fields: found = False for group in form.groups: if relative in group.fields: found = True break if not found: raise KeyError("Field %s not found" % relative) field = remove(form, field_name) group = None index = None if relative in form.fields: index = form.fields.keys().index(relative) elif orig_relative == '*' and relative_prefix is None: if before: index = 0 else: index = len(form.fields.keys()) - 1 else: for group in form.groups: if relative in group.fields: index = group.fields.keys().index(relative) break elif orig_relative == '*' and relative_prefix == group.prefix: if before: index = 0 else: index = len(group.fields.keys()) - 1 if index is None: raise KeyError("Field %s not found" % relative) add(form, field, group=group, index=index + offset)
def update(self): """See interfaces.IWidgets""" # Create a unique prefix. prefix = util.expandPrefix(self.form.prefix) prefix += util.expandPrefix(self.prefix) # Walk through each field, making a widget out of it. uniqueOrderedKeys = [] for field in self.form.fields.values(): # Step 0. Determine whether the context should be ignored. #------------------------------------------------------------------- if self.draftable: ignoreContext = False else: ignoreContext = self.ignoreContext if field.ignoreContext is not None: ignoreContext = field.ignoreContext #------------------------------------------------------------------- # Step 1: Determine the mode of the widget. mode = self.mode if field.mode is not None: mode = field.mode elif field.field.readonly and not self.ignoreReadonly: mode = interfaces.DISPLAY_MODE elif not ignoreContext: # If we do not have enough permissions to write to the # attribute, then switch to display mode. #try: dm = zope.component.getMultiAdapter( (self.content, field.field), interfaces.IDataManager) if not dm.canWrite(): mode = interfaces.DISPLAY_MODE #except TypeError: # # If datamanager can not adapt, then we can't write and # # must ignore context (since it could not adapt) # ignoreContext = True # Step 2: Get the widget for the given field. shortName = field.__name__ newWidget = True if shortName in self._data: # reuse existing widget widget = self._data[shortName] newWidget = False elif field.widgetFactory.get(mode) is not None: factory = field.widgetFactory.get(mode) widget = factory(field.field, self.request) else: widget = zope.component.getMultiAdapter( (field.field, self.request), interfaces.IFieldWidget) # Step 2.5: If widget is draftable and no widget exists, create draft if self.draftable == False and IDraftable.providedBy(widget): proxy = zope.component.queryMultiAdapter((self.content, self.request, self.form), IZ3cFormDataContext) if proxy is not None: proxy.createDraft = True self.content = proxy.adapt() if IZ3cDraft.providedBy(self.content): self.draftable = True ignoreContext = False # Step 3: Set the prefix for the widget widget.name = prefix + shortName widget.id = (prefix + shortName).replace('.', '-') # Step 4: Set the context widget.context = self.content # Step 5: Set the form widget.form = self.form # Optimization: Set both interfaces here, rather in step 4 and 5: # ``alsoProvides`` is quite slow zope.interface.alsoProvides( widget, interfaces.IContextAware, interfaces.IFormAware) # Step 6: Set some variables widget.ignoreContext = ignoreContext widget.ignoreRequest = self.ignoreRequest # Step 7: Set the mode of the widget widget.mode = mode # Step 8: Update the widget widget.update() #------------------------------------------------------------------- # Save converted widget value on draft if it different from what is # already stored on draft if self.draftable and self.draftWritable == True and ignoreContext == False: dm = zope.component.getMultiAdapter( (self.content, field.field), interfaces.IDataManager) try: value = interfaces.IDataConverter(widget).toFieldValue(widget.value) #if getattr(self.content, field.__name__, None) != value: if dm.query() != value: dm.set(value) except ValueError: pass #------------------------------------------------------------------- zope.event.notify(AfterWidgetUpdateEvent(widget)) # Step 9: Add the widget to the manager if widget.required: self.hasRequiredFields = True uniqueOrderedKeys.append(shortName) if newWidget: self._data_values.append(widget) self._data[shortName] = widget zope.location.locate(widget, self, shortName) # allways ensure that we add all keys and keep the order given from # button items self._data_keys = uniqueOrderedKeys
def update(self): """See interfaces.IWidgets""" # Create a unique prefix. prefix = util.expandPrefix(self.form.prefix) prefix += util.expandPrefix(self.prefix) # Walk through each field, making a widget out of it. uniqueOrderedKeys = [] for field in self.form.fields.values(): # Step 0. Determine whether the context should be ignored. ignoreContext = self.ignoreContext if field.ignoreContext is not None: ignoreContext = field.ignoreContext # Step 1: Determine the mode of the widget. mode = self.mode if field.mode is not None: mode = field.mode elif field.field.readonly and not self.ignoreReadonly: mode = interfaces.DISPLAY_MODE elif not ignoreContext: # If we do not have enough permissions to write to the # attribute, then switch to display mode. dm = zope.component.getMultiAdapter( (self.content, field.field), interfaces.IDataManager) if not dm.canWrite(): mode = interfaces.DISPLAY_MODE # Step 2: Get the widget for the given field. shortName = field.__name__ newWidget = True if shortName in self._data: # reuse existing widget widget = self._data[shortName] newWidget = False elif field.widgetFactory.get(mode) is not None: factory = field.widgetFactory.get(mode) widget = factory(field.field, self.request) else: widget = zope.component.getMultiAdapter( (field.field, self.request), interfaces.IFieldWidget) # Step 3: Set the prefix for the widget widget.name = prefix + shortName widget.id = (prefix + shortName).replace('.', '-') # Step 4: Set the context widget.context = self.content # Step 5: Set the form widget.form = self.form # Optimization: Set both interfaces here, rather in step 4 and 5: # ``alsoProvides`` is quite slow zope.interface.alsoProvides(widget, interfaces.IContextAware, interfaces.IFormAware) # Step 6: Set some variables widget.ignoreContext = ignoreContext widget.ignoreRequest = self.ignoreRequest if field.showDefault is not None: widget.showDefault = field.showDefault # Step 7: Set the mode of the widget widget.mode = mode # Step 8: Update the widget widget.update() zope.event.notify(AfterWidgetUpdateEvent(widget)) # Step 9: Add the widget to the manager if widget.required: self.hasRequiredFields = True uniqueOrderedKeys.append(shortName) if newWidget: self._data_values.append(widget) self._data[shortName] = widget zope.location.locate(widget, self, shortName) # always ensure that we add all keys and keep the order given from # button items self._data_keys = uniqueOrderedKeys
def move(form, field_name, before=None, after=None, prefix=None, relative_prefix=None): """Move the field with the given name before or after another field. """ if prefix: field_name = expandPrefix(prefix) + field_name if before and after: raise ValueError(u"Only one of 'before' or 'after' is allowed") offset = 0 if after: offset = 1 relative = orig_relative = before or after if relative_prefix: relative = expandPrefix(relative_prefix) + relative if field_name not in form.fields: found = False for group in getattr(form, 'groups', []): if field_name in group.fields: found = True break if not found: raise KeyError("Field %s not found" % field_name) if relative != '*' and relative not in form.fields: found = False for group in form.groups: if relative in group.fields: found = True break if not found: raise KeyError("Field %s not found" % relative) field = remove(form, field_name) group = None index = None if relative in form.fields: index = form.fields.keys().index(relative) elif orig_relative == '*' and relative_prefix is None: if before: index = 0 else: index = len(form.fields.keys()) - 1 else: for group in form.groups: if relative in group.fields: index = group.fields.keys().index(relative) break elif orig_relative == '*' and relative_prefix == group.prefix: if before: index = 0 else: index = len(group.fields.keys()) - 1 if index is None: raise KeyError("Field %s not found" % relative) add(form, field, group=group, index=index+offset)
def update(self): form = self.form content = self.content request = self.request formbuttons = form.buttons buttons = [] allbuttons = [formbuttons] allbuttons.extend( [b for n, b in getAdapters( (content, form, request), interfaces.IButtons)]) prefix = util.expandPrefix(form.prefix) weight = 100 for btns in allbuttons: bprefix = prefix + util.expandPrefix(btns.prefix) for name, button in btns.items(): if button.condition is not None and not button.condition(form): continue weight += 1 bweight = getattr(button, 'weight', weight) buttons.append((bweight, bprefix + name, button)) for name, button in getAdapters((content, form, request), IWizardButton): if not button.isAvailable(): continue bprefix = prefix + util.expandPrefix( button.prefix or formbuttons.prefix) weight += 1 bweight = button.weight or weight buttons.append((bweight, str(bprefix + name), button)) buttons.sort() for weight, name, button in buttons: if button.actionFactory is not None: buttonAction = button.actionFactory(request, button) else: buttonAction = getMultiAdapter( (request, button), interfaces.IButtonAction) # Step 3: Set the name on the button buttonAction.name = name # Step 4: Set any custom attribute values. title = queryMultiAdapter( (form, request, content, button, self), interfaces.IValue, name='title') if title is not None: buttonAction.title = title.get() # Step 5: Set the form buttonAction.form = form interface.alsoProvides(buttonAction, interfaces.IFormAware) # Step 6: Update the new action buttonAction.update() event.notify(AfterWidgetUpdateEvent(buttonAction)) # Step 7: Add the widget to the manager self._data_keys.append(name) self._data_values.append(buttonAction) self._data[name] = buttonAction locate(buttonAction, self, name)
def traverse(self, name, ignored): form = self._prepareForm() # Since we cannot check security during traversal, # we delegate the check to the widget view. alsoProvides(self.request, IDeferSecurityCheck) form.update() noLongerProvides(self.request, IDeferSecurityCheck) # If name begins with form.widgets., remove it form_widgets_prefix = util.expandPrefix( form.prefix) + util.expandPrefix(form.widgets.prefix) if name.startswith(form_widgets_prefix): name = name[len(form_widgets_prefix):] # Split string up into dotted segments and work through target = aq_base(form) parts = name.split('.') while len(parts) > 0: part = parts.pop(0) if type(getattr( target, 'widgets', None)) is list: # i.e. a z3c.form.widget.MultiWidget try: # part should be integer index in list, look it up target = target.widgets[int(part)] except IndexError: raise TraversalError("'" + part + "' not in range") except ValueError: #HACK: part isn't integer. Iterate through widgets to # find matching name. This is required for # DataGridField, which appends 'AA' and 'TT' rows to # it's widget list. full_name = util.expandPrefix(target.prefix) + part filtered = [ w for w in target.widgets if w.name == full_name ] if len(filtered) == 1: target = filtered[0] else: raise TraversalError("'" + part + "' not valid index") elif hasattr(target, 'widgets'): # Either base form, or subform # Check to see if we can find a "Behaviour.widget" new_target = None if len(parts) > 0: new_target = self._form_traverse(target, part + '.' + parts[0]) if new_target is not None: # Remove widget name from stack too parts.pop(0) else: # Find widget in form without behaviour prefix new_target = self._form_traverse(target, part) target = new_target elif hasattr( target, 'subform' ): # subform-containing widget, only option is to go into subform if part == 'widgets': target = target.subform else: target = None else: raise TraversalError('Cannot traverse through ' + target.__repr__()) # Could not traverse from target to part if target is None: raise TraversalError(part) # Make the parent of the widget the traversal parent. # This is required for security to work in Zope 2.12 if target is not None: target.__parent__ = aq_inner(self.context) return target raise TraversalError(name)
def traverse(self, name, ignored): form = self._prepareForm() # Since we cannot check security during traversal, # we delegate the check to the widget view. alsoProvides(self.request, IDeferSecurityCheck) form.update() noLongerProvides(self.request, IDeferSecurityCheck) # If name begins with form.widgets., remove it form_widgets_prefix = util.expandPrefix(form.prefix)+util.expandPrefix(form.widgets.prefix) if name.startswith(form_widgets_prefix): name = name[len(form_widgets_prefix):] # Split string up into dotted segments and work through target = aq_base(form) parts = name.split('.') while len(parts) > 0: part = parts.pop(0) if type(getattr(target,'widgets',None)) is list: # i.e. a z3c.form.widget.MultiWidget try: # part should be integer index in list, look it up target = target.widgets[int(part)] except IndexError: raise TraversalError("'"+part+"' not in range") except ValueError: #HACK: part isn't integer. Iterate through widgets to # find matching name. This is required for # DataGridField, which appends 'AA' and 'TT' rows to # it's widget list. full_name = util.expandPrefix(target.prefix) + part filtered = [w for w in target.widgets if w.name == full_name] if len(filtered) == 1: target = filtered[0] else: raise TraversalError("'"+part+"' not valid index") elif hasattr(target,'widgets'): # Either base form, or subform # Check to see if we can find a "Behaviour.widget" new_target = None if len(parts) > 0: new_target = self._form_traverse(target,part+'.'+parts[0]) if new_target is not None: # Remove widget name from stack too parts.pop(0) else: # Find widget in form without behaviour prefix new_target = self._form_traverse(target,part) target = new_target elif hasattr(target,'subform'): # subform-containing widget, only option is to go into subform if part=='widgets': target = target.subform else: target = None else: raise TraversalError('Cannot traverse through '+target.__repr__()) # Could not traverse from target to part if target is None: raise TraversalError(part) # Make the parent of the widget the traversal parent. # This is required for security to work in Zope 2.12 if target is not None: target.__parent__ = aq_inner(self.context) return target raise TraversalError(name)