I'm porting my existing project to TG. The project uses Cheetah for dynamic form
generation. For instance, my template is responsible for rendering required
fields with an asterisk, plus some JavaScript checks.
On this evidence I would like to use formencode.htmlfill_schemabuilder to
generate embedded validation schema (it's very simple) along with the form
itself (like in Subway). But I couldn't find any way to do this straight away.
I would appreciate any help!
Thanks in advance,
--
Timur Izhbulatov
OILspace, 26 Leninskaya sloboda, bld. 2, 2nd floor, 115280 Moscow, Russia
P:+7 495 105 7245 + ext.205 F:+7 495 105 7246 E:TimurIz...@oilspace.com
Building Successful Supply Chains - One Solution At A Time.
www.oilspace.com
> I'm porting my existing project to TG. The project uses Cheetah for
> dynamic form
> generation. For instance, my template is responsible for rendering
> required
> fields with an asterisk, plus some JavaScript checks.
>
> On this evidence I would like to use
> formencode.htmlfill_schemabuilder to
> generate embedded validation schema (it's very simple) along with
> the form
> itself (like in Subway). But I couldn't find any way to do this
> straight away.
You could try implementing your own template engine (it's a pretty
simple interface) which does the Cheetah+schemabuilder work for you.
Kevin
You mean http://www.turbogears.org/docs/plugins/template.html? I took a look at
the interface and the TurboCheetah plugin code as example.
Well, looks like it's possible to do the schema work somewhere in load_module.
But how will I use the resulting schema for validation after that? I will need
to make it available in the controller somehow.
>
> On Mon, Sep 04, 2006 at 10:46:06AM -0400, Kevin Dangoor wrote:
>>
>> On Sep 4, 2006, at 3:22 AM, Timur Izhbulatov wrote:
>>
>>> I'm porting my existing project to TG. The project uses Cheetah for
>>> dynamic form
>>> generation. For instance, my template is responsible for rendering
>>> required
>>> fields with an asterisk, plus some JavaScript checks.
>>>
>>> On this evidence I would like to use
>>> formencode.htmlfill_schemabuilder to
>>> generate embedded validation schema (it's very simple) along with
>>> the form
>>> itself (like in Subway). But I couldn't find any way to do this
>>> straight away.
>>
>> You could try implementing your own template engine (it's a pretty
>> simple interface) which does the Cheetah+schemabuilder work for you.
>
> You mean http://www.turbogears.org/docs/plugins/template.html? I
> took a look at
> the interface and the TurboCheetah plugin code as example.
Yes, that was the interface I meant.
> Well, looks like it's possible to do the schema work somewhere in
> load_module.
> But how will I use the resulting schema for validation after that?
> I will need
> to make it available in the controller somehow.
Start with the schema in the controller and pass it back to the
template engine either via expose (I believe arbitrary arguments to
expose will get passed through to the template engine, but I could be
wrong, because that's not something I've ever used) *or* via the
dict. Just as TurboGears itself uses "tg_*" values that are returned
in the dict, you can have your template engine take advantage of
things that are returned in the dict.
Kevin
Kevin,
Sorry, but I still don't get your idea. I agree, I can pass the schema from the
controller to the template engine through expose using its mapping argument. But
how the validate decorator will receive it than?
I mean my controller method has to be decorated by validate at the application
startup but the schema it needs will be generated by the template engine only
after the turbogears.view.base.render() function is called.
Looks like I'm missing something (this is my first TG experience). Could you
please post some code snippets for clarification?
> Sorry, but I still don't get your idea. I agree, I can pass the
> schema from the
> controller to the template engine through expose using its mapping
> argument. But
> how the validate decorator will receive it than?
Ahh. I think I might have missed something with your original
thought. I thought the schema was known beforehand...
if that's not the case, the only way at present to dynamically
provide a schema to validate is by passing a callable (eg a function)
to the decorator, and it will call that at the time that it wants to
do validation. (I know you can do this with the form, I'm not 100%
sure you can do this with a schema...)
> I mean my controller method has to be decorated by validate at the
> application
> startup but the schema it needs will be generated by the template
> engine only
> after the turbogears.view.base.render() function is called.
>
> Looks like I'm missing something (this is my first TG experience).
> Could you
> please post some code snippets for clarification?
Yeah, I was not envisioning the template engine creating the schema.
I was envisioning that the template engine would use a schema that is
passed in.
Kevin
That's what I was afraid of. I have to create my own decorator. The existing
decorators I've seen (like validate) look rather complex (or even scary :)
The problem is that I can build schema only when I already have a business
object which I display form for. In my original application I get an object plus
some metadata for validation from the model and pass everything to the template
engine which generates the form, the validation logic resides in the controller.
My initial goal was to have the form and the schema generated in one place and
get rid of my own validation logic in favour of TG's validate. But taking into
account that I have to write my own decorator and some callable for schema
generation, looks like there is no point in using htmlfill_schemabuilder
anymore.
> Yeah, I was not envisioning the template engine creating the schema.
> I was envisioning that the template engine would use a schema that is
> passed in.
Thank you for the clarification, Kevin!
I don't think you have to write your own decorator. You just need to
pass a callable to @validate.
BTW, the decorator stuff is only a bit scary because it works hard to
preserve the original method signature. We have an overhaul in mind
for TG 1.1 that will behave the same but be extraordinarily simple
inside.
Kevin
Yes, I noticed that @validate checks if form is callable. At that moment I
thought the form argument can be only useful if you are working with widgets. I
didn't use widgets and was focused on validators.
The other thing which confused me was that @validate didn't try to catch any
exception while calling form. I needed to do some kind of "prevalidation" inside
the callable and to return possible validation errors back to the decorator.
While typing this I realized that in case of an error I could merely return the
form validating only the field which caused the error:
class my_callable_form(object):
def __call__(self):
args = cherrypy.request.params
id_ = args.get('id', '')
try:
id_ = self.id_validator.to_python(id_)
except Invalid, error:
return self.get_form_for_id()
data = model.get_metadata(id_)
return self.get_complete_form(data)
Looks good enough.
> BTW, the decorator stuff is only a bit scary because it works hard to
> preserve the original method signature. We have an overhaul in mind
> for TG 1.1 that will behave the same but be extraordinarily simple
> inside.
All this signature magic seem to cause some weird effects (unexpected field
'self'..., multiple values for keyword argument 'foo') in python 2.3. I'll try
to find out more next week.
http://trac.turbogears.org/turbogears/wiki/DynamicValidation
Any suggestions/additions/corrections are welcome.
I knew I was forgetting something when I was writing the docs for
@validate. I'll be incorporating this at some point.