In the previous chapter we demonstrated the use of Albatross input tags to transfer values from the execution context into HTML <input> tags, and from the browser request back into the execution context. In this section we present the same process using an Albatross application object.
The sample program from this section is supplied in the samples/form4 directory and can be installed in your web server cgi-bin directory by running the following commands.
cd samples/form4 python install.py
The form.html template file used by the application follows.
<html> <head> <title>Display Form Input</title> </head> <body> Input some values to the following form and press the submit button. <al-form method="post"> Text field: <al-input name="text"><br> Singleton checkbox: <al-input type="checkbox" name="singleton"><br> Checkbox group: <al-input type="checkbox" name="group" list value="check1"> <al-input type="checkbox" name="group" list value="check2"><br> Radio buttons: <al-input type="radio" name="radio" value="radio1"> <al-input type="radio" name="radio" value="radio2"><br> Option menu: <al-select name="select"> <al-option>option1</al-option> <al-option>option2</al-option> <al-option>option3</al-option> </al-select> <al-input type="submit" name="submit" value="submit"> </al-form> number of requests: <al-value expr="num"><br> text: <al-value expr="text"><br> singleton: <al-value expr="singleton"><br> group: <al-value expr="group"><br> radio: <al-value expr="radio"><br> select: <al-value expr="select"><br> </body> </html>
The most important new features in the template file are the use of the <al-form> tag, and the list attribute in the <al-input type="checkbox"> tag.
Most execution contexts created by application objects inherit from the NameRecorderMixin. The NameRecorderMixin records the name, type and multiple value disposition of each input tag in a form in a cryptographically signed hidden field named __albform__. This mechanism prevents clients from being able to merge arbitrary data into the local namespace, as well as providing additional information to make the merging process more reliable. The recording process requires that all <al-input> tags be enclosed by an <al-form> tag.
When the resulting form is submitted, the contents of the
__albform__ field controls merging of form fields into
ctx.locals
. Only fields tracked by __albform__ will be
merged. Consequently, if submission occurs via a GET request without an
__albform__ field (for example, as a result of the user following
an <al-a>), the application must explicitly request relevent
fields be merged via the merge_vars(...) method. 4.1
Any input field with the list attribute will always receive a list value from a POST browser request regardless of how many values (including none) were sent by the browser. An exception will be raised if you specify multiple input tags with the same name in a form and do not include the list attribute. The input tag types radio, image, and submit can only have a single value, even if multiple inputs of the same name appear in a form, and the list attribute should not be specified on these.
The form.py program is show below.
#!/usr/bin/python from albatross import SimpleApp from albatross.cgiapp import Request class Form: def page_enter(self, ctx): ctx.locals.text = ctx.locals.singleton = ctx.locals.group = \ ctx.locals.radio = ctx.locals.select = None ctx.locals.num = 0 ctx.add_session_vars('num') def page_display(self, ctx): ctx.locals.num += 1 ctx.run_template('form.html') app = SimpleApp(base_url='form.py', template_path='.', start_page='form', secret='-=-secret-=-') app.register_page('form', Form()) if __name__ == '__main__': app.run(Request())
You can run the program by pointing your browser at http://www.object-craft.com.au/cgi-bin/alsamp/form4/form.py.
Notice that the browser request is automatically merged into the local namespace and then extracted by the template when generating the HTML response.
The program uses the SimpleApp application class. SimpleApp uses an object to define each page served by the application. Each of the page objects must be registered with the application via the register_page() method.
When the application enters a new page SimpleApp calls the
page_enter() method of the page object to allow the
application to initialise execution context values. In the above
program the page_enter() method initialises all values used
by the HTML form to None
, initialises the variable num to
0
and places it into the session.
As shown in the application processing sequence on page
When an Albatross application needs to display the result of processing a request it calls the page_display() method of the current page. In the above program this method increments num and then runs the form.html template. It is important to note that any changes to session values after executing a template will be lost as the session state is saved in the HTML produced by the template.
It is worth explaining again that the program does not perform any request merging -- this is all done automatically by the Albatross application and execution context objects.