Index: django/utils/datastructures.py
===================================================================
--- django/utils/datastructures.py	(revision 2415)
+++ django/utils/datastructures.py	(working copy)
@@ -224,3 +224,25 @@
                 current[bits[-1]] = v
             except TypeError: # Special-case if current isn't a dict.
                 current = {bits[-1] : v}
+
+class LazySettings:
+    """
+    A lazy proxy for either global django settings or a custom settings object.
+    """
+    def __init__(self):
+        self.__dict__['_target'] = None
+
+    def __getattr__(self, name):
+        if self._target is None:
+            self.import_settings()
+        return getattr(self._target, name)
+
+    def __setattr__(self, name, value):
+        if name == '_target':
+            self.__dict__[name] = value
+        else:
+            setattr(self._target, name, value)
+
+    def import_settings(self):
+        from django.conf import settings
+        self.__dict__['_target'] = settings
Index: django/template/defaultfilters.py
===================================================================
--- django/template/defaultfilters.py	(revision 2415)
+++ django/template/defaultfilters.py	(working copy)
@@ -1,7 +1,6 @@
 "Default variable filters"
 
-from django.template import resolve_variable, Library
-from django.conf import settings
+from django.template import resolve_variable, Library, settings
 from django.utils.translation import gettext
 import re
 import random as random_module
@@ -327,14 +326,18 @@
 # DATES           #
 ###################
 
-def date(value, arg=settings.DATE_FORMAT):
+def date(value, arg=None):
     "Formats a date according to the given format"
     from django.utils.dateformat import format
+    if arg is None:
+        arg = settings.DATE_FORMAT
     return format(value, arg)
 
-def time(value, arg=settings.TIME_FORMAT):
+def time(value, arg=None):
     "Formats a time according to the given format"
     from django.utils.dateformat import time_format
+    if arg is None:
+        arg = settings.TIME_FORMAT
     return time_format(value, arg)
 
 def timesince(value):
Index: django/template/__init__.py
===================================================================
--- django/template/__init__.py	(revision 2415)
+++ django/template/__init__.py	(working copy)
@@ -57,7 +57,8 @@
 import re
 from inspect import getargspec
 from django.utils.functional import curry
-from django.conf import settings
+from django.utils.datastructures import LazySettings
+settings = LazySettings()
 from django.template.context import Context, RequestContext, ContextPopException
 
 __all__ = ('Template', 'Context', 'RequestContext', 'compile_string')
@@ -90,6 +91,38 @@
 # global list of libraries to load by default for a new parser
 builtins = []
 
+#################
+# CONFIGURATION #
+#################
+class TemplateSettings:
+    # TODO - eliminate duplication of global_settings?
+    TEMPLATE_DIRS = () 
+    DEFAULT_CHARSET = "utf-8"
+    DEBUG = False
+    DATE_FORMAT = 'N j, Y'
+    DATETIME_FORMAT = 'N j, Y, P'
+    TEMPLATE_LOADERS = (
+        'django.template.loaders.filesystem.load_template_source',
+        'django.template.loaders.app_directories.load_template_source',
+#        'django.template.loaders.eggs.load_template_source',
+    )
+    TEMPLATE_FILE_EXTENSION = '.html'
+    TEMPLATE_DEBUG = False
+    TEMPLATE_STRING_IF_INVALID = ''
+
+def configure(**options):
+    """Set configuration options for the template package."""
+    global settings 
+    new_settings = TemplateSettings()
+    for k, v in options.items():
+        if not hasattr(new_settings, k):
+            raise Exception('"%s" is not a valid template config setting' % k)
+        setattr(new_settings, k, v)
+    settings._target = new_settings
+
+#######################
+# TEMPLATE EXCEPTIONS #
+#######################
 class TemplateSyntaxError(Exception):
     pass
 
Index: django/template/loaders/app_directories.py
===================================================================
--- django/template/loaders/app_directories.py	(revision 2415)
+++ django/template/loaders/app_directories.py	(working copy)
@@ -1,33 +1,38 @@
 # Wrapper for loading templates from "template" directories in installed app packages.
 
-from django.conf import settings
 from django.core.exceptions import ImproperlyConfigured
-from django.template import TemplateDoesNotExist
+from django.template import TemplateDoesNotExist, settings
 import os
 
-# At compile time, cache the directories to search.
-app_template_dirs = []
-for app in settings.INSTALLED_APPS:
-    i = app.rfind('.')
-    if i == -1:
-        m, a = app, None
-    else:
-        m, a = app[:i], app[i+1:]
-    try:
-        if a is None:
-            mod = __import__(m, '', '', [])
-        else:
-            mod = getattr(__import__(m, '', '', [a]), a)
-    except ImportError, e:
-        raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0])
-    template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
-    if os.path.isdir(template_dir):
-        app_template_dirs.append(template_dir)
+app_template_dirs = None
 
