1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | # Mostly the same as the prior callable routing, except in middleware.py from routes import request_config import types def eat_blank_iters(app_iter, response, environ, start_response): content_written = False del response.headers['Content-Length'] while True: try: content = app_iter.next() except: if hasattr(app_iter, 'close'): app_iter.close() content_written = True break if content and not content_written: start_response(response.status, response.headerlist) yield content elif content: yield content if not content_written: start_response(response.status, response.headerlist) yield '' raise StopIteration class MyApp(PylonsApp): def resolve(self, environ, start_response): # Update the Routes config object in case we're using Routes config = request_config() config.redirect = self.redirect_to match = environ['wsgiorg.routing_args'][1] environ['pylons.routes_dict'] = match controller = match.get('func') if not controller: # Use existing lookup scheme if no classname is around controller = match.get('controller') if not controller: return else: return self.find_controller(controller) if self.log_debug: log.debug("Resolved URL to controller: %r", controller) return controller def dispatch(self, controller, environ, start_response): match = environ['wsgiorg.routing_args'][1] # Assume we're doing a single function if we have a func if 'func' in match: ctx = environ['pylons.pylons'] response = controller(ctx) if isinstance(response, types.GeneratorType): return eat_blank_iters(response, ctx.response, environ, start_response) else: del ctx.response.headers['Content-Length'] ctx.response.headers['Content-Length'] = len(response) start_response('200 OK', ctx.response.headers.items()) return [response] else: return PylonsApp.dispatch(self, controller, environ, start_response) # and routing.py now hooks up like so: map.connect('hello/:action', func=hello.hello, action='index') # and the function 'hello' in the controllers/hello.py module: def hello(ctx): yield '' yield 'hello world,' yield ' the environ is %s' % ctx.request.environ |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | # This patch, lets you setup routes like so in addition to normal style # NOTE: This requires the latest development tip of Routes and Pylons map.connect('hello/:action', callable=hello.Hello, action='index') # For example, in routing.py: import helloworld.controllers.hello as hello def make_map(): """Create, configure and return the routes Mapper""" map = Mapper(directory=config['pylons.paths']['controllers'], always_scan=config['debug']) map.connect('error/:action/:id', controller='error') # CUSTOM ROUTES HERE map.connect('hello/:action', callable=hello.Hello, action='index') map.connect('bye/:action', callable=hello.Bye, action='index') # Then inside controllers/hello.py import logging from pylons import request, response, session from pylons import tmpl_context as c from pylons.controllers.util import abort, redirect_to, url_for from helloworld.lib.base import BaseController, render #import helloworld.model as model log = logging.getLogger(__name__) class Hello(BaseController): def index(self): return 'Hello World' class Bye(BaseController): def index(self): return 'Bye World' # And inside of config/middleware.py: # Add to imports from routes import request_config # Add class before make_app: class MyApp(PylonsApp): def resolve(self, environ, start_response): # Update the Routes config object in case we're using Routes config = request_config() config.redirect = self.redirect_to match = environ['wsgiorg.routing_args'][1] environ['pylons.routes_dict'] = match controller = match.get('callable') if not controller: # Use existing lookup scheme if no classname is around controller = match.get('controller') if not controller: return else: return self.find_controller(controller) if self.log_debug: log.debug("Resolved URL to controller: %r", controller) return controller # And inside make_app, replace PylonsApp() with: # My Pylons WSGI app app = MyApp() |
1 2 3 4 5 6 7 8 9 10 11 | from pylons import request def to_https(match_dict): # specify that the protocol needs to be https, if it is not already if request.scheme == 'http': match_dict['_protocol'] = 'https' return match_dict ... map.connect('login', '/login', controller='login', action='index', _filter=to_https) |
1 2 3 4 5 6 7 8 | >>> from routes import * >>> m = Mapper() >>> m.connect('gallery_thumb', 'images/gallery/:(image_id)_thumbnail.jpg') >>> m.connect('gallery', 'images/gallery/:(image_id)') >>> url_for('gallery_thumb', image_id=1) '/images/gallery/1_thumbnail.jpg' >>> url_for('gallery', image_id=1) '/images/gallery/1_thumbnail.jpg' |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | """ Setup your Routes options here """ import os from routes import Mapper def make_map(global_conf={}, app_conf={}): root_path = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) map = Mapper(directory=os.path.join(root_path, 'controllers')) # This route handles displaying the error page and graphics used in the 404/500 # error pages. It should likely stay at the top to ensure that the error page is # displayed properly. map.connect('error/:action/:id', controller='error') # Define your routes. The more specific and detailed routes should be defined first, # so they may take precedent over the more generic routes. For more information, refer # to the routes manual @ http://routes.groovie.org/docs/ map.connect('', controller='view_materials', action='view_section', section='main') map.connect('files', 'files/:file', controller='get_file_contents') map.connect('categories', 'categories/:category', controller='view_materials', action='view_category') map.connect('materials', 'materials/:category/:seo_title/:id', controller='view_materials', action='view_material') map.connect('attachments', 'attachments/:type/:seo_title/:id', controller='view_materials', action='view_attachment') map.connect('tags', 'tags/:tag', controller='view_materials', action='view_materials_by_tag') map.connect('users', 'users/:login', controller='view_profile') map.connect(':controller/:action/:id') map.connect('*url', controller='template', action='view') return map |
1 2 3 4 5 6 7 8 9 10 11 12 13 | url: /clients 1094719808 routes.middleware DEBUG Matched GET /clients 1094719808 routes.middleware DEBUG Route path: 'clients', defaults: {'action': u'index', 'controller': u'clients'} 1094719808 routes.middleware DEBUG Match dict: {'action': u'index', 'controller': u'clients'} Now I click the following link on the page: <a href="#" onclick="new Ajax.Updater('tab_content', '/clients?tab=sites', {asynchronous:true, evalScripts:true}); return false;">Sites</a> 1126189376 routes.middleware DEBUG Matched POST /clients 1126189376 routes.middleware DEBUG Route path: 'clients', defaults: {'action': u'create', 'controller': u'clients'} 1126189376 routes.middleware DEBUG Match dict: {'action': u'create', 'controller': u'clients'} |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | fixes an AttributeError raised in line base.py:991 (self.prior not existing) Index: routes/base.py =================================================================== --- routes/base.py (revision 324) +++ routes/base.py (working copy) @@ -50,6 +50,7 @@ self.routepath = routepath self.sub_domains = False + self.prior = None # Don't bother forming stuff we don't need if its a static route self.static = kargs.get('_static', False) @@ -234,7 +235,7 @@ partreg = '(?P<' + var + '>' + self.reqs[var] + ')' elif var == 'controller': partreg = '(?P<' + var + '>' + '|'.join(map(re.escape, clist)) + ')' - elif getattr(self, 'prior', None) == '/': + elif self.prior == '/': partreg = '(?P<' + var + '>[^/]+?)' else: partreg = '(?P<' + var + '>[^%s]+?)' % ''.join(self.done_chars) |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Index: base.py =================================================================== --- base.py (revision 323) +++ base.py (working copy) @@ -50,6 +50,7 @@ self.routepath = routepath self.sub_domains = False + self.prior = None # Don't bother forming stuff we don't need if its a static route self.static = kargs.get('_static', False) @@ -234,7 +235,7 @@ partreg = '(?P<' + var + '>' + self.reqs[var] + ')' elif var == 'controller': partreg = '(?P<' + var + '>' + '|'.join(map(re.escape, clist)) + ')' - elif getattr(self, 'prior', None) == '/': + elif self.prior == '/': partreg = '(?P<' + var + '>[^/]+?)' else: partreg = '(?P<' + var + '>[^%s]+?)' % ''.join(self.done_chars) |
1 2 3 | -1610551928 routes.middleware DEBUG Initialized with method overriding = True, and path info altering = True
28217344 routes.middleware DEBUG Matched GET /
28217344 routes.middleware DEBUG Route path: '', defaults: {'action': u'view', 'url': u'index.html', 'controller': u'template'}
|