diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py
index c08ecc4..ca1fd3f 100644
--- a/django/template/defaulttags.py
+++ b/django/template/defaulttags.py
@@ -406,18 +406,18 @@ 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, varlist, namelist, nodelist):
+        self.varlist = varlist
+        self.namelist = namelist
         self.nodelist = nodelist
 
     def __repr__(self):
         return "<WithNode>"
 
     def render(self, context):
-        val = self.var.resolve(context)
         context.push()
-        context[self.name] = val
+        for name, var in zip(self.namelist, self.varlist):
+            context[name] = var.resolve(context)
         output = self.nodelist.render(context)
         context.pop()
         return output
@@ -1148,21 +1148,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`` which are evaluated sequentially.
 
     For example::
 
         {% with person.some_sql_method as total %}
             {{ total }} object{{ total|pluralize }}
         {% endwith %}
+
+        {% with value1 as var1 and value2 as var2 %}
+            {{ var1 }} ... {{ var2 }}
+        {% 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(varlist, namelist, nodelist)
 do_with = register.tag('with', do_with)
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt
index 17e6e8b..d98ac9f 100644
--- a/docs/ref/templates/builtins.txt
+++ b/docs/ref/templates/builtins.txt
@@ -799,6 +799,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 22d7f7d..57554da 100644
--- a/tests/regressiontests/templates/tests.py
+++ b/tests/regressiontests/templates/tests.py
@@ -903,9 +903,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 l.0 as first and l|slice:"1:" as rest %}{{first}}+{{rest|join:","}}{% endwith %}', {'l':['1','2','3','4']}, '1+2,3,4'),
 
             '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
