[Twisted-web] Livepage, ClientHandle and context
Alexey Shamrin
shamrin at gmail.com
Mon Jun 6 10:24:51 MDT 2005
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 <dp at ulaluma.com> wrote:
> 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
More information about the Twisted-web
mailing list