diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index 318ae5f..b595a54 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -410,18 +410,19 @@ class WidthRatioNode(Node):
         return str(int(round(ratio)))
 
 class WithNode(Node):
-    def __init__(self, var, name, nodelist):
-        self.var = var
-        self.name = name
+    def __init__(self, names, vars, nodelist):
+        self.names = names
+        self.vars = vars
         self.nodelist = nodelist
 
     def __repr__(self):
         return "<WithNode>"
 
     def render(self, context):
-        val = self.var.resolve(context)
+        values = [var.resolve(context) for var in self.vars]
         context.push()
-        context[self.name] = val
+        for name, value in zip(self.names, values):
+            context[name] = value
         output = self.nodelist.render(context)
         context.pop()
         return output
@@ -1191,21 +1192,36 @@ widthratio = register.tag(widthratio)
 def do_with(parser, token):
     """
     Adds a value to the context (inside of this block) for caching and easy
-    access.
+    access. You bind a value to a new name using ``as``. You can chain multiple
+    bindings with ``and``. This works simillar to Python assignment.
 
     For example::
 
         {% with person.some_sql_method as total %}
             {{ total }} object{{ total|pluralize }}
         {% endwith %}
+
+        {% with 0 as z and x|add:5 as y and y as x %}
+            ({{ x }}, {{ y }}, {{ z }})
+        {% endwith %}
     """
     bits = list(token.split_contents())
-    if len(bits) != 4 or bits[2] != "as":
-        raise TemplateSyntaxError("%r expected format is 'value as name'" %
-                                  bits[0])
-    var = parser.compile_filter(bits[1])
-    name = bits[3]
+    try:
+        if len(bits) % 4:
+            raise TemplateSyntaxError()
+        for b in bits[2::4]:
+            if b != 'as':
+                raise TemplateSyntaxError()
+        for b in bits[4::4]:
+            if b != 'and':
+                raise TemplateSyntaxError()
+    except TemplateSyntaxError:
+        raise TemplateSyntaxError("'%s' statements should use the format "
+                                  "'with value as name [and value as name]...'"
+                                  ": %s" % (bits[0], token.contents))
+    varlist = [parser.compile_filter(b) for b in bits[1::4]]
+    namelist = bits[3::4]
     nodelist = parser.parse(('endwith',))
     parser.delete_first_token()
-    return WithNode(var, name, nodelist)
+    return WithNode(namelist, varlist, nodelist)
 do_with = register.tag('with', do_with)
diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py
index b8bc741..8a4edd9 100644
--- a/django/template/loader_tags.py
+++ b/django/template/loader_tags.py
@@ -1,6 +1,7 @@
 from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
 from django.template import Library, Node, TextNode
 from django.template.loader import get_template
+from django.template.defaulttags import WithNode, kwarg_re
 from django.conf import settings
 from django.utils.safestring import mark_safe
 
@@ -201,19 +202,44 @@ def do_extends(parser, token):
 
 def do_include(parser, token):
     """
-    Loads a template and renders it with the current context.
+    Loads a template and renders it with the current context. You can pass
+    additional context using keyword arguments.
 
     Example::
 
         {% include "foo/some_include" %}
+        {% include "foo/some_include" with bar="BAZZ!" %}
+
     """
     bits = token.split_contents()
-    if len(bits) != 2:
-        raise TemplateSyntaxError("%r tag takes one argument: the name of the template to be included" % bits[0])
+    if len(bits) < 2:
+        raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included." % bits[0])
+    namelist, varlist = [], []
+    if len(bits) > 2:
+        if bits[2] == 'with':
+            for bit in bits[3:]:
+                match = kwarg_re.match(bit)
+                if not match:
+                    raise TemplateSyntaxError("Malformed arguments to %r tag." % bits[0])
+                name, value = match.groups()
+                if not name:
+                    raise TemplateSyntaxError('''"with" part of %r tag accepts only keyword arguments.''' % bits[0])
+                namelist.append(name)
+                varlist.append(parser.compile_filter(value))
+            if not namelist:
+                raise TemplateSyntaxError('''"with" in %r tag needs at least one keyword argument.''' % bits[0])
+        else:
+            raise TemplateSyntaxError('''Invalid option %r for %r tag.''' % (bits[2], bits[0]))
     path = bits[1]
     if path[0] in ('"', "'") and path[-1] == path[0]:
