-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hello Krishnakant,

On 28 Sep 2009, at 20:30, Krishnakant wrote:

> I am Krishnakant from Mumbai (India).

/me has fond childhood memories of Mumbai, living in a shoreside  
apartment on what used to be known as Neapan Sea Road, overlooking  
Baroda palace just down a ways from Breach Candy. I remember that in  
the mornings, there was a bird across the way that seemed to  
constantly urging me to get up and go to school, raucously calling  
"C'mon, c'mon, c'mon".

> I am totally blind and amongst the few blind people who love to do web
> development.

All power to your elbow, squire. Mind you, you're not making it any  
easier for yourself, choosing to use a language with a syntax that is  
whitespace-sensitive - or is that offset by the comparative lack of  
single-character syntax markers such as line-terminating semi-colons,  
etc? Thinking about it for a moment, I guess spoken perl must sound  
like something from Victor Borge's "phonological punctuation" skit.

> Toscawidgets, formbuild, form alchemy, and webhelpers

> Now I would like to know which library will help me to structure the
> layout of the form using python code.

> Now a  a blind person,I have fortunately developed a good imagination
> and I have techniques to visualise layouts like the once I mentioned.
> So such a system is easy for me to handle.
>
> Can some one provide me some advice on this?


I'll give it a go. You'll probably end up mixing and matching to suit  
the task.

As you've already spotted, with webhelpers, layout is left to the  
developer. Instead, webhelpers provides specifically targeted  
solutions, such as the generation (and handling) of CSRF-resistant  
<form> tags. They offer particular and specific solutions to some  
common tasks. Form generation is a whole other ball of wax, which is  
where Toscawidgets (tw, for short), formalchemy and sprox come in ---  
and, given your mention of java, mako form tags [1] which give you a  
basic taglib to build on (but you'd have to craft the rest of it  
yourself, Mako form tags only gives you the building blocks).

Toscawidgets would fit your bill. It runs as middleware. This is the  
simplest expression of a form definition:

import tw.forms as twf

movie_form = twf.TableForm('movie_form', action='save_movie', children=[
     twf.HiddenField('id'),
     twf.TextField('title', validator=twf.validators.NotEmpty),
     twf.TextField('year', size=4),
     twf.CalendarDatePicker('release_date'),
     twf.SingleSelectField('genera', options=['', 'Action', 'Comedy',  
'Other']),
     twf.TextArea('description'),
])

You can define your own custom fields and custom validators. I usually  
import my forms from a "forms" folder containing a file per form, this  
"Page" [2] is a typical example of my approach. As you can see from  
the above, structuring your form is a matter of picking and sequencing  
the field list that is bound to the "children" keyword arg.

A more dynamic means of constructing forms is offered by Toscawidgets  
2 (tw2) [3].

Using tw forms in the controller is quite straightforward:

# instantiate the forms
page_form = PageForm('page_form', location = "headbottom")
new_page_form = NewPageForm('new_page_form', location = "headbottom")

[ ... ]

def new(self):
     """GET /new: Form to create a new item."""
     c.title = _('New Page')
     c.w = WidgetBunch()
     c.w.form = new_page_form
     c.legend = "New Page ..."
     c.value = None
     c.action = url('create_page')
     return render('page_add.mako')

@authorize(SignedIn())
def edit(self, id):
     """GET /id;edit: Form to edit an existing item."""
     c.page = get_object_or_404(model.Page, id=id)
     c.title = c.page.title
     c.w = WidgetBunch()
     c.w.form = page_form
     c.legend = "Editing Page ..."
     c.value = c.page
     c.action = url('save_page', id=id)
     return render('dashboard/page.mako')

To render the form in a Mako template, call the "display()" method  
with the value and action as arg&kwarg.

<div id="twform">
     ${c.w.form.display(c.value, action=c.action)|n}
</div>

As shown above in the "edit" action, to populate a form with values  
for editing, simply bind c.value to the entity to be edited and call  
the display() method with the arg+kwarg.

In tw, forms are rendered as semantic (X)HTML, the tags of which are  
appropriately decorated with class and id values, ready for CSS  
styling. I use a(n ostensibly) accessible form approach published in a  
2006 ALA article "Prettier Accessible Forms" [4], it is readily  
adapted to the fieldset, div and ol structures used in the tw widget  
templates - and if you're up for it, you can hack your own tw widgets  
and templates to suit.

FormAlchemy [5] builds upon tw.forms to present a higher level of  
abstraction - which may or may not suit your specific purpose. FA  
offers standard Fieldset and Grid objects which, when given a SQLA- 
mapped entity as arg, will introspect it and automatically generate a  
form:

fs = FieldSet(User)
fs.configure(options=[]) # put all configuration stuff here
user = session.query(User).first()
c.fs = fs.bind(user)

