-----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('&', '&'))
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
-~----------~----~----~----~------~----~------~--~---