And, more or less, with some slight differences in spellings, and one
additional feature this is what is now in Colander 0.8:

http://docs.repoze.org/colander/binding.html

- C


On Wed, 2010-09-08 at 12:25 -0400, Chris McDonough wrote:
> I've been thinking about how to solve this problem, and what I've come
> up with so far is this:
> 
> - Schemas may be bound to a set of values.  When a schema is bound, 
>   it is cloned, and any "deferred" values it has will be resolved.
> 
> - A deferred value is a callable that accepts the schema node being
>   bound and a set of arbitrary keyword arguments.  It should
>   return a value appropriate for its usage (a widget, a missing value,
>   a validator, etc).
> 
> - Deferred values are not resolved until the schema is bound.
> 
> - Schemas are bound via "SomeSchema().bind(**kw)".  The values in "kw"
>   are passed to each deferred value along with the schema node being
>   bound.
> 
> Here's an example:
> 
> """
> @colander.deferred
> def deferred_date_validator(node, **kw):
>     max_date = kw.get('max_date')
>     if max_date is None:
>         max_date = datetime.date.today()
>     return colander.Range(min=datetime.date.min, max=max_date)
> 
> @colander.deferred
> def deferred_date_description(node, **kw):
>     max_date = kw.get('max_date')
>     if max_date is None:
>         max_date = datetime.date.today()
>     return 'Blog post date (no earlier than %s)' % max_date.ctime()
> 
> @colander.deferred
> def deferred_date_missing(node, **kw):
>     default_date = kw.get('default_date')
>     if default_date is None:
>         default_date = datetime.date.today()
>     return default_date
> 
> @colander.deferred
> def deferred_body_validator(node, **kw):
>     max_bodylen = kw.get('max_bodylen')
>     if max_bodylen is None:
>         max_bodylen = 1 << 18
>     return colander.Length(max=max_bodylen)
> 
> @colander.deferred
> def deferred_body_description(node, **kw):
>     max_bodylen = kw.get('max_bodylen')
>     if max_bodylen is None:
>         max_bodylen = 1 << 18
>     return 'Blog post body (no longer than %s bytes)' % max_bodylen
> 
> @colander.deferred
> def deferred_body_widget(node, **kw):
>     body_type = kw.get('body_type')
>     if body_type == 'richtext':
>         widget = deform.widget.RichTextWidget()
>     else:
>         widget = deform.widget.TextAreaWidget()
>     return widget
> 
> @colander.deferred
> def deferred_category_validator(node, **kw):
>     categories = kw.get('categories', [])
>     return colander.OneOf([ x[0] for x in categories ])
> 
> @colander.deferred
> def deferred_category_widget(node, **kw):
>     categories = kw.get('categories', [])
>     return deform.widget.RadioChoiceWidget(values=categories)
> 
> class BlogPostSchema(Schema):
>     title = SchemaNode(
>         colander.String(),
>         title = 'Title',
>         description = 'Blog post title',
>         validator = colander.Length(min=5, max=100),
>         widget = deform.widget.TextInputWidget(),
>         )
>     date = SchemaNode(
>         colander.Date(),
>         title = 'Date',
>         missing = deferred_date_missing,
>         description = deferred_date_description,
>         validator = deferred_date_validator,
>         widget = deform.widget.DateInputWidget(),
>         )
>     body = SchemaNode(
>         colander.String(),
>         title = 'Body',
>         description = deferred_body_description,
>         validator = deferred_body_validator,
>         widget = deferred_body_widget,
>         )
>     category = SchemaNode(
>         colander.String(),
>         title = 'Category',
>         description = 'Blog post category',
>         validator = deferred_category_validator,
>         widget = deferred_category_widget,
>         )
>         
> schema = BlogPostSchema().bind(
>     max_date = datetime.date.max,
>     max_bodylen = 5000,
>     body_type = 'richtext',
>     default_date = datetime.date.today(),
>     )
> form = deform.Form(schema)
> """
> 
> This proposal does not deal with conditional inclusion or exclusion of
> schema nodes, only resolving deferred schema properties.
> 
> Comments are appreciated.
> 
> - C
> 
> 
> 
> 
> On Tue, 2010-09-07 at 20:37 +0800, Tim Hoffman wrote:
> > Bummer ;-)
> > 
> > 
> > I don't think I have a developed an application in the last 10 years
> > that hasn't has to do this.
> > I was quite surprised when I discovered this feature was missing in
> > formish, but it seems to be missing in quite a
> > few other form libs like wtforms as well.
> > 
> > I suppose at least they all have declarative method of defining the
> > schema, but it does mean the actual schema definition is a bit more
> > obscured.
> > 
> > Cheers
> > 
> > T
> > 
> > 
> > 
> > 
> > On Tue, Sep 7, 2010 at 8:20 PM, Chris McDonough <chr...@plope.com> wrote:
> > > Hi Tim,
> > >
> > > Sorry, there is no built-in solution that will allow you to use
> > > declarative-module-scope code only.  You'll need to generate schemas and
> > > widgets at render time.
> > >
> > > - C
> > >
> > >
> > > On Tue, 2010-09-07 at 12:56 +0800, Tim Hoffman wrote:
> > >> Hi Chris.
> > >>
> > >> Am just starting too look at deform in some detail and I have question.
> > >>
> > >> One of the things I have struggled with formish has been the fact I
> > >> can't easily
> > >> define a source of values for widgets like checkbox or validators such
> > >> as OneOf to
> > >> only be resolved late at render time. And I can't see how I would go
> > >> about it with deform.
> > >>
> > >> In your example http://docs.repoze.org/deform/app.html you have
> > >>  colors = (('red', 'Red'), ('green', 'Green'), ('blue', 'Blue')) used
> > >> as values for
> > >>
> > >> widget.RadioChoiceWidget values and for the validator OneOf
> > >>
> > >> So in my contrived example I would like the set of possible values
> > >> for color is dependent on the
> > >> user and some other factor.  Looking at the code for SelectWidget and
> > >> RadioChoice widget
> > >> it appears they won't take a callable and lazily render those values
> > >> at render time.
> > >>
> > >>
> > >> With formish I basically constructed the form structure (schema)
> > >> but only applied widget definitions  and validators just before render
> > >> time. So that I could use things
> > >> like the current context to determine values for validation or
> > >> choices.  This was a bit of a hack.
> > >>
> > >>
> > >> So do you have a strategy or suggestion on how to approach this use case 
> > >> ?
> > >>
> > >> I suppose I could work with imperative schema definition performed
> > >> late, but I much prefer to work with classes.
> > >> (I currently generate Formish (structures) directly from UML).
> > >>
> > >> Cheers
> > >>
> > >> Tim
> > >> _______________________________________________
> > >> Repoze-dev mailing list
> > >> Repoze-dev@lists.repoze.org
> > >> http://lists.repoze.org/listinfo/repoze-dev
> > >>
> > >
> > >
> > >
> > 
> 


_______________________________________________
Repoze-dev mailing list
Repoze-dev@lists.repoze.org
http://lists.repoze.org/listinfo/repoze-dev

Reply via email to