and in the template:

${c.fs.render()|n}

As ever, most of the effort goes into tweaking the "configure()"  
options.

Sprox [6] takes a schema introspection approach to automatically  
generating forms and offers a reasonably rich means of configuring and  
customizing.

In the example below, a Grid model is shown, the FieldSet equivalent  
runs along much the same lines.

After importing the relevant classes we define a table base class for  
our database entity schema (an "Organization" in this case). The  
schema (model.Organisation) is bound and we get to say which fields  
will be used, set the column widths and identify fields whose value  
will be provided as XML ("logo" in this case) - by a corresponding  
method definition in the associated Filler class. The TableFiller  
provides the values for the grid and overriding the special method:  
do_get_provider_count_and_objs() (as shown below) is the standard  
means of marshalling data for the grid.

import tw.forms as twf, tw.dynforms as twd

from sprox.tablebase import TableBase
from sprox.fillerbase import TableFiller

class OrganisationTable(TableBase):
     __model__ = model.Organisation
     __limit_fields__ = ['title', 'city', 'country', 'logo']
     __column_widths__ = {'title':"30%",
                          'city':"24%",
                          'country':"10%",
                          'logo':"10%"}
     __xml_fields__ = ['logo']

class OrganisationTableFiller(TableFiller):
     __model__ = model.Organisation

     def _do_get_provider_count_and_objs(self, **kw):
         organisations = model.Session.query(
                             model.Organisation).order_by(
                                  
func.lower(model.Organisation.title).asc()).all()
         return len(organisations), organisations

     def logo(self, obj):
         from xml.sax.saxutils import escape
         if obj.logo:
             return '<img height="48" src="%s" alt="%s" />' % \
                     ('/img/logos/%s.gif' % obj.id,  
str(obj.title).replace('&', '&amp;'))
         else:
             return '<span>%s</span>' % escape(str(obj.title))

The sprox dox give full details of the limiting, overriding and  
customising facilities.

In the controller action, the Table and TableFiller is used thusly:

def editindex(self):
     c.table = OrganisationTable(model.Session)
     c.table_value = OrganisationTableFiller(
                         model.Session).get_value()
     return render('editindex.mak')

and in the Mako template:

<div width="100%" style="padding:0;margin:0;">
     ${c.table(value=c.table_value)|n}
</div>

I hope that's given you an idea of the different approaches that are  
available. Given your particular focus, you will need lots of forms  
and will probably want Ajax to handle a goodly part of the interaction  
load. You're going to spend a lot of time on the UI because getting it  
right it will matter, a lot. Some of the forms will be fairly  
straightforward and suitable for auto-generation, some will require a  
lot of configuring and customization --- usually in direct proportion  
to the importance of their role in the user taskflow. There's a degree  
of linkage to javascript libraries but tw2 is planning to make the  
significant move of offering widget controllers for separate  
middleware handling of the Ajax call and response cycle, taking the  
Ajax load off the Pylons controllers. Depending on your approach, that  
might offer you a big win but at some increased risk 'cos tw2 is still  
alpha.

So: your own taglib, a suite of widgets, a couple of introspection- 
based generators or a middleware Ajax facility. At least you have a  
choice.

To be honest, the relative importance of the factors in the choice  
will only really become clear when they are viewed in the full context  
of your planned app - its orientation, the kind of tasks it needs to  
support, the extent of your resources, etc.


[1] http://techspot.zzzeek.org/?p=28
[2] 
http://bitbucket.org/gjhiggins/shabti/src/tip/shabti/templates/microsite/+package+/forms/page.py_tmpl
[3] http://toscawidgets.org/documentation/tw2.core/
[4] http://www.alistapart.com/articles/prettyaccessibleforms
[5] http://docs.formalchemy.org/
[6] http://www.sprox.org/

Cheers,

Graham

http://www.linkedin.com/in/ghiggins




-----BEGIN PGP SIGNATURE-----

iEYEARECAAYFAkrBnMkACgkQOsmLt1Nhivy0swCfeWuYCVG6D3QO6snd+E17QddC
5pMAoOT3VwUfuG5M9PeN6KssTTcB0yZ/iQCVAgUBSsGcyVnrWVZ7aXD1AQKapQQA
wICemCR26bk/8nR9IKSzUE/mIbBAa9N3Lg2KYztCfUfLvbaWyEVQobEQ/BtRjig6
K3kvthT1kBdXyp08YymEl5m6PL4la2RR5MTS3llMTaCM3CtJw5cl97m1pbR22OdJ
D+eT/GXki788SiHLr49AW6ljf5VzvQiclul/ln9wGdo=
=sZJr
-----END PGP SIGNATURE-----


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"pylons-discuss" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/pylons-discuss?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to