summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Ronacher <armin.ronacher@active-4.com>2007-06-02 12:12:56 +0200
committerArmin Ronacher <armin.ronacher@active-4.com>2007-06-02 12:12:56 +0200
commit2165ce64ea867fd20c2b3cfd0a7e385701020e44 (patch)
tree0963aa9538fa8730839ff8f9db1c53a63e5dcbb0
parentccdc022189e196ed3b19174475f779380b174854 (diff)
downloadjinja2-2165ce64ea867fd20c2b3cfd0a7e385701020e44.tar.gz
[svn] made jinja platform depending and adedd manifest for the built documentation. Improved loader documentation
--HG-- branch : trunk
-rw-r--r--MANIFEST.in1
-rw-r--r--docs/src/loaders.txt103
-rw-r--r--jinja/environment.py13
-rw-r--r--setup.py1
4 files changed, 108 insertions, 10 deletions
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..69083cd
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+include docs/build/*.html
diff --git a/docs/src/loaders.txt b/docs/src/loaders.txt
index 306b14d..18a8fbd 100644
--- a/docs/src/loaders.txt
+++ b/docs/src/loaders.txt
@@ -15,10 +15,11 @@ modification:
Loader Baseclasses
==================
-With Jinja 1.1 onwards all the loaders have (except of the uncached) now have
-baseclasses you can use to mix your own caching layer in. This technique is
-explained below. The `BaseLoader` itself is also a loader baseclass but because
-it's the baseclass of each loader it's explained in detail below.
+With Jinja 1.1 onwards all the loaders have (except of the uncached)
+baseclasses. You can use them to mix your own caching layer in. This technique
+is described below. The `BaseLoader` itself is also a loader baseclass but
+because it's the baseclass of all loaders it's covered in the "Developing
+Loaders" section.
[[list_of_baseloaders]]
@@ -144,3 +145,97 @@ for the `FunctionLoader`:
)
.. _memcached: http://www.danga.com/memcached/
+
+How Mixin Classes Work
+======================
+
+The idea of the cached loader mixins is that you override the `load`
+method of the other base class so that it's only called to get the data
+from the loader and put it into a cache and then bypass the original `load`.
+
+This works because mixin classes, as well as the loaders are so called "new
+style classes" with a MRO (method resolution order). So it's possible to
+access the parent without actually knowing the name of it.
+
+Here as small mixin class that stores everything after loading in a
+dict:
+
+.. sourcecode:: python
+
+ class SimpleCacheMixin(object):
+
+ def __init__(self):
+ self.__cache = {}
+
+ def load(self, environment, name, translator):
+ if name in self.__cache:
+ return self.__cache[name]
+ tmpl = super(SimpleCacheMixin, self).load(environment, name,
+ translator)
+ self.__cache[name] = tmpl
+ return tmpl
+
+You can then mix the class in like any other mixin class. Note that
+all non public attributes **must** be prefixed with two underscores to
+enable the name mangling. Otherwise the mixin class could break the
+internal structure of the loader.
+
+The ``super(SimpleCacheMixin, self)`` call returns an object that looks
+up all the attributes you request in all the parent classes. The
+`SimpleCacheMixin` just has the `object` parent which makes it a new
+style class, but as soon as a loader is mixed in it will call the
+`load` method of the loader that is the other parent of the resulting
+class. Here a full example.
+
+Combining Everything
+====================
+
+Here a full example with a custom cache mixin and a custom base loader:
+
+.. sourcecode:: python
+
+ import codecs
+ from os.path import join
+ from jinja.loaders import BaseLoader
+ from jinja.exceptions import TemplateNotFound
+
+ class SimpleBaseLoader(BaseLoader):
+
+ def __init__(self, path):
+ self.path = path
+
+ def get_source(self, environment, name, parent):
+ filename = join(self.path, name)
+ if not path.exists(filename):
+ raise TemplateNotFound(name)
+ f = codecs.open(filename, 'r', environment.template_charset)
+ try:
+ return f.read()
+ finally:
+ f.close()
+
+
+ class SimpleCacheMixin(object):
+
+ def __init__(self):
+ self.__cache = {}
+
+ def load(self, environment, name, translator):
+ if name in self.__cache:
+ return self.__cache[name]
+ tmpl = super(SimpleCacheMixin, self).load(environment, name,
+ translator)
+ self.__cache[name] = tmpl
+ return tmpl
+
+
+ class SimpleLoader(SimpleBaseLoader, SimpleCacheMixin):
+
+ def __init__(self, path):
+ SimpleBaseLoader.__init__(self, path)
+ SimpleCacheMixin.__init__()
+
+You can of course put all the functionallity into the `SimpleLoader` but then
+you cannot exchange parts of it without rewriting much code. In the example
+above replacing the `SimpleCacheMixin` with a `MemcachedLoaderMixin` is a
+matter of 20 seconds.
diff --git a/jinja/environment.py b/jinja/environment.py
index 91cd2a5..034d092 100644
--- a/jinja/environment.py
+++ b/jinja/environment.py
@@ -129,8 +129,12 @@ class Environment(object):
self.template_charset = template_charset
self.charset = charset
self.loader = loader
- self.filters = filters is None and DEFAULT_FILTERS.copy() or filters
- self.tests = tests is None and DEFAULT_TESTS.copy() or tests
+ if filters is None:
+ filters = DEFAULT_FILTERS.copy()
+ self.filters = filters
+ if tests is None:
+ tests = DEFAULT_TESTS.copy()
+ self.tests = tests
self.default_filters = default_filters or []
self.context_class = context_class
self.undefined_singleton = undefined_singleton
@@ -138,9 +142,8 @@ class Environment(object):
# global namespace
if namespace is None:
- self.globals = DEFAULT_NAMESPACE.copy()
- else:
- self.globals = namespace
+ namespace = DEFAULT_NAMESPACE.copy()
+ self.globals = namespace
# jinja 1.0 compatibility
if auto_escape:
diff --git a/setup.py b/setup.py
index a0be447..456a5b9 100644
--- a/setup.py
+++ b/setup.py
@@ -73,7 +73,6 @@ setup(
('docs', list(list_files('docs/build'))),
('docs/txt', list(list_files('docs/src')))
],
- platforms = 'any',
entry_points='''
[python.templating.engines]
jinja = jinja.plugin:BuffetPlugin