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
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)
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 {}
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 {}
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
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
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
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
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
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
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
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
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
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
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)
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
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
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
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')
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))