def render_tag(self, *value, **extra_attributes): """ return a piece of unicode HTML that """ assert len(value) <= 1, "Can't pass more than one argument as value" inner = [] attributes = {} # notice the order of these update() calls! It matters name_prefix = extra_attributes.pop("name_prefix", "") # It's an option to called render_tag() with in_filter=True which tells # us that this tag is rendered as a filter, in the filter options. # This is something that can be done on-the-fly and it means that # certain things should work differently. For example, a 'select' type # input get's an added 'size' and 'multiple' attribute when used as a # filter. in_filter = extra_attributes.pop("in_filter", False) # core attributes dom_id = self.attributes.get("dom_id", "id_%s" % self.getId()) attributes.update({"name": self._wrapPythonTypeName(name_prefix), "id": dom_id, "title": self.getTitle()}) # saved attributes attributes.update(dict(self.attributes)) # extra on rendering attributes attributes.update(extra_attributes) # Now, "hack" the attributes if this is used in a filter if in_filter: if self.input_type == "select": attributes["multiple"] = "multiple" if "size" not in attributes: attributes["size"] = min(5, len(list(self.getOptionsIterable()))) # filler is a dict that we will use to render the template filler = {} if self.input_type == "textarea": template = u"<textarea %(inner)s>%(value)s</textarea>" v = None if value: v = value[0] # from the argument elif "value" in attributes: v = attributes.pop("value") if v: filler["value"] = Utils.safe_html_quote(v) else: filler["value"] = u"" elif self.input_type == "select": template = u"<select %(inner)s>\n%(all_options)s\n</select>" all_options = [] v = [] if value: v = value[0] # makes sure the value doesn't become a nested list if isinstance(v, list): v = Utils.flatten_lines(v) elif "value" in attributes: v = attributes.pop("value") if not isinstance(v, (tuple, list)): v = [v] # if the value passed to render this select contains # items that are not in the list of options, don't # use the list of options. _values_selected = [] for option in self.getOptionsIterable(): if isinstance(option, (tuple, list)): value, label = option else: value, label = option, option if self.getPythonType() == "int": try: value = int(value) except ValueError: pass elif self.getPythonType() == "float": try: value = float(value) except ValueError: pass if value in v: tmpl = u'<option value="%s" selected="selected">%s</option>' _values_selected.append(value) else: tmpl = u'<option value="%s">%s</option>' all_options.append(tmpl % (value, label)) if Set(v) - Set(_values_selected): # there were values that weren't in the list of options! _values_not_in_options = list(Set(v) - Set(_values_selected)) # if nothing was matched in the list of options, # reset the whole all_options list. if not _values_selected and all_options: all_options = [] for value in _values_not_in_options: label = value tmpl = u'<option value="%s" selected="selected">%s</option>' all_options.append(tmpl % (value, label)) filler["all_options"] = "\n".join(all_options) elif self.input_type == "radio": # special case if not self.getOptionsIterable(): template = u"ERROR: No options" else: template = u"%(all_inputs)s" all_inputs = [] v = None if value: v = value[0] # from the argument elif "value" in attributes: v = attributes.pop("value") special_attributes = "" inner = [] for k, v2 in attributes.items(): if k in ("id",): continue inner.append('%s="%s"' % (k, v2)) if inner: special_attributes = " " + " ".join(inner) for option in self.getOptions(): if isinstance(option, (tuple, list)): value, label = option else: value, label = option, option if value == v: tmpl = u'<input type="radio" value="%s" checked="checked"%s /> %s<br />' else: tmpl = u'<input type="radio" value="%s"%s/> %s<br />' all_inputs.append(tmpl % (value, special_attributes, label)) filler["all_inputs"] = "\n".join(all_inputs) elif self.input_type == "checkbox": # another special case v = None if value: v = value[0] # from the argument elif "value" in attributes: v = attributes.pop("value") # If there are no options you can work this like a normal text input if not self.getOptions(): # but what if it should be a boolean and it's true, then the # tag needs to contain checked="checked" if v: template = u'<input type="checkbox" checked="checked" %(inner)s />' else: template = u'<input type="checkbox" %(inner)s />' else: # crap! template = u"%(all_inputs)s" all_inputs = [] special_attributes = "" inner = [] for k, v2 in attributes.items(): if k in ("id",): continue inner.append('%s="%s"' % (k, v2)) if inner: special_attributes = " " + " ".join(inner) for option in self.getOptions(): if isinstance(option, (tuple, list)): value, label = option else: value, label = option, option if value == v: tmpl = u'<input type="checkbox" value="%s" checked="checked"%s /> %s<br />' else: tmpl = u'<input type="checkbox" value="%s"%s/> %s<br />' all_inputs.append(tmpl % (value, special_attributes, label)) filler["all_inputs"] = "\n".join(all_inputs) elif self.input_type == "password": template = u'<input type="password" %(inner)s />' elif self.input_type == "file": template = u'<input type="file" %(inner)s />' else: # type text template = u"<input %(inner)s />" if not (self.input_type == "radio" or (self.input_type == "checkbox" and self.getOptions())): if value and self.input_type not in ("select",): if value and value[0]: # This overrides the default value attributes["value"] = value[0] for key, val in sorted(attributes.items()): inner.append('%s="%s"' % (key, val)) filler["inner"] = " ".join(inner) return template % filler
def testValidValue(self, value): """ return a tuple of (valid or not [bool], message [unicode]) if the value passes all the validation expressions (assuming the field has any) """ # check the python type if self.python_type == "ustring": # should be possible to do this try: unicode(value) except TypeError: return False, u"Not a unicode string" elif self.python_type == "int": try: int(value) except ValueError: return False, u"Not an integer number" elif self.python_type == "float": try: float(value) except ValueError: return False, u"Not a floating point number" elif self.python_type == "long": try: long(value) except ValueError: return False, u"Not a long integer number" elif self.python_type == "date": try: if isinstance(value, basestring): DateTime(value) except DateError: return False, u"Not a valid date" elif self.python_type == "ulines": if isinstance(value, basestring): try: [unicode(x) for x in value.splitlines()] except ValueError: return False, u"Not a list of unicode strings" elif value is not None: value = Utils.flatten_lines(value) try: [unicode(x) for x in value] except ValueError: return False, u"Not a list of unicode strings" elif self.python_type == "lines": if isinstance(value, basestring): try: [str(x) for x in value.splitlines()] except ValueError: return False, u"Not a list of strings" elif value is not None: value = Utils.flatten_lines(value) try: [str(x) for x in value] except ValueError: return False, u"Not a list of strings" # check each TALES expression for ve in self.getValidationExpressions(): ec = self._getExprContext(self, extra_namespaces=dict(value=value)) ex = Expression(ve.expression) if not bool(ex(ec)): return False, ve.message # by default no validation expression made it invalid return True, None
def setCustomFieldData(self, field, key, value): """ append this to self.custom_fields_data (dict). The parameter @field is the custom field object. """ if field.input_type == "file": # upload the file into the issue and change @value to the id value.read(1) if self._isFile(value): # upload it! folder_id = "upload-%s" % field.getId() if not safe_hasattr(self, folder_id): self.manage_addFolder(folder_id) container = getattr(self, folder_id) ids = self._uploadFileattachments(container, [value]) ids = ["%s/%s" % (folder_id, x) for x in ids] value = ids[0] else: # nothing worth saving return elif field.python_type == "int": value = int(value) elif field.python_type == "float": value = float(value) elif field.python_type == "long": value = long(value) elif field.python_type == "lines": if isinstance(value, tuple): value = list(value) elif isinstance(value, basestring): value = [value] else: # due to way Zope's cast handles <selects> # with name "foo:ulines" you get # ['one', ['two']] value = Utils.flatten_lines(value) assert isinstance(value, list), "value not a list" # every item should be a str value = [str(x) for x in value] elif field.python_type == "ulines": if isinstance(value, tuple): value = list(value) elif isinstance(value, basestring): value = [value] elif value is None: value = [] else: # due to way Zope's cast handles <selects> # with name "foo:ulines" you get # ['one', ['two']] if isinstance(value, list): value = Utils.flatten_lines(value) assert isinstance(value, list), "value not a list it's a %s" % type(value) # every item should be a str value = [unicodify(x) for x in value] elif field.python_type == "date": if isinstance(value, basestring): value = DateTime(value) elif field.python_type == "boolean": value = bool(value) elif field.python_type == "ustring": value = unicodify(value) else: value = str(value) data = getattr(self, "custom_fields_data", None) if data is None: self.custom_fields_data = PersistentMapping() self.custom_fields_data[key] = value