diff --git a/CHANGES b/CHANGES
index 07c9ff48098d9295dd19fe45dc8ae0a65a659be7..c24d19b6715f26a9fc873335441b8634dcf3aeb1 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,12 @@
-0.5.1
+0.6.0
+- [feature/bug] Can now refer to context variables
+  within extra arguments to <%block>, <%def>, i.e.
+  <%block name="foo" cache_key="${somekey}">.
+  Filters can also be used in this way, i.e.
+  <%def name="foo()" filter="myfilter">
+  then template.render(myfilter=some_callable)
+  [ticket:180]
+
 - Template caching has been converted into a plugin
   system, whereby the usage of Beaker is just the
   default plugin.   Template and TemplateLookup
diff --git a/mako/__init__.py b/mako/__init__.py
index d3c2796222070e496d38dc30adbc9967ab93be12..2362d3a447c929ce1f6861f9fe11da8c1a4ea34f 100644
--- a/mako/__init__.py
+++ b/mako/__init__.py
@@ -5,5 +5,5 @@
 # the MIT License: http://www.opensource.org/licenses/mit-license.php
 
 
-__version__ = '0.5.1'
+__version__ = '0.6.0'
 
diff --git a/mako/codegen.py b/mako/codegen.py
index 0310964998a40e5c7dbf425bfd7d4224d9ab1553..5a7737bf61bd2c17a08cbb8d80487556462ed1a7 100644
--- a/mako/codegen.py
+++ b/mako/codegen.py
@@ -414,7 +414,7 @@ class _GenerateRenderMethod(object):
         # (this is used for the caching decorator)
         if limit is not None:
             to_write = to_write.intersection(limit)
- 
+
         if toplevel and getattr(self.compiler, 'has_ns_imports', False):
             self.printer.writeline("_import_ns = {}")
             self.compiler.has_imports = True
@@ -866,7 +866,6 @@ class _Identifiers(object):
     """tracks the status of identifier names as template code is rendered."""
  
     def __init__(self, node=None, parent=None, nested=False):
- 
         if parent is not None:
             # if we are the branch created in write_namespaces(),
             # we don't share any context from the main body().
@@ -1000,6 +999,7 @@ class _Identifiers(object):
         if node is self.node:
             for ident in node.declared_identifiers():
                 self.argument_declared.add(ident)
+
             for n in node.nodes:
                 n.accept_visitor(self)
 
@@ -1016,6 +1016,10 @@ class _Identifiers(object):
                         "Named block '%s' not allowed inside of <%%call> tag" 
                         % (node.name, ), **node.exception_kwargs)
 
+        for ident in node.undeclared_identifiers():
+            if ident != 'context' and ident not in self.declared.union(self.locally_declared):
+                self.undeclared.add(ident)
+ 
         if not node.is_anonymous:
             self._check_name_exists(self.topleveldefs, node)
             self.undeclared.add(node.funcname)
diff --git a/mako/parsetree.py b/mako/parsetree.py
index 9896dd8e6db2833395e7933a39c9f0a12f736427..98a8701054603a7395098f544dfd4d67846546a1 100644
--- a/mako/parsetree.py
+++ b/mako/parsetree.py
@@ -431,10 +431,13 @@ class DefTag(Tag):
         for c in self.function_decl.defaults:
             res += list(ast.PythonCode(c, **self.exception_kwargs).
                                     undeclared_identifiers)
-        return res + list(self.filter_args.\
+        return set(res).union(
+            self.filter_args.\
                             undeclared_identifiers.\
                             difference(filters.DEFAULT_ESCAPES.keys())
-                        )
+        ).union(
+            self.expression_undeclared_identifiers
+        )
 
 class BlockTag(Tag):
     __keyword__ = 'block'
@@ -487,7 +490,12 @@ class BlockTag(Tag):
         return self.body_decl.argnames
 
     def undeclared_identifiers(self):
