How to insert an Athena event handler using Stan?

Hi all.
I've got some LiveElements in an Athena page to which I want to attach event handlers. Their XHTML is stan-based.
What I've got right now (which works) is something like this, which I've understood is the Right Way to do it if you're explicitly using inline Javascript:
_js = ( "Nevow.Athena.Widget.get(this).keyPressed(this, event); " + "return false;" )
docFactory = loaders.stan ( T.div ( render = T.directive ( 'liveElement' ), ) [ "Blah Text Label", T.input ( type = "text", _class = "sw-input", onkeyup = _js, ), T.div ( _class = "sw-output" ) [ "Blah More Text" ], ] )
There are messages in the mailing list (for example, from JP on October 11th 2006) recommending that one should use the athena:handler feature, like this:
<textarea> <athena:handler event="onkeypress" handler="keyPressed" /> </textarea>
However, if one has stan-based rather than file-based XHTML, it's neither documented nor obvious how this should be done. I've managed to get this far:
from nevow import stan ... _athena = stan.Proto ( 'athena:handler event="onkeypress" handler="keyPressed"' ) ... T.input ( type = "text", _class = "sw-input" ) [ _athena ]
This serialises OK, but it doesn't work, because the node doesn't get rewritten; that is, the generated XHTML contains the athena:handler node verbatim.
Now, rewriteEventHandlerNodes() in Nevow/nevow/athena.py (around line 962) seems to traverse the tree looking for athena:handler nodes and replacing them with "Nevow.Athena.Widget.handleEvent()" Javascript, so I presume that the node I'm creating fails to get identified as an athena:handler node because I'm creating it incorrectly.
What is the correct way to create such a node such that it gets picked up by rewriteEventHandlerNodes()?
Regards,
Ricky

* kgi iacovou@gmail.com [2006-10-31 11:58:35 +0200]:
However, if one has stan-based rather than file-based XHTML, it's neither documented nor obvious how this should be done. I've managed to get this far:
from nevow import stan ... _athena = stan.Proto ( 'athena:handler event="onkeypress" handler="keyPressed"' ) ... T.input ( type = "text", _class = "sw-input" ) [ _athena ]
stan.Proto takes a tag name, so you would really want just stan.Proto('athena:handler'). However, there's already one of these in athena, so you can just do:
from nevow import stan, athena # ... T.input(type='text', _class='sw-input')[ athena.handler(event='onkeypress', handler='keypressed']

On Tuesday 31 October 2006 15:12, Tristan Seligmann wrote:
- kgi iacovou@gmail.com [2006-10-31 11:58:35 +0200]:
However, if one has stan-based rather than file-based XHTML, it's neither documented nor obvious how this should be done. I've managed to get this far:
from nevow import stan ... _athena = stan.Proto ( 'athena:handler event="onkeypress" handler="keyPressed"' ) ... T.input ( type = "text", _class = "sw-input" ) [ _athena ]
stan.Proto takes a tag name, so you would really want just stan.Proto('athena:handler'). However, there's already one of these in athena, so you can just do:
from nevow import stan, athena # ... T.input(type='text', _class='sw-input')[ athena.handler(event='onkeypress', handler='keypressed']
Thanks, Tristan; that's certainly a step forward: the tag is now being recognised and replaced. However, it's not quite perfect yet: the generated HTML is escaped:
_handler = athena.handler ( event = 'onkeypress', handler = 'keyPressed' ) ... T.input ( _class = "sw-input", type = "text" ) [ _handler ],
Results in:
<input type="text" class="sw-input" onkeypress="return Nevow.Athena.Widget.handleEvent(this, "onkeypress", "keyPressed");" />
Should I be wrapping it in anything else (T.raw()?).
Ricky