-# It won't change, so convert it to a tuple to save memory.
-app_template_dirs = tuple(app_template_dirs)
+def _ensure_setup():
+    # cache the directories to search.
+    global app_template_dirs
+    if app_template_dirs is None:
+        app_template_dirs = []
+        for app in settings.INSTALLED_APPS:
+            i = app.rfind('.')
+            if i == -1:
+                m, a = app, None
+            else:
+                m, a = app[:i], app[i+1:]
+            try:
+                if a is None:
+                    mod = __import__(m, '', '', [])
+                else:
+                    mod = getattr(__import__(m, '', '', [a]), a)
+            except ImportError, e:
+                raise ImproperlyConfigured, 'ImportError %s: %s' % (app, e.args[0])
+            template_dir = os.path.join(os.path.dirname(mod.__file__), 'templates')
+            if os.path.isdir(template_dir):
+                app_template_dirs.append(template_dir)
+    
+        # It won't change, so convert it to a tuple to save memory.
+        app_template_dirs = tuple(app_template_dirs)
 
 def get_template_sources(template_name, template_dirs=None):
+    _ensure_setup()
     for template_dir in app_template_dirs:
         yield os.path.join(template_dir, template_name) + settings.TEMPLATE_FILE_EXTENSION
 
Index: django/template/loaders/filesystem.py
===================================================================
--- django/template/loaders/filesystem.py	(revision 2415)
+++ django/template/loaders/filesystem.py	(working copy)
@@ -1,7 +1,6 @@
 # Wrapper for loading templates from the filesystem.
 
-from django.conf import settings
-from django.template import TemplateDoesNotExist
+from django.template import TemplateDoesNotExist, settings
 import os
 
 def get_template_sources(template_name, template_dirs=None):
Index: django/template/defaulttags.py
===================================================================
--- django/template/defaulttags.py	(revision 2415)
+++ django/template/defaulttags.py	(working copy)
@@ -2,8 +2,7 @@
 
 from django.template import Node, NodeList, Template, Context, resolve_variable
 from django.template import TemplateSyntaxError, VariableDoesNotExist, BLOCK_TAG_START, BLOCK_TAG_END, VARIABLE_TAG_START, VARIABLE_TAG_END
-from django.template import get_library, Library, InvalidTemplateLibrary
-from django.conf import settings
+from django.template import get_library, Library, InvalidTemplateLibrary, settings
 import sys
 
 register = Library()
Index: django/template/context.py
===================================================================
--- django/template/context.py	(revision 2415)
+++ django/template/context.py	(working copy)
@@ -1,4 +1,4 @@
-from django.conf import settings
+from django.template import settings
 from django.core.exceptions import ImproperlyConfigured
 
 _standard_context_processors = None
Index: django/template/loader_tags.py
===================================================================
--- django/template/loader_tags.py	(revision 2415)
+++ django/template/loader_tags.py	(working copy)
@@ -1,7 +1,7 @@
 from django.template import TemplateSyntaxError, TemplateDoesNotExist, resolve_variable
 from django.template import Library, Context, Node
 from django.template.loader import get_template, get_template_from_string, find_template_source
-from django.conf import settings
+from django.template import settings
 
 register = Library()
 
Index: django/template/loader.py
===================================================================
--- django/template/loader.py	(revision 2415)
+++ django/template/loader.py	(working copy)
@@ -22,7 +22,7 @@
 
 from django.core.exceptions import ImproperlyConfigured
 from django.template import Origin, StringOrigin, Template, Context, TemplateDoesNotExist, add_to_builtins
-from django.conf import settings
+from django.template import settings
 
 template_source_loaders = None
 
Index: tests/standalone_tests.py
===================================================================
--- tests/standalone_tests.py	(revision 0)
+++ tests/standalone_tests.py	(revision 0)
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+# Runs the test scripts in the 'standalone' dir
+import os
+STANDALONE_TESTS_DIR = "standalone"
+
+standalone_tests_dir = os.path.join(os.path.dirname(__file__), STANDALONE_TESTS_DIR)
+for f in os.listdir(standalone_tests_dir):
+    if f.endswith('.py') and not f.startswith('__init__'):
+        # run script
+        # TODO - What's the correct cross platform way to do this?
+        print "Running test script %s:" % f
+        print "---------------------" + "-" * len(f)
+        os.system('"%s"' % os.path.join(standalone_tests_dir, f))

Property changes on: tests/standalone_tests.py
___________________________________________________________________
Name: svn:executable
   + *

Index: tests/standalone/components.py
===================================================================
--- tests/standalone/components.py	(revision 0)
+++ tests/standalone/components.py	(revision 0)
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+# Tests to ensure that Django components are usable without 
+# a DJANGO_SETTINGS_MODULE.  This must be executed as a standalone 
+# script to make sure django.settings hasn't already been imported
+
+import os
+try:
+    del os.environ['DJANGO_SETTINGS_MODULE']
+except KeyError:
+    pass
+
+import unittest
+
+class TestTemplate(unittest.TestCase):
+
+    def test_import(self):
+        # make sure we can import django.template without exceptions
+        from django import template
+
+    def test_loader(self):
+        from django import template
+        from django.template import loader
+
+        template.configure(TEMPLATE_DIRS=(os.path.dirname(__file__),))
+        s = loader.render_to_string('template_test')
+        self.assertEqual(s, 'Hello world')
+
+if __name__ == '__main__':
+    unittest.main()
+

Property changes on: tests/standalone/components.py
___________________________________________________________________
Name: svn:executable
   + *

Index: tests/standalone/template_test.html
===================================================================
--- tests/standalone/template_test.html	(revision 0)
+++ tests/standalone/template_test.html	(revision 0)
@@ -0,0 +1 @@
+Hello world
\ No newline at end of file
