Example #1
0
    def __init__(self, values=None, vocabulary=None, source=None, **kw):
        """Initialize object."""
        if vocabulary is not None:
            assert (isinstance(vocabulary, string_types)
                    or IBaseVocabulary.providedBy(vocabulary))
            assert source is None, (
                "You cannot specify both source and vocabulary.")
        elif source is not None:
            vocabulary = source

        assert not (values is None and vocabulary is None), (
            "You must specify either values or vocabulary.")
        assert values is None or vocabulary is None, (
            "You cannot specify both values and vocabulary.")

        self.vocabulary = None
        self.vocabularyName = None
        if values is not None:
            self.vocabulary = SimpleVocabulary.fromValues(values)
        elif isinstance(vocabulary, string_types):
            self.vocabularyName = vocabulary
        else:
            assert (ISource.providedBy(vocabulary)
                    or IContextSourceBinder.providedBy(vocabulary))
            self.vocabulary = vocabulary
        # Before a default value is checked, it is validated. However, a
        # named vocabulary is usually not complete when these fields are
        # initialized. Therefore signal the validation method to ignore
        # default value checks during initialization of a Choice tied to a
        # registered vocabulary.
        self._init_field = (bool(self.vocabularyName) or
                            IContextSourceBinder.providedBy(self.vocabulary))
        super(Choice, self).__init__(**kw)
        self._init_field = False
Example #2
0
    def __init__(self, values=None, vocabulary=None, source=None, **kw):
        """Initialize object."""
        if vocabulary is not None:
            assert (isinstance(vocabulary, basestring)
                    or IBaseVocabulary.providedBy(vocabulary))
            assert source is None, (
                "You cannot specify both source and vocabulary.")
        elif source is not None:
            vocabulary = source

        assert not (values is None and vocabulary is None), (
               "You must specify either values or vocabulary.")
        assert values is None or vocabulary is None, (
               "You cannot specify both values and vocabulary.")

        self.vocabulary = None
        self.vocabularyName = None
        if values is not None:
            self.vocabulary = SimpleVocabulary.fromValues(values)
        elif isinstance(vocabulary, (unicode, str)):
            self.vocabularyName = vocabulary
        else:
            assert (ISource.providedBy(vocabulary) or
                    IContextSourceBinder.providedBy(vocabulary))
            self.vocabulary = vocabulary
        # Before a default value is checked, it is validated. However, a
        # named vocabulary is usually not complete when these fields are
        # initialized. Therefore signal the validation method to ignore
        # default value checks during initialization of a Choice tied to a
        # registered vocabulary.
        self._init_field = (bool(self.vocabularyName) or
                            IContextSourceBinder.providedBy(self.vocabulary))
        super(Choice, self).__init__(**kw)
        self._init_field = False
    def _get_vocabulary_value(self, obj, value):
        res = value
        if res:
            vocabulary = self.field.vocabulary
            # for source vocabulary
            if IContextSourceBinder.providedBy(vocabulary):
                vocabulary = vocabulary(obj)
            # for named vocabulary
            if not vocabulary:
                vocabularyName = self.field.vocabularyName
                if vocabularyName:
                    vocabulary = getUtility(IVocabularyFactory,
                                            name=vocabularyName)(obj)

            if vocabulary:
                try:
                    term = vocabulary.getTermByToken(value)
                except LookupError:
                    term = None
            else:
                term = None

            if term:
                title = term.title
                if not title:
                    res = value
                else:
                    res = title
            else:
                res = value
        return safe_unicode(res)
Example #4
0
    def additional(self):
        vocab_name = getattr(self.field, "vocabularyName", None)
        if vocab_name:
            return {
                "vocabulary": {
                    "@id":
                    get_vocabulary_url(vocab_name, self.context, self.request)
                }
            }

        # Maybe we have an unnamed vocabulary or source.

        vocabulary = getattr(self.field, "vocabulary", None)
        if IContextSourceBinder.providedBy(vocabulary):
            vocabulary = vocabulary(self.context)

        if hasattr(vocabulary, "__iter__") and self.should_render_choices:
            # choices and enumNames are v5 proposals, for now we implement both
            choices = []
            enum = []
            enum_names = []

            for term in vocabulary:
                title = translate(term.title, context=self.request)
                choices.append((term.token, title))
                enum.append(term.token)
                enum_names.append(title)

            return {"enum": enum, "enumNames": enum_names, "choices": choices}
        else:
            return {}
