Index: django/template/defaulttags.py
===================================================================
--- django/template/defaulttags.py	(revision 4758)
+++ django/template/defaulttags.py	(working copy)
@@ -354,6 +354,23 @@
             return ''
         return str(int(round(ratio)))
 
+class WithNode(Node):
+    def __init__(self, var, name, nodelist):
+        self.var = var
+        self.name = name
+        self.nodelist = nodelist
+
+    def __repr__(self):
+        return "<WithNode>"
+
+    def render(self, context):
+        val = self.var.resolve(context)
+        context.push()
+        context[self.name] = val
+        output = self.nodelist.render(context)
+        context.pop()
+        return output
+
 #@register.tag
 def comment(parser, token):
     """
@@ -967,3 +984,23 @@
     return WidthRatioNode(parser.compile_filter(this_value_expr),
                           parser.compile_filter(max_value_expr), max_width)
 widthratio = register.tag(widthratio)
+
+#@register.tag
+def do_with(parser, token):
+    """
+    Add a value to the context (inside of this block) for caching and easy
+    access. For example::
+
+        {% with person.some_sql_method as total %}
+            {{ total }} object{{ total|pluralize }}
+        {% endwith %}
+    """
+    bits = list(token.split_contents())
+    if len(bits) != 4 or bits[2] != "as":
+        raise TemplateSyntaxError, "%r expected format is 'value as name'" % tagname
+    var = parser.compile_filter(bits[1])
+    name = bits[3]
+    nodelist = parser.parse(('endwith',))
+    parser.delete_first_token()
+    return WithNode(var, name, nodelist)
+do_with = register.tag('with', do_with)
Index: docs/templates.txt
===================================================================
--- docs/templates.txt	(revision 4758)
+++ docs/templates.txt	(working copy)
@@ -878,6 +878,22 @@
 above example will be 88 pixels wide (because 175/200 = .875; .875 * 100 = 87.5
 which is rounded up to 88).
 
+with
+~~~~
+
+**New in Django development version**
+
+Useful for caching a method which will be used more than once.
+
+For example::
+
+    {% with person.some_sql_method as total %}
+        {{ total }} person object{{ total|pluralize }}
+    {% endwith %}
+
+The populated variable (in the example above, ``total``) is only available
+inside of ``{% with %}`` block.
+
 Built-in filter reference
 -------------------------
 
Index: tests/regressiontests/templates/tests.py
===================================================================
--- tests/regressiontests/templates/tests.py	(revision 4758)
+++ tests/regressiontests/templates/tests.py	(working copy)
@@ -650,6 +650,10 @@
             'widthratio09': ('{% widthratio a b %}', {'a':50,'b':100}, template.TemplateSyntaxError),
             'widthratio10': ('{% widthratio a b 100.0 %}', {'a':50,'b':100}, template.TemplateSyntaxError),
 
+            ### 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')),
+
             ### NOW TAG ########################################################
             # Simple case
             'now01' : ('{% now "j n Y"%}', {}, str(datetime.now().day) + ' ' + str(datetime.now().month) + ' ' + str(datetime.now().year)),
