spyce
home
license
community
download
examples
resources
wishlist
contrib (@sf)
documentation
intro
lang
runtime
modules
tags
install
exits
sourceforge
statistics
freshmeat

Documentation - Modules
[[ Spyce ]]
Python Server Pages
by Rimon Barr

Prev: 4.4 - Stdout Up: 4 - Modules Next: 4.6 - Taglib

4.5. Spylambda

The spylambda module is loaded implicitly and allows the definition of functions based on Spyce scripts. The spylambda module provides the following methods:

  • define( args, code, [memoize] ):
    Returns a function that accepts the given args and executes the Spyce script defined by the code parameter. Note that the code is compiled immediately and that spyce.spyceSyntaxError or spyce.spycePythonError exceptions can be thrown for invalid code arguments. The optional memoize parameter sets whether the spyce can or can not be memoized, with the default being false. Memoizing a function means capturing the result and output and caching them, keyed on the function parameters. Later, if a function is called again with the same parameters, the cached information is returned, if it exists, and the function may not actually be called. Thus, you should only memoize functions that are truly functional, i.e. they do not have side-effects: they only return a value and output data to the response object, and their behaviour depends exclusively on their parameters. If you memoize code that does have side-effects, those side-effects may not occur on every invocation.
  • __call__( args, code, _spyceCache ):
    This is an alias to the define function. Because of the special method name, the spylambda module object can be called as if it were a function.
This function is not frequently called directly from Spyce code, because writing the Spyce code argument in a manner that does not conflict with the Spyce tag delimiters is cumbersome. Rather the Spyce lambda syntax is used and translated into this function call at compilation time, as in the example below.

examples/spylambda.spy
[[
  # table template
  table = [[spy! title, data: 
    <table>
      <tr>
        [[for cell in title: {]]
          <td><b>[[=cell]]</b></td>
        [[}]]
      </tr>
      [[for row in data: {]]
        <tr>
          [[for cell in row: {]]
            <td>[[=cell]]</td>
          [[}]]
        </tr>
      [[}]]
    </table> 
  ]]

  # table information
  title = ['Country', 'Size', 'Population', 'GDP per capita']
  data = [
    [ 'USA', '9,158,960', '280,562,489', '$36,300' ],
    [ 'Canada', '9,220,970', '31,902,268', '$27,700' ],
    [ 'Mexico', '1,923,040', '103,400,165', '$9,000' ],
  ]
]]

[[-- emit web page --]]
<html><body>
  [[ table(title, data) ]]
</body></html>

Run this code.
(requires Spyce-enabled web server)

It often useful to use the spylambda module directly from other Spyce modules that may need to perform significant amounts of output. Rather than calling print repeatedly, it is more convenient to invoke a Spyce, as in the example below. Though highly simplified, this example also shows how Spyce lambdas can be used to easily build a complex rendering environment.

examples/myPortal.spy
[[.import name=myPortal]]
[[
# this data might be pulled from a database
news = {
  'heading': 'News',
  'data': [
    ('<a href="http://www.nytimes.com">nyt</a>', 
      'today', 'sun rose'),
    ('<a href="http://www.cnn.com">cnn</a>', 
      'yesterday', 'sun set'),
    ('<a href="http://news.google.com">goo</a>', 
      'long time ago', 'let there be light!'), ] }
weather = {
  'heading': 'Weather',
  'data': [
    ('nyc', 'too cold'),
    ('seattle', 'too wet'),
    ('tucson', 'too dry'),
    ('houston', 'too humid'),
    ('chicago', 'too windy'),
    ('<a href="http://www.carrier.com/">carrier</a>', 
      'just right'), ] }
movies = {
  'heading': 'Movies',
  'data': [
    ('over-priced theatre', '15 movies'),
    ("'el cheapo", '3 movies'),
    ('home', 'blockbuster'), ] }
selection = [ news, movies, weather ]
]]

<html><body>
    Dear user [[='XYZ']], <br>
    Welcome to your portal. Here are your selected views... <br>
    [[-- a module that does a lot of output --]]
    [[ myPortal.show( selection ) ]]
</body></html>
Run this code.
(requires Spyce-enabled web server)

examples/myPortal.py
from spyceModule import spyceModule

__doc__ = '''This module takes care of presenting the portal.
Spyce lambdas are easier to use to perform the output.'''

class myPortal(spyceModule):
  def start(self):
    self.show = self._api.getModule('spylambda')(spysigPortal, spycodePortal)
    self.showView = self._api.getModule('spylambda')(spysigItem, spycodeItem)

spysigPortal = 'selection'
spycodePortal = '''
  <html><body>
    <table align=center valign=center border=1 width=100% bgcolor="#aaaaaa"><tr>
      <td width=30% >
        [[ for view in selection: {]]
          [[myPortal.showView(view['heading'], view['data'])]]
          <p>
        [[ } ]]
      </td>
      <td align=center valign=center width=50% ><b>main panel</b></td>
      <td align=center valign=center width=20% ><b>other stuff</b></td>
    </tr><table>
  </body></html>
'''

spysigItem = 'heading, data'
spycodeItem = '''
  <table cellspacing=0 border=0 bgcolor="#ffdddd" width=100% >
    <tr><td bgcolor="#bbddff" colspan=[[=max(map(len, data))]]>
      <b>[[=heading]]<b>
    </td></tr>
    [[ for row in data: { ]]
      <tr> 
        [[ for i in row: { ]]
          <td>[[=i]]</td> 
        [[ } ]]
      </tr>
    [[ } ]]
  </table>
'''


Prev: 4.4 - Stdout Up: 4 - Modules Next: 4.6 - Taglib


© 2002-08 Rimon Barr
email: rimon@acm.org
Spyce Powered SourceForge Logo [[ Spyce ]]
Python Server Pages
version 1.3.13