Example #5
0
    def additional(self):
        # choices and enumNames are v5 proposals, for now we implement both
        choices = []
        enum = []
        enum_names = []
        if self.field.vocabularyName:
            vocabulary = getUtility(
                IVocabularyFactory,
                name=self.field.vocabularyName)(self.context)
        else:
            vocabulary = self.field.vocabulary

        if IContextSourceBinder.providedBy(vocabulary):
            vocabulary = vocabulary(self.context)

        if hasattr(vocabulary, '__iter__') and self.should_render_choices:
            for term in vocabulary:
                title = translate(term.title, context=self.request)
                choices.append((term.token, title))
                enum.append(term.token)
                enum_names.append(title)

            return {
                'enum': enum,
                'enumNames': enum_names,
                'choices': choices,
            }
        else:
            return {}
Example #6
0
def choicePersistentFieldAdapter(context):
    """Special handling for Choice fields.
    """

    instance = persistentFieldAdapter(context)
    if instance is None:
        return None

    if ISource.providedBy(context.vocabulary) or \
            IContextSourceBinder.providedBy(context.vocabulary):

        safe = False

        # Attempt to reverse engineer a 'values' argument
        if isinstance(context.vocabulary, SimpleVocabulary):
            values = []
            safe = True
            for term in context.vocabulary:
                if term.token == str(term.value) and is_primitive(term.value):
                    values.append(term.value)
                else:
                    safe = False
                    break
            if safe:
                instance._values = values

        if not safe:
            __traceback_info__ = "Persistent fields only support named vocabularies " + \
                                    "or vocabularies based on simple value sets."
            return None

    return instance
Example #7
0
def choicePersistentFieldAdapter(context):
    """Special handling for Choice fields.
    """
    
    instance = persistentFieldAdapter(context)
    if instance is None:
        return None
    
    if ISource.providedBy(context.vocabulary) or \
            IContextSourceBinder.providedBy(context.vocabulary):
        
        safe = False
        
        # Attempt to reverse engineer a 'values' argument
        if isinstance(context.vocabulary, SimpleVocabulary):
            values = []
            safe = True
            for term in context.vocabulary:
                if term.token == str(term.value) and is_primitive(term.value):
                    values.append(term.value)
                else:
                    safe = False
                    break
            if safe:
                instance._values = values
        
        if not safe:
            __traceback_info__ = "Persistent fields only support named vocabularies " + \
                                    "or vocabularies based on simple value sets."
            return None

    return instance
Example #8
0
    def bound_source(self):
        if self._bound_source is None:
            source = self.source
            if IContextSourceBinder.providedBy(source):
                source = source(self.context)
            assert ISource.providedBy(source)

            # custom
            if IElephantVocabulary.providedBy(source):
                try:
                    # If we cannot adapt the behavior or schema interface,
                    # the context is wrong (e.g. we are one add form on the
                    # parent). So we skip adding the current value.
                    storage = self.field.interface(self.context)
                except TypeError:
                    value = None
                else:
                    value = getattr(storage, self.field.__name__)

                if value and value not in source.vocab:
                    term = source.vocab.createTerm(
                        value, value, value)
                    source.vocab._terms.append(term)
                    source.vocab.by_value[term.value] = term
                    source.vocab.by_token[term.token] = term
                    source.hidden_terms.append(value)
            # end custom
            self._bound_source = source
        return self._bound_source