On Tue, 31 Oct 2006 16:38:22 +0200, kgi iacovou@gmail.com wrote:
On Tuesday 31 October 2006 15:12, Tristan Seligmann wrote:
- kgi iacovou@gmail.com [2006-10-31 11:58:35 +0200]:
However, if one has stan-based rather than file-based XHTML, it's neither documented nor obvious how this should be done. I've managed to get this far:
from nevow import stan ... _athena = stan.Proto ( 'athena:handler event="onkeypress" handler="keyPressed"' ) ... T.input ( type = "text", _class = "sw-input" ) [ _athena ]
stan.Proto takes a tag name, so you would really want just stan.Proto('athena:handler'). However, there's already one of these in athena, so you can just do:
from nevow import stan, athena # ... T.input(type='text', _class='sw-input')[ athena.handler(event='onkeypress', handler='keypressed']
Thanks, Tristan; that's certainly a step forward: the tag is now being recognised and replaced. However, it's not quite perfect yet: the generated HTML is escaped:
_handler = athena.handler ( event = 'onkeypress', handler = 'keyPressed' ) ... T.input ( _class = "sw-input", type = "text" ) [ _handler ],
Results in:
<input type="text" class="sw-input" onkeypress="return Nevow.Athena.Widget.handleEvent(this, "onkeypress", "keyPressed");" />
Should I be wrapping it in anything else (T.raw()?).
Are you sure this is causing a problem? It looks correct to me. :)
<tag onkeypress="return foo("bar")"> would seriously confuse an html parser.
Jean-Paul

On Oct 31, 2006, at 10:25 AM, Jean-Paul Calderone wrote:
On Tuesday 31 October 2006 15:12, Tristan Seligmann wrote: Results in:
<input type="text" class="sw-input" onkeypress="return Nevow.Athena.Widget.handleEvent(this, "onkeypress", "keyPressed");" />
Should I be wrapping it in anything else (T.raw()?).
Are you sure this is causing a problem? It looks correct to me. :)
<tag onkeypress="return foo("bar")"> would seriously confuse an html parser.
I am seeing the same behavior in my app, where I was working on implementing a feature similar to Tristan's. I'm seeing:
<input onkeypress="return Nevow.Athena.Widget.handleEvent(this, "onkeypress", "parse");" type="text" size="80" />
I updated before trying it, so this is from SVN r9862.
-phil

On Oct 31, 2006, at 10:44 AM, Phil Christensen wrote:
On Oct 31, 2006, at 10:25 AM, Jean-Paul Calderone wrote:
Are you sure this is causing a problem? It looks correct to me. :)
<tag onkeypress="return foo("bar")"> would seriously confuse an html parser.
I am seeing the same behavior in my app, where I was working on implementing a feature similar to Tristan's. I'm seeing:
Now I'm just realizing what JP was referring to. That's definitely acceptable syntax, but it still doesn't seem to be working for me. Using this:
T.div(render=T.directive('liveElement'))[ T.input(type="text", size=80, onKeyUp='Nevow.Athena.Widget.get (this).parse(event)') ]
works, but this:
T.div(render=T.directive('liveElement'))[ T.input(type='text', size=80)[athena.handler(event='onkeypress', handler='parse')]]) ]
fails without generating any error. I guess I'm okay with the first version for my particular use-case, but I'd be interested to know if there's something obvious I'm missing, or other information I can supply.
-phil

On Tue, 31 Oct 2006 11:57:05 -0500, Phil Christensen phil@bubblehouse.org wrote:
[snip]
Now I'm just realizing what JP was referring to. That's definitely acceptable syntax, but it still doesn't seem to be working for me. Using this:
T.div(render=T.directive('liveElement'))[ T.input(type="text", size=80, onKeyUp='Nevow.Athena.Widget.get (this).parse(event)') ]
works, but this:
T.div(render=T.directive('liveElement'))[ T.input(type='text', size=80)[athena.handler(event='onkeypress', handler='parse')]]) ]
fails without generating any error. I guess I'm okay with the first version for my particular use-case, but I'd be interested to know if there's something obvious I'm missing, or other information I can supply.
How does it fail? Can you throw together a minimal self-contained example? I use this in a lot of places and it works and as far as I understand there is no reason it shouldn't.
Jean-Paul

On Tuesday 31 October 2006 21:56, Jean-Paul Calderone wrote:
How does it fail? Can you throw together a minimal self-contained example? I use this in a lot of places and it works and as far as I understand there is no reason it shouldn't.
Jean-Paul
Here you go. At least, I hope I haven't broken it in some other way while whittling it down.
twistd -noy stuff.py, then browse to http://localhost:8080
stuff.py as it stands it doesn't work. However, edit line 48 of stuff.py to read:
docFactory = docFactoryJS
instead of
docFactory = docFactoryAthena
and it starts working.
I'm fully prepared for the possibility of eating humble pie over some typo, but if it is a typo, my eyes are incapable of seeing it :-)
Regards,
Ricky
participants (4)
-
Jean-Paul Calderone
-
kgi
-
Phil Christensen
-
Tristan Seligmann