Hello everybody, I am using Quixote and form2 and I must say I am extremely happy with it. There are a few enhancements I would like to propose. *** a 'deaf' attribute: I would like to make it possible to create forms that _don't_ listen to the POST data, e.g. I receive form input, store some data to a database, read some new data from a database and display a new form with new values, but the widget's names are often identical to the ones used for the POST data. If I don't make the new form 'deaf', they POST data interferes with my new values. Other uses include several forms on one page, where you only want one of them to react to user input. *** a set_title() method: Is there a reason why the set_title() method is missing? If not, I propose there should be one. *** localisation: I think for us international users it would be nice if strings that show up in the user interface were not hardcoded into the source code, but could get translated somehow independently from the source. There are a few hard coded strings both in form.py and widget.py, e.g. in Form --> _render_error_notice, the 'required' string in Widget --> parse, the error messages in IntWidget and FloatWidget. I'm not sure what the best method for doing this would be, currently I turned a lot of those strings into class level constants, which i override after importing the widget, but there might be a better way. *** double escape trouble in ButtonWidget --> render_content I had trouble with the line value = (self.label and htmlescape(self.label) or None) My labels ended up getting double escaped. From what I understand from the sources, this method calls htmltag() with value being one of the attributes. htmltag() calls _escape_string() on its attributes, so if value was already htmlescape()'d it now gets escaped a second time. I changed that to simply value = self.label and it seems to work for me, but am I missing something here? So long, Stefan the patches: *** a 'deaf' attribute: in class Widget: -------- 8< ------------- 8< ------------- 8< ------------- def __init__(self, name, value=None, title="", hint="", required=False, - render_br=True, attrs=None, **kwattrs): + render_br=True, deaf = False, attrs=None,**kwattrs): assert self.__class__ is not Widget, "abstract class" self.name = name self.value = value self.error = None self.title = title self.hint = hint self.required = required self.render_br = render_br + self.deaf = deaf self.attrs = merge_attrs(attrs, kwattrs) self._parsed = False -------- 8< ------------- 8< ------------- 8< ------------- -------- 8< ------------- 8< ------------- 8< ------------- def parse(self, request=None): if not self._parsed: self._parsed = True if request is None: request = get_request() - if request.form: + if not self.deaf and request.form: try: self._parse(request) except WidgetValueError, exc: self.set_error(str(exc)) if (self.required and self.value is None and not self.has_error()): self.set_error('required') return self.value -------- 8< ------------- 8< ------------- 8< ------------- in class OptionSelectWidget: -------- 8< ------------- 8< ------------- 8< ------------- def parse(self, request=None): if not self._parsed: if request is None: request = get_request() - self._parse(request) + if not self.deaf: + self._parse(request) self._parsed = True return self.value -------- 8< ------------- 8< ------------- 8< ------------- *** a set_title() method: in class Widget: -------- 8< ------------- 8< ------------- 8< ------------- def clear_error(self, request=None): self.parse(request=request) self.error = None + def set_title(self, title): + self.title = title + def get_title(self): return self.title def set_hint(self, hint): self.hint = hint -------- 8< ------------- 8< ------------- 8< -------------