diff --git a/README.rst b/README.rst
index 701e6b272bdbf550eda03cbd7b7ffcf275cb7dd3..b65a8ded8366ba5c42f68dff3c24382cc676c0ab 100644
--- a/README.rst
+++ b/README.rst
@@ -3,8 +3,8 @@ Template
 
 A CLI tool for generating files from Jinja2 templates and environment variables.
 
-Example
--------
+Examples
+--------
 
 .. code:: shell
 
@@ -26,7 +26,32 @@ Example
     $ cat username
     John
 
-TODO
-----
 
-- Complex data types (process environment variables, Jinja filters).
+Jinja filters
+-------------
+
+The following Jinja filters were added:
+
+- to_yaml: Convert to yaml.
+- from_yaml: Convert from yaml.
+- to_json: Convert to json.
+- from_json: Convert from json.
+- pprint: Pretty print variable.
+- combine: Combine 2 dictionaries.
+
+Example usage can be seen in :code:`tests.sh`.
+
+
+License
+-------
+
+This software is licensed under the AGPL 3+ license (see the :code:`LICENSE.txt`
+file).
+
+Author
+------
+
+Nimrod Adar, `contact me <nimrod@shore.co.il>`_ or visit my `website
+<https://www.shore.co.il/>`_. Patches are welcome via `git send-email
+<http://git-scm.com/book/en/v2/Git-Commands-Email>`_. The repository is located
+at: https://www.shore.co.il/git/.
diff --git a/VERSION b/VERSION
index 341cf11faf9a29504168de4e54beaad182c5adc5..9325c3ccda9850bb6e102aef07d314210f5c9f41 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.0
\ No newline at end of file
+0.3.0
\ No newline at end of file
diff --git a/setup.py b/setup.py
index 7a70257cf977beb39c3fc8f7942c7fef45b59d31..68c110afa8b5485f2ca86cd5ae5c449e9f3fddd2 100644
--- a/setup.py
+++ b/setup.py
@@ -21,7 +21,7 @@ setup(
     ],
     keywords='config configuration jinja template environment',
     packages=find_packages(),
-    install_requires=['Jinja2'],
+    install_requires=['Jinja2', 'PyYAML'],
     extras_require={
         'dev': ['tox'], },
     entry_points={
diff --git a/template/__init__.py b/template/__init__.py
index e34e3eb41eb45a20eb051115038e28379ef16a7f..f476a5cdb163df62c18a565e4ed83f15fff5331d 100755
--- a/template/__init__.py
+++ b/template/__init__.py
@@ -3,15 +3,20 @@
 
 from __future__ import (absolute_import, division,
                         print_function, unicode_literals)
-from jinja2 import Template
+from jinja2 import Environment
 from os import environ
 from sys import stdin, stdout
 import argparse
 from argparse import ArgumentParser
+import template.filters
 
 
-def render(template):
-    t = Template(template)
+def render(template_string):
+    env = Environment()
+    # Add all functions in template.filters as Jinja filters.
+    for tf in filter(lambda x: not x.startswith('_'), dir(template.filters)):
+        env.filters[tf] = template.filters.__getattribute__(tf)
+    t = env.from_string(template_string)
     return t.render(environ)
 
 
diff --git a/template/filters.py b/template/filters.py
index 355b82095561c684fffe90eb1312768855dad490..4fb5250089437896ba1ce20d3b9361c7fda780a6 100644
--- a/template/filters.py
+++ b/template/filters.py
@@ -2,24 +2,31 @@
 
 
 def to_yaml(value):
-    raise NotImplemented
+    from yaml import safe_dump
+    return safe_dump(value)
 
 
 def to_json(value):
-    raise NotImplemented
+    from json import dumps
+    return dumps(value)
 
 
 def from_json(value):
-    raise NotImplemented
+    from json import loads
+    return loads(value)
 
 
 def from_yaml(value):
-    raise NotImplemented
+    from yaml import safe_load
+    return safe_load(value)
 
 
 def pprint(value):
-    raise NotImplemented
+    from pprint import pformat
+    return pformat(value)
 
 
 def combine(lefthand, righthand):
-    raise NotImplemented
+    combined = lefthand.copy()
+    combined.update(righthand)
+    return combined
diff --git a/tests.sh b/tests.sh
index 474723022216230dad34169f89c8c1e11a89c8a7..256671433eedfa85fbd984211895af92d57aa2ad 100755
--- a/tests.sh
+++ b/tests.sh
@@ -1,10 +1,40 @@
 #!/bin/sh -e
 
-export name='John'
-test "$(echo 'Hello {{ name if name is defined else 'world' }}.' | template)" = "Hello John."
 export infile="$(mktemp)"
 export outfile="$(mktemp)"
+
+echo Basic test.
+export name='John'
+test "$(echo 'Hello {{ name if name is defined else 'world' }}.' | template)" = "Hello John."
+
+echo Testing arguments and reading/ writing to file.
 echo '{{ USER }}' > "$infile"
 template --output "$outfile" "$infile"
 test "$(cat $outfile)" = "$USER"
+
+echo Testing JSON parsing.
+export json='{"a": 1, "b": 2}'
+echo '{{ (json|from_json)["a"] }}' > "$infile"
+test "$(template $infile)" = "1"
+
+echo Testing JSON output.
+echo '{{ [1, 1+2, 3] | to_json }}' > "$infile"
+test "$(template $infile)" = '[1, 3, 3]'
+
+echo Testing YAML parsing.
+export yaml='a: 1
+b: 2'
+echo '{{ (yaml|from_yaml)["a"] }}' > "$infile"
+test "$(template $infile)" = "1"
+
+echo Testing YAML output.
+echo '{{ [1, 1+2, 3] | to_yaml }}' > "$infile"
+test "$(template $infile)" = '[1, 3, 3]'
+
+echo Testing pprint.
+echo '{{ [1, ] + [2, ] }}' > "$infile"
+test "$(template $infile)" = "[1, 2]"
+
+echo Testing combining dictionaries.
+
 rm "$infile" "$outfile"