spyce
         
home     documentation     download     Spyce logo


Documentation - Tags

Prev: 3.9.2 - Form Up: 3.9 - Tags Next: 3.9.4 - Writing Tag Libraries

3.9.3. Active Handlers

Active Handlers allow you to "attach" python functions to Spyce form submissions. Instead of old-fashioned inspection of the request environment, Spyce will pull the parameters required by your function's signature out for you. Let's have a look at an example. Here, we define a calculate function and assign it to be the handler for our submit input:

examples/handlerintro.spy
[[!
def calculate(self, api, x, y):
    self.result = x * y
]]

<spy:parent title="Active Handler example" />
<f:form>
    <f:text name="x:float" default="2" label="first value" />
    <f:text name="y:float" default="3" label="second value" />

    <f:submit handler="self.calculate" value="Multiply" />
</f:form>

<p>
Result: [[= hasattr(self, 'result') and self.result or '(no result yet)' ]]
</p>
Run this code

  • Handlers may be inline, as the calculate handler is here, or in a separate Python module. When using a handler from a Python module, Spyce will automatically import the module when needed. (Handler parameters are strings, not Python references.) The todo demo demonstrates using handlers this way.
  • You can give your form inputs a data type; Spyce will perform the conversion automatically before passing parameters to your handler function.

Active Handlers also make it easy to incorporate user-friendly error messages into your forms simply by raising a HandlerError:

examples/handlervalidate.spy
[[!
def calculate(self, api, x):
    from spyceException import HandlerError
    try:
        x = float(x)
    except ValueError:
        raise HandlerError('Value', 'Please input a number')
    if x < 0:
        raise HandlerError('Value', 'Cannot take the square root of negative numbers!')
    self.result = x ** 0.5
]]

<spy:parent title="Active Handler Validation" />
<f:form>
    <f:text name="x" default="-1" label="Value:" />
    <f:submit handler="self.calculate" value="Square root" />
</f:form>

<p>
Result: [[= hasattr(self, 'result') and self.result or '(no result yet)' ]]
</p>
Run this code

You can show multiple errors at once with a CompoundHandlerError:

examples/handlervalidate2.spy
[[!
def errors(self, api):
    from spyceException import HandlerError, CompoundHandlerError
    cve = CompoundHandlerError()
    cve.add(HandlerError('One', 'First error'))
    cve.add(HandlerError('Two', 'Second error'))
    if cve:
        raise cve
]]

<spy:parent title="Active Handler Validation 2" />
<f:form>
    <f:submit handler="self.errors" value="Show me some errors" />
</f:form>
Run this code

All Spyce modules are available via the api handler parameter (which should always be the first parameter (after self in a class). Here is an example that uses the db module:

examples/db.spy
<spy:parent title="To-do demo" />

[[!
def list_new(self, api, name):
    if api.db.todo_lists.selectfirst_by(name=name):
        raise HandlerError('New list', 'a list with that description already exists')
    api.db.todo_lists.insert(name=name)
    api.db.flush()
]]

(This is an self-contained example using the same database as the
<a href=/demos/to-do/index.spy>to-do demo</a>.)

<h2>To-do lists</h2>

[[ lists = db.todo_lists.select(order_by=db.todo_lists.c.name) ]]
<spy:ul data="[L.name for L in lists]" />

<h2>New list</h2>
<f:form>
<f:submit value="New list" handler=self.list_new />:
<f:text name=name value="" />
</f:form>
Run this code

Handlers in Active Tags allow you to create reusable components, as in the the chat demo.

(Since Spyce captures stdout, you can use print to debug handlers.)


Prev: 3.9.2 - Form Up: 3.9 - Tags Next: 3.9.4 - Writing Tag Libraries


Spyce logo
Python Server Pages
version 2.1.3
Spyce Powered SourceForge Logo