-        return []
+        return (self.filter_args.\
+                            undeclared_identifiers.\
+                            difference(filters.DEFAULT_ESCAPES.keys())
+                ).union(self.expression_undeclared_identifiers)
+
+
 
 class CallTag(Tag):
     __keyword__ = 'call'
diff --git a/test/test_cache.py b/test/test_cache.py
index d898b02955c85a7dfa914b888d0080967a5536b8..1c7b42aed09278a048aeb9537def789ea8b0e219 100644
--- a/test/test_cache.py
+++ b/test/test_cache.py
@@ -139,6 +139,37 @@ class CacheTest(TemplateTest):
         ]
         assert m.kwargs == {}
 
+    def test_dynamic_key_with_context(self):
+        t = Template("""
+            <%block name="foo" cached="True" cache_key="${mykey}">
+                some block
+            </%block>
+        """)
+        m = self._install_mock_cache(t)
+        t.render(mykey="thekey")
+        t.render(mykey="thekey")
+        eq_(
+            result_lines(t.render(mykey="thekey")),
+            ["some block"]
+        )
+        eq_(m.key, "thekey")
+
+        t = Template("""
+            <%def name="foo()" cached="True" cache_key="${mykey}">
+                some def
+            </%def>
+            ${foo()}
+        """)
+        m = self._install_mock_cache(t)
+        t.render(mykey="thekey")
+        t.render(mykey="thekey")
+        eq_(
+            result_lines(t.render(mykey="thekey")),
+            ["some def"]
+        )
+        eq_(m.key, "thekey")
+
+
     def test_dynamic_key_with_funcargs(self):
         t = Template("""
             <%def name="foo(num=5)" cached="True" cache_key="foo_${str(num)}">
diff --git a/test/test_filters.py b/test/test_filters.py
index 13492d8b3e19371533f6f87011a7419d9e986d68..684705d8da25935eba2af7784827ef2c2f270983 100644
--- a/test/test_filters.py
+++ b/test/test_filters.py
@@ -3,7 +3,7 @@
 from mako.template import Template
 import unittest
 from mako import util
-from test import TemplateTest, eq_, skip_if
+from test import TemplateTest, eq_, skip_if, assert_raises
 from util import result_lines, flatten_result
 
 class FilterTest(TemplateTest):
@@ -60,7 +60,11 @@ class FilterTest(TemplateTest):
             ${foo()}
 """)
 
-        assert flatten_result(t.render(x="this is x", myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)) == "MYFILTER-> this is foo <-MYFILTER"
+        eq_(
+            flatten_result(t.render(x="this is x", 
+                        myfilter=lambda t: "MYFILTER->%s<-MYFILTER" % t)),
+            "MYFILTER-> this is foo <-MYFILTER"
+        )
 
     def test_import(self):
         t = Template("""
@@ -104,6 +108,33 @@ class FilterTest(TemplateTest):
         """)
         assert t.render().strip()  == "&lt;tag&gt;this is html&lt;/tag&gt;"
 
+    def test_block_via_context(self):
+        t = Template("""
+            <%block name="foo" filter="myfilter">
+                some text
+            </%block>
+        """)
+        def myfilter(text):
+            return "MYTEXT" + text
+        eq_(
+            result_lines(t.render(myfilter=myfilter)),
+            ["MYTEXT", "some text"]
+        )
+
+    def test_def_via_context(self):
+        t = Template("""
+            <%def name="foo()" filter="myfilter">
+                some text
+            </%def>
+            ${foo()}
+        """)
+        def myfilter(text):
+            return "MYTEXT" + text
+        eq_(
+            result_lines(t.render(myfilter=myfilter)),
+            ["MYTEXT", "some text"]
+        )
+
     def test_nflag(self):
         t = Template("""
             ${"<tag>this is html</tag>" | n}
@@ -122,7 +153,7 @@ class FilterTest(TemplateTest):
         """)
         assert t.render().strip()  == "&lt;tag&gt;this is html&lt;/tag&gt;"
  
-    def testnonexpression(self):
+    def test_non_expression(self):
         t = Template("""
         <%!
             def a(text):