[Checkins] SVN: hurry.resource/trunk/ Add a WSGI middleware that will pull in resources.
Martijn Faassen
faassen at startifact.com
Tue Jul 13 11:36:26 EDT 2010
Log message for revision 114697:
Add a WSGI middleware that will pull in resources.
Changed:
U hurry.resource/trunk/CHANGES.txt
U hurry.resource/trunk/buildout.cfg
U hurry.resource/trunk/setup.py
U hurry.resource/trunk/src/hurry/resource/README.txt
U hurry.resource/trunk/src/hurry/resource/__init__.py
A hurry.resource/trunk/src/hurry/resource/wsgi.py
-=-
Modified: hurry.resource/trunk/CHANGES.txt
===================================================================
--- hurry.resource/trunk/CHANGES.txt 2010-07-13 11:15:40 UTC (rev 114696)
+++ hurry.resource/trunk/CHANGES.txt 2010-07-13 15:36:25 UTC (rev 114697)
@@ -1,9 +1,17 @@
CHANGES
*******
-0.4.2 (unreleased)
-==================
+0.5 (unreleased)
+================
+* WSGI support: ``hurry.resource.Middleware`` can be used to wrap WSGI
+ applications. If the application supplies a ``NeededInclusions``
+ object in ``environ`` with the key ``hurry.resource.needed``, the
+ middleware will pick up on this and insert the needed inclusions.
+
+ The WebOb library is needed to make this work and depending on
+ ``hurry.resource [wsgi]`` will pull in the required dependency.
+
* Fixed some typos in README.txt.
0.4.1 (2009-12-16)
Modified: hurry.resource/trunk/buildout.cfg
===================================================================
--- hurry.resource/trunk/buildout.cfg 2010-07-13 11:15:40 UTC (rev 114696)
+++ hurry.resource/trunk/buildout.cfg 2010-07-13 15:36:25 UTC (rev 114697)
@@ -2,12 +2,13 @@
develop = .
parts = test releaser
versions = versions
+unzip = true
[versions]
[test]
recipe = zc.recipe.testrunner
-eggs = hurry.resource
+eggs = hurry.resource [test]
defaults = ['--tests-pattern', '^f?tests$', '-v']
[releaser]
Modified: hurry.resource/trunk/setup.py
===================================================================
--- hurry.resource/trunk/setup.py 2010-07-13 11:15:40 UTC (rev 114696)
+++ hurry.resource/trunk/setup.py 2010-07-13 15:36:25 UTC (rev 114697)
@@ -33,5 +33,7 @@
'zope.interface',
'zope.component',
],
+ extras_require = dict(test=['WebOb'],
+ wsgi=['WebOb']),
entry_points={},
)
Modified: hurry.resource/trunk/src/hurry/resource/README.txt
===================================================================
--- hurry.resource/trunk/src/hurry/resource/README.txt 2010-07-13 11:15:40 UTC (rev 114696)
+++ hurry.resource/trunk/src/hurry/resource/README.txt 2010-07-13 15:36:25 UTC (rev 114697)
@@ -937,6 +937,58 @@
<script type="text/javascript" src="http://localhost/static/foo/c.js"></script>
<script type="text/javascript" src="http://localhost/static/foo/y2.js"></script></body></html>
+Using WSGI middleware to insert into HTML
+=========================================
+
+There is also a WSGI middleware available to insert the top (and bottom)
+into the HTML. We are using WebOb to create a response object that will
+serve as our WSGI application::
+
+We create a simple WSGI application. In our application we declare that
+we need a resource (``y1``) and put that in the WSGI ``environ`` under the
+key ``hurry.resource.needed``::
+
+ >>> def app(environ, start_response):
+ ... start_response('200 OK', [])
+ ... needed = environ['hurry.resource.needed'] = NeededInclusions()
+ ... needed.need(y1)
+ ... return ['<html><head></head><body</body></html>']
+
+We now wrap this in our middleware, so that the middleware is activated::
+
+ >>> from hurry.resource import Middleware
+ >>> wrapped_app = Middleware(app)
+
+Now we make a request (using webob for convenience)::
+
+ >>> import webob
+ >>> req = webob.Request.blank('/')
+ >>> res = req.get_response(wrapped_app)
+
+We can now see that the resources are added to the HTML by the middleware::
+
+ >>> print res.body
+ <html><head>
+ <link rel="stylesheet" type="text/css" href="http://localhost/static/foo/b.css" />
+ <script type="text/javascript" src="http://localhost/static/foo/a.js"></script>
+ <script type="text/javascript" src="http://localhost/static/foo/c.js"></script>
+ </head><body</body></html>
+
+When we set the response Content-Type to non-HTML, the middleware
+won't be active even if we need things and the body appears to contain
+HTML::
+
+ >>> def app(environ, start_response):
+ ... start_response('200 OK', [('Content-Type', 'text/plain')])
+ ... needed = environ['hurry.resource.needed'] = NeededInclusions()
+ ... needed.need(y1)
+ ... return ['<html><head></head><body</body></html>']
+ >>> wrapped_app = Middleware(app)
+ >>> req = webob.Request.blank('/')
+ >>> res = req.get_response(wrapped_app)
+ >>> res.body
+ '<html><head></head><body</body></html>'
+
bottom convenience
==================
Modified: hurry.resource/trunk/src/hurry/resource/__init__.py
===================================================================
--- hurry.resource/trunk/src/hurry/resource/__init__.py 2010-07-13 11:15:40 UTC (rev 114696)
+++ hurry.resource/trunk/src/hurry/resource/__init__.py 2010-07-13 15:36:25 UTC (rev 114697)
@@ -10,3 +10,4 @@
from hurry.resource.core import (sort_inclusions_topological,
sort_inclusions_by_extension,
generate_code)
+from hurry.resource.wsgi import Middleware
Added: hurry.resource/trunk/src/hurry/resource/wsgi.py
===================================================================
--- hurry.resource/trunk/src/hurry/resource/wsgi.py (rev 0)
+++ hurry.resource/trunk/src/hurry/resource/wsgi.py 2010-07-13 15:36:25 UTC (rev 114697)
@@ -0,0 +1,21 @@
+import webob
+
+# TODO: would be nice to make middleware smarter so it could work with
+# a streamed HTML body instead of serializing it out to body. That
+# would complicate the middleware signicantly, however. We would for
+# instance need to recalculate content_length ourselves.
+
+class Middleware(object):
+ def __init__(self, application):
+ self.application = application
+
+ def __call__(self, environ, start_response):
+ req = webob.Request(environ)
+ res = req.get_response(self.application)
+ if not res.content_type.lower() in ['text/html', 'text/xml']:
+ return res(environ, start_response)
+ needed = environ.get('hurry.resource.needed', None)
+ if needed is None:
+ return res(environ, start_response)
+ res.body = needed.render_topbottom_into_html(res.body)
+ return res(environ, start_response)
More information about the checkins
mailing list