Example #9
0
    def _get_vocabulary(self, field):
        """Try to determine the vocabulary for a field, if possible.

        Loosely based on z3c.form.widget.Widget.update().
        """
        field_vocab = None
        vf = None
        if isinstance(field, Choice):
            # First check whether an override is defined in the configuration
            # for vocabularies we can't (or don't want to) serialize
            override = self._get_vocab_override(field)
            if override is not None:
                return override

            elif field.vocabulary:
                if IVocabularyFactory.providedBy(field.vocabulary):
                    vf = field.vocabulary
                # we (sometimes) use IContextSourceBinder independent of
                # context - for fields where we don't we should define an
                # override
                elif IContextSourceBinder.providedBy(field.vocabulary):
                    vf = field.vocabulary
            elif field.vocabularyName:
                try:
                    vf = getUtility(
                        IVocabularyFactory, name=field.vocabularyName)
                except ComponentLookupError:
                    pass

            if vf is not None:
                # Ignore context dependent vocabularies
                vocabulary = vf(None)
                terms = [t.value for t in vocabulary._terms]
                field_vocab = terms
        return field_vocab
    def bound_source(self):
        if self._bound_source is None:
            source = self.source
            if IContextSourceBinder.providedBy(source):
                source = source(self.context)
            assert ISource.providedBy(source)

            # custom
            if IElephantVocabulary.providedBy(source):
                try:
                    # If we cannot adapt the behavior or schema interface,
                    # the context is wrong (e.g. we are one add form on the
                    # parent). So we skip adding the current value.
                    storage = self.field.interface(self.context)
                except TypeError:
                    value = None
                else:
                    value = getattr(storage, self.field.__name__)

                if value and value not in source.vocab:
                    contact_info = getUtility(IContactInformation)
                    term = source.vocab.createTerm(
                        value, value, contact_info.describe(value))
                    source.vocab._terms.append(term)
                    source.vocab.by_value[term.value] = term
                    source.vocab.by_token[term.token] = term
                    source.hidden_terms.append(value)
            # end custom
            self._bound_source = source
        return self._bound_source
Example #11
0
 def bound_source(self):
     if self._bound_source is None:
         source = self.source
         if IContextSourceBinder.providedBy(source):
             source = source(self.context)
         assert ISource.providedBy(source)
         self._bound_source = source
     return self._bound_source
Example #12
0
 def bound_source(self):
     if self._bound_source is None:
         source = self.source
         if IContextSourceBinder.providedBy(source):
             source = source(self.context)
         assert ISource.providedBy(source)
         self._bound_source = source
     return self._bound_source
Example #13
0
def patched_init(self, context, request, form, field, widget):
    self.context = context
    self.request = request
    self.form = form
    self.field = field
    self.widget = widget
    if field.vocabulary is None or IContextSourceBinder.providedBy(field.vocabulary):
        field = field.bind(context)
    self.terms = field.vocabulary
Example #14
0
    def _get_vocabulary(self, field):
        """Try to determine the vocabulary for a field, if possible.

        Loosely based on z3c.form.widget.Widget.update().
        """
        # XXX: Refactor this method

        field_vocab = None
        vf = None
        if isinstance(field, Choice):
            # First check whether an override is defined in the configuration
            # for vocabularies we can't (or don't want to) serialize
            override = self._get_vocab_override(field)
            if override is not None:
                return override

            elif field.vocabulary:
                if IVocabularyFactory.providedBy(field.vocabulary):
                    vocabulary = field.vocabulary(None)
                elif IContextSourceBinder.providedBy(field.vocabulary):
                    vocabulary = field.vocabulary(None)
                else:
                    vocabulary = field.vocabulary

            elif field.vocabularyName:
                try:
                    vf = getUtility(
                        IVocabularyFactory, name=field.vocabularyName)
                except ComponentLookupError:
                    pass

                vocabulary = vf(None)

            # Determine whether term order is significant or not
            order_significant = True
            wrapped_vocab = vocabulary
            if IElephantVocabulary.providedBy(vocabulary):
                # VDEX vocaby might be potentially wrapped by Elephant vocabs.
                # In that case, we need to inspect the wrapped vocab to
                # determine whether order is significant or not
                wrapped_vocab = queryUtility(
                    IVocabularyFactory, name=field.vocabulary.vocab)

            if isinstance(wrapped_vocab, VdexVocabulary):
                order_significant = wrapped_vocab.vdex.isOrderSignificant()

            # Build list of terms
            if vocabulary is not None:
                terms = [t.value for t in vocabulary._terms]

                if not order_significant:
                    # For VDEX vocabularies with orderSignificant="false" we
                    # explicitly sort terms to get a stable sort order
                    terms = sorted(terms)

                field_vocab = terms
        return field_vocab
