On Tue, 2011-02-01 at 10:42 +0100, Stéphane Klein wrote:
> Le 31/01/2011 17:42, Jim Washington a écrit :
> > ZODB  + Pyramid + Pyjamas + PureMVC.
> 
> I'm curious about "Pyjamas + PureMVC". Can you say more about your 
> utilization of this tools ?
> 
> Thanks for your feedback.

Hi, Stéphane

I presume you ask three questions:
Pyramid + Pyjamas
Pyramid + JSON-RPC (server communication for Pyjamas)
Pyjamas + PureMVC (PureMVC in Pyjamas on the client side)

Apologies for the length of this message.

Disclaimer: I am a Pyjamas developer, and I am posting this partly
because we can always use more smart and able developers using and
contributing to the project, and providing easy usage methodology helps
with that idea.

Pyjamas: http://pyjs.org (use the git repository):

I use Pyjamas because my application is very dynamic. There are a lot of
widgets, and a lot of data updates, and I can update the data in any
particular widget without refreshing the entire page.  Plus, my Pyjamas
code is all python.  Python on the server + Python on the client =
bliss. The application feels very application-like instead of
web-page-like, but I can use css for styling and widget placement.

Pyjamas is very easy to use with Pyramid.  Each Pyjamas app just needs
to reside somewhere static: e.g., static/app1/App1.html  I set the
--output to that directory for the pyjsbuild command in the Pyjamas
app's build.sh file.  I let nginx or apache serve static.

JSON-RPC:

Pyjamas uses JSON-RPC for communication with the server. The following
can probably be adapted for any JSON-RPC client, and maybe for non-ZODB
models. For JSON-RPC on the server side, I use lovely.jsonrpc.  

from lovely.jsonrpc import JSONRPCDispatcher

For any ZODB location I wish to directly access without special
permissions, I set a view config in my Pyramid app's views.py:

@view_config(context="myapp.models.MyClass", request_method="POST")
def my_class_rpc(request):
    body=request.body
    context = request.context
    resp = JSONRPCDispatcher(context).dispatch(body)
    # resp is the JSON-RPC response for the context's method. 
    # Fail if the method returns something that is
    # not representable in JSON.    
    r = Response(resp, content_type='application/json')
    r.cache_control = 'no-cache'
    r.pragma = 'no-cache'
    return r

The above allows all methods in any MyClass object to the client's
JSON-RPC implementation. This simplifies operations while developing the
app. Client's JSONProxy uses http:// mySite/path/to/object as its url.
If I want different methods and permissions for the view, I make a view
class:

class MySpecialView(object):
    """do something silly"""
    def __init__(self, context):
        self.context = context

    def _private_method(self, param):
        resp = self.context.twiddle_param(param)
        # context returns something JSON-representable
        return resp

    def some_method(self, some_param):
        intermediate, OK = self.context.safe_method(some_param)
        if not OK:
            return self._private_method(intermediate)
        return intermediate

And then my view config looks like: 

@view_config(context="myapp.models.MyClass", request_method="POST",
permission="some.permission")
def my_class_rpc(request):
    body=request.body
    context = MySpecialView(request.context)
    resp = JSONRPCDispatcher(context).dispatch(body)
    r = Response(resp, content_type='application/json')
    r.cache_control = 'no-cache'
    r.pragma = 'no-cache'
    return r

In this case, JSON-RPC from the client only has
MySpecialView.some_method available to use.  If I wanted to use "Zope
Component Architecture", MySpecialView would be an adapter.

If I want the request url to end in something other than '/':
the view_config can look like

@view_config("jsonrpc", context="myapp.models.MyClass",
request_method="POST", permission="some.permission")

and the client's JSONProxy's url would be
http://my_site/path/to/object/jsonrpc

PureMVC : http://puremvc.org
 
PureMVC has a pure python implementation, which imports into Pyjamas
without any trouble. See the Pyjamas EmployeeAdmin example within the
Pyjamas source for example usage.

I use PureMVC as an organizational tool for developing the client-side
app, and its notification (event) oriented nature simplifies
between-widget and app-to-server coordination. It also reduces the
potential for circular imports, which Pyjamas does not handle well.

I had a jargon hurdle to overcome with PureMVC, but my understanding of
it is as follows:

For PureMVC, I work with five modules, "components", "controller",
"consts", "model", and "view".  These may be split up into sub-modules,
and may be enhanced with objects from other modules, but for simplicity,
I will refer only to these five modules.

The objects in the "view", "model", and "controller" modules are
registered and looked up by name, which is a string. Notifications are
also named as strings, but ordinarily are held in the "consts" module to
reduce the possibility of typographical errors in my code.

For the following, when I refer to "view" objects, they are actually
"Mediator" objects, and when I refer to "model" objects, they are
actually "Proxy" objects. Methods in the "controller" are actually
"Command" objects.  Forget that jargon for the moment. I simplify a bit
in the following.

The "components" module has the Pyjamas application, with all of its ui
widgets.

The "view" module has objects that can listen for "onXXX" events
belonging to particular widgets within the app.  A "view" object's
"onRegister" method sets up the listeners for the widget's "onXXX"
methods. When the "view" object hears an event, it can send
notifications for other "view" objects or "controller" methods, and can
call methods on "model" objects. "View" objects also listen for
particular notifications sent by other "view" objects, "model" objects,
and "controller" methods, so that the widget in the app can be queried
or updated. 

The "model" module holds the business data. The objects here can
communicate with the server and send notifications for "view" objects or
"controller" methods to handle. For example, when data is received from
the server, a notification may be sent.

The "controller" module holds methods that are invoked upon
notification. These methods can send notifications, and can call methods
on objects in the "model" and "view" modules.

The app itself can be pretty dumb, and is unaware that it is used in a
PureMVC system. It may be developed separately, and the PureMVC system
can be "bolted on" later.

The above sounds complicated, but at least I did not throw "Command" ,
"Proxy", and "Mediator" around to confuse the description. :)

Maybe a data path will help explain how PureMVC simplifies things.

Here is a sample data path through a PureMVC pyjamas app:

o User clicks a button in the app.
o The app may directly handle the onClick event with some visual cue.
o A "view" object also handles the onClick event by looking up a
particular "model" object by name and calling a method on that object
with some data. The data may come from a different widget in the app,
and may be requested from that widget's "view" object, which can ask the
widget for the data.
o The "model" object has a method that makes a JSON-RPC call to the
server with the data as a parameter.
o When the server responds, the "model" object stores the data and sends
a notification that new data has been received. The data may be sent as
part of the notification.
o Any "controller" method or "view" object listening for that
notification handles the "model" object's notification appropriately, by
updating widgets in the app and maybe sending additional notifications.

I probably have a few details a bit wrong, but hopefully the general
idea is understandable.

- Jim Washington


-- 
You received this message because you are subscribed to the Google Groups 
"pylons-devel" group.
To post to this group, send email to pylons-devel@googlegroups.com.
To unsubscribe from this group, send email to 
pylons-devel+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/pylons-devel?hl=en.

Reply via email to