Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'feature/mw-registration' into develop

  • Loading branch information...
commit df0d7a80e1c7ac875c186c713fce6bddff26720f 2 parents 6ec1a2d + 374c566
@ralphbean ralphbean authored
View
7 docs/design.rst
@@ -287,10 +287,11 @@ Sometimes widgets will want to define controller methods. This is particularly u
For the :meth:`request` method to be called, the widget must be registered with the :class:`ControllersApp` in the middleware. By default, the path is constructed from /controllers/, and the widget's id. A request to /controllers/ refers to a widget with id ``index``. You can specify :attr:`controllers_prefix` in the configuration.
-For convenience, widgets that have a :meth:`request` method, and an :attr:`id` will be registered automatically. By default, this uses a global :class:`ControllersApp` instance, which is also the default controllers_app for :func:`make_middleware`. If you want to use multiple controller applications in a single python instance, you will need to override this. Set :attr:`tw2_controllers` as a global variable, and this will affect all widgets defined in that module. Set this to None to disable automatic registration. You can also manually register widgets::
+For convenience, widgets that have a :meth:`request` method, and an :attr:`id` will be registered automatically. By default, this uses a global :class:`ControllersApp` instance, which is also the default controllers for :func:`make_middleware`. If you want to use multiple controller applications in a single python instance, you will need to override this.
- mw = twc.core.request_local()['middleware']
- mw.controllers.register(MyWidget, 'mywidget')
+You can also manually register widgets::
+
+ twc.core.register_controller(MyWidget, 'mywidget')
**Methods to override**
View
6 docs/pyramid.rst
@@ -238,8 +238,7 @@ Now done with ``myapp/models.py``, edit ``myapp/views.py`` and replace the defin
import tw2.core
def view_widget(context, request):
context.fetch_data(request)
- mw = tw2.core.core.request_local()['middleware']
- mw.controllers.register(context, 'movie_submit')
+ tw2.core.register_controller(context, 'movie_submit')
return {'widget': context}
Lastly, edit ``myapp/widgets.py`` and add::
@@ -368,8 +367,7 @@ Add the following to your view configuration in ``myapp/__init__.py``::
Add that view to ``myapp/views.py`` itself::
def view_grid_widget(context, request):
- mw = tw2.core.core.request_local()['middleware']
- mw.controllers.register(context, 'db_jqgrid')
+ tw2.core.register_controller(context, 'db_jqgrid')
return {'widget': context}
Finally add another hook into ``MyApp.__getitem__(...)``::
View
8 docs/standalone.rst
@@ -320,13 +320,7 @@ And add another two whole classes near the bottom of the file but above
'height': 'auto',
}
- def prepare(self):
- # This controller registration does not generally have to occur inside
- # 'prepare', but we place it here so we're sure the middleware has
- # been initialized by tw2.devtools.dev_server before we make demands of it.
- mw = tw2.core.core.request_local()['middleware']
- mw.controllers.register(self.__class__, 'db_jqgrid')
- super(GridWidget, self).prepare()
+ tw2.core.register_controller(GridWidget, 'db_jqgrid')
class Grid(tw2.core.Page):
title = 'jQuery jqGrid'
View
6 docs/turbogears.rst
@@ -256,8 +256,7 @@ And the last for the `MovieForm`, change ``genres = tw2.forms.CheckBoxList( ...
And (still in ``myapp/controllers/movie.py``) inside the MovieController's movie method, just below the line ``w = MovieForm(...`` add the three lines::
w.fetch_data(request)
- mw = tw2.core.core.request_local()['middleware']
- mw.controllers.register(w, 'movie_submit')
+ tw2.core.register_controller(w, 'movie_submit')
Now, in your command prompt run::
@@ -351,8 +350,7 @@ And add the following method to the ``MovieController`` class::
@expose('myapp.templates.widget')
def grid(self, *args, **kw):
- mw = tw2.core.core.request_local()['middleware']
- mw.controllers.register(GridWidget, 'db_jqgrid')
+ tw2.core.register_controller(GridWidget, 'db_jqgrid')
return dict(widget=GridWidget, page='movie')
Redirect your browser to http://localhost:8080/movie/grid and you should
View
1  setup.py
@@ -41,6 +41,7 @@ def get_description(fname='README.rst'):
'PasteDeploy',
'weberror',
'speaklater',
+ 'decorator',
],
tests_require = [
'nose',
View
6 tw2/core/__init__.py
@@ -25,7 +25,11 @@
Any, All,
)
-from middleware import (make_middleware, dev_server)
+from middleware import (
+ make_middleware,
+ dev_server,
+ register_controller,
+)
from js import js_symbol, js_callback, js_function
View
38 tw2/core/middleware.py
@@ -2,6 +2,9 @@
from pkg_resources import iter_entry_points, DistributionNotFound
from paste.deploy.converters import asbool, asint
+import logging
+log = logging.getLogger(__name__)
+
class Config(object):
'''
ToscaWidgets Configuration Set
@@ -147,7 +150,14 @@ def __init__(self, app, controllers=None, **config):
self.config = Config(**config)
self.engines = template.EngineManager()
self.resources = resources.ResourcesApp(self.config)
- self.controllers = controllers
+ self.controllers = controllers or ControllersApp()
+
+ rl = core.request_local()
+ for widget, path in rl.get('queued_controllers', []):
+ self.controllers.register(widget, path)
+
+ rl['queued_controllers'] = []
+
def __call__(self, environ, start_response):
rl = core.request_local()
@@ -185,6 +195,7 @@ def __init__(self):
self._widgets = {}
def register(self, widget, path=None):
+ log.info("Registered controller %r->%r" % (path, widget))
if path is None:
path = widget.id
self._widgets[path] = widget
@@ -205,12 +216,33 @@ def __call__(self, req):
resp = widget.request(req)
return resp
-global_controllers = ControllersApp()
+
+def register_controller(widget, path):
+ """ API function for registering widget controllers.
+
+ If the middleware is available, the widget is directly registered with the
+ ControllersApp.
+
+ If the middleware is not available, the widget is stored in the
+ request_local dict. When the middleware is later initialized, those
+ waiting registrations are processed.
+ """
+
+ rl = core.request_local()
+ mw = rl.get('middleware')
+ if mw:
+ mw.controllers.register(widget, path)
+ else:
+ rl['queued_controllers'] = \
+ rl.get('queued_controllers', []) + [(widget, path)]
+ log.info("No middleware in place. Queued %r->%r registration." %
+ (path, widget))
+
def make_middleware(app=None, config=None, **kw):
config = (config or {}).copy()
config.update(kw)
- app = TwMiddleware(app, controllers=global_controllers, **config)
+ app = TwMiddleware(app, **config)
return app
View
4 tw2/core/testbase/base.py
@@ -329,10 +329,10 @@ class TestInPage(object):
inject_widget = TestWidget(id='a', resources=[js,css])
def setup(self):
- self.mw = twc.make_middleware(self)
- self.app = wt.TestApp(self.mw)
global _request_local
_request_local = {}
+ self.mw = twc.make_middleware(self)
+ self.app = wt.TestApp(self.mw)
def __call__(self, environ, start_response):
req = wo.Request(environ)
View
5 tw2/core/widgets.py
@@ -142,9 +142,8 @@ def post_define(cls):
if hasattr(cls, 'request') and getattr(cls, 'id', None):
import middleware
- capp = getattr(cls.__module__, 'tw2_controllers', middleware.global_controllers)
- if capp:
- capp.register(cls, cls._gen_compound_id(for_url=True))
+ path = cls._gen_compound_id(for_url=True)
+ middleware.register_controller(cls, path)
if cls.validator:
if cls.validator is pm.Required:
Please sign in to comment.
Something went wrong with that request. Please try again.