diff options
| author | Chris McDonough <chrism@agendaless.com> | 2008-08-17 17:32:54 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2008-08-17 17:32:54 +0000 |
| commit | 0e21c22166f5160a2a64fad714d69d81897ef7d3 (patch) | |
| tree | 6a576d0edfafe0e204a1770c094f13ff8aa74487 /repoze | |
| parent | 157721dda97f5aea95f40e307d9d5dceb1014f83 (diff) | |
| download | pyramid-0e21c22166f5160a2a64fad714d69d81897ef7d3.tar.gz pyramid-0e21c22166f5160a2a64fad714d69d81897ef7d3.tar.bz2 pyramid-0e21c22166f5160a2a64fad714d69d81897ef7d3.zip | |
- Add ``<bfg:settings>`` directive. This directive currently allows
only one attribute: ``reload_templates``. If e.g.::
<bfg:settings reload_templates="true"/>
is in your application's ZCML, you will not need to restart the
appserver in order for ``z3c.pt`` or XSLT template changes to be
detected and displayed.
Diffstat (limited to 'repoze')
| -rw-r--r-- | repoze/bfg/interfaces.py | 7 | ||||
| -rw-r--r-- | repoze/bfg/meta.zcml | 6 | ||||
| -rw-r--r-- | repoze/bfg/sampleapp/configure.zcml | 3 | ||||
| -rw-r--r-- | repoze/bfg/template.py | 33 | ||||
| -rw-r--r-- | repoze/bfg/tests/test_zcml.py | 31 | ||||
| -rw-r--r-- | repoze/bfg/zcml.py | 27 |
6 files changed, 94 insertions, 13 deletions
diff --git a/repoze/bfg/interfaces.py b/repoze/bfg/interfaces.py index 4f1a203df..3a4c45373 100644 --- a/repoze/bfg/interfaces.py +++ b/repoze/bfg/interfaces.py @@ -27,7 +27,7 @@ class ITraverserFactory(Interface): """ Return an object that implements IPublishTraverser """ class ITemplateFactory(Interface): - def __call__(path): + def __call__(path, auto_reload=False): """ Return an an ITemplate given a filesystem path """ class ITemplate(Interface): @@ -79,3 +79,8 @@ class INewResponse(Interface): """ An event type that is emitted whenever any repoze.bfg view returns a response.""" response = Attribute('The response object') + +class ISettings(Interface): + """ Runtime settings for repoze.bfg """ + reload_templates = Attribute('Reload templates when they change') + diff --git a/repoze/bfg/meta.zcml b/repoze/bfg/meta.zcml index 72e963ae6..91b4f40e8 100644 --- a/repoze/bfg/meta.zcml +++ b/repoze/bfg/meta.zcml @@ -10,6 +10,12 @@ handler=".zcml.view" /> + <meta:directive + name="settings" + schema=".zcml.ISettingsDirective" + handler=".zcml.settings" + /> + </meta:directives> </configure> diff --git a/repoze/bfg/sampleapp/configure.zcml b/repoze/bfg/sampleapp/configure.zcml index a5f27595e..d20d7d8f9 100644 --- a/repoze/bfg/sampleapp/configure.zcml +++ b/repoze/bfg/sampleapp/configure.zcml @@ -4,6 +4,9 @@ <include package="repoze.bfg" /> + <bfg:settings + reload_templates="true"/> + <utility provides="repoze.bfg.interfaces.ISecurityPolicy" factory="repoze.bfg.security.RemoteUserACLSecurityPolicy" diff --git a/repoze/bfg/template.py b/repoze/bfg/template.py index 3c60dd19e..de049f5fa 100644 --- a/repoze/bfg/template.py +++ b/repoze/bfg/template.py @@ -13,14 +13,19 @@ from zope.interface import implements from repoze.bfg.interfaces import ITemplateFactory from repoze.bfg.interfaces import ITemplate from repoze.bfg.interfaces import INodeTemplate +from repoze.bfg.interfaces import ISettings class Z3CPTTemplateFactory(object): classProvides(ITemplateFactory) implements(ITemplate) - def __init__(self, path): + def __init__(self, path, auto_reload=False): from z3c.pt import PageTemplateFile - self.template = PageTemplateFile(path) + try: + self.template = PageTemplateFile(path, auto_reload=auto_reload) + except TypeError: + # z3c.pt before 1.0 + self.template = PageTemplateFile(path) def __call__(self, **kw): result = self.template.render(**kw) @@ -30,11 +35,12 @@ class XSLTemplateFactory(object): classProvides(ITemplateFactory) implements(INodeTemplate) - def __init__(self, path): + def __init__(self, path, auto_reload=False): self.path = path + self.auto_reload = auto_reload def __call__(self, node, **kw): - processor = get_processor(self.path) + processor = get_processor(self.path, self.auto_reload) result = str(processor(node, **kw)) return result @@ -42,13 +48,14 @@ class XSLTemplateFactory(object): import threading from lxml import etree xslt_pool = threading.local() -def get_processor(xslt_fn): - try: - return xslt_pool.processors[xslt_fn] - except AttributeError: - xslt_pool.processors = {} - except KeyError: - pass +def get_processor(xslt_fn, auto_reload=False): + if not auto_reload: + try: + return xslt_pool.processors[xslt_fn] + except AttributeError: + xslt_pool.processors = {} + except KeyError: + pass # Make a processor and add it to the pool source = etree.ElementTree(file=xslt_fn) @@ -74,7 +81,9 @@ def _get_template(path, **kw): if template is None: if not os.path.exists(path): raise ValueError('Missing template file: %s' % path) - template = Z3CPTTemplateFactory(path) + settings = queryUtility(ISettings) + auto_reload = settings and settings.reload_templates + template = Z3CPTTemplateFactory(path, auto_reload) registerTemplate(ITemplate, template, path) return template diff --git a/repoze/bfg/tests/test_zcml.py b/repoze/bfg/tests/test_zcml.py index 663022796..407eaf24e 100644 --- a/repoze/bfg/tests/test_zcml.py +++ b/repoze/bfg/tests/test_zcml.py @@ -114,6 +114,37 @@ class TestViewDirective(unittest.TestCase, PlacelessSetup): self.assertEqual(regadapt['args'][4], '') self.assertEqual(regadapt['args'][5], None) +class TestSettingsDirective(unittest.TestCase, PlacelessSetup): + def setUp(self): + PlacelessSetup.setUp(self) + + def tearDown(self): + PlacelessSetup.tearDown(self) + + def _getFUT(self): + from repoze.bfg.zcml import settings + return settings + + def test_defaults(self): + context = DummyContext() + settings = self._getFUT() + settings(context) + actions = context.actions + from repoze.bfg.interfaces import ISettings + from zope.component.zcml import handler + self.assertEqual(len(actions), 1) + action = actions[0] + self.assertEqual(action['discriminator'], ('settings', ISettings)) + self.assertEqual(action['callable'], handler) + self.assertEqual(len(action['args']), 5) + self.assertEqual(action['args'][0], 'registerUtility') + settings = action['args'][1] + self.assertEqual(settings.reload_templates, False) + self.failUnless(ISettings.providedBy(settings), settings) + self.assertEqual(action['args'][2], ISettings) + self.assertEqual(action['args'][3], '') + self.assertEqual(action['args'][4], context.info) + class TestSampleApp(unittest.TestCase, PlacelessSetup): def setUp(self): PlacelessSetup.setUp(self) diff --git a/repoze/bfg/zcml.py b/repoze/bfg/zcml.py index 343abc1d7..bb37c6581 100644 --- a/repoze/bfg/zcml.py +++ b/repoze/bfg/zcml.py @@ -2,17 +2,44 @@ from zope.component.zcml import handler from zope.component.interface import provideInterface from zope.configuration.exceptions import ConfigurationError from zope.configuration.fields import GlobalObject +from zope.configuration.fields import Bool from zope.interface import Interface +from zope.interface import implements from zope.schema import TextLine from repoze.bfg.interfaces import IRequest from repoze.bfg.interfaces import IViewPermission from repoze.bfg.interfaces import IView +from repoze.bfg.interfaces import ISettings from repoze.bfg.security import ViewPermissionFactory +def _handler(*arg, **kw): + import pdb; pdb.set_trace() + return handler(*arg, **kw) + +class Settings(object): + implements(ISettings) + def __init__(self, reload_templates=False): + self.reload_templates = reload_templates + +def settings(_context, reload_templates=False): + settings = Settings(reload_templates=reload_templates) + _context.action( + discriminator = ('settings', ISettings), + callable = handler, + args = ('registerUtility', settings, ISettings, '', _context.info), + ) + +class ISettingsDirective(Interface): + reload_templates = Bool( + title=u"Reload templates when they change", + description=(u"Specifies whether templates should be reloaded when" + "a change is made"), + default=False) + def view(_context, permission=None, for_=None, |