Example #15
0
    def additional(self):
        # Named global vocabulary
        vocab_name = getattr(self.field, "vocabularyName", None)
        if vocab_name:
            return {
                "vocabulary": {
                    "@id": get_vocabulary_url(vocab_name, self.context, self.request)
                }
            }

        # Maybe an unnamed vocabulary or source.
        vocabulary = getattr(self.field, "vocabulary", None)
        if IContextSourceBinder.providedBy(vocabulary):
            vocabulary = vocabulary(self.context)

        # Query source
        if IQuerySource.providedBy(vocabulary):
            return {
                "querysource": {
                    "@id": get_querysource_url(self.field, self.context, self.request)
                }
            }

        # Unamed ISource or vocabulary - render link addressing it via field
        #
        # Even though the URL will point to the @sources endpoint, we also
        # list it under the 'vocabulary' key, because the semantics for an
        # API consumer are exactly the same: A GET to that URL will enumerate
        # terms, and will support batching and filtering by title/token.
        result = {
            "vocabulary": {
                "@id": get_source_url(self.field, self.context, self.request)
            }
        }

        # Optionally inline choices for unnamed sources
        # (this is for BBB, and may eventually be deprecated)
        if hasattr(vocabulary, "__iter__") and self.should_render_choices:
            # choices and enumNames are v5 proposals, for now we implement both
            choices = []
            enum = []
            enum_names = []

            for term in vocabulary:
                if term.title:
                    title = translate(term.title, context=self.request)
                else:
                    title = None
                choices.append((term.token, title))
                enum.append(term.token)
                enum_names.append(title)

            result.update({"enum": enum, "enumNames": enum_names, "choices": choices})

        return result
Example #16
0
    def __init__(self, values=None, vocabulary=None, source=None, **kw):
        """Initialize object."""
        if vocabulary is not None:
            if (not isinstance(vocabulary, string_types)
                    and not IBaseVocabulary.providedBy(vocabulary)):
                raise ValueError('vocabulary must be a string or implement '
                                 'IBaseVocabulary')
            if source is not None:
                raise ValueError(
                    "You cannot specify both source and vocabulary.")
        elif source is not None:
            vocabulary = source

        if (values is None and vocabulary is None):
            raise ValueError(
                "You must specify either values or vocabulary."
            )
        if values is not None and vocabulary is not None:
            raise ValueError(
                "You cannot specify both values and vocabulary."
            )

        self.vocabulary = None
        self.vocabularyName = None
        if values is not None:
            self.vocabulary = SimpleVocabulary.fromValues(values)
        elif isinstance(vocabulary, string_types):
            self.vocabularyName = vocabulary
        else:
            if (not ISource.providedBy(vocabulary)
                    and not IContextSourceBinder.providedBy(vocabulary)):
                raise ValueError('Invalid vocabulary')
            self.vocabulary = vocabulary
        # Before a default value is checked, it is validated. However, a
        # named vocabulary is usually not complete when these fields are
        # initialized. Therefore signal the validation method to ignore
        # default value checks during initialization of a Choice tied to a
        # registered vocabulary.
        self._init_field = (bool(self.vocabularyName) or
                            IContextSourceBinder.providedBy(self.vocabulary))
        super(Choice, self).__init__(**kw)
        self._init_field = False
Example #17
0
 def bind(self, object):
     clone = zope.schema.Field.bind(self, object)
     # get registered vocabulary if needed:
     if IContextSourceBinder.providedBy(self.vocabulary):
         clone._vocabulary = self.vocabulary(object)
         assert zope.schema.interfaces.ISource.providedBy(clone.vocabulary)
     elif clone.vocabulary is None and self.vocabularyName is not None:
         vr = zope.schema.vocabulary.getVocabularyRegistry()
         clone._vocabulary = vr.get(object, self.vocabularyName)
         assert zope.schema.interfaces.ISource.providedBy(clone.vocabulary)
     return clone
Example #18
0
    def bind(self, object):
        """See zope.schema._bootstrapinterfaces.IField."""
        clone = super(Choice, self).bind(object)
        # get registered vocabulary if needed:
        if IContextSourceBinder.providedBy(self.vocabulary):
            clone.vocabulary = self.vocabulary(object)
            assert ISource.providedBy(clone.vocabulary)
        elif clone.vocabulary is None and self.vocabularyName is not None:
            vr = getVocabularyRegistry()
            clone.vocabulary = vr.get(object, self.vocabularyName)
            assert ISource.providedBy(clone.vocabulary)

        return clone
Example #19
0
    def bind(self, object):
        """See zope.schema._bootstrapinterfaces.IField."""
        clone = super(Choice, self).bind(object)
        # get registered vocabulary if needed:
        if IContextSourceBinder.providedBy(self.vocabulary):
            clone.vocabulary = self.vocabulary(object)
            assert ISource.providedBy(clone.vocabulary)
        elif clone.vocabulary is None and self.vocabularyName is not None:
            vr = getVocabularyRegistry()
            clone.vocabulary = vr.get(object, self.vocabularyName)
            assert ISource.providedBy(clone.vocabulary)

        return clone
