On Jun 26, 2005, at 11:30 PM, Chris (FeedTagger) wrote:

Sorry, just registered so unable to join existing thread.

I'm having similar problems that are outlined here:
"I also can't see a way to use handler_* methods, because this methods
must be inside a rend.Fragment subclass in my case."

There's no way Nevow can automatically determine that a handler event should be dispatched to your Fragment instance, so you'll have to tell it. Your expectation below is correct:

I expect this can be rectified in livepage.py (line 728 on my co):
    def locateHandler(self, ctx, path, name):
        ### XXX TODO: Handle path
        return getattr(self, 'handle_%s' % (name, ))

The path here is meant to be a string which names a Fragment or other dispatch path. As you can see, none of this is implemented yet, but this is my solution to this problem that you and others on this list have had. Basically the API in javascript would look something like this:

server.handleWithPath('onclick', 'some/path', 'someArgument')

locateHandler would change to look more like locateChild, breaking apart the path into segments and consuming them until it locates the target. I'm not sure how the default locateHandler implementation will locate action targets; perhaps with dispatch_* prefixed methods? Here is a small example:

class MainPage(Page):
    docFactory = loaders.xmlstring("""<html xmlns:n="http://nevow.com/ns/nevow/0.1">
  <a onclick="server.handleWithPath('onclick', 'someFragment', 'someArg')">
    Click me
  <span n:render="liveid" />
  <span n:render="liveglue" />

    def dispatch_someFragment(self, ctx):
        return MyFragment()

class MyFragment(Fragment):
    def handle_onclick(self, ctx, someArg):
         assert someArg == 'someArg'

Suggestions on different names other than "dispatch_*" are welcome; the main reason I haven't implemented this functionality yet is because I can't decide what to call it! :-)

My implementation is slightly different in that I'm not using
rend.Fragment, I have a Page broker that responds to requests and
returns a new page that implements from a master page.


pageMappings ] {
  'search': search.Page
  'index': index.Page

class Page(livepage.LivePage):
  def locateChild(self,ctx,segments):
    # depending on the value of segments[0] return the correct page
    # from a predefined map, otherwise 404
    page = pageMappings[segments[0]]
    return page(), segments[1]

Then in index.Page.py:
class Page(_master.FrontPage):

  def render_button(self,ctx,data):
    return ctx.tag(onclick="server.handle('click')")

  def handle_click(self,ctx,client):
    client.alert('clicked button')


class CorePage(livepage.LivePage):
  # various properties that all generic pages should exhibit

class FrontPage(CorePage):
  # load front page template
  # provide any default slot fills etc.

Now the problem as I see it (with primitive livepage knowledge) is
that the livepage request that's sent with server.handle('click') is
attempting to be mapped to myserver.Page, instead of my intended
index.Page class.
Is it possible to provide this functionality or should this whole
template based approach be re-worked in some other fashion?

Again, you want the above proposed architecture to be finished, but it isn't finished yet.

... as a side note using a generic dispatcher of pages (myserver.Page)
I can do cool things like detect /xml appended to url and instead of
loading .xhtml templates, load the appropriate .xml templates. Hence
without changing any application code I can generate xml versions of
every single webpage across a site.

I suggest using a query parameter rather than an additional URL segment. xml is a different "view" of the same "object"; in my opinion, URLs should represent "objects" (Resources) and query parameters should be used to parameterize how the view renders. One might also be able to use the "Accept" header that browsers send to negotiate the rendered content type. But this is just a suggestion. Whatever works for you is fine with me :-)

And yes, this is a cool capability to want to have.