HG changeset patch User Alexander Solovyov piranha piranha org ua Date

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# HG changeset patch
# User Alexander Solovyov <piranha@piranha.org.ua>
# Date 1249326986 -10800
# Node ID 2967868b59b8ddc2a0838bcbfbfe5c174a1a3ef5
# Parent 2e291c2aa8072edaa2fd9dc4dfc95543b13e6418
revamp of template loading
diff --git a/samples/simple/test/manage.py b/samples/simple/test/manage.py
old mode 100644
new mode 100755
diff --git a/samples/simple/test/settings.py b/samples/simple/test/settings.py
--- a/samples/simple/test/settings.py
+++ b/samples/simple/test/settings.py
@@ -1,3 +1,6 @@
+from os import path as op
+ROOT = op.normpath(op.dirname(__file__))
+
# Aliases mapping
ALIASES = {
}
@@ -11,7 +14,7 @@ import urls
URLCONF = urls.url_map
# Jinja2 template path
-TEMPLATE_PATH = 'templates'
+TEMPLATE_PATHS = [op.join(ROOT, 'templates')]
# SQL Alchemy settings
SQLA_URL = 'sqlite:///data.db'
diff --git a/svarga/core/settings/default_settings.py b/svarga/core/settings/default_settings.py
--- a/svarga/core/settings/default_settings.py
+++ b/svarga/core/settings/default_settings.py
@@ -5,28 +5,33 @@ SETTINGS_PROVIDER = 'svarga.core.provide
# List of global-configuration initializers.
# By default, Svarga will create virtual mappings for registered applications
-GLOBAL_INIT = (
+GLOBAL_INIT = [
'svarga.alias.init',
'svarga.apps.init',
- )
+ ]
# List of local-configuration initializers
# Their responsibility is to map settings to the request-level configuration.
-LOCAL_INIT = (
+LOCAL_INIT = [
'svarga.template.LocalSettingsProvider',
'svarga.apps.LocalSettingsProvider',
- )
+ ]
# Application initializers
-APPS_INIT = (
+APPS_INIT = [
'svarga.models.apps.contribute',
- )
+ ]
+
+TEMPLATE_LOADERS = [
+ 'svarga.template.loaders.PathLoader',
+ 'svarga.template.loaders.AppLoader'
+ ]
# Virtual application mapping. First value is application identification string.
# Second parameter is module to use.
# Mappings are generated only once, when Svarga global configuration is
# initialized.
-# You can import applications using virtual path starting with 'svarga.apps'.
+# You can import applications using virtual path starting with 'svarga.alias'.
# Sample:
# ALIASES = {
# 'contrib.auth': 'svarga.contrib.auth',
@@ -34,7 +39,7 @@ APPS_INIT = (
# }
# In above example, you can access 'contrib.auth' application using
# 'import svarga.alias.contrib.auth'. You're not limited with app module only
-# import. If you reference any submodules undef given application.
+# import, you can reference any submodules under given application.
# So, from svarga.alias.contrib.auth.models import User will also work, if you
# have 'models' module with 'User' in it.
ALIASES = {}
diff --git a/svarga/template/__init__.py b/svarga/template/__init__.py
--- a/svarga/template/__init__.py
+++ b/svarga/template/__init__.py
@@ -1,18 +1,15 @@
-from jinja2 import Environment, FileSystemLoader
+from jinja2 import Environment, ChoiceLoader
-from svarga.core.exceptions import ImproperlyConfigured
+from svarga.utils.imports import import_attribute
class LocalSettingsProvider(object):
"""Create jinja2 environment using configuration settings."""
def __init__(self, env_class):
- template_path = getattr(env_class.settings, 'TEMPLATE_PATH', None)
-
- if template_path is None:
- raise ImproperlyConfigured('Failed to initialize Jinja2 context - missing TEMPLATE_PATH in local settings')
-
# Get any user supplied extensions (if any)
extensions = getattr(env_class.settings, 'JINJA_EXTENSIONS', [])
extensions.extend(['svarga.template.tags.UrlReverseExtension'])
+ loaders = map(lambda x: import_attribute(x)(env_class),
+ env_class.settings.TEMPLATE_LOADERS)
- env_class.jinja = Environment(loader=FileSystemLoader(template_path),
- extensions=extensions)
+ env_class.jinja = Environment(loader=ChoiceLoader(loaders),
+ extensions=extensions)
diff --git a/svarga/template/loaders.py b/svarga/template/loaders.py
new file mode 100644
--- /dev/null
+++ b/svarga/template/loaders.py
@@ -0,0 +1,30 @@
+from jinja2 import FileSystemLoader, PackageLoader
+from jinja2.exceptions import TemplateNotFound
+
+from svarga.core.exceptions import ImproperlyConfigured
+
+class PathLoader(FileSystemLoader):
+ def __init__(self, env_class):
+ self.encoding = 'utf-8'
+ self.searchpath = getattr(env_class.settings, 'TEMPLATE_PATHS', None)
+ if not self.searchpath:
+ raise ImproperlyConfigured('Failed to inialize PathLoader - settings has no or empty TEMPLATE_PATHS')
+
+class AppLoader(PackageLoader):
+ def __init__(self, env_class):
+ from pkg_resources import ResourceManager
+ self.encoding = 'utf-8'
+ self.package_path = 'templates'
+ self.env_class = env_class
+ self.manager = ResourceManager()
+
+ def get_source(self, environment, template):
+ from pkg_resources import get_provider, DefaultProvider
+ for app in self.env_class.apps:
+ self.provider = get_provider(app)
+ self.filesystem_bound = isinstance(self.provider, DefaultProvider)
+ try:
+ return super(AppLoader, self).get_source(environment, template)
+ except TemplateNotFound:
+ pass
+ raise TemplateNotFound(template)