Example #20
0
 def _constructField(self, attributes):
     if 'vocabulary' in attributes:
         try:
             component = resolve(attributes['vocabulary'])
             if IBaseVocabulary.providedBy(component):
                 attributes['vocabulary'] = component
             elif (ISource.providedBy(component)
                   or IContextSourceBinder.providedBy(component)):
                 attributes['source'] = component
                 del attributes['vocabulary']
         except ImportError:
             # regular named vocabulary, leave as is
             pass
     return super(QueryChoiceHandler, self)._constructField(attributes)
Example #21
0
 def getChoices(self, form):
     source = self.source
     if source is None:
         factory = self.vocabularyFactory
         assert factory is not None, \
             "No vocabulary source available."
         if (IContextSourceBinder.providedBy(factory) or
             IVocabularyFactory.providedBy(factory)):
             source = factory(form.context)
         elif IFormSourceBinder.providedBy(factory):
             source = factory(form)
         assert IVocabularyTokenized.providedBy(source), \
             "No valid vocabulary available, %s is not valid for %s" % (
             source, self)
     return source
Example #22
0
    def __init__(self, value_type, vocabulary, **kw):
        
        # complain if value_type is not a field
        if value_type is not None and not IField.providedBy(value_type):#IGNORE:E1101
            raise ValueError("'value_type' must be field instance.")
        self.value_type = value_type
        self.vocabulary = None
        self.vocabularyName = None

        if isinstance(vocabulary, (unicode, str)):
            self.vocabularyName = vocabulary
        else: 
            assert (ISource.providedBy(vocabulary) or             #IGNORE:E1101
                    IContextSourceBinder.providedBy(vocabulary))  #IGNORE:E1101
            self.vocabulary = vocabulary
        self._init_field = bool(self.vocabularyName)
        Field.__init__(self, **kw)      # initializing List or Choice would mess up 
                                        # the vocabulary 
        self._init_field = False
Example #23
0
    def _resolve_vocabulary(self, value):
        # Find the vocabulary we should use, raising
        # an exception if this isn't possible, and returning
        # an ISource otherwise.
        vocabulary = self.vocabulary
        if IContextSourceBinder.providedBy(vocabulary) and self.context is not None:
            vocabulary = vocabulary(self.context)
        elif vocabulary is None and self.vocabularyName is not None:
            vr = getVocabularyRegistry()
            try:
                vocabulary = vr.get(self.context, self.vocabularyName)
            except LookupError:
                raise MissingVocabularyError(
                    "Can't validate value without vocabulary named %r" % (self.vocabularyName,)
                ).with_field_and_value(self, value)

        if not ISource.providedBy(vocabulary):
            raise InvalidVocabularyError(vocabulary).with_field_and_value(self, value)

        return vocabulary
