Permalink
Browse files

Add support for loading asset specs.

  • Loading branch information...
1 parent 3d143d8 commit 637efbda537593b30bd9fd270d4c3043dfc93838 @malthe malthe committed Dec 13, 2011
Showing with 53 additions and 23 deletions.
  1. +11 −0 CHANGES.rst
  2. +18 −7 src/chameleon/loader.py
  3. +18 −16 src/chameleon/tales.py
  4. +1 −0 src/chameleon/tests/inputs/081-load-spec.pt
  5. +5 −0 src/chameleon/tests/outputs/081.pt
View
@@ -3,6 +3,17 @@ Changes
In next releases ...
+Features:
+
+- The ``load:`` expression now accepts asset specs; these are resolved
+ by the ``pkg_resources.resource_filename`` function::
+
+ <package_name>:<path>
+
+ An example from the test suite::
+
+ chameleon:tests/inputs/hello_world.pt
+
Bugfixes:
- If an attribute name for translation was not a valid Python
View
@@ -5,6 +5,7 @@
import logging
import functools
import tempfile
+import pkg_resources
log = logging.getLogger('chameleon.loader')
@@ -23,6 +24,11 @@ def load(self, *args, **kwargs):
return load
+def abspath_from_asset_spec(spec):
+ pname, filename = spec.split(':', 1)
+ return pkg_resources.resource_filename(pname, filename)
+
+
class TemplateLoader(object):
"""Template loader class.
@@ -51,22 +57,27 @@ def __init__(self, search_path=None, default_extension=None, **kwargs):
self.kwargs = kwargs
@cache
- def load(self, filename, cls=None):
+ def load(self, spec, cls=None):
if cls is None:
raise ValueError("Unbound template loader.")
- if self.default_extension is not None and '.' not in filename:
- filename += self.default_extension
+ spec = spec.strip()
+
+ if self.default_extension is not None and '.' not in spec:
+ spec += self.default_extension
+
+ if ':' in spec:
+ spec = abspath_from_asset_spec(spec)
- if os.path.isabs(filename):
- return cls(filename, **self.kwargs)
+ if os.path.isabs(spec):
+ return cls(spec, **self.kwargs)
for path in self.search_path:
- path = os.path.join(path, filename)
+ path = os.path.join(path, spec)
if os.path.exists(path):
return cls(path, **self.kwargs)
- raise ValueError("Template not found: %s." % filename)
+ raise ValueError("Template not found: %s." % spec)
def bind(self, cls):
return functools.partial(self.load, cls=cls)
View
@@ -249,22 +249,6 @@ def translate(self, expression, target):
return [ast.Assign(targets=[target], value=value)]
-class ProxyExpr(TalesExpr):
- def __init__(self, name, *args):
- super(ProxyExpr, self).__init__(*args)
- self.name = name
-
- def translate(self, expression, target):
- path = expression.strip()
- return [ast.Assign(targets=[target], value=ast.Call(
- func=load(self.name),
- args=[ast.Str(s=path)],
- keywords=[],
- starargs=None,
- kwargs=None
- ))]
-
-
class ImportExpr(object):
re_dotted = re.compile(r'^[A-Za-z.]+$')
@@ -438,6 +422,24 @@ def __call__(self, name, engine):
return self.translator(name, engine)
+class ProxyExpr(StringExpr):
+ def __init__(self, name, *args):
+ super(ProxyExpr, self).__init__(*args)
+ self.name = name
+
+ def __call__(self, target, engine):
+ assignment = super(ProxyExpr, self).__call__(target, engine)
+ return assignment + [
+ ast.Assign(targets=[target], value=ast.Call(
+ func=load(self.name),
+ args=[target],
+ keywords=[],
+ starargs=None,
+ kwargs=None
+ ))
+ ]
+
+
class ExistsExpr(object):
"""Boolean wrapper.
@@ -0,0 +1 @@
+<html metal:use-macro="load: chameleon:tests/inputs/hello_world.pt" />
@@ -0,0 +1,5 @@
+<html>
+ <body>
+ Hello world!
+ </body>
+</html>

0 comments on commit 637efbd

Please sign in to comment.