Commits

Anonymous committed b1d676f

[routes,plugins] Added plugin listening for IRoutesExtensions to be loaded and reloads the routing map

Comments (0)

Files changed (3)

ckan/config/environment.py

 
 import ckan.lib.app_globals as app_globals
 import ckan.lib.helpers
-from ckan.config.routing import make_map
+from ckan.config.routing import ReloadableMapperWrapper, make_map
 from ckan import model
 from ckan import plugins
 
     # load all CKAN plugins
     plugins.load_all(config)
     
-    config['routes.map'] = make_map()
+    config['routes.map'] = ReloadableMapperWrapper(make_map)
     config['pylons.app_globals'] = app_globals.Globals()
     config['pylons.h'] = ckan.lib.helpers
         

ckan/config/routing.py

 from pylons import config
 from routes import Mapper
 from formalchemy.ext.pylons import maps # routes generator
-from ckan.plugins import ExtensionPoint, IRoutesExtension
+from ckan.plugins import ExtensionPoint, SingletonPlugin, implements
+from ckan.plugins.interfaces import IRoutesExtension, IPluginObserver
 
 routing_plugins = ExtensionPoint(IRoutesExtension)
+routing_middleware = None
+
+class ReloadableMapperWrapper(object):
+    """
+    A wrapper around a mapper that lets the mapper be reloaded.
+    """
+
+    def __init__(self, make_mapper):
+        """
+        :param make_mapper: a callable returning a routes.Mapper object
+        """
+        self.make_mapper = make_mapper
+        self.mapper = make_mapper()
+
+    def __getattr__(self, attr):
+        return getattr(self.mapper, attr)
+
+    def reload(self):
+        """
+        Reload the wrapped mapper object from the make_mapper function
+        """
+        self.mapper = self.make_mapper()
+
+class ReloadRoutesMapsPlugin(SingletonPlugin):
+    """
+    Hook into the plugin system to reload the routes mappings wheneve a
+    IRoutesExtension plugin is loaded.
+    """
+
+    implements(IPluginObserver, inherit=True)
+
+    def after_load(self, service):
+        if IRoutesExtension.provided_by(service):
+            config['routes.map'].reload()
+
 
 def make_map():
     """Create, configure and return the routes Mapper"""
 
     [ckan.system_plugins]
     domain_object_notifications = ckan.model.notifier:DomainObjectNotificationExtension
+    routes_reloader = ckan.config.routing:ReloadRoutesMapsPlugin
     """,
     # setup.py test command needs a TestSuite so does not work with py.test
     # test_suite = 'nose.collector',