I just improve my default method to enable it handle controller.

class Sub2(tg.controllers.Controller):
    @tg.expose()
    def m2(self):
        return 'm2 site : ' + cherrypy.request.site.site_name

class Sub1(tg.controllers.Controller):
    sub2 = Sub2()

    @tg.expose()
    def m1(self):
        return 'm1 site : ' + cherrypy.request.site.site_name

class SiteController(tg.controllers.Controller):
    sub1 = Sub1()

    @tg.expose(template="...")
    def item_list(self, category):
        ....

    @tg.expose(template="...")
    def item_detail(self, asin):
        ...

    @tg.expose()
    def default(self, site_name, *args, **kwargs):
        site = model.Site.get_by(site_name=site_name)
        assert site is not None, _(u'Site %s does not exist') %
site_name
        cherrypy.request.site = site

        # remove parameters in path we get
        path = cherrypy.request.path.split('/')
        path = filter(lambda x: len(x), path)
        del path[-len(args)-1]
        # get the handler and path
        page_handler, object_path, virtual_path =
cherrypy.request.mapPathToObject(tg.url(path, kwargs))
        object_path = '/' + '/'.join(object_path[1:])
        # check is the object path same
        if object_path == cherrypy.request.object_path:
            raise cherrypy.NotFound
        virtual_path = [x.replace("%2F", "/") for x in virtual_path]
        return page_handler(*virtual_path, **kwargs)

Here, now I can access any resource under site/the-site-name/
resource...

Like this

http://127.0.0.1:8080/site/foo/sub1/sub2/m2
http://127.0.0.1:8080/site/foo/sub1/m1
http://127.0.0.1:8080/site/foo/item_list
http://127.0.0.1:8080/site/foo/item_detail

All of these method can access site from cherrypy.request.site. Hope
this little recipe would be helpful :P

On 2月13日, 下午11時12分, Victor <[email protected]> wrote:
> Thanks your relying.
> Both of your solution works. I would like to share what I was learned.
>
> I got a little try. That would be very useful for hierarchical web
> design. Without that I have to write exposed function like this:
>
> @expose()
> def foo(self, site, ...)
>     # get site... do some check..
>
> @expose()
> def bar(self, site, ...)
>     # get site... do some check..
>
> @expose()
> def add_category(self, site, section, category, ...)
>     # get site... do some check..
>     # get section ... do some check
>
> @expose()
> def del_category(self, site, section, category...)
>     # get site... do some check..
>     # get section ... do some check
>
> As you see, everything as a parent level should be parameters. And you
> have to write housekeeping code, such as passing parent parameters.
> When your function goes into a deep level of your site, that would be
> a nightmare. Now I found a better solution.
>
>     @tg.expose()
>     def default(self, site_name, action_name, *args, **kwargs):
>         site = model.Site.get_by(site_name=site_name)
>         assert site is not None, _(u'Site %s does not exist') %
> site_name
>         cherrypy.request.site = site
>
>         action = getattr(self, action_name, None)
>         if action is not None:
>             assert getattr(action, 'exposed', False) == True, _
> (u'Access deny')
>             return action(*args, **kwargs)
>         raise cherrypy.HTTPError(404, _(u'No such action %s') %
> action_name)
>
> Now you can access the site like this:
>
> http://examplesite.com/foo/book_list/TurboGears
>
> The default method will do the housekeeping work for you. It get the
> site and assign to cherrypy.request, so you can access it in your
> method later. But however, that might be dangerous to allow user call
> any method of controller. For example, you have a method like this
>
>     def _do_something_evil(self, *args, **kwargs):
>         return 'you will go to hell'
>
> And then you can do some evil thing by visit the url
>
> http://examplesite.com/foo/_do_something_evil/
>
> So that's better to limit functions default can called. My example
> code is just a simple implement. It may not works if there is
> something needed to be called in sub-controller. But I think it should
> be not too difficult to solve. Hope this would be helpful. :P
>
> Finally...although it works, I am wondering are there any potential
> issues?
>
> On 2月13日, 上午1時02分, Remi Jolin - SysGroup <[email protected]>
> wrote:
>
> > le 12.02.2009 15:30 Victor a écrit:
>
> > > Hi,
>
> > >     @tg.expose()
> > >     def default(self, name, action, *args, **kwargs):
> > >         return "hello %s %s %s %s" % (name, action, args, kwargs)
>
> > > It works. But here comes the problem is. How can I redirect the
> > > request without change of url to my controller? I know that I can
> > > redirect with redirect function like this:
>
> > >     @tg.expose()
> > >     def default(self, name, action, *args, **kwargs):
> > >         redirect(tg.url('/site', dict(name=name, action=action,
> > > **kwargs)))
>
> > That's a good start...
>
> > @tg.expose()
> > def default(self, name, action, *args, **kwargs):
> > # check if action is a method of your controller
> > action_method = getattr(self, action, None)
> > if action_method:
> > return action_method(name, *args, **kwargs)
> > ...
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to 
[email protected]
For more options, visit this group at 
http://groups.google.com/group/turbogears?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to