Merge branch 'feature.macrorenderers'
| | |
| | | </span> |
| | | </html> |
| | | |
| | | |
| | | Using A Chameleon Macro Name Within a Chameleon ZPT Template |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | Sommetime you'd like to render a macro inside of a Chameleon ZPT template |
| | | instead of the full Chameleon ZPT template. To render the content of a |
| | | ``define-macro`` field inside a Chameleon ZPT template, given a Chameleon |
| | | template file named ``foo.pt`` and a macro named ``bar`` defined within it |
| | | (e.g. ``<div metal:define-macro="bar">...</div>``, you can configure the |
| | | template as a :term:`renderer` like so: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | | |
| | | from pyramid.view import view_config |
| | | |
| | | @view_config(renderer='foo#bar.pt') |
| | | def my_view(request): |
| | | return {'project':'my project'} |
| | | |
| | | The above will render the ``bar`` macro from within the ``foo.pt`` template |
| | | instead of the entire template. |
| | | |
| | | |
| | | .. index:: |
| | | single: Chameleon text templates |
| | | |
| | |
| | | :term:`renderer globals`. See the `the Mako documentation |
| | | <http://www.makotemplates.org/>`_ to use more advanced features. |
| | | |
| | | Using def inside Mako Templates |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | Using A Mako def name Within a Renderer Name |
| | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| | | |
| | | To use a def inside a Mako template, given a :term:`Mako` template file named |
| | | ``foo.mak`` and a def named ``bar``, you can configure the template as a |
| | | :term:`renderer` like so: |
| | | Sommetime you'd like to render a ``def`` inside of a Mako template instead of |
| | | the full Mako template. To render a def inside a Mako template, given a |
| | | :term:`Mako` template file named ``foo.mak`` and a def named ``bar``, you can |
| | | configure the template as a :term:`renderer` like so: |
| | | |
| | | .. code-block:: python |
| | | :linenos: |
| | |
| | | def my_view(request): |
| | | return {'project':'my project'} |
| | | |
| | | The above will render the ``bar`` def from within the ``foo.mak`` template |
| | | instead of the entire template. |
| | | |
| | | .. index:: |
| | | single: automatic reloading of templates |
| | | single: template automatic reload |
| | |
| | | |
| | | @implementer(ITemplateRenderer) |
| | | class TextTemplateRenderer(object): |
| | | def __init__(self, path, lookup): |
| | | def __init__(self, path, lookup, macro=None): |
| | | self.path = path |
| | | self.lookup = lookup |
| | | |
| | |
| | | |
| | | @implementer(ITemplateRenderer) |
| | | class ZPTTemplateRenderer(object): |
| | | def __init__(self, path, lookup): |
| | | def __init__(self, path, lookup, macro=None): |
| | | self.path = path |
| | | self.lookup = lookup |
| | | self.macro = macro |
| | | |
| | | @reify # avoid looking up reload_templates before manager pushed |
| | | def template(self): |
| | | if sys.platform.startswith('java'): # pragma: no cover |
| | | raise RuntimeError( |
| | | 'Chameleon templates are not compatible with Jython') |
| | | return PageTemplateFile(self.path, |
| | | auto_reload=self.lookup.auto_reload, |
| | | debug=self.lookup.debug, |
| | | translate=self.lookup.translate) |
| | | tf = PageTemplateFile(self.path, |
| | | auto_reload=self.lookup.auto_reload, |
| | | debug=self.lookup.debug, |
| | | translate=self.lookup.translate) |
| | | if self.macro: |
| | | # render only the portion of the template included in a |
| | | # define-macro named the value of self.macro |
| | | macro_renderer = tf.macros[self.macro].include |
| | | tf._render = macro_renderer |
| | | return tf |
| | | |
| | | def implementation(self): |
| | | return self.template |
| | | |
| | | def __call__(self, value, system): |
| | | try: |
| | | system['renderer'] = self |
| | | system['template'] = self.template |
| | | system.update(value) |
| | | except (TypeError, ValueError): |
| | | raise ValueError('renderer was passed non-dictionary as value') |
| | |
| | | import json |
| | | import os |
| | | import re |
| | | import pkg_resources |
| | | import threading |
| | | |
| | |
| | | raise ValueError('Missing template file: %s' % spec) |
| | | renderer = registry.queryUtility(ITemplateRenderer, name=spec) |
| | | if renderer is None: |
| | | renderer = self.impl(spec, self) |
| | | renderer = self.impl(spec, self, macro=None) |
| | | # cache the template |
| | | try: |
| | | self.lock.acquire() |
| | |
| | | # spec is a package:relpath asset spec |
| | | renderer = registry.queryUtility(ITemplateRenderer, name=spec) |
| | | if renderer is None: |
| | | p = re.compile( |
| | | r'(?P<asset>[\w_.:/]+)' |
| | | r'(?:\#(?P<defname>[\w_]+))?' |
| | | r'(\.(?P<ext>.*))' |
| | | ) |
| | | asset, macro, ext = p.match(spec).group( |
| | | 'asset', 'defname', 'ext') |
| | | spec = '%s.%s' % (asset, ext) |
| | | try: |
| | | package_name, filename = spec.split(':', 1) |
| | | except ValueError: # pragma: no cover |
| | |
| | | if not pkg_resources.resource_exists(package_name, filename): |
| | | raise ValueError( |
| | | 'Missing template asset: %s (%s)' % (spec, abspath)) |
| | | renderer = self.impl(abspath, self) |
| | | renderer = self.impl(abspath, self, macro=macro) |
| | | settings = info.settings |
| | | if not settings.get('reload_assets'): |
| | | # cache the template |
| | |
| | | if path.endswith('.pyc'): # pragma: no cover |
| | | path = path[:-1] |
| | | self.assertTrue(factory.path.startswith(path)) |
| | | self.assertEqual(factory.kw, {}) |
| | | self.assertEqual(factory.kw, {'macro':None}) |
| | | |
| | | def test___call__spec_withmacro(self): |
| | | import os |
| | | from pyramid import tests |
| | | module_name = tests.__name__ |
| | | relpath = 'fixtures/withmacro#foo.pt' |
| | | renderer = {} |
| | | factory = DummyFactory(renderer) |
| | | spec = '%s:%s' % (module_name, relpath) |
| | | info = DummyRendererInfo({ |
| | | 'name':spec, |
| | | 'package':None, |
| | | 'registry':self.config.registry, |
| | | 'settings':{}, |
| | | 'type':'type', |
| | | }) |
| | | lookup = self._makeOne(factory) |
| | | result = lookup(info) |
| | | self.assertTrue(result is renderer) |
| | | path = os.path.join( |
| | | os.path.dirname(os.path.abspath(__file__)), |
| | | 'fixtures', |
| | | 'withmacro.pt') |
| | | self.assertTrue(factory.path.startswith(path)) |
| | | self.assertEqual(factory.kw, {'macro':'foo'}) |
| | | |
| | | def test___call__reload_assets_true(self): |
| | | import pyramid.tests |