Hello!
Thank you for good explanations! As far as I can see you have already
commited good docstrings and backward-compatibility code into your
branch (r1545). It looks good!
On 6/2/05, Donovan Preston
I also need to know how people want to use LivePage, and if it has any usability shortcomings with this new design which I describe below.
As you ask to describe how people use LivePage, here is my small example. In a smaill project I am doing I use LivePage as follows (simplified extract from the working code -- I haven't tested it...): # example.py from nevow import loaders, livepage, rend, tags as T def get_teachers_list(): # some code that returns the list of teachers goes here pass class Editor(rend.Page): """Base class providing template for all pages""" addSlash=True docFactory = loaders.stan(T.html[T.body[T.directive('main_area')]]) class TeachersEditor(Editor,livepage.LivePage): """This page is exposed to the web""" def render_main_area(self, ctx, data): return livepage.glue, TeachersList(get_teachers_list()) class TeachersList(rend.Fragment): docFactory = loaders.stan([ T.ul(render=rend.sequence, id='teachers_list')[ T.li(pattern='item', render=T.directive('teacher_item'))[ T.a(render=T.directive('teacher_link'), href='#')[ T.slot(name='teacher_name')]]], T.div(id='teacher_details')]) def render_teacher_item(self, ctx, teacher): return ctx.tag(id='teacher_%d' % teacher.id) def render_teacher_link(self, ctx, teacher): @livepage.handler def show_teacher(client): client.set('teacher_details',TeacherDetails(teacher)) ctx.fillSlots('teacher_name', teacher.name) return ctx.tag(onclick=show_teacher, id='teacher_link_%d' % teacher.id) class TeacherDetails(rend.Fragment): # this rend.Fragment also has @livepage.handler-ed closures pass # end of example.py As you can see, I use LivePage from inside rend.Fragment's subclasses (TeacherDetails and TeachersList). But only the main rend.Page subclass (TeacherEditor) is a subclass of livepage.LivePage. I also use livepage.handler's as closures (TeachersList.render_teacher_link). There were two problems with your branch and my code: 1. Backward compatible code didn't work for me (I don't remember what was the reason. If you need details, I can make a better, working, example.). 2. I tried to use new LivePage api, but I couldn't figure out how to translate my code using it. For example, your ClientHandler.transient seems to provide the ability to make browser-callable functions as closures, but I am confused about the limitation of one-time calling. Is it really necessary for a solution of garbage problem you mention? I also can't see a way to use handler_* methods, because this methods must be inside a rend.Fragment subclass in my case. How can use the new api in my application?
2. I think you should have "nevow_" prefix for all things in liveglue.js. I agree, except I think I want the new "server" object to keep that name. It will be much easier for people to understand and use livepage if they know that calling server.handle('foo') in javascript invokes the handle_foo method on the server. Are there other things in there that aren't prefixed with nevow_?
Lot's of them. Just look inside liveglue.js... createRequest, connect, auto_load, listener etc. Or you can you preuso object-oriented approach like in Prototype (http://prototype.conio.net/) or dojo.
I have an incredible LivePage app I wrote recently I am calling "Pavel". I will be cleaning it up soon and I will create a new open source project for it (rather than including it as a nevow example). I think it really showcases the power of LivePage and I'm excited to show it to people, but for now it is somewhat of a secret :-)
I am looking forward for that!
So if you were sending the following:
client.send([ ��� livepage.alert('hello'), ��� livepage.set('name', 'Donovan Preston')])
You would need to terminate each statement, otherwise the javascript won't be correct. The above example would render as:
alert('hello')set('name', 'Donovan Preston')
Right now, you need to do:
client.send([ ��� livepage.alert('hello'), livepage.eol, ��� livepage.set('name', 'Donovan Preston')])
Which will render down to:
alert('hello') set('name', 'Donovan Preston')
It occurs to me that it may be possible for Nevow to just infer that a newline is required between each element of a list or a tuple while in JavascriptContext. I will have to experiment and see whether this causes any�inadvertent problems. If not, the requirement to manually insert newline characters will go away (horray!)
I am not sure, but may be something like livepage.do would do the job a little better? client.send(livepage.do[ livepage.alert('hello'), livepage.set('name', 'Donovan Preston')]) (or even livepage.progn...) -- Alexey