Example #24
0
    def additional(self):
        # choices and enumNames are v5 proposals, for now we implement both
        choices = []
        enum = []
        enum_names = []
        vocabulary = None

        if getattr(self.field, 'vocabularyName', None):
            vocabulary = getUtility(IVocabularyFactory,
                                    name=self.field.vocabularyName)(
                                        self.context)
        elif getattr(self.field, 'vocabulary', None):
            vocabulary = self.field.vocabulary
        else:
            tagged = get_tagged_values([self.field.interface], WIDGETS_KEY)
            tagged_field_values = tagged.get(self.field.getName(), {})
            vocab_name = tagged_field_values.get('vocabulary', None)
            if vocab_name:
                vocab_fac = getUtility(IVocabularyFactory, name=vocab_name)
                vocabulary = vocab_fac(self.context)

        if IContextSourceBinder.providedBy(vocabulary):
            vocabulary = vocabulary(self.context)

        if hasattr(vocabulary, '__iter__') and self.should_render_choices:
            for term in vocabulary:
                title = translate(term.title, context=self.request)
                choices.append((term.token, title))
                enum.append(term.token)
                enum_names.append(title)

            return {
                'enum': enum,
                'enumNames': enum_names,
                'choices': choices,
            }
        else:
            return {}
    def __call__(self):
        self.request.response.setHeader(
            'Content-Type', 'application/json; charset=utf-8')

        field = self.request['field']
        slavename = self.request['name']
        slaveid = self.request['slaveID']
        masterid = self.request['masterID']
        value = self.request['value']

        for slave in self.widget.getSlaves():
            # Loop until we find the slave we want
            if slave['name'] != slavename:
                continue

            action = slave.get('action')
            if action not in ['vocabulary', 'value', 'attr']:
                continue

            # --- VALUE --------------------------------------------------------
            if action == 'value':
                value = self.getVocabulary(slave, value, '')
                return json.dumps(translate(value, self.request))

            # --- ATTR- --------------------------------------------------------
            if action == 'attr':
                result = self.getVocabulary(slave, value, None)
                if isinstance(result, dict) and 'attr' in result and 'value' in result:
                    return json.dumps(result)
                else:
                    raise ValueError('Bad attr dictionary for %s.' % slavename)

            # --- VOCABULARY ---------------------------------------------------
            vocabulary = self.getVocabulary(slave, value)

            if isinstance(vocabulary, (tuple, list)):
                vocabulary = self.createVocaabulary(vocabulary)

            widget = self.widget.form.widgets.get(slave['name'])
            if widget is None:
                raise ValueError('Can not find widget: %s' % slave['name'])

            if (IContextSourceBinder.providedBy(vocabulary)
                or IVocabularyTokenized.providedBy(vocabulary)):

                if hasattr(widget.field, 'value_type'):
                    widget.field.value_type.vocabulary = vocabulary
                else:
                    widget.field.vocabulary = vocabulary
                widget.terms = None
                widget.updateTerms()
                widget.update()
                # widget may define items as a property or as a method
                items = widget.items if not callable(widget.items) else widget.items() 
                responseJSON = {'items': items}

                # disable select box if term length = 'disable_length'
                #if len(widget.terms) == slave.get('disable_length', None):
                #    responseJSON['disabled'] = True

                return json.dumps(responseJSON)

        raise ValueError('No such master-slave combo')
Example #26
0
    def __call__(self):
        self.request.response.setHeader('Content-Type',
                                        'application/json; charset=utf-8')

        field = self.request['field']
        slavename = self.request['name']
        slaveid = self.request['slaveID']
        masterid = self.request['masterID']
        value = self.request['value']

        for slave in self.widget.getSlaves():
            # Loop until we find the slave we want
            if slave['name'] != slavename:
                continue

            action = slave.get('action')
            if action not in ['vocabulary', 'value', 'attr']:
                continue

            # --- VALUE --------------------------------------------------------
            if action == 'value':
                value = self.getVocabulary(slave, value, '')
                return json.dumps(translate(value, self.request))

            # --- ATTR- --------------------------------------------------------
            if action == 'attr':
                result = self.getVocabulary(slave, value, None)
                if isinstance(result,
                              dict) and 'attr' in result and 'value' in result:
                    return json.dumps(result)
                else:
                    raise ValueError('Bad attr dictionary for %s.' % slavename)

            # --- VOCABULARY ---------------------------------------------------
            vocabulary = self.getVocabulary(slave, value)

            if isinstance(vocabulary, (tuple, list)):
                vocabulary = self.createVocaabulary(vocabulary)

            widget = self.widget.form.widgets.get(slave['name'])
            if widget is None:
                raise ValueError('Can not find widget: %s' % slave['name'])

            if (IContextSourceBinder.providedBy(vocabulary)
                    or IVocabularyTokenized.providedBy(vocabulary)):

                widget.field = copy.copy(widget.field)
                if hasattr(widget.field, 'value_type'):
                    widget.field.value_type.vocabulary = vocabulary
                else:
                    widget.field.vocabulary = vocabulary
                widget.terms = None
                widget.updateTerms()
                widget.update()
                # widget may define items as a property or as a method
                items = widget.items if not callable(
                    widget.items) else widget.items()
                # translate if possible. content can be a Message, a string, a unicode
                for item in items:
                    item['content'] = translate(safe_unicode(item['content']),
                                                context=self.request)
                responseJSON = {'items': items}

                # disable select box if term length = 'disable_length'
                #if len(widget.terms) == slave.get('disable_length', None):
                #    responseJSON['disabled'] = True

                return json.dumps(responseJSON)

        raise ValueError('No such master-slave combo: %s %s' %
                         (field, slavename))