diff --git a/CHANGES b/CHANGES
index de2a311a39bc6359379e774ec537e4edca368b84..04ee958105b053cd32e1a702a40d2f0466402a42 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,8 @@
 0.1.1
 - AST parsing fixes: fixed TryExcept identifier parsing
+- added "encoding()" filter; this allows a filter expression to specify the encoding and error
+handling for the given expression.
+usage is like:  ${data | encoding('utf-8', errors='strict')}
 
 0.1.0
 
diff --git a/lib/mako/codegen.py b/lib/mako/codegen.py
index f4f5350fe70bf31897f606512d0556a66c0d0a44..a0bc70ac1008b53d82cc8ab77dfef83aa5d6993e 100644
--- a/lib/mako/codegen.py
+++ b/lib/mako/codegen.py
@@ -377,7 +377,14 @@ class _GenerateRenderMethod(object):
         if self.compiler.pagetag:
             args += self.compiler.pagetag.filter_args.args
         for e in args:
-            e = d.get(e, e)
+            # if filter given as a function, get just the identifier portion
+            m = re.match(r'(.+?)(\(.*\))', e)
+            if m:
+                (ident, fargs) = m.group(1,2)
+                f = d.get(ident, ident)
+                e = f + fargs
+            else:
+                e = d.get(e, e)
             target = "%s(%s)" % (e, target)
         return target
         
diff --git a/lib/mako/filters.py b/lib/mako/filters.py
index d4a7626d47a67be3b7e851b76397ca2706eb366a..b6fdb8e7c17b5504a82ce38788aa75d739c95eff 100644
--- a/lib/mako/filters.py
+++ b/lib/mako/filters.py
@@ -38,7 +38,9 @@ def url_unescape(string):
 def trim(string):
     return string.strip()
     
-
+def encoding(encoding, errors='strict'):
+    return lambda x:unicode(x, encoding=encoding, errors=errors)
+    
 _ASCII_re = re.compile(r'\A[\x00-\x7f]*\Z')
 
 def is_ascii_str(text):
@@ -148,6 +150,7 @@ DEFAULT_ESCAPES = {
     'u':url_escape,
     'trim':trim,
     'entity':html_entities_escape,
+    'encoding':encoding
 }
     
 
diff --git a/test/def.py b/test/def.py
index b9aad1bc686538109b94c6637f1c12c9c3ff7841..896a1d80a307e490b4cc61b9e4bbb32d94d3e02b 100644
--- a/test/def.py
+++ b/test/def.py
@@ -337,7 +337,7 @@ class ScopeTest(unittest.TestCase):
         """)
         
         # test via inheritance
-        print l.get_template("main").code
+        #print l.get_template("main").code
         assert result_lines(l.get_template("main").render()) == [
             "this is main. x is 12",
             "this is a, x is 12"
diff --git a/test/filters.py b/test/filters.py
index 8e8c23773c462ff70ec976c15d4861456c8208d3..0e77c1c73af4bc6aeaea543b4fda6cbad7da69d7 100644
--- a/test/filters.py
+++ b/test/filters.py
@@ -1,3 +1,5 @@
+# -*- coding: utf-8 -*-
+
 from mako.template import Template
 import unittest
 from util import result_lines, flatten_result
@@ -18,6 +20,14 @@ class FilterTest(unittest.TestCase):
             return lambda x: "MYFILTER->%s<-%s" % (x, y)
         assert flatten_result(t.render(x="this is x", myfilter=myfilter, y="this is y")) == "MYFILTER->this is x<-this is y"
 
+    def test_builtin_func(self):
+        t = Template("""
+            ${x | encoding('utf-8')}
+        """)
+        udata = u"""Alors vous imaginez ma surprise, au lever du jour, quand une drôle de petit voix m’a réveillé. Elle disait: « S’il vous plaît… dessine-moi un mouton! »"""
+        utf8data = udata.encode('utf-8')
+        assert flatten_result(t.render_unicode(x=utf8data)) == udata
+        
     def test_def(self):
         t = Template("""
             <%def name="foo()" filter="myfilter">
diff --git a/test_htdocs/read_unicode.html b/test_htdocs/read_unicode.html
index 91261b59538d9c061d83e1a7b0c1463ac375aac0..aeb728190347fdb181f6649cf02f6ac652e96937 100644
--- a/test_htdocs/read_unicode.html
+++ b/test_htdocs/read_unicode.html
@@ -3,8 +3,8 @@ try:
     file_content = open(path)
 except:
     raise "Should never execute here"
-doc_content = ''.join(file_content.readlines()).decode('utf-8')
+doc_content = ''.join(file_content.readlines())
 file_content.close()
 %>
 
-${doc_content}
+${doc_content | encoding('utf-8')}