Monday, April 18, 2005

Spyce active tags, version 2

(Updated with a little more explanation as to what's going on.)

The Spyce Active Tag compiler is coming along nicely. Spyce has had active tags since 1.3.0 (current active release is 1.3.13; it's very, very stable by now), but writing a tag library shares a lot of the problems that JSP 1.x tag libraries had; it takes a lot of code to get something done.

Now, I've updated the Spyce compiler to be able to compile tag libaries, and tied it in to the active handler feature as a bonus. Meaning, tags can wrapping their control logic together with the view so all the user has to write is a single tag, like "<chat:boxlet />" below. (You could put the controller logic into another module and write handler="foo.addLine" instead of self, but I'm keeping it simple here.)

Here's a simple example that defines and uses a chatbox component. Chat state is stored in the server globals area for simplicity. This code is running (for the next few days at least) over here. Update: original demo is down, but a slightly more sophisticated version (showing two chatboxes on the same page) is up at the spyce 2.0 prerelease site.

(I hope to get a beta of the next Spyce release (1.4? 2.0?) out later this week.)

(chatbox.spy)

[[.tagcollection ]]

[[.begin name=boxlet singleton=True ]]
[[.attr name=width default=300 ]]
[[.attr name=lines default=5 ]]

[[\  # this code runs when user hits Send
  def addLine(self):
    # (use get() in case server restarted)
    request._api.getServerGlobals().get('chatlines', []).append(request['newline'])
]]

[[.import names="pool"]] [[-- creates pool alias for request._api.getServerGlobals() --]]

<div width="[[= width ]]">
  [[     i = -int(lines)
     line = None # for first export
  ]]
  [[ for line in pool.setdefault('chatlines', [])[i:]:{ ]]
  <div>[[= line ]]</div>
  [[ } ]]
  <div>
  <f:text name=newline />
  <f:submit handler='self.addLine' value="Send" />
  <f:submit value="Refresh" />
  </div>
</div>

[[.export var=line as=last ]] [[-- sends this variable to the calling scope --]]
[[.end]]

(demo.spy)

[[.taglib as='chat' from='chatbox.spy']]

<html>
  <head>
    <title>Active tag handler test</title>
  </head>

  <body>
    <f:form>
      <chat:boxlet />
      The last line in chat is: [[= last ]]
    </f:form>
  </body>
</html>

(whitenoise added to keep blogger from screwing up my formatting...)

1 comment:

Thai chat said...

useful code !