Index: django/template/base.py
===================================================================
--- django/template/base.py	(revision 14922)
+++ django/template/base.py	(working copy)
@@ -805,7 +805,7 @@
             return ''
         return _render_value_in_context(output, context)
 
-def generic_tag_compiler(params, defaults, name, node_class, parser, token):
+def generic_tag_compiler(params, defaults, name, node_class, parser, token, takes_context=False):
     "Returns a template.Node subclass."
     bits = token.split_contents()[1:]
     bmax = len(params)
@@ -817,6 +817,8 @@
         else:
             message = "%s takes between %s and %s arguments" % (name, bmin, bmax)
         raise TemplateSyntaxError(message)
+    if takes_context:  
+ 	    node_class = curry(node_class, takes_context=takes_context) 
     return node_class(bits)
 
 class Library(object):
@@ -872,22 +874,44 @@
         self.filters[getattr(func, "_decorated_function", func).__name__] = func
         return func
 
-    def simple_tag(self,func):
-        params, xx, xxx, defaults = getargspec(func)
+    def simple_tag(self, compile_function=None, takes_context=None): 
+        def dec(func): 
+            params, xx, xxx, defaults = getargspec(func) 
+            if takes_context:
+                if params[0] == 'context':
+                    params = params[1:]
+                else:
+                    raise TemplateSyntaxError("Any tag function decorated with takes_context=True must have a first argument of 'context'")
+            
+            class SimpleNode(Node):
+                def __init__(self, vars_to_resolve, takes_context=False): 
+                    self.vars_to_resolve = map(Variable, vars_to_resolve)
+                    self.takes_context = takes_context
 
-        class SimpleNode(Node):
-            def __init__(self, vars_to_resolve):
-                self.vars_to_resolve = map(Variable, vars_to_resolve)
+                def render(self, context): 
+                    resolved_vars = [var.resolve(context) for var in self.vars_to_resolve] 
+                    if self.takes_context: 
+                        func_args = [context] + resolved_vars 
+                    else: 
+                        func_args = resolved_vars 
+                    return func(*func_args) 
+            compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode, takes_context=takes_context) 
+            compile_func.__doc__ = func.__doc__ 
+            self.tag(getattr(func, "_decorated_function", func).__name__, compile_func) 
+            return func 
+         
+        if takes_context is not None: 
+            # Example: @register.simple_tag(takes_context=True) 
+            return dec 
+        elif compile_function is None: 
+            # @register.simple_tag() 
+            return dec 
+        elif callable(compile_function): 
+            # @register.simple_tag
+            return dec(compile_function) 
+        else: 
+            raise TemplateSyntaxError("Incorrect parameters for the simple_tag decorator.")
 
-            def render(self, context):
-                resolved_vars = [var.resolve(context) for var in self.vars_to_resolve]
-                return func(*resolved_vars)
-
-        compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, SimpleNode)
-        compile_func.__doc__ = func.__doc__
-        self.tag(getattr(func, "_decorated_function", func).__name__, compile_func)
-        return func
-
     def inclusion_tag(self, file_name, context_class=Context, takes_context=False):
         def dec(func):
             params, xx, xxx, defaults = getargspec(func)
Index: tests/regressiontests/templates/tests.py
===================================================================
--- tests/regressiontests/templates/tests.py	(revision 14922)
+++ tests/regressiontests/templates/tests.py	(working copy)
@@ -22,6 +22,7 @@
 from django.utils.safestring import mark_safe
 from django.utils.tzinfo import LocalTimezone
 
+from decorators import DecoratorsTest
 from context import ContextTests
 from custom import CustomTests
 from parser import ParserTests
Index: tests/regressiontests/templates/decorators.py
===================================================================
--- tests/regressiontests/templates/decorators.py	(revision 0)
+++ tests/regressiontests/templates/decorators.py	(revision 0)
@@ -0,0 +1,40 @@
+from unittest import TestCase
+from sys import version_info
+
+from django import template
+
+register = template.Library()
+
+# Very simple tag, with no parameters.
+def a_simple_tag_without_parameters(arg):
+    """Expected __doc__"""
+    return "Expected result"
+a_simple_tag_without_parameters.anything = "Expected __dict__"
+
+# Tag that takes the context.
+def a_simple_tag_with_context(context, arg):
+    """Expected __doc__"""
+    return "Expected result"
+a_simple_tag_with_context.anything = "Expected __dict__"
+
+class DecoratorsTest(TestCase):
+    def verify_decorator(self, decorator, func_name):
+        self.assertEquals(decorator.__name__, func_name)
+        self.assertEquals(decorator.__doc__, 'Expected __doc__')
+        self.assertEquals(decorator.__dict__['anything'], 'Expected __dict__')
+
+    def test_simple_tag(self):
+        # Test that the decorators preserve the decorated function's docstring, name and attributes.
+        decorator = register.simple_tag(a_simple_tag_without_parameters)
+        self.verify_decorator(decorator, 'a_simple_tag_without_parameters')
+        
+        decorator = register.simple_tag(takes_context=False)(a_simple_tag_without_parameters)
+        self.verify_decorator(decorator, 'a_simple_tag_without_parameters')
+        
+        decorator = register.simple_tag(takes_context=True)(a_simple_tag_with_context)
+        self.verify_decorator(decorator, 'a_simple_tag_with_context')
+        
+        # Test that the 'context' parameter is present when takes_context is True
+        decorator = register.simple_tag(takes_context=True)
+        self.assertRaises(template.TemplateSyntaxError, decorator, a_simple_tag_without_parameters)
+
Index: docs/howto/custom-template-tags.txt
===================================================================
--- docs/howto/custom-template-tags.txt	(revision 14922)
+++ docs/howto/custom-template-tags.txt	(working copy)
@@ -669,10 +669,25 @@
     * If the argument was a template variable, our function is passed the
       current value of the variable, not the variable itself.
 
-When your template tag does not need access to the current context, writing a
-function to work with the input values and using the ``simple_tag`` helper is
-the easiest way to create a new tag.
+If your template tag needs to access the current context, you can use the
+``takes_context`` option as follows::
 
+    # The first argument *must* be called "context" here.
+    def current_time(context, format_string):
+        timezone = context['timezone']
+        ...
+
+    register.simple_tag(takes_context=True)(current_time)
+
+You may also use the decorator syntax::
+
+    @register.simple_tag(takes_context=True)
+    def current_time(context, format_string):
+        ...
+
+For more information on how the ``takes_context`` option works, see the section
+on `inclusion tags`_.
+
 .. _howto-custom-template-tags-inclusion-tags:
 
 Inclusion tags
