"you can easily do that, just by providing your own function to set up
the routes map. You can update the routes defaults by overriding the
setup_routes method of the base_config object in app_cfg.py."
Well, it's not that clear . setup routes() is a method of AppConfig.
If you just implement your own function in app_cfg.py it is never
called. You can subclass AppConfig and provide your own setup_routes()
method or you can create a custom setup_routes() function and assign
it to the original AppConfig before you instantiate base_config:
You will also need to import a bunch of stuff from tg.configuration
such as Mapper and config.
Once, I got that part right and my custom_setup_routes function was
actually called, it just did,'t work. I can't even get a simple hard-
coded path to work. Here is my custom_setup_routes() function:
def custom_setup_routes(self):
"""Setup the default TG2 routes
Override this and set up your own routes maps if you want to use
routes.
"""
#from dbgp.client import brk; brk(port=9011)
map = Mapper(directory=config['pylons.paths']['controllers'],
always_scan=config['debug'])
# Setup a default route for the root of object dispatch
map.connect('*url', controller='root',
action='routes_placeholder')
config['routes.map'] = map
I expect that the /prefix/foo URL will result in a call to the foo()
method on my RootController, but it doesn't. The standard object
dospatch works just fine, so /foo does get to my foo() method.
Can someone tell me what I'm doing wrong and/or explain how to debug
routing and/or show a full-fledged example of custom routes in TG2?
> "you can easily do that, just by providing your own function to set up
> the routes map. You can update the routes defaults by overriding the
> setup_routes method of the base_config object in app_cfg.py."
> Well, it's not that clear . setup routes() is a method of AppConfig.
> If you just implement your own function in app_cfg.py it is never
> called. You can subclass AppConfig and provide your own setup_routes()
> method or you can create a custom setup_routes() function and assign
> it to the original AppConfig before you instantiate base_config:
> You will also need to import a bunch of stuff from tg.configuration
> such as Mapper and config.
> Once, I got that part right and my custom_setup_routes function was
> actually called, it just did,'t work. I can't even get a simple hard-
> coded path to work. Here is my custom_setup_routes() function:
> def custom_setup_routes(self):
> """Setup the default TG2 routes
> Override this and set up your own routes maps if you want to use
> routes.
> """
> #from dbgp.client import brk; brk(port=9011)
> map = Mapper(directory=config['pylons.paths']['controllers'],
> always_scan=config['debug'])
> # Setup a default route for the root of object dispatch
> map.connect('*url', controller='root',
> action='routes_placeholder')
> config['routes.map'] = map
> I expect that the /prefix/foo URL will result in a call to the foo()
> method on my RootController, but it doesn't. The standard object
> dospatch works just fine, so /foo does get to my foo() method.
> Can someone tell me what I'm doing wrong and/or explain how to debug
> routing and/or show a full-fledged example of custom routes in TG2?
Mark,
Thanks for the quick response. It didn't work though. My
RootController now subclasses tg.controllers.DecoratedController and I
get the following error even on http://localhost:8080/ (the root):
AttributeError: 'function' object has no attribute 'decoration'
The code expects 'controller' to be an object with a 'decoration'
attribute, but in my case the controller is the __before__ method of
RootController:
>>> controller
<bound method RootController.__before__ of
<nine.controllers.root.RootController object at 0x99a3d0>>
Is it possible to post a fully working TG2 custom routes example? It
doesn't even have to be the entire project just the differences from a
standard quickstarted project.
Thanks, Carl
On Mar 13, 7:40 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> Yea, those docs are missing some important details.
> One think you do need to know is that the
> TGController/ObjectDispatchController expects to be routed to for
> object dispatch, not for a final page.
> So you want to use DecoratedController when defining your own custom routes.
> All of this should go on the RoutesIntegration page.
> --Mark
> On Fri, Mar 13, 2009 at 6:23 AM, Carl <tg2.u...@gmail.com> wrote:
> > "you can easily do that, just by providing your own function to set up
> > the routes map. You can update the routes defaults by overriding the
> > setup_routes method of the base_config object in app_cfg.py."
> > Well, it's not that clear . setup routes() is a method of AppConfig.
> > If you just implement your own function in app_cfg.py it is never
> > called. You can subclass AppConfig and provide your own setup_routes()
> > method or you can create a custom setup_routes() function and assign
> > it to the original AppConfig before you instantiate base_config:
> > You will also need to import a bunch of stuff from tg.configuration
> > such as Mapper and config.
> > Once, I got that part right and my custom_setup_routes function was
> > actually called, it just did,'t work. I can't even get a simple hard-
> > coded path to work. Here is my custom_setup_routes() function:
> > Override this and set up your own routes maps if you want to use
> > routes.
> > """
> > #from dbgp.client import brk; brk(port=9011)
> > map = Mapper(directory=config['pylons.paths']['controllers'],
> > always_scan=config['debug'])
> > # Setup a default route for the root of object dispatch
> > map.connect('*url', controller='root',
> > action='routes_placeholder')
> > config['routes.map'] = map
> > I expect that the /prefix/foo URL will result in a call to the foo()
> > method on my RootController, but it doesn't. The standard object
> > dospatch works just fine, so /foo does get to my foo() method.
> > Can someone tell me what I'm doing wrong and/or explain how to debug
> > routing and/or show a full-fledged example of custom routes in TG2?
I think there was a bug with __before__ and the decoration object
that has been fixed in the last beta, what version of tg2 are you
using (you can check with paster tginfo).
I have not tried making the RootController into a decorated
controller, I'd try making a new controller and routing to that. I
won't have time to make a doc this afternoon, but I can try to look at
it tomorrow if you don't get it working before then.
On Fri, Mar 13, 2009 at 1:01 PM, Carl <tg2.u...@gmail.com> wrote:
> Mark,
> Thanks for the quick response. It didn't work though. My
> RootController now subclasses tg.controllers.DecoratedController and I
> get the following error even on http://localhost:8080/ (the root):
> Module tg.controllers:125 in _perform_call
>>> controller.decoration.run_hooks('before_validate', remainder,
> AttributeError: 'function' object has no attribute 'decoration'
> The code expects 'controller' to be an object with a 'decoration'
> attribute, but in my case the controller is the __before__ method of
> RootController:
>>>> controller
> <bound method RootController.__before__ of
> <nine.controllers.root.RootController object at 0x99a3d0>>
> Is it possible to post a fully working TG2 custom routes example? It
> doesn't even have to be the entire project just the differences from a
> standard quickstarted project.
> Thanks, Carl
> On Mar 13, 7:40 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
>> Yea, those docs are missing some important details.
>> One think you do need to know is that the
>> TGController/ObjectDispatchController expects to be routed to for
>> object dispatch, not for a final page.
>> So you want to use DecoratedController when defining your own custom routes.
>> All of this should go on the RoutesIntegration page.
>> --Mark
>> On Fri, Mar 13, 2009 at 6:23 AM, Carl <tg2.u...@gmail.com> wrote:
>> > "you can easily do that, just by providing your own function to set up
>> > the routes map. You can update the routes defaults by overriding the
>> > setup_routes method of the base_config object in app_cfg.py."
>> > Well, it's not that clear . setup routes() is a method of AppConfig.
>> > If you just implement your own function in app_cfg.py it is never
>> > called. You can subclass AppConfig and provide your own setup_routes()
>> > method or you can create a custom setup_routes() function and assign
>> > it to the original AppConfig before you instantiate base_config:
>> > You will also need to import a bunch of stuff from tg.configuration
>> > such as Mapper and config.
>> > Once, I got that part right and my custom_setup_routes function was
>> > actually called, it just did,'t work. I can't even get a simple hard-
>> > coded path to work. Here is my custom_setup_routes() function:
>> > Override this and set up your own routes maps if you want to use
>> > routes.
>> > """
>> > #from dbgp.client import brk; brk(port=9011)
>> > map = Mapper(directory=config['pylons.paths']['controllers'],
>> > always_scan=config['debug'])
>> > # Setup a default route for the root of object dispatch
>> > map.connect('*url', controller='root',
>> > action='routes_placeholder')
>> > config['routes.map'] = map
>> > I expect that the /prefix/foo URL will result in a call to the foo()
>> > method on my RootController, but it doesn't. The standard object
>> > dospatch works just fine, so /foo does get to my foo() method.
>> > Can someone tell me what I'm doing wrong and/or explain how to debug
>> > routing and/or show a full-fledged example of custom routes in TG2?
> I think there was a bug with __before__ and the decoration object
> that has been fixed in the last beta, what version of tg2 are you
> using (you can check with paster tginfo).
> I have not tried making the RootController into a decorated
> controller, I'd try making a new controller and routing to that. I
> won't have time to make a doc this afternoon, but I can try to look at
> it tomorrow if you don't get it working before then.
> --Mark
> On Fri, Mar 13, 2009 at 1:01 PM, Carl <tg2.u...@gmail.com> wrote:
> > Mark,
> > Thanks for the quick response. It didn't work though. My
> > RootController now subclasses tg.controllers.DecoratedController and I
> > get the following error even onhttp://localhost:8080/(the root):
> > Module tg.controllers:125 in _perform_call
> >>> controller.decoration.run_hooks('before_validate', remainder,
> > AttributeError: 'function' object has no attribute 'decoration'
> > The code expects 'controller' to be an object with a 'decoration'
> > attribute, but in my case the controller is the __before__ method of
> > RootController:
> >>>> controller
> > <bound method RootController.__before__ of
> > <nine.controllers.root.RootController object at 0x99a3d0>>
> > Is it possible to post a fully working TG2 custom routes example? It
> > doesn't even have to be the entire project just the differences from a
> > standard quickstarted project.
> > Thanks, Carl
> > On Mar 13, 7:40 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> >> Yea, those docs are missing some important details.
> >> One think you do need to know is that the
> >> TGController/ObjectDispatchController expects to be routed to for
> >> object dispatch, not for a final page.
> >> So you want to use DecoratedController when defining your own custom routes.
> >> All of this should go on the RoutesIntegration page.
> >> --Mark
> >> On Fri, Mar 13, 2009 at 6:23 AM, Carl <tg2.u...@gmail.com> wrote:
> >> > "you can easily do that, just by providing your own function to set up
> >> > the routes map. You can update the routes defaults by overriding the
> >> > setup_routes method of the base_config object in app_cfg.py."
> >> > Well, it's not that clear . setup routes() is a method of AppConfig.
> >> > If you just implement your own function in app_cfg.py it is never
> >> > called. You can subclass AppConfig and provide your own setup_routes()
> >> > method or you can create a custom setup_routes() function and assign
> >> > it to the original AppConfig before you instantiate base_config:
> >> > You will also need to import a bunch of stuff from tg.configuration
> >> > such as Mapper and config.
> >> > Once, I got that part right and my custom_setup_routes function was
> >> > actually called, it just did,'t work. I can't even get a simple hard-
> >> > coded path to work. Here is my custom_setup_routes() function:
> >> > Override this and set up your own routes maps if you want to use
> >> > routes.
> >> > """
> >> > #from dbgp.client import brk; brk(port=9011)
> >> > map = Mapper(directory=config['pylons.paths']['controllers'],
> >> > always_scan=config['debug'])
> >> > # Setup a default route for the root of object dispatch
> >> > map.connect('*url', controller='root',
> >> > action='routes_placeholder')
> >> > config['routes.map'] = map
> >> > I expect that the /prefix/foo URL will result in a call to the foo()
> >> > method on my RootController, but it doesn't. The standard object
> >> > dospatch works just fine, so /foo does get to my foo() method.
> >> > Can someone tell me what I'm doing wrong and/or explain how to debug
> >> > routing and/or show a full-fledged example of custom routes in TG2?
> >> > Thanks, Carl
> >> --
> >> Mark Ramm-Christensen
> >> email: mark at compoundthinking dot com
> >> blog:www.compoundthinking.com/blog
Ok. I followed the code through the internals. I created a separate
controller derived from DecoratedController and updates the
setup_routes() function. The routing works just fine and returns
eventually my new controller. Then we get into the actuall object
dispatch and it looks like the TG piece and the Pylons piece don't
agree exactly on what's going on.
- In pylons/controllers/core.py the __call__() method of the
WSGIController is called
- The __call__() method calls _inspect_call() with the __before__
attribute, which is a function
- The _inspect_call() method after a lot of arg checks and other stuff
calls the _perform_call with the __before__ attribute
- The _inspect_call() method is implemented by TG proper in
tg.controllers.DecoratedController. This expects the passed in func
object to have a 'decoration' attribute, but the __before__ function
passed by Pylons have no such attribute, so we get AttributeError and
everything blows up.
Does it ring a bell? I can't figure out all the implicit assumptions
and expectations in the code. I can't even tell if there is a bug or
if I'm doing something wrong/missing some configuration step.
Thanks, Carl
On Mar 13, 11:50 am, Carl <tg2.u...@gmail.com> wrote:
> and it told me I already have the latest. I'll try routing to a
> different controller.
> Thanks, Carl
> On Mar 13, 10:49 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > I think there was a bug with __before__ and the decoration object
> > that has been fixed in the last beta, what version of tg2 are you
> > using (you can check with paster tginfo).
> > I have not tried making the RootController into a decorated
> > controller, I'd try making a new controller and routing to that. I
> > won't have time to make a doc this afternoon, but I can try to look at
> > it tomorrow if you don't get it working before then.
> > --Mark
> > On Fri, Mar 13, 2009 at 1:01 PM, Carl <tg2.u...@gmail.com> wrote:
> > > Mark,
> > > Thanks for the quick response. It didn't work though. My
> > > RootController now subclasses tg.controllers.DecoratedController and I
> > > get the following error even onhttp://localhost:8080/(theroot):
> > > Module tg.controllers:125 in _perform_call
> > >>> controller.decoration.run_hooks('before_validate', remainder,
> > > AttributeError: 'function' object has no attribute 'decoration'
> > > The code expects 'controller' to be an object with a 'decoration'
> > > attribute, but in my case the controller is the __before__ method of
> > > RootController:
> > >>>> controller
> > > <bound method RootController.__before__ of
> > > <nine.controllers.root.RootController object at 0x99a3d0>>
> > > Is it possible to post a fully working TG2 custom routes example? It
> > > doesn't even have to be the entire project just the differences from a
> > > standard quickstarted project.
> > > Thanks, Carl
> > > On Mar 13, 7:40 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > >> Yea, those docs are missing some important details.
> > >> One think you do need to know is that the
> > >> TGController/ObjectDispatchController expects to be routed to for
> > >> object dispatch, not for a final page.
> > >> So you want to use DecoratedController when defining your own custom routes.
> > >> All of this should go on the RoutesIntegration page.
> > >> --Mark
> > >> On Fri, Mar 13, 2009 at 6:23 AM, Carl <tg2.u...@gmail.com> wrote:
> > >> > "you can easily do that, just by providing your own function to set up
> > >> > the routes map. You can update the routes defaults by overriding the
> > >> > setup_routes method of the base_config object in app_cfg.py."
> > >> > Well, it's not that clear . setup routes() is a method of AppConfig.
> > >> > If you just implement your own function in app_cfg.py it is never
> > >> > called. You can subclass AppConfig and provide your own setup_routes()
> > >> > method or you can create a custom setup_routes() function and assign
> > >> > it to the original AppConfig before you instantiate base_config:
> > >> > You will also need to import a bunch of stuff from tg.configuration
> > >> > such as Mapper and config.
> > >> > Once, I got that part right and my custom_setup_routes function was
> > >> > actually called, it just did,'t work. I can't even get a simple hard-
> > >> > coded path to work. Here is my custom_setup_routes() function:
> > >> > Override this and set up your own routes maps if you want to use
> > >> > routes.
> > >> > """
> > >> > #from dbgp.client import brk; brk(port=9011)
> > >> > map = Mapper(directory=config['pylons.paths']['controllers'],
> > >> > always_scan=config['debug'])
> > >> > # Setup a default route for the root of object dispatch
> > >> > map.connect('*url', controller='root',
> > >> > action='routes_placeholder')
> > >> > config['routes.map'] = map
> > >> > I expect that the /prefix/foo URL will result in a call to the foo()
> > >> > method on my RootController, but it doesn't. The standard object
> > >> > dospatch works just fine, so /foo does get to my foo() method.
> > >> > Can someone tell me what I'm doing wrong and/or explain how to debug
> > >> > routing and/or show a full-fledged example of custom routes in TG2?
> > >> > Thanks, Carl
> > >> --
> > >> Mark Ramm-Christensen
> > >> email: mark at compoundthinking dot com
> > >> blog:www.compoundthinking.com/blog
I've had no problem while using custom routes; attached is the app_cfg.py file of a project which uses them. I didn't have to deal with DecoratedControllers or something else, just what you see in the attached file.
> Ok. I followed the code through the internals. I created a separate
> controller derived from DecoratedController and updates the
> setup_routes() function. The routing works just fine and returns
> eventually my new controller. Then we get into the actuall object
> dispatch and it looks like the TG piece and the Pylons piece don't
> agree exactly on what's going on.
> - In pylons/controllers/core.py the __call__() method of the
> WSGIController is called
> - The __call__() method calls _inspect_call() with the __before__
> attribute, which is a function
> - The _inspect_call() method after a lot of arg checks and other stuff
> calls the _perform_call with the __before__ attribute
> - The _inspect_call() method is implemented by TG proper in
> tg.controllers.DecoratedController. This expects the passed in func
> object to have a 'decoration' attribute, but the __before__ function
> passed by Pylons have no such attribute, so we get AttributeError and
> everything blows up.
> Does it ring a bell? I can't figure out all the implicit assumptions
> and expectations in the code. I can't even tell if there is a bug or
> if I'm doing something wrong/missing some configuration step.
> Thanks, Carl
> On Mar 13, 11:50 am, Carl <tg2.u...@gmail.com> wrote:
> > I'm using the latest TurboGears2 2.0b7 (according to paster tginfo). I
> > also did:
> > and it told me I already have the latest. I'll try routing to a
> > different controller.
> > Thanks, Carl
> > On Mar 13, 10:49 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > > I think there was a bug with __before__ and the decoration object
> > > that has been fixed in the last beta, what version of tg2 are you
> > > using (you can check with paster tginfo).
> > > I have not tried making the RootController into a decorated
> > > controller, I'd try making a new controller and routing to that. I
> > > won't have time to make a doc this afternoon, but I can try to look at
> > > it tomorrow if you don't get it working before then.
> > > --Mark
> > > On Fri, Mar 13, 2009 at 1:01 PM, Carl <tg2.u...@gmail.com> wrote:
> > > > Mark,
> > > > Thanks for the quick response. It didn't work though. My
> > > > RootController now subclasses tg.controllers.DecoratedController and
> > > > I get the following error even onhttp://localhost:8080/(theroot):
> > > > Module tg.controllers:125 in _perform_call
> > > > AttributeError: 'function' object has no attribute 'decoration'
> > > > The code expects 'controller' to be an object with a 'decoration'
> > > > attribute, but in my case the controller is the __before__ method of
> > > > RootController:
> > > >>>> controller
> > > > <bound method RootController.__before__ of
> > > > <nine.controllers.root.RootController object at 0x99a3d0>>
> > > > Is it possible to post a fully working TG2 custom routes example? It
> > > > doesn't even have to be the entire project just the differences from
> > > > a standard quickstarted project.
> > > > Thanks, Carl
> > > > On Mar 13, 7:40 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > > >> Yea, those docs are missing some important details.
> > > >> One think you do need to know is that the
> > > >> TGController/ObjectDispatchController expects to be routed to for
> > > >> object dispatch, not for a final page.
> > > >> So you want to use DecoratedController when defining your own custom
> > > >> routes.
> > > >> All of this should go on the RoutesIntegration page.
> > > >> --Mark
> > > >> On Fri, Mar 13, 2009 at 6:23 AM, Carl <tg2.u...@gmail.com> wrote:
> > > >> > Hi,
> > > >> > I'm trying to do custom routes with TG2 and failing so far. The
> > > >> > instructions
> > > >> > inhttp://turbogears.org/2.0/docs/main/RoutesIntegration.html tell
> > > >> > you to:
> > > >> > "you can easily do that, just by providing your own function to
> > > >> > set up the routes map. You can update the routes defaults by
> > > >> > overriding the setup_routes method of the base_config object in
> > > >> > app_cfg.py."
> > > >> > Well, it's not that clear . setup routes() is a method of
> > > >> > AppConfig. If you just implement your own function in app_cfg.py
> > > >> > it is never called. You can subclass AppConfig and provide your
> > > >> > own setup_routes() method or you can create a custom
> > > >> > setup_routes() function and assign it to the original AppConfig
> > > >> > before you instantiate base_config:
> > > >> > You will also need to import a bunch of stuff from
> > > >> > tg.configuration such as Mapper and config.
> > > >> > Once, I got that part right and my custom_setup_routes function
> > > >> > was actually called, it just did,'t work. I can't even get a
> > > >> > simple hard- coded path to work. Here is my custom_setup_routes()
> > > >> > function:
> > > >> > # Setup a default route for the root of object dispatch
> > > >> > map.connect('*url', controller='root',
> > > >> > action='routes_placeholder')
> > > >> > config['routes.map'] = map
> > > >> > I expect that the /prefix/foo URL will result in a call to the
> > > >> > foo() method on my RootController, but it doesn't. The standard
> > > >> > object dospatch works just fine, so /foo does get to my foo()
> > > >> > method.
> > > >> > Can someone tell me what I'm doing wrong and/or explain how to
> > > >> > debug routing and/or show a full-fledged example of custom routes
> > > >> > in TG2?
> > > >> > Thanks, Carl
> > > >> --
> > > >> Mark Ramm-Christensen
> > > >> email: mark at compoundthinking dot com
> > > >> blog:www.compoundthinking.com/blog
> > > --
> > > Mark Ramm-Christensen
> > > email: mark at compoundthinking dot com
> > > blog:www.compoundthinking.com/blog
Hello Gustavo,
I tried it but it didn't work for me. Maybe I got the URL syntax
wrong. What URLs map to your custom routes? Also, from reading the
Routes manual I got the impression that variables are words with a
colon in the end (e.g 'prefix:'), but your routes look like regular
expressions.
Thanks, Carl
On Mar 13, 9:07 pm, Gustavo Narea <m...@gustavonarea.net> wrote:
> I've had no problem while using custom routes; attached is the app_cfg.py file
> of a project which uses them. I didn't have to deal with DecoratedControllers
> or something else, just what you see in the attached file.
> Cheers.
> On Friday March 13, 2009 20:40:58 Carl wrote:
> > Ok. I followed the code through the internals. I created a separate
> > controller derived from DecoratedController and updates the
> > setup_routes() function. The routing works just fine and returns
> > eventually my new controller. Then we get into the actuall object
> > dispatch and it looks like the TG piece and the Pylons piece don't
> > agree exactly on what's going on.
> > - In pylons/controllers/core.py the __call__() method of the
> > WSGIController is called
> > - The __call__() method calls _inspect_call() with the __before__
> > attribute, which is a function
> > - The _inspect_call() method after a lot of arg checks and other stuff
> > calls the _perform_call with the __before__ attribute
> > - The _inspect_call() method is implemented by TG proper in
> > tg.controllers.DecoratedController. This expects the passed in func
> > object to have a 'decoration' attribute, but the __before__ function
> > passed by Pylons have no such attribute, so we get AttributeError and
> > everything blows up.
> > Does it ring a bell? I can't figure out all the implicit assumptions
> > and expectations in the code. I can't even tell if there is a bug or
> > if I'm doing something wrong/missing some configuration step.
> > Thanks, Carl
> > On Mar 13, 11:50 am, Carl <tg2.u...@gmail.com> wrote:
> > > I'm using the latest TurboGears2 2.0b7 (according to paster tginfo). I
> > > also did:
> > > and it told me I already have the latest. I'll try routing to a
> > > different controller.
> > > Thanks, Carl
> > > On Mar 13, 10:49 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > > > I think there was a bug with __before__ and the decoration object
> > > > that has been fixed in the last beta, what version of tg2 are you
> > > > using (you can check with paster tginfo).
> > > > I have not tried making the RootController into a decorated
> > > > controller, I'd try making a new controller and routing to that. I
> > > > won't have time to make a doc this afternoon, but I can try to look at
> > > > it tomorrow if you don't get it working before then.
> > > > --Mark
> > > > On Fri, Mar 13, 2009 at 1:01 PM, Carl <tg2.u...@gmail.com> wrote:
> > > > > Mark,
> > > > > Thanks for the quick response. It didn't work though. My
> > > > > RootController now subclasses tg.controllers.DecoratedController and
> > > > > I get the following error even onhttp://localhost:8080/(theroot):
> > > > > Module tg.controllers:125 in _perform_call
> > > > > AttributeError: 'function' object has no attribute 'decoration'
> > > > > The code expects 'controller' to be an object with a 'decoration'
> > > > > attribute, but in my case the controller is the __before__ method of
> > > > > RootController:
> > > > >>>> controller
> > > > > <bound method RootController.__before__ of
> > > > > <nine.controllers.root.RootController object at 0x99a3d0>>
> > > > > Is it possible to post a fully working TG2 custom routes example? It
> > > > > doesn't even have to be the entire project just the differences from
> > > > > a standard quickstarted project.
> > > > > Thanks, Carl
> > > > > On Mar 13, 7:40 am, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > > > >> Yea, those docs are missing some important details.
> > > > >> One think you do need to know is that the
> > > > >> TGController/ObjectDispatchController expects to be routed to for
> > > > >> object dispatch, not for a final page.
> > > > >> So you want to use DecoratedController when defining your own custom
> > > > >> routes.
> > > > >> All of this should go on the RoutesIntegration page.
> > > > >> --Mark
> > > > >> On Fri, Mar 13, 2009 at 6:23 AM, Carl <tg2.u...@gmail.com> wrote:
> > > > >> > Hi,
> > > > >> > I'm trying to do custom routes with TG2 and failing so far. The
> > > > >> > instructions
> > > > >> > inhttp://turbogears.org/2.0/docs/main/RoutesIntegration.htmltell > > > > >> > you to:
> > > > >> > "you can easily do that, just by providing your own function to
> > > > >> > set up the routes map. You can update the routes defaults by
> > > > >> > overriding the setup_routes method of the base_config object in
> > > > >> > app_cfg.py."
> > > > >> > Well, it's not that clear . setup routes() is a method of
> > > > >> > AppConfig. If you just implement your own function in app_cfg.py
> > > > >> > it is never called. You can subclass AppConfig and provide your
> > > > >> > own setup_routes() method or you can create a custom
> > > > >> > setup_routes() function and assign it to the original AppConfig
> > > > >> > before you instantiate base_config:
> > > > >> > You will also need to import a bunch of stuff from
> > > > >> > tg.configuration such as Mapper and config.
> > > > >> > Once, I got that part right and my custom_setup_routes function
> > > > >> > was actually called, it just did,'t work. I can't even get a
> > > > >> > simple hard- coded path to work. Here is my custom_setup_routes()
> > > > >> > function:
> > > > >> > # Setup a default route for the root of object dispatch
> > > > >> > map.connect('*url', controller='root',
> > > > >> > action='routes_placeholder')
> > > > >> > config['routes.map'] = map
> > > > >> > I expect that the /prefix/foo URL will result in a call to the
> > > > >> > foo() method on my RootController, but it doesn't. The standard
> > > > >> > object dospatch works just fine, so /foo does get to my foo()
> > > > >> > method.
> > > > >> > Can someone tell me what I'm doing wrong and/or explain how to
> > > > >> > debug routing and/or show a full-fledged example of custom routes
> > > > >> > in TG2?
> > > > >> > Thanks, Carl
> > > > >> --
> > > > >> Mark Ramm-Christensen
> > > > >> email: mark at compoundthinking dot com
> > > > >> blog:www.compoundthinking.com/blog
> > > > --
> > > > Mark Ramm-Christensen
> > > > email: mark at compoundthinking dot com
> > > > blog:www.compoundthinking.com/blog
I have made a few more almost successful experiments. My
RootController now sub-classes DecoratedController as Mark suggested.
Before I do the subclassing I remove the __before__ and __after__
attributes from DecoratedController:
That almost works. The routing works and if my custom route is:
m.connect('prefix/{action}', controller='root')
Then it gets to the proper method on the RootController. The problem
is that now the pylons.request object has no response_type attribute.
It's not surprizing because the __before__ and __after__ methods are
probably there for a reason.
So, I renew my plea for a working example of custom routes in TG2.
> I tried it but it didn't work for me. Maybe I got the URL syntax > wrong. What URLs map to your custom routes?
Those whose paths look like: /<string>/<integer>
> Also, from reading the > Routes manual I got the impression that variables are words with a > colon in the end (e.g 'prefix:'), but your routes look like regular > expressions.
Placeholders can be defined with {brackets} and :colons:, but the later is deprecated.
In my case I just wanted to force an integer in one of the variables, hence I used a regular expression. It's optional.
Cheers!
PS: What didn't exactly work? -- Gustavo Narea <xri://=Gustavo>. | Tech blog: =Gustavo/(+blog)/tech ~ About me: =Gustavo/about |
Hello Gustavo,
What didn't work for me is that if my controller I just subclasses
the BaseController, then it looks like the routing in app_cfg.py is
ignored. TGController calls a _get_routing_info() function defined in
ObjectDispatchController that does just object dispatch.
Gigi
On Mar 16, 9:46 am, Gustavo Narea <m...@gustavonarea.net> wrote:
> > I tried it but it didn't work for me. Maybe I got the URL syntax
> > wrong. What URLs map to your custom routes?
> Those whose paths look like: /<string>/<integer>
> > Also, from reading the
> > Routes manual I got the impression that variables are words with a
> > colon in the end (e.g 'prefix:'), but your routes look like regular
> > expressions.
> Placeholders can be defined with {brackets} and :colons:, but the later is
> deprecated.
> In my case I just wanted to force an integer in one of the variables, hence I
> used a regular expression. It's optional.
On Mon, Mar 16, 2009 at 2:43 PM, Carl <tg2.u...@gmail.com> wrote:
> Hello Gustavo,
> What didn't work for me is that if my controller I just subclasses
> the BaseController, then it looks like the routing in app_cfg.py is
> ignored. TGController calls a _get_routing_info() function defined in
> ObjectDispatchController that does just object dispatch.
> Gigi
> On Mar 16, 9:46 am, Gustavo Narea <m...@gustavonarea.net> wrote:
>> Hello, Carl.
>> On Saturday March 14, 2009 16:49:17 Carl wrote:
>> > I tried it but it didn't work for me. Maybe I got the URL syntax
>> > wrong. What URLs map to your custom routes?
>> Those whose paths look like: /<string>/<integer>
>> > Also, from reading the
>> > Routes manual I got the impression that variables are words with a
>> > colon in the end (e.g 'prefix:'), but your routes look like regular
>> > expressions.
>> Placeholders can be defined with {brackets} and :colons:, but the later is
>> deprecated.
>> In my case I just wanted to force an integer in one of the variables, hence I
>> used a regular expression. It's optional.
Ok. This is on a new quickstarted project with my changes for custom
routes. Here is the traceback and the changes to app_cfg.py and
root.py are bellow. If it's helpful I can upload the entire project.
URL: http://localhost:8080/prefix/1/about File '/Users/carl/tg2env/lib/python2.5/site-packages/WebError-0.10.1-
py2.5.egg/weberror/evalexception.py', line 431 in respond
app_iter = self.application(environ, detect_start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
py2.5.egg/tg/configuration.py', line 631 in wrapper
return app(environ, start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
py2.5.egg/tg/configuration.py', line 534 in remover
return app(environ, start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/repoze.tm2-1.0a3-
py2.5.egg/repoze/tm/__init__.py', line 19 in __call__
result = self.application(environ, save_status_and_headers)
File '/Users/carl/tg2env/lib/python2.5/site-packages/
ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
36 in __call__
return self.wsgi_app(environ, start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/
ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
59 in wsgi_app
resp = req.get_response(self.application)
File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
in get_response
File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
in call_application
File '/Users/carl/tg2env/lib/python2.5/site-packages/
ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/
resource_injector.py', line 67 in _injector
resp = req.get_response(app)
File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
in get_response
File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
in call_application
File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
py2.5.egg/beaker/middleware.py', line 81 in __call__
return self.app(environ, start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
py2.5.egg/beaker/middleware.py', line 160 in __call__
return self.wrap_app(environ, session_start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/Routes-1.10.3-
py2.5.egg/routes/middleware.py', line 130 in __call__
response = self.app(environ, start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
py2.5.egg/pylons/wsgiapp.py', line 125 in __call__
response = self.dispatch(controller, environ, start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
py2.5.egg/pylons/wsgiapp.py', line 324 in dispatch
return controller(environ, start_response)
File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
py2.5.egg/pylons/controllers/core.py', line 217 in __call__
response = self._inspect_call(self.__before__)
File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
py2.5.egg/pylons/controllers/core.py', line 107 in _inspect_call
result = self._perform_call(func, args)
File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
py2.5.egg/tg/controllers.py', line 125 in _perform_call
controller.decoration.run_hooks('before_validate', remainder,
AttributeError: 'function' object has no attribute 'decoration'
Here is my app_cfg.py:
# -*- coding: utf-8 -*-
"""
Global configuration file for TG2-specific settings in custom-routes.
This file complements development/deployment.ini.
"""
from tg.configuration import AppConfig, Bunch
# Carl: needed for setup_custom_routes
from tg.configuration import Mapper, config
import custom_routes
from custom_routes import model
from custom_routes.lib import app_globals, helpers
# Carl: added custom routes function to override the default in
AppConfig
def custom_setup_routes(self):
"""Setup the default TG2 routes
Override this and set up your own routes maps if you want to use
routes.
"""
map = Mapper(directory=config['pylons.paths']['controllers'],
always_scan=config['debug'])
# Setup a default route for the root of object dispatch
map.connect('*url', controller='root',
action='routes_placeholder')
config['routes.map'] = map
# Carl: assign the custom routes function to AppConfig.
# It's equivalent to subclassing AppConfig in this case
AppConfig.setup_routes = custom_setup_routes
#Set the default renderer
base_config.default_renderer = 'genshi'
base_config.renderers.append('genshi')
# if you want raw speed and have installed chameleon.genshi
# you should try to use this renderer instead.
# warning: for the moment chameleon does not handle i18n translations
#base_config.renderers.append('chameleon_genshi')
#Configure the base SQLALchemy Setup
base_config.use_sqlalchemy = True
base_config.model = custom_routes.model
And here are my changes to the RootController:
# -*- coding: utf-8 -*-
"""Main Controller"""
from tg import expose, flash, require, url, request, redirect,
validate
from pylons.i18n import ugettext as _, lazy_ugettext as l_
from custom_routes.lib.base import BaseController
# Carl: DecoratedController will be the base class for the root
controller
from tg.controllers import DecoratedController
from custom_routes.model import DBSession, metadata
from custom_routes.controllers.error import ErrorController
__all__ = ['RootController']
class RootController(DecoratedController):
#class RootController(BaseController):
# The rest is the same
On Mar 16, 1:09 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> A code sample, and traceback would help us help you better ;)
> On Mon, Mar 16, 2009 at 2:43 PM, Carl <tg2.u...@gmail.com> wrote:
> > Hello Gustavo,
> > What didn't work for me is that if my controller I just subclasses
> > the BaseController, then it looks like the routing in app_cfg.py is
> > ignored. TGController calls a _get_routing_info() function defined in
> > ObjectDispatchController that does just object dispatch.
> > Gigi
> > On Mar 16, 9:46 am, Gustavo Narea <m...@gustavonarea.net> wrote:
> >> Hello, Carl.
> >> On Saturday March 14, 2009 16:49:17 Carl wrote:
> >> > I tried it but it didn't work for me. Maybe I got the URL syntax
> >> > wrong. What URLs map to your custom routes?
> >> Those whose paths look like: /<string>/<integer>
> >> > Also, from reading the
> >> > Routes manual I got the impression that variables are words with a
> >> > colon in the end (e.g 'prefix:'), but your routes look like regular
> >> > expressions.
> >> Placeholders can be defined with {brackets} and :colons:, but the later is
> >> deprecated.
> >> In my case I just wanted to force an integer in one of the variables, hence I
> >> used a regular expression. It's optional.
> Ok. This is on a new quickstarted project with my changes for custom
> routes. Here is the traceback and the changes to app_cfg.py and
> root.py are bellow. If it's helpful I can upload the entire project.
> URL:http://localhost:8080/prefix/1/about > File '/Users/carl/tg2env/lib/python2.5/site-packages/WebError-0.10.1-
> py2.5.egg/weberror/evalexception.py', line 431 in respond
> app_iter = self.application(environ, detect_start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> py2.5.egg/tg/configuration.py', line 631 in wrapper
> return app(environ, start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> py2.5.egg/tg/configuration.py', line 534 in remover
> return app(environ, start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/repoze.tm2-1.0a3-
> py2.5.egg/repoze/tm/__init__.py', line 19 in __call__
> result = self.application(environ, save_status_and_headers)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/
> ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> 36 in __call__
> return self.wsgi_app(environ, start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/
> ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> 59 in wsgi_app
> resp = req.get_response(self.application)
> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> in get_response
> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> in call_application
> File '/Users/carl/tg2env/lib/python2.5/site-packages/
> ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/
> resource_injector.py', line 67 in _injector
> resp = req.get_response(app)
> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> in get_response
> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> in call_application
> File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> py2.5.egg/beaker/middleware.py', line 81 in __call__
> return self.app(environ, start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> py2.5.egg/beaker/middleware.py', line 160 in __call__
> return self.wrap_app(environ, session_start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/Routes-1.10.3-
> py2.5.egg/routes/middleware.py', line 130 in __call__
> response = self.app(environ, start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> py2.5.egg/pylons/wsgiapp.py', line 125 in __call__
> response = self.dispatch(controller, environ, start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> py2.5.egg/pylons/wsgiapp.py', line 324 in dispatch
> return controller(environ, start_response)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> py2.5.egg/pylons/controllers/core.py', line 217 in __call__
> response = self._inspect_call(self.__before__)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> py2.5.egg/pylons/controllers/core.py', line 107 in _inspect_call
> result = self._perform_call(func, args)
> File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> py2.5.egg/tg/controllers.py', line 125 in _perform_call
> controller.decoration.run_hooks('before_validate', remainder,
> AttributeError: 'function' object has no attribute 'decoration'
> Here is my app_cfg.py:
> # -*- coding: utf-8 -*-
> """
> Global configuration file for TG2-specific settings in custom-routes.
> This file complements development/deployment.ini.
> """
> from tg.configuration import AppConfig, Bunch
> # Carl: needed for setup_custom_routes
> from tg.configuration import Mapper, config
> import custom_routes
> from custom_routes import model
> from custom_routes.lib import app_globals, helpers
> # Carl: added custom routes function to override the default in
> AppConfig
> def custom_setup_routes(self):
> """Setup the default TG2 routes
> Override this and set up your own routes maps if you want to use
> routes.
> """
> map = Mapper(directory=config['pylons.paths']['controllers'],
> always_scan=config['debug'])
> # Setup a default route for the root of object dispatch
> map.connect('*url', controller='root',
> action='routes_placeholder')
> config['routes.map'] = map
> # Carl: assign the custom routes function to AppConfig.
> # It's equivalent to subclassing AppConfig in this case
> AppConfig.setup_routes = custom_setup_routes
> #Set the default renderer
> base_config.default_renderer = 'genshi'
> base_config.renderers.append('genshi')
> # if you want raw speed and have installed chameleon.genshi
> # you should try to use this renderer instead.
> # warning: for the moment chameleon does not handle i18n translations
> #base_config.renderers.append('chameleon_genshi')
> #Configure the base SQLALchemy Setup
> base_config.use_sqlalchemy = True
> base_config.model = custom_routes.model
> And here are my changes to the RootController:
> # -*- coding: utf-8 -*-
> """Main Controller"""
> from tg import expose, flash, require, url, request, redirect,
> validate
> from pylons.i18n import ugettext as _, lazy_ugettext as l_
> from custom_routes.lib.base import BaseController
> # Carl: DecoratedController will be the base class for the root
> controller
> from tg.controllers import DecoratedController
> from custom_routes.model import DBSession, metadata
> from custom_routes.controllers.error import ErrorController
> __all__ = ['RootController']
> class RootController(DecoratedController):
> #class RootController(BaseController):
> # The rest is the same
> On Mar 16, 1:09 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > A code sample, and traceback would help us help you better ;)
> > On Mon, Mar 16, 2009 at 2:43 PM, Carl <tg2.u...@gmail.com> wrote:
> > > Hello Gustavo,
> > > What didn't work for me is that if my controller I just subclasses
> > > the BaseController, then it looks like the routing in app_cfg.py is
> > > ignored. TGController calls a _get_routing_info() function defined in
> > > ObjectDispatchController that does just object dispatch.
> > > Gigi
> > > On Mar 16, 9:46 am, Gustavo Narea <m...@gustavonarea.net> wrote:
> > >> Hello, Carl.
> > >> On Saturday March 14, 2009 16:49:17 Carl wrote:
> > >> > I tried it but it didn't work for me. Maybe I got the URL syntax
> > >> > wrong. What URLs map to your custom routes?
> > >> Those whose paths look like: /<string>/<integer>
> > >> > Also, from reading the
> > >> > Routes manual I got the impression that variables are words with a
> > >> > colon in the end (e.g 'prefix:'), but your routes look like regular
> > >> > expressions.
> > >> Placeholders can be defined with {brackets} and :colons:, but the later is
> > >> deprecated.
> > >> In my case I just wanted to force an integer in one of the variables, hence I
> > >> used a regular expression. It's optional.
I found a workaround, but it's not pretty. The solution is to override
the _perform_call() method of DecoratedController in your controller:
def _perform_call(self, controller, params, remainder=None):
# If not a decorated method just call it (needed for
__before__ and __after__)
if not hasattr(controller, 'decoration'):
if remainder is None:
remainder = []
> On Mar 17, 2:00 am, Carl <tg2.u...@gmail.com> wrote:
> > Ok. This is on a new quickstarted project with my changes for custom
> > routes. Here is the traceback and the changes to app_cfg.py and
> > root.py are bellow. If it's helpful I can upload the entire project.
> > URL:http://localhost:8080/prefix/1/about > > File '/Users/carl/tg2env/lib/python2.5/site-packages/WebError-0.10.1-
> > py2.5.egg/weberror/evalexception.py', line 431 in respond
> > app_iter = self.application(environ, detect_start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > py2.5.egg/tg/configuration.py', line 631 in wrapper
> > return app(environ, start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > py2.5.egg/tg/configuration.py', line 534 in remover
> > return app(environ, start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/repoze.tm2-1.0a3-
> > py2.5.egg/repoze/tm/__init__.py', line 19 in __call__
> > result = self.application(environ, save_status_and_headers)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> > 36 in __call__
> > return self.wsgi_app(environ, start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> > 59 in wsgi_app
> > resp = req.get_response(self.application)
> > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> > in get_response
> > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> > in call_application
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/
> > resource_injector.py', line 67 in _injector
> > resp = req.get_response(app)
> > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> > in get_response
> > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> > in call_application
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> > py2.5.egg/beaker/middleware.py', line 81 in __call__
> > return self.app(environ, start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> > py2.5.egg/beaker/middleware.py', line 160 in __call__
> > return self.wrap_app(environ, session_start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/Routes-1.10.3-
> > py2.5.egg/routes/middleware.py', line 130 in __call__
> > response = self.app(environ, start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > py2.5.egg/pylons/wsgiapp.py', line 125 in __call__
> > response = self.dispatch(controller, environ, start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > py2.5.egg/pylons/wsgiapp.py', line 324 in dispatch
> > return controller(environ, start_response)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > py2.5.egg/pylons/controllers/core.py', line 217 in __call__
> > response = self._inspect_call(self.__before__)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > py2.5.egg/pylons/controllers/core.py', line 107 in _inspect_call
> > result = self._perform_call(func, args)
> > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > py2.5.egg/tg/controllers.py', line 125 in _perform_call
> > controller.decoration.run_hooks('before_validate', remainder,
> > AttributeError: 'function' object has no attribute 'decoration'
> > Here is my app_cfg.py:
> > # -*- coding: utf-8 -*-
> > """
> > Global configuration file for TG2-specific settings in custom-routes.
> > This file complements development/deployment.ini.
> > """
> > from tg.configuration import AppConfig, Bunch
> > # Carl: needed for setup_custom_routes
> > from tg.configuration import Mapper, config
> > import custom_routes
> > from custom_routes import model
> > from custom_routes.lib import app_globals, helpers
> > # Carl: added custom routes function to override the default in
> > AppConfig
> > def custom_setup_routes(self):
> > """Setup the default TG2 routes
> > Override this and set up your own routes maps if you want to use
> > routes.
> > """
> > map = Mapper(directory=config['pylons.paths']['controllers'],
> > always_scan=config['debug'])
> > # Setup a default route for the root of object dispatch
> > map.connect('*url', controller='root',
> > action='routes_placeholder')
> > config['routes.map'] = map
> > # Carl: assign the custom routes function to AppConfig.
> > # It's equivalent to subclassing AppConfig in this case
> > AppConfig.setup_routes = custom_setup_routes
> > #Set the default renderer
> > base_config.default_renderer = 'genshi'
> > base_config.renderers.append('genshi')
> > # if you want raw speed and have installed chameleon.genshi
> > # you should try to use this renderer instead.
> > # warning: for the moment chameleon does not handle i18n translations
> > #base_config.renderers.append('chameleon_genshi')
> > #Configure the base SQLALchemy Setup
> > base_config.use_sqlalchemy = True
> > base_config.model = custom_routes.model
> > And here are my changes to the RootController:
> > from tg import expose, flash, require, url, request, redirect,
> > validate
> > from pylons.i18n import ugettext as _, lazy_ugettext as l_
> > from custom_routes.lib.base import BaseController
> > # Carl: DecoratedController will be the base class for the root
> > controller
> > from tg.controllers import DecoratedController
> > from custom_routes.model import DBSession, metadata
> > from custom_routes.controllers.error import ErrorController
> > __all__ = ['RootController']
> > class RootController(DecoratedController):
> > #class RootController(BaseController):
> > # The rest is the same
> > On Mar 16, 1:09 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > > A code sample, and traceback would help us help you better ;)
> > > On Mon, Mar 16, 2009 at 2:43 PM, Carl <tg2.u...@gmail.com> wrote:
> > > > Hello Gustavo,
> > > > What didn't work for me is that if my controller I just subclasses
> > > > the BaseController, then it looks like the routing in app_cfg.py is
> > > > ignored. TGController calls a _get_routing_info() function defined in
> > > > ObjectDispatchController that does just object dispatch.
> > > > Gigi
> > > > On Mar 16, 9:46 am, Gustavo Narea <m...@gustavonarea.net> wrote:
> > > >> Hello, Carl.
> > > >> On Saturday March 14, 2009 16:49:17 Carl wrote:
> > > >> > I tried it but it didn't work for me. Maybe I got the URL syntax
> > > >> > wrong. What URLs map to your custom routes?
> > > >> Those whose paths look like: /<string>/<integer>
> > > >> > Also, from reading the
> > > >> > Routes manual I got the impression that variables are words with a
> > > >> > colon in the end (e.g 'prefix:'), but your routes look like regular
> > > >> > expressions.
> > > >> Placeholders can be defined with {brackets} and :colons:, but the later is
> > > >> deprecated.
> > > >> In my case I just wanted to force an integer in one of the variables, hence I
> > > >> used a regular expression. It's optional.
Correction :-(. It doesn't really work. The Pylons request object
doesn't have a response_type attribute. This line in the controller
method raises AttributeError for 'response_type'
if pylons.request.response_type == 'application/json':
...
I'll leave it to the experts to figure it out. Please do.
Hjhj
Danke schein, Carl
On Mar 18, 11:12 am, Carl <tg2.u...@gmail.com> wrote:
> I found a workaround, but it's not pretty. The solution is to override
> the _perform_call() method of DecoratedController in your controller:
> def _perform_call(self, controller, params, remainder=None):
> # If not a decorated method just call it (needed for
> __before__ and __after__)
> if not hasattr(controller, 'decoration'):
> if remainder is None:
> remainder = []
> > On Mar 17, 2:00 am, Carl <tg2.u...@gmail.com> wrote:
> > > Ok. This is on a new quickstarted project with my changes for custom
> > > routes. Here is the traceback and the changes to app_cfg.py and
> > > root.py are bellow. If it's helpful I can upload the entire project.
> > > URL:http://localhost:8080/prefix/1/about > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/WebError-0.10.1-
> > > py2.5.egg/weberror/evalexception.py', line 431 in respond
> > > app_iter = self.application(environ, detect_start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > > py2.5.egg/tg/configuration.py', line 631 in wrapper
> > > return app(environ, start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > > py2.5.egg/tg/configuration.py', line 534 in remover
> > > return app(environ, start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/repoze.tm2-1.0a3-
> > > py2.5.egg/repoze/tm/__init__.py', line 19 in __call__
> > > result = self.application(environ, save_status_and_headers)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> > > 36 in __call__
> > > return self.wsgi_app(environ, start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> > > 59 in wsgi_app
> > > resp = req.get_response(self.application)
> > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> > > in get_response
> > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> > > in call_application
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/
> > > resource_injector.py', line 67 in _injector
> > > resp = req.get_response(app)
> > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> > > in get_response
> > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> > > in call_application
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> > > py2.5.egg/beaker/middleware.py', line 81 in __call__
> > > return self.app(environ, start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> > > py2.5.egg/beaker/middleware.py', line 160 in __call__
> > > return self.wrap_app(environ, session_start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Routes-1.10.3-
> > > py2.5.egg/routes/middleware.py', line 130 in __call__
> > > response = self.app(environ, start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > py2.5.egg/pylons/wsgiapp.py', line 125 in __call__
> > > response = self.dispatch(controller, environ, start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > py2.5.egg/pylons/wsgiapp.py', line 324 in dispatch
> > > return controller(environ, start_response)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > py2.5.egg/pylons/controllers/core.py', line 217 in __call__
> > > response = self._inspect_call(self.__before__)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > py2.5.egg/pylons/controllers/core.py', line 107 in _inspect_call
> > > result = self._perform_call(func, args)
> > > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > > py2.5.egg/tg/controllers.py', line 125 in _perform_call
> > > controller.decoration.run_hooks('before_validate', remainder,
> > > AttributeError: 'function' object has no attribute 'decoration'
> > > Here is my app_cfg.py:
> > > # -*- coding: utf-8 -*-
> > > """
> > > Global configuration file for TG2-specific settings in custom-routes.
> > > This file complements development/deployment.ini.
> > > """
> > > from tg.configuration import AppConfig, Bunch
> > > # Carl: needed for setup_custom_routes
> > > from tg.configuration import Mapper, config
> > > import custom_routes
> > > from custom_routes import model
> > > from custom_routes.lib import app_globals, helpers
> > > # Carl: added custom routes function to override the default in
> > > AppConfig
> > > def custom_setup_routes(self):
> > > """Setup the default TG2 routes
> > > Override this and set up your own routes maps if you want to use
> > > routes.
> > > """
> > > map = Mapper(directory=config['pylons.paths']['controllers'],
> > > always_scan=config['debug'])
> > > # Setup a default route for the root of object dispatch
> > > map.connect('*url', controller='root',
> > > action='routes_placeholder')
> > > config['routes.map'] = map
> > > # Carl: assign the custom routes function to AppConfig.
> > > # It's equivalent to subclassing AppConfig in this case
> > > AppConfig.setup_routes = custom_setup_routes
> > > #Set the default renderer
> > > base_config.default_renderer = 'genshi'
> > > base_config.renderers.append('genshi')
> > > # if you want raw speed and have installed chameleon.genshi
> > > # you should try to use this renderer instead.
> > > # warning: for the moment chameleon does not handle i18n translations
> > > #base_config.renderers.append('chameleon_genshi')
> > > #Configure the base SQLALchemy Setup
> > > base_config.use_sqlalchemy = True
> > > base_config.model = custom_routes.model
> > > And here are my changes to the RootController:
> > > from tg import expose, flash, require, url, request, redirect,
> > > validate
> > > from pylons.i18n import ugettext as _, lazy_ugettext as l_
> > > from custom_routes.lib.base import BaseController
> > > # Carl: DecoratedController will be the base class for the root
> > > controller
> > > from tg.controllers import DecoratedController
> > > from custom_routes.model import DBSession, metadata
> > > from custom_routes.controllers.error import ErrorController
> > > __all__ = ['RootController']
> > > class RootController(DecoratedController):
> > > #class RootController(BaseController):
> > > # The rest is the same
> > > On Mar 16, 1:09 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > > > A code sample, and traceback would help us help you better ;)
> > > > On Mon, Mar 16, 2009 at 2:43 PM, Carl <tg2.u...@gmail.com> wrote:
> > > > > Hello Gustavo,
> > > > > What didn't work for me is that if my controller I just subclasses
> > > > > the BaseController, then it looks like the routing in app_cfg.py is
> > > > > ignored. TGController calls a _get_routing_info() function defined in
> > > > > ObjectDispatchController that does just object dispatch.
> > > > >> > Also, from reading the
> > > > >> > Routes manual I got the impression that variables are words with a
> > > > >> > colon in the end (e.g 'prefix:'), but your routes look like regular
> > > > >> > expressions.
> > > > >> Placeholders can be defined with {brackets} and :colons:, but the later is
> > > > >> deprecated.
> > > > >> In my case I just wanted to force an integer in one of the variables, hence I
> > > > >> used a regular expression. It's optional.
Oops, I thought this was fixed because of Gustavo's message, but it
seems that it wasn't -- so I'm committing a fix to the 2.0 branch
tonight.
Basically the fix is to do this:
#Special case __before__ and __after__ so don't need to be
@exposed
if controller.__name__ in ['__before__', '__after__']:
return controller(*remainder, **dict(params))
inside of _perform_call so that __before__ and __after__ don't need
decoration attributes since they really are special methods that you
want called on every request.
I'd very much apriciate it if someone could verify that routes work
from the hg.turbogears.org repo. The whole routing sytem is different
here, but I think we'll need to apply the same fix there. I think
this is a missing test that we ought to add, since using routes is
something we want to encourage.
--Mark Ramm
On Mar 18, 7:29 pm, Carl <tg2.u...@gmail.com> wrote:
> Correction :-(. It doesn't really work. The Pylons request object
> doesn't have a response_type attribute. This line in the controller
> method raises AttributeError for 'response_type'
> if pylons.request.response_type == 'application/json':
> ...
> I'll leave it to the experts to figure it out. Please do.
> Hjhj
> Danke schein, Carl
> On Mar 18, 11:12 am, Carl <tg2.u...@gmail.com> wrote:
> > I found a workaround, but it's not pretty. The solution is to override
> > the _perform_call() method of DecoratedController in your controller:
> > def _perform_call(self, controller, params, remainder=None):
> > # If not a decorated method just call it (needed for
> > __before__ and __after__)
> > if not hasattr(controller, 'decoration'):
> > if remainder is None:
> > remainder = []
> > > On Mar 17, 2:00 am, Carl <tg2.u...@gmail.com> wrote:
> > > > Ok. This is on a new quickstarted project with my changes for custom
> > > > routes. Here is the traceback and the changes to app_cfg.py and
> > > > root.py are bellow. If it's helpful I can upload the entire project.
> > > > URL:http://localhost:8080/prefix/1/about > > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/WebError-0.10.1-
> > > > py2.5.egg/weberror/evalexception.py', line 431 in respond
> > > > app_iter = self.application(environ, detect_start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > > > py2.5.egg/tg/configuration.py', line 631 in wrapper
> > > > return app(environ, start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > > > py2.5.egg/tg/configuration.py', line 534 in remover
> > > > return app(environ, start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/repoze.tm2-1.0a3-
> > > > py2.5.egg/repoze/tm/__init__.py', line 19 in __call__
> > > > result = self.application(environ, save_status_and_headers)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > > > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> > > > 36 in __call__
> > > > return self.wsgi_app(environ, start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > > > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/middleware.py', line
> > > > 59 in wsgi_app
> > > > resp = req.get_response(self.application)
> > > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> > > > in get_response
> > > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> > > > in call_application
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/
> > > > ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/
> > > > resource_injector.py', line 67 in _injector
> > > > resp = req.get_response(app)
> > > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1325
> > > > in get_response
> > > > File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py', line 1293
> > > > in call_application
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> > > > py2.5.egg/beaker/middleware.py', line 81 in __call__
> > > > return self.app(environ, start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Beaker-1.2.2-
> > > > py2.5.egg/beaker/middleware.py', line 160 in __call__
> > > > return self.wrap_app(environ, session_start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Routes-1.10.3-
> > > > py2.5.egg/routes/middleware.py', line 130 in __call__
> > > > response = self.app(environ, start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > > py2.5.egg/pylons/wsgiapp.py', line 125 in __call__
> > > > response = self.dispatch(controller, environ, start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > > py2.5.egg/pylons/wsgiapp.py', line 324 in dispatch
> > > > return controller(environ, start_response)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > > py2.5.egg/pylons/controllers/core.py', line 217 in __call__
> > > > response = self._inspect_call(self.__before__)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/Pylons-0.9.7-
> > > > py2.5.egg/pylons/controllers/core.py', line 107 in _inspect_call
> > > > result = self._perform_call(func, args)
> > > > File '/Users/carl/tg2env/lib/python2.5/site-packages/TurboGears2-2.0b7-
> > > > py2.5.egg/tg/controllers.py', line 125 in _perform_call
> > > > controller.decoration.run_hooks('before_validate', remainder,
> > > > AttributeError: 'function' object has no attribute 'decoration'
> > > > Here is my app_cfg.py:
> > > > # -*- coding: utf-8 -*-
> > > > """
> > > > Global configuration file for TG2-specific settings in custom-routes.
> > > > This file complements development/deployment.ini.
> > > > """
> > > > from tg.configuration import AppConfig, Bunch
> > > > # Carl: needed for setup_custom_routes
> > > > from tg.configuration import Mapper, config
> > > > import custom_routes
> > > > from custom_routes import model
> > > > from custom_routes.lib import app_globals, helpers
> > > > # Carl: added custom routes function to override the default in
> > > > AppConfig
> > > > def custom_setup_routes(self):
> > > > """Setup the default TG2 routes
> > > > Override this and set up your own routes maps if you want to use
> > > > routes.
> > > > """
> > > > map = Mapper(directory=config['pylons.paths']['controllers'],
> > > > always_scan=config['debug'])
> > > > # Setup a default route for the root of object dispatch
> > > > map.connect('*url', controller='root',
> > > > action='routes_placeholder')
> > > > config['routes.map'] = map
> > > > # Carl: assign the custom routes function to AppConfig.
> > > > # It's equivalent to subclassing AppConfig in this case
> > > > AppConfig.setup_routes = custom_setup_routes
> > > > #Set the default renderer
> > > > base_config.default_renderer = 'genshi'
> > > > base_config.renderers.append('genshi')
> > > > # if you want raw speed and have installed chameleon.genshi
> > > > # you should try to use this renderer instead.
> > > > # warning: for the moment chameleon does not handle i18n translations
> > > > #base_config.renderers.append('chameleon_genshi')
> > > > from tg import expose, flash, require, url, request, redirect,
> > > > validate
> > > > from pylons.i18n import ugettext as _, lazy_ugettext as l_
> > > > from custom_routes.lib.base import BaseController
> > > > # Carl: DecoratedController will be the base class for the root
> > > > controller
> > > > from tg.controllers import DecoratedController
> > > > from custom_routes.model import DBSession, metadata
> > > > from custom_routes.controllers.error import ErrorController
> > > > __all__ = ['RootController']
> > > > class RootController(DecoratedController):
> > > > #class RootController(BaseController):
> > > > # The rest is the same
> > > > On Mar 16, 1:09 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> > > > > A code sample, and traceback would help us help you better ;)
> > > > > On Mon, Mar 16, 2009 at 2:43 PM, Carl <tg2.u...@gmail.com> wrote:
> > > > > > Hello Gustavo,
> > > > > > What didn't work for me is that if my controller I just subclasses
> > > > > > the BaseController, then it looks like the routing in app_cfg.py is
> > > > > > ignored. TGController calls a _get_routing_info() function defined in
> > > > > > ObjectDispatchController that does just object dispatch.
I haven't had a chance to check out the latest patch, but since the
thread of conversation has picked up again, I figured I'd share
something I wrote a couple days ago: http://simplestation.com/locomotion/routes-in-tg2/
I'm going to guess my solution is very similar to the solution in the
patch, but doesn't require updating TG itself.
On May 13, 6:43 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
> Oops, I thought this was fixed because of Gustavo's message, but it
> seems that it wasn't -- so I'm committing a fix to the 2.0 branch
> tonight.
> Basically the fix is to do this:
> #Special case __before__ and __after__ so don't need to be
> @exposed
> if controller.__name__ in ['__before__', '__after__']:
> return controller(*remainder, **dict(params))
> inside of _perform_call so that __before__ and __after__ don't need
> decoration attributes since they really are special methods that you
> want called on every request.
> I'd very much apriciate it if someone could verify that routes work
> from the hg.turbogears.org repo. The whole routing sytem is different
> here, but I think we'll need to apply the same fix there. I think
> this is a missing test that we ought to add, since using routes is
> something we want to encourage.
> --Mark Ramm
> On Mar 18, 7:29 pm, Carl <tg2.u...@gmail.com> wrote:
> > Correction :-(. It doesn't really work. The Pylons request object
> > doesn't have a response_type attribute. This line in the controller
> > method raises AttributeError for 'response_type'
> > if pylons.request.response_type == 'application/json':
> > ...
> > I'll leave it to the experts to figure it out. Please do.
> > Hjhj
> > Danke schein, Carl
> > On Mar 18, 11:12 am, Carl <tg2.u...@gmail.com> wrote:
> > > I found a workaround, but it's not pretty. The solution is to override
> > > the _perform_call() method of DecoratedController in your controller:
> > > def _perform_call(self, controller, params, remainder=None):
> > > # If not a decorated method just call it (needed for
> > > __before__ and __after__)
> > > if not hasattr(controller, 'decoration'):
> > > if remainder is None:
> > > remainder = []
> > > > On Mar 17, 2:00 am, Carl <tg2.u...@gmail.com> wrote:
> > > > > Ok. This is on a new quickstarted project with my changes for custom
> > > > > routes. Here is the traceback and the changes to app_cfg.py and
> > > > > root.py are bellow. If it's helpful I can upload the entire project.
> > > > > # -*- coding: utf-8 -*-
> > > > > """
> > > > > Global configuration file for TG2-specific settings in custom-routes.
> > > > > This file complements development/deployment.ini.
> > > > > """
> > > > > from tg.configuration import AppConfig, Bunch
> > > > > # Carl: needed for setup_custom_routes
> > > > > from tg.configuration import Mapper, config
> > > > > import custom_routes
> > > > > from custom_routes import model
> > > > > from custom_routes.lib import app_globals, helpers
> > > > > # Carl: added custom routes function to override the default in
> > > > > AppConfig
> > > > > def custom_setup_routes(self):
> > > > > """Setup the default TG2 routes
> > > > > Override this and set up your own routes maps if you want to use
> > > > > routes.
> > > > > """
> > > > > map = Mapper(directory=config['pylons.paths']['controllers'],
> > > > > always_scan=config['debug'])
> > > > > #Set the default renderer
> > > > > base_config.default_renderer = 'genshi'
> > > > > base_config.renderers.append('genshi')
> > > > > # if you want raw speed and have installed chameleon.genshi
> > > > > # you should try to use this renderer instead.
> > > > > # warning: for the moment chameleon does not handle i18n translations
> > > > > #base_config.renderers.append('chameleon_genshi')
> > > > > from tg import expose, flash, require, url, request, redirect,
> > > > > validate
> > > > > from pylons.i18n import ugettext as _, lazy_ugettext as l_
> > > > > from custom_routes.lib.base import BaseController
> > > > > # Carl: DecoratedController will be the base class for the root
> > > > > controller
> > > > > from tg.controllers import DecoratedController
> > > > > from custom_routes.model import DBSession, metadata
> > > > > from custom_routes.controllers.error import ErrorController
> > > > > __all__ = ['RootController']
> > > > > class RootController(DecoratedController):
> > > > > #class RootController(BaseController):
> > > > > # The rest is the same
> > > > > On Mar 16, 1:09 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
The "'function' object has no attribute 'decoration'" error is not
fixed in the latest 2.0 from SVN.
It is avoided entirely in 2.1, because you can't directly subclass
DecoratedController, since it's not a WSGIController anymore.
What isn't addressed, however, is that the _perform_call(self, func,
args) method in TGController (inherited from ObjectDispatchController
in 2.0 and from Dispatcher in 2.1) still ignores the 'action'
parameter of routing paths. It still dispatches the request according
to object dispatch, even if a route has specified the action to
render. (This happens in 2.0 and 2.1). This is the behaviour that the
parents in this thread were trying to avoid by subclassing
DecoratedController.
I continue to work around this problem by using my RoutingController
(subclassing DecoratedController in 2.0 and TGController in 2.1)
[code: http://simplestation.com/locomotion/routes-in-tg2]. Which,
essentially, implements TGController's _perform_call() method, but
removes all Object Dispatch logic.
I think a superior solution would be to have TGController's
_perform_call() method detect if a route was active, and if that
route specified an action side-step object dispatch routing. Perhaps
by checking the values in args['environ']['pylons.routes_dict'].
Perhaps this change could go into 2.1, and something like the
RoutingController could go into 2.0, to prevent breaking anybody's
apps that already rely on the current functionality.
Thoughts? Is anybody else out there using Routes in tg2?
> I haven't had a chance to check out the latest patch, but since the
> thread of conversation has picked up again, I figured I'd share
> something I wrote a couple days ago: http://simplestation.com/ > locomotion/routes-in-tg2/
> I'm going to guess my solution is very similar to the solution in the
> patch, but doesn't require updating TG itself.
> On May 13, 6:43 pm, Mark Ramm <mark.mchristen...@gmail.com> wrote:
>> Oops, I thought this was fixed because of Gustavo's message, but it
>> seems that it wasn't -- so I'm committing a fix to the 2.0 branch
>> tonight.
>> Basically the fix is to do this:
>> #Special case __before__ and __after__ so don't need to be
>> @exposed
>> if controller.__name__ in ['__before__', '__after__']:
>> return controller(*remainder, **dict(params))
>> inside of _perform_call so that __before__ and __after__ don't need
>> decoration attributes since they really are special methods that you
>> want called on every request.
>> I'd very much apriciate it if someone could verify that routes work
>> from the hg.turbogears.org repo. The whole routing sytem is
>> different
>> here, but I think we'll need to apply the same fix there. I think
>> this is a missing test that we ought to add, since using routes is
>> something we want to encourage.
>> --Mark Ramm
>> On Mar 18, 7:29 pm, Carl <tg2.u...@gmail.com> wrote:
>>> Correction :-(. It doesn't really work. The Pylons request object
>>> doesn't have a response_type attribute. This line in the controller
>>> method raises AttributeError for 'response_type'
>>> if pylons.request.response_type == 'application/json':
>>> ...
>>> I'll leave it to the experts to figure it out. Please do.
>>> Hjhj
>>> Danke schein, Carl
>>> On Mar 18, 11:12 am, Carl <tg2.u...@gmail.com> wrote:
>>>> I found a workaround, but it's not pretty. The solution is to
>>>> override
>>>> the _perform_call() method of DecoratedController in your
>>>> controller:
>>>> def _perform_call(self, controller, params, remainder=None):
>>>> # If not a decorated method just call it (needed for
>>>> __before__ and __after__)
>>>> if not hasattr(controller, 'decoration'):
>>>> if remainder is None:
>>>> remainder = []
>>>> On Mar 17, 1:59 am, Raphael Slinckx <rslin...@gmail.com> wrote:
>>>>> See also this post from me from a while ago:http:// >>>>> groups.google.com/group/turbogears/browse_thread/thread/ab9c8a...
>>>>> No solution though..
>>>>> On Mar 17, 2:00 am, Carl <tg2.u...@gmail.com> wrote:
>>>>>> Ok. This is on a new quickstarted project with my changes for
>>>>>> custom
>>>>>> routes. Here is the traceback and the changes to app_cfg.py and
>>>>>> root.py are bellow. If it's helpful I can upload the entire
>>>>>> project.
>>>>>> URL:http://localhost:8080/prefix/1/about >>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> WebError-0.10.1-
>>>>>> py2.5.egg/weberror/evalexception.py', line 431 in respond
>>>>>> app_iter = self.application(environ, detect_start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> TurboGears2-2.0b7-
>>>>>> py2.5.egg/tg/configuration.py', line 631 in wrapper
>>>>>> return app(environ, start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> TurboGears2-2.0b7-
>>>>>> py2.5.egg/tg/configuration.py', line 534 in remover
>>>>>> return app(environ, start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> repoze.tm2-1.0a3-
>>>>>> py2.5.egg/repoze/tm/__init__.py', line 19 in __call__
>>>>>> result = self.application(environ, save_status_and_headers)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/
>>>>>> ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/ >>>>>> middleware.py', line
>>>>>> 36 in __call__
>>>>>> return self.wsgi_app(environ, start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/
>>>>>> ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/ >>>>>> middleware.py', line
>>>>>> 59 in wsgi_app
>>>>>> resp = req.get_response(self.application)
>>>>>> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py',
>>>>>> line 1325
>>>>>> in get_response
>>>>>> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py',
>>>>>> line 1293
>>>>>> in call_application
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/
>>>>>> ToscaWidgets-0.9.5dev_20081026-py2.5.egg/tw/core/
>>>>>> resource_injector.py', line 67 in _injector
>>>>>> resp = req.get_response(app)
>>>>>> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py',
>>>>>> line 1325
>>>>>> in get_response
>>>>>> File 'build/bdist.macosx-10.3-i386/egg/webob/__init__.py',
>>>>>> line 1293
>>>>>> in call_application
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> Beaker-1.2.2-
>>>>>> py2.5.egg/beaker/middleware.py', line 81 in __call__
>>>>>> return self.app(environ, start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> Beaker-1.2.2-
>>>>>> py2.5.egg/beaker/middleware.py', line 160 in __call__
>>>>>> return self.wrap_app(environ, session_start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> Routes-1.10.3-
>>>>>> py2.5.egg/routes/middleware.py', line 130 in __call__
>>>>>> response = self.app(environ, start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> Pylons-0.9.7-
>>>>>> py2.5.egg/pylons/wsgiapp.py', line 125 in __call__
>>>>>> response = self.dispatch(controller, environ, start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> Pylons-0.9.7-
>>>>>> py2.5.egg/pylons/wsgiapp.py', line 324 in dispatch
>>>>>> return controller(environ, start_response)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> Pylons-0.9.7-
>>>>>> py2.5.egg/pylons/controllers/core.py', line 217 in __call__
>>>>>> response = self._inspect_call(self.__before__)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> Pylons-0.9.7-
>>>>>> py2.5.egg/pylons/controllers/core.py', line 107 in _inspect_call
>>>>>> result = self._perform_call(func, args)
>>>>>> File '/Users/carl/tg2env/lib/python2.5/site-packages/ >>>>>> TurboGears2-2.0b7-
>>>>>> py2.5.egg/tg/controllers.py', line 125 in _perform_call
>>>>>> controller.decoration.run_hooks('before_validate', remainder,
>>>>>> AttributeError: 'function' object has no attribute 'decoration'
>>>>>> Here is my app_cfg.py:
>>>>>> # -*- coding: utf-8 -*-
>>>>>> """
>>>>>> Global configuration file for TG2-specific settings in custom- >>>>>> routes.
>>>>>> This file complements development/deployment.ini.
>>>>>> """
>>>>>> from tg.configuration import AppConfig, Bunch
>>>>>> # Carl: needed for setup_custom_routes
>>>>>> from tg.configuration import Mapper, config
>>>>>> import custom_routes
>>>>>> from custom_routes import model
>>>>>> from custom_routes.lib import app_globals, helpers
>>>>>> # Carl: added custom routes function to override the default in
>>>>>> AppConfig
>>>>>> def custom_setup_routes(self):
>>>>>> """Setup the default TG2 routes
>>>>>> Override this and set up your own routes maps if you want
>>>>>> to use
>>>>>> routes.
>>>>>> """
>>>>>> map = Mapper(directory=config['pylons.paths']['controllers'],
>>>>>> always_scan=config['debug'])
Turbogears 2.0.3 doesn't support Routes yet. Turbogears 2.0.4 will (a release looks promising soon).
For now, we've got support for Routes in the mercurial repository and you can install from there if you want support built in: http://bitbucket.org/turbogears/tg-2_0/
Controllers you want to use Routes with should then extend RoutingController.
But beware that if you stick with 2.0.3 there are some additional bugs with pagination and positional url arguments that you might encounter (these are fixed in the mercurial repository, and will be fixed in 2.0.4).
-- Anthony
PS: I hope you don't mind that I've forwarded this message to the turbogears mailing list--but I bet you're not the only person with that question, and maybe we can help somebody else too.
> so, in order to be able to use custom routes, should the controller > class extend DecoratedController? if so, i'm getting this error too. > if not why i'm getting a 404? i have turbogears 2.0.3.