-        return ConstantIncludeNode(path[1:-1])
-    return IncludeNode(bits[1])
+        node = ConstantIncludeNode(path[1:-1])
+    else:
+        node = IncludeNode(bits[1])
+    if namelist:
+        nodelist = parser.create_nodelist()
+        parser.extend_nodelist(nodelist, node, token)
+        node = WithNode(namelist, varlist, nodelist)
+    return node
 
 register.tag('block', do_block)
 register.tag('extends', do_extends)
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 002aa3f..7a08994 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -1036,6 +1036,12 @@ For example::
 The populated variable (in the example above, ``total``) is only available
 between the ``{% with %}`` and ``{% endwith %}`` tags.
 
+Multiple variables can be cached by using the word ``"and"`` as a delimiter::
+
+    {% with items.0 as first and items|slice:"1:" as rest %}
+        {{ first }} comes first and {{ rest|join:", " }} follow.
+    {% endwith %}
+
 .. _ref-templates-builtins-filters:
 
 Built-in filter reference
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
index 5902e8d..1290c86 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -911,6 +911,15 @@ class Templates(unittest.TestCase):
             'include 05': ('template with a space', {}, 'template with a space'),
             'include06': ('{% include "include 05"%}', {}, 'template with a space'),
 
+            # extra inline context
+            'include07': ('{% include "basic-syntax02" with headline="Inline" %}', {'headline': 'Included'}, 'Inline'),
+            'include08': ('{{ first }}--{% include "basic-syntax03" with first=second|lower|upper second=first|upper %}--{{ second }}', {'first': 'Ul', 'second': 'lU'}, 'Ul--LU --- UL--lU'),
+
+            'include-error01': ('{% include "basic-syntax01" with %}', {}, template.TemplateSyntaxError),
+            'include-error02': ('{% include "basic-syntax01" with "no key" %}', {}, template.TemplateSyntaxError),
+            'include-error03': ('{% include "basic-syntax01" with dotted.arg="error" %}', {}, template.TemplateSyntaxError),
+            'include-error04': ('{% include "basic-syntax01" something_random %}', {}, template.TemplateSyntaxError),
+
             ### NAMED ENDBLOCKS #######################################################
 
             # Basic test
@@ -1197,9 +1206,14 @@ class Templates(unittest.TestCase):
             ### WITH TAG ########################################################
             'with01': ('{% with dict.key as key %}{{ key }}{% endwith %}', {'dict': {'key':50}}, '50'),
             'with02': ('{{ key }}{% with dict.key as key %}{{ key }}-{{ dict.key }}-{{ key }}{% endwith %}{{ key }}', {'dict': {'key':50}}, ('50-50-50', 'INVALID50-50-50INVALID')),
+            'with03': ('{% with dict.k1 as k1 and dict.k2 as k2 %}{{ k1 }}+{{ k2 }}{% endwith %}', {'dict': {'k1':3, 'k2':4}}, '3+4'),
+            'with04': ('{% with 42 as z and x|add:5 as y and y as x %}({{ x }},{{ y }},{{ z }}){% endwith %}', {'x': 13, 'y': -5}, '(-5,18,42)'),
 
             'with-error01': ('{% with dict.key xx key %}{{ key }}{% endwith %}', {'dict': {'key':50}}, template.TemplateSyntaxError),
             'with-error02': ('{% with dict.key as %}{{ key }}{% endwith %}', {'dict': {'key':50}}, template.TemplateSyntaxError),
+            'with-error03': ('{% with dict.k1 as k1 and dict.k2 %}{{ key }}{% endwith %}', {'dict': {'k1':3, 'k2':4}}, template.TemplateSyntaxError),
+            'with-error04': ('{% with dict.k1 equals k1 %}{{ key }}{% endwith %}', {'dict': {'k1':3, 'k2':4}}, template.TemplateSyntaxError),
+            'with-error05': ('{% with dict.k1 as k1, dict.k2 as k2 %}{{ key }}{% endwith %}', {'dict': {'k1':3, 'k2':4}}, template.TemplateSyntaxError),
 
             ### NOW TAG ########################################################
             # Simple case
