On 7/13/09 7:59 AM, Alberto Valverde wrote: > Hello, > > I'm factoring out the core logic of a bunch of views into a generic CRUD > "controller" for a bfg app which looks something like this: > > class GenericCrud(..): > def __init__(self, bunch of configuration options): > # update __dict__ with these options and some derived ones > > def member_view(self, context, request): > # dispatch to helper method on HTTP method > > def collection_view(self, context, request): > # ditto > > # collection_view dispatches to this on POST > def create(self, context, request): > # just a normal view function but have settings and helper (quite > possibly overridden) > # methods accessible at 'self'. The instance is *never* modified here > > # member_view to this on PUT > def update(...): ... > > which is used like this: > > # some_views.py, module scope: > class UserCrud(GenericCrud): > # some template methods implemented > > # Instantiate a module-scope (stateless) singleton > user_crud = UserCrud(some overrides like grid columns, form fields, etc...) > > # Now the work-arounds so the views can be registered I'd like to get > rid of, > # I'll explain below. > user_member_view = user_crud.member_view > user_collection_view = user_crud.collection_view > > This is wired up into the ZCA registry like this, configure.zcml: > > <view > for=".interfaces.IUsers" > view=".views.user.user_config_view" > name="config.js" > permission="view" > /> > <view > for=".interfaces.IUsers" > view=".views.user.user_collection_view" > request_type="GET" > permission="view" > /> > <view > for=".interfaces.IUsers" > view=".views.user.user_collection_view" > request_type="POST" > permission="create" > /> > <view > for=".interfaces.IUser" > view=".views.user.user_member_view" > request_type="GET" > permission="view" > /> > <view > for=".interfaces.IUser" > view=".views.user.user_member_view" > request_type="PUT" > permission="update" > /> > <view > for=".interfaces.IUser" > view=".views.user.user_member_view" > request_type="DELETE" > permission="delete" > /> > > Ok, the above zcml sucks a bit right now in the terseness department > since there needs to be a directive for each request_type just to > declare permissions (it wouldn't be needed otherwise since the > "controller" takes care of dispatching) but I'll eventually write my > custom zcml directive-processors which will take care of the > bolier-plate when I find some time to learn how-to.
Right. > > Anyway, I'd like to remove the work-arounds I mentioned (the user_*_view > aliases at module-scope) since the "view" directive doesn't seem able to > import an instancemethod (or any non-module-global for that matter, I > think). Yes, the resolver won't descend past module scope to find names. > They're not too bad at the moment but it will soon be when I > wire up all the exposed domain models.... > > Would this be possible or even desirable? Is there a better pattern to > do this kind of "pre-configured" views that someone can share? I'd > happily send a patch for this with tests, just point me in the right > direction (I'm still mapping the repoze.* namespace in my head...). I'm not sure if this helps, but instead of making a view out of an instancemethod with a special name, maybe you could make N view classes, one for each alias you currently have: class UserCrud(GenericCrud): def __init__(self, context, request): self.context = context self.request = request class UserMemberView(UserCrud): def __call__(self): ... do member-related dispatching ... ... return response .. class UserCollectionView(UserCrud): def __call__(self): ... do collection-related dispatching ... ... return response .. then in ZCML: <view for=".interfaces.IUsers" view=".views.user.UserCollectionView" request_type="GET" permission="view" /> <view for=".interfaces.IUsers" view=".views.user.UserCollectionView" request_type="POST" permission="create" /> <view for=".interfaces.IUser" view=".views.user.UserMemberView" request_type="GET" permission="view" /> <view for=".interfaces.IUser" view=".views.user.UserMemberView" request_type="PUT" permission="update" /> <view for=".interfaces.IUser" view=".views.user.UserMemberView" request_type="DELETE" permission="delete" /> > I've already evaluated using a class as a view [1] but having the Aw you left us hanging. > PS: I'm having *a lot* of fun with bfg! Big thanks for extracting all > these zope gems (and the non-zope ones you've created) into easily > digestible eggs for the rest of us. :) Thanks for the feedback! - C _______________________________________________ Repoze-dev mailing list Repoze-dev@lists.repoze.org http://lists.repoze.org/listinfo/repoze-dev