Index: defaulttags.py
===================================================================
--- defaulttags.py	(.../trunk/django/core/defaulttags.py)	(revision 803)
+++ defaulttags.py	(.../branches/new-admin/django/core/defaulttags.py)	(revision 803)
@@ -2,6 +2,7 @@
 
 import sys
 import template
+import template_loader
 
 class CommentNode(template.Node):
     def render(self, context):
@@ -226,6 +227,35 @@
                 return '' # Fail silently for invalid included templates.
         return output
 
+
+class ConstantIncludeNode(template.Node):
+    def __init__(self, template_path):
+        try: 
+            t = template_loader.get_template(template_path)        
+            self.nodelist = t.nodelist
+        except Exception, e:
+            self.nodelist = None
+
+    def render(self, context):
+        if self.nodelist:
+            return self.nodelist.render(context)
+        else:
+            return ''
+
+class IncludeNode(template.Node):
+    def __init__(self, template_path_var):
+        self.template_path_var = template_path_var
+
+    def render(self, context):
+         try:
+             template_path = template.resolve_variable(self.template_path_var, context)
+             print "IncludeNode rendering %s" % template_path 
+             t = template_loader.get_template(template_path)
+             return t.render(context)
+         except Exception, e:
+             return '' # Fail silently for invalid included templates.
+
+
 class LoadNode(template.Node):
     def __init__(self, taglib):
         self.taglib = taglib
@@ -607,6 +637,20 @@
             raise template.TemplateSyntaxError, "Second (optional) argument to %s tag must be 'parsed'" % bits[0]
     return SsiNode(bits[1], parsed)
 
+def do_include(parser, token):
+    """
+    Loads a template using standard resolution mechanisms, and renders it in the current context.     
+    """
+    bits = token.contents.split()
+    parsed = False
+    if len(bits) != 2:
+        raise template.TemplateSyntaxError, "'include' tag takes one argument: the path to the template to be included"
+    
+    path = bits[1]
+    if path[0] in ('"', "'") and path[-1] == path[0]:
+        return ConstantIncludeNode(path[1:-1]) 
+    return IncludeNode(bits[1])
+
 def do_load(parser, token):
     """
     Load a custom template tag set.
@@ -622,8 +666,8 @@
     # check at compile time that the module can be imported
     try:
         LoadNode.load_taglib(taglib)
-    except ImportError:
-        raise template.TemplateSyntaxError, "'%s' is not a valid tag library" % taglib
+    except ImportError, e:
+        raise template.TemplateSyntaxError, "'%s' is not a valid tag library, %s" % (taglib, e)
     return LoadNode(taglib)
 
 def do_now(parser, token):
@@ -762,6 +806,7 @@
 template.register_tag('ifnotequal', lambda parser, token: do_ifequal(parser, token, True))
 template.register_tag('if', do_if)
 template.register_tag('ifchanged', do_ifchanged)
+template.register_tag('include', do_include)
 template.register_tag('regroup', do_regroup)
 template.register_tag('ssi', do_ssi)
 template.register_tag('load', do_load)
