[Paste] webob "marshalling"

Top Page
Author: Chris McDonough
Date:  
To: paste-users
Subject: [Paste] webob "marshalling"

Zope2 has a handy feature that allows you to add "modifiers" to form element
(and query string element) names, e.g. for a form posted with a field named
"foo:int", Zope will present the field "foo" as an integer value when it's
retrieved from its request object a certain way. There are other handy
modifiers, such as grouping fields into records, and marshalling a number of
fields into a single list, and so on (see the below "science fiction" docs for
more).

I've spent a little time working code supporting this feature into WebOb.
Essentially, when you access:

request.marshalled

It returns a dictionary with the marshalled elements (from both the query string
and the POST file pointer, if any).

similar methods exist:

request.marshalled_GET

and

request.marshalled_POST

Should I bother submitting a patch (or checking in) or is this too much of a
clash of worlds?

Science fiction docs...

Marshalling
-----------

Marshalling is a feature of webob which will return a dictionary back
containing "converted" form/query string elements. The form and query
string elements contained in the request are converted into simple
Python types when the form element names are decorated with special
suffixes. For example, in an HTML form that you'd like monty to
convert a form element for, you might say::

   <form action=".">
      Age : <input type="hidden" name="age:int" value="20"/>
      <input type="submit" name="Submit"/>
   </form>

Likewise, in the query string of the URL, you could put::

    http://example.com/mypage?age:int=20

In both of these cases, when you use webob marshalling, it might
return a dictionary like so::

   {'age':20}

webob marshalling is a generalized version of the form marshalling
machinery originated in Zope 2.

Form/Query String Element Marshalling
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

webob marshalling provides a way for you to specify form input types
in the form, rather than needing to unwind these types manually in
your application code. For example, instead of converting an *age*
variable to an integer in a controller or view, you can indicate that
it is an integer in the form itself::

   Age <input type="text" name="age:int" />

The ':int' appended to the form input name tells webob to convert the
form input to an integer when it is invoked. This process is called
*marshalling*. If the user of your form types something that cannot be
converted to an integer in the above case (such as "22 going on 23")
then the field will just not be converted.

Here is a list of webob marshalling's basic parameter converters.

*bool*

   Converts a variable to true or false. Variables that are 0, None, an
   empty string, or an empty sequence are false, all others are true.

*int*

   Converts a variable to an integer.

*float*

   Converts a variable to a floating point number.

*text*

   Converts a variable to a string with normalized line breaks.
   Different browsers on various platforms encode line endings
   differently, so this script makes sure the line endings are
   consistent, regardless of how they were encoded by the browser.

*list*

   Converts a variable to a Python list.

*tuple*

   Converts a variable to a Python tuple.

*tokens*

   Converts a string to a tuple by breaking it on white spaces.

*lines*

   Converts a string to a list by breaking it on new lines.

*ignore_empty*

   Excludes the variable from the returned dictionary if the variable
   is an empty string.

These converters all work in more or less the same way to coerce a
form variable, which is a string, into another specific type.

The *list* and *tuple* converters can be used in combination with
other converters. This allows you to apply additional converters to
each element of the list or tuple. Consider this form::

        <form action=".">

          <p>I like the following numbers</p>

          <input type="checkbox" name="favorite_numbers:list:int"
          value="1" /> One<br />

          <input type="checkbox" name="favorite_numbers:list:int"
          value="2" />Two<br />

          <input type="checkbox" name="favorite_numbers:list:int"
          value="3" />Three<br />

          <input type="checkbox" name="favorite_numbers:list:int"
          value="4" />Four<br />

          <input type="checkbox" name="favorite_numbers:list:int"
          value="5" />5<br />

          <input type="submit" />
        </form>

A more complex type of form conversion is to convert a series of
inputs into *records.* Records are structures that have
attributes. Using records, you can combine a number of form inputs
into one variable with attributes. The available record converters
are:

*record*

   Converts a variable to a record attribute.

*records*

   Converts a variable to a record attribute in a list of records.

*default*

   Provides a default value for a record attribute if the variable is
   empty.

*ignore_empty*

   Skips a record attribute if the variable is empty.

Here are some examples of how these converters are used::

        <form action=".">

          First Name <input type="text" name="person.fname:record" /><br />
          Last Name <input type="text" name="person.lname:record" /><br />
          Age <input type="text" name="person.age:record:int" /><br />

          <input type="submit" />
        </form>

If the information represented by this form post is present in the
environment, the result dictionary will container one parameter,
*person*. The *person* variable will have the attributes *fname*,
*lname* and *age*.

The *records* converter works like the *record* converter except
that it produces a list of records, rather than just one. Here is
an example form::

   <form action=".">

     <p>Please, enter information about one or more of your next of
     kin.</p>

     <p>
       First Name <input type="text" name="people.fname:records" />
       Last Name <input type="text" name="people.lname:records" />
     </p>

     <p>
       First Name <input type="text" name="people.fname:records" />
       Last Name <input type="text" name="people.lname:records" />
     </p>

     <p>
       First Name <input type="text" name="people.fname:records" />
       Last Name <input type="text" name="people.lname:records" />
     </p>

     <input type="submit" />
   </form>

If you access request.marshalled with a form posted from the above
HTML, a dictionary will be returned from it with a variable called
*people* that is a list of records. Each record will have *fname* and
*lname* attributes. Note the difference between the *records*
converter and the *list:record* converter: the former would create a
list of records, whereas the latter would produce a single record
whose attributes *fname* and *lname* would each be a list of values.

The order of combined modifiers does not matter; for example,
*int:list* is identical to *list:int*.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups "Paste Users" group.
To post to this group, send email to paste-users@???
To unsubscribe from this group, send email to paste-users+unsubscribe@???
For more options, visit this group at http://groups.google.com/group/paste-users?hl=en
-~----------~----~----~----~------~----~------~--~---