From 395e690cd608300b8fb02a8cc07db428a0126ed6 Mon Sep 17 00:00:00 2001
From: Mike Bayer <mike_mp@zzzcomputing.com>
Date: Mon, 20 Nov 2006 18:21:52 +0000
Subject: [PATCH] cstringio, template lookup

---
 lib/mako/codegen.py    |  5 ++---
 lib/mako/exceptions.py |  5 ++++-
 lib/mako/runtime.py    | 11 +++++++----
 lib/mako/template.py   | 10 +++++-----
 lib/mako/util.py       |  5 +++++
 5 files changed, 23 insertions(+), 13 deletions(-)

diff --git a/lib/mako/codegen.py b/lib/mako/codegen.py
index 7b97b96..5151feb 100644
--- a/lib/mako/codegen.py
+++ b/lib/mako/codegen.py
@@ -1,6 +1,5 @@
 """provides the Compiler object for generating module source code."""
 
-from StringIO import StringIO
 import time
 from mako.pygen import PythonPrinter
 from mako import util, ast, parsetree
@@ -12,7 +11,7 @@ class Compiler(object):
         self.node = node
         self.filename = filename
     def render(self):
-        buf = StringIO()
+        buf = util.StringIO()
         printer = PythonPrinter(buf)
         
         # module-level names, python code
@@ -174,7 +173,7 @@ class _GenerateRenderMethod(object):
 
     def visitIncludeTag(self, node):
         self.write_source_comment(node)
-        self.printer.writeline("context.include_file(%s, import=%s)" % (repr(node.attributes['file']), repr(node.attributes.get('import', False))))
+        self.printer.writeline("runtime.include_file(context, %s, import_symbols=%s)" % (repr(node.attributes['file']), repr(node.attributes.get('import', False))))
     def visitNamespaceTag(self, node):
         self.write_source_comment(node)
         self.printer.writeline("def make_namespace():")
diff --git a/lib/mako/exceptions.py b/lib/mako/exceptions.py
index 0f056b1..eea5003 100644
--- a/lib/mako/exceptions.py
+++ b/lib/mako/exceptions.py
@@ -16,4 +16,7 @@ class SyntaxException(MakoException):
     def __init__(self, message, lineno, pos):
         MakoException.__init__(self, message + " at line: %d char: %d" % (lineno, pos))
         self.lineno =lineno
-        self.pos = pos
\ No newline at end of file
+        self.pos = pos
+        
+class TemplateLookupException(MakoException):
+    pass
\ No newline at end of file
diff --git a/lib/mako/runtime.py b/lib/mako/runtime.py
index f50632a..6a4959f 100644
--- a/lib/mako/runtime.py
+++ b/lib/mako/runtime.py
@@ -3,11 +3,11 @@ from mako import exceptions
 
 class Context(object):
     """provides runtime namespace and output buffer for templates."""
-    def __init__(self, buffer, **data):
+    def __init__(self, template, buffer, **data):
         self.buffer = buffer
         self.data = data
         # the Template instance currently rendering with this context.
-        self.with_template = None
+        self.with_template = template
     def __getitem__(self, key):
         return self.data[key]
     def get(self, key, default=None):
@@ -19,8 +19,7 @@ class Context(object):
         with the given keyword arguments."""
         x = self.data.copy()
         x.update(args)
-        c = Context(self.buffer, **x)
-        c.with_template = self.with_template
+        c = Context(self.with_template, self.buffer, **x)
         return c
         
 class Namespace(object):
@@ -53,4 +52,8 @@ class Namespace(object):
                 pass
         raise exceptions.RuntimeException("Namespace '%s' has no member '%s'" % (self.name, key))
         
+def include_file(context, uri, import_symbols):
+    lookup = context.with_template.lookup
+    template = lookup.get_template(uri)
+    template.render_context(context)
         
\ No newline at end of file
diff --git a/lib/mako/template.py b/lib/mako/template.py
index 08d925f..46f24cd 100644
--- a/lib/mako/template.py
+++ b/lib/mako/template.py
@@ -4,8 +4,8 @@ as well as template runtime operations."""
 from mako.lexer import Lexer
 from mako.codegen import Compiler
 from mako.runtime import Context
+from mako import util
 import imp, time, inspect, weakref, sys
-from StringIO import StringIO
 
 _modules = weakref.WeakValueDictionary()
 _inmemory_templates = weakref.WeakValueDictionary()
@@ -17,7 +17,7 @@ class _ModuleMarker(object):
 
 class Template(object):
     """a compiled template"""
-    def __init__(self, text=None, module=None, identifier=None, filename=None, format_exceptions=True, error_handler=None):
+    def __init__(self, text=None, module=None, identifier=None, filename=None, format_exceptions=True, error_handler=None, lookup=None):
         """construct a new Template instance using either literal template text, or a previously loaded template module
         
         text - textual template source, or None if a module is to be provided
@@ -46,6 +46,7 @@ class Template(object):
         self.callable_ = self.module.render
         self.format_exceptions = format_exceptions
         self.error_handler = error_handler
+        self.lookup = lookup
         _modules[module.__name__] = _ModuleMarker(module)
 
     source = property(lambda self:_get_template_source(self.callable_), doc="""return the template source code for this Template.""")
@@ -89,8 +90,8 @@ def _compile_text(text, identifier, filename):
     
 def _render(template, callable_, *args, **data):
     """given a Template and a callable_ from that template, create a Context and return the string output."""
-    buf = StringIO()
-    context = Context(buf, **data)
+    buf = util.StringIO()
+    context = Context(template, buf, **data)
     kwargs = {}
     argspec = inspect.getargspec(callable_)
     namedargs = argspec[0] + [v for v in argspec[1:3] if v is not None]
@@ -101,7 +102,6 @@ def _render(template, callable_, *args, **data):
     return buf.getvalue()
 
 def _render_context(template, callable_, context, *args, **kwargs):
-    context.with_template = template
     _exec_template(callable_, context, args=args, kwargs=kwargs)
 
 def _exec_template(callable_, context, args=None, kwargs=None):
diff --git a/lib/mako/util.py b/lib/mako/util.py
index bdcbe4c..9f63825 100644
--- a/lib/mako/util.py
+++ b/lib/mako/util.py
@@ -5,4 +5,9 @@ except:
     import sets
     Set = sets.Set
 
+try:
+    from cStringIO import StringIO
+except:
+    from StringIO import StringIO
+    
 
-- 
GitLab