Commits

Anonymous committed 7520ee3

Couldn’t make my mind up about what to call the README.

  • Participants
  • Parent commits 336d781

Comments (0)

Files changed (2)

File README.markdown

-# DjanJinja v0.5
-
-DjanJinja: the sound you make when you've got peanut butter stuck to the roof of
-your mouth. Incidentally, it also happens to be the name of a new re-usable
-Django app. This one, in fact.
-
-DjanJinja exists to help you leverage the power of
-[Jinja2](http://jinja.pocoo.org/2/) templates in your Django projects. It's
-simple to get started.
-
-## Installing and Using DjanJinja
-
-### Installing DjanJinja
-
-1. Install DjanJinja using `easy_install djanjinja`, `pip install djanjinja`, or
-   by grabbing a copy of the Mercurial repo and running `python setup.py
-   install`.
-2. Add `'djanjinja'` to your `INSTALLED_APPS` list.
-3. (Optionally) add `'djanjinja.middleware.RequestContextMiddleware'` to your
-   `MIDDLEWARE_CLASSES` list.
-
-It’s assumed that you have fairly recent versions of Jinja2 and Django
-installed. The author recommends the *most recent* stable versions of each,
-which should be installable via PyPI (i.e. a simple `easy_install` or `pip
-install`). A lot of people have their own ways of installing things, so the
-author hasn’t put any explicit requirements in the `setup.py` file. DjanJinja
-just expects to find `jinja2` and `django` on the import path.
-
-### Using DjanJinja
-
-* Instead of using `django.shortcuts.render_to_response`, use one of the
-  Jinja2-based functions provided.
-* Instead of using the Django loaders to load templates, get them from the
-  Jinja2 environment created for you by DjanJinja.
-* Instead of using Django’s provided generic views, use those contained within
-  `djanjinja.generic` (at the moment the only one is `direct_to_template()`).
-
-## Bundles
-
-A Jinja2 environment can contain additional filters, tests and global variables
-which will be available in all templates rendered through that environment.
-Since individual Django apps will have their own set of things to add to the
-environment, DjanJinja adds the concept of ‘bundles’; small objects containing
-some global variables, filters and tests. Each app may define any number of
-these bundles which can then be loaded as required.
-
-### Defining Bundles
-
-It’s relatively easy to define a bundle; an example is shown below:
-    
-    from djanjinja.loader import Bundle
-    
-    foo = Bundle()
-    foo.globals['myvar'] = 12345
-    
-    @foo.envfilter
-    def myenvfilter(environment, value):
-        pass # do something here...
-    
-    @foo.ctxfunction
-    def mycontextfunction(context, value):
-        pass # do something here...
-
-Here we define a bundle called `foo`, with a global variable of `myvar`
-containing the value `12345`, an environment filter and a context function (for
-more information on each of these please consult the Jinja2 documentation). The
-`Bundle` class also supplies these handy decorators (the full list can be found
-as `djanjinja.loader.Bundle.TYPES`) to define various components.
-
-DjanJinja expects to find bundles in a `bundles` submodule of your Django app.
-You can lay things out in one of two ways:
-    
-    * Add a file called `bundles.py` to your app, and within this define
-      multiple `Bundle` instances.
-    * Add a package called `bundles` to your app (i.e. a `bundles` directory
-      containing an empty file called `__init__.py`), and within this define
-      submodules for each of your bundles. Each submodule should have a
-      top-level `bundle` variable which is an instance of the `Bundle` class.
-
-You can actually mix and match these; you could add some bundle instances to the
-`bundles/__init__.py` file with different names, in addition to having the
-submodules. These are loaded lazily, so DjanJinja sees no real difference. It
-doesn’t scour the `bundles` module for definitions, it just loads what you ask
-it to.
-
-### Addressing Bundles
-
-In order to use the functions, filters and tests defined in a bundle, you first
-have to load it into the environment. Bundles are specified in two parts: the
-‘app label’ and the ‘bundle name’. The app label is simply the name of the app
-which contains it. For example, it may be `django.contrib.auth`, or simply
-`auth`, since you may just give the last part of the full name and DjanJinja
-will figure it out from looking at the `INSTALLED_APPS` setting.
-
-If a bundle is defined within a `bundles.py` or a `bundles/__init__.py` file,
-then the bundle name will be the name in the module with which it was defined.
-For example:
-    
-    # in the file `myapp/bundles.py`
-    foo = Bundle()
-    foo.globals['myvar'] = 12345
-
-In this case, the app label will be `myapp`, and the bundle name will be `foo`.
-If the bundles are defined in submodules, then the bundle name will be the name
-of the submodule.
-
-### Loading Bundles
-
-In order to load any bundles into the Jinja2 environment, you need to specify a
-`DJANJINJA_BUNDLES` setting in your `settings.py` file. This is a list or tuple
-of bundle specifiers in an `'app_label.bundle_name'` format. For example:
-
-    DJANJINJA_BUNDLES = (
-        'djanjinja.cache',
-        'djanjinja.humanize',
-        'djanjinja.site',
-    )
-
-You can also add bundles to the environment programmatically. This is useful
-when:
-
-* Your app needs to do some initial setup before a bundle is loaded.
-* Your app relies on a particular bundle being present in the environment
-  anyway, and you don’t want the user to have to add the bundle to
-  `DJANJINJA_BUNDLES` manually.
-* Your app needs to load bundles dynamically.
-
-You can load a bundle into an environment like this:
-
-    import djanjinja
-    env = djanjinja.get_env()
-    env.load('app_label', 'bundle_name', reload=False)
-
-This will load the bundle into the environment, passing through if it’s already
-loaded. If you specify `reload=True`, you can make it reload a bundle even if
-it’s been loaded.
-
-You should put this code somewhere where it will get executed when you want it
-to. If you want it to be executed immediately, as Django starts up, put it in
-`myapp/__init__.py`.
-
-### Caveats and Limitations
-
-Jinja2 does not yet support scoped filters and tests; as a result of this, the
-contents of bundles will be loaded into the global environment. It is important
-to make sure that definitions in your bundle do not override those in another
-bundle. This is especially important with threaded web applications, as multiple
-bundles overriding one another could cause unpredictable behavior in the
-templates.
-
-### Included Bundles
-
-DjanJinja provides three bundles already which either replace Django
-counterparts or add some useful functionality to your Jinja2 templates:
-    
-    * `djanjinja.cache`: Loading this bundle will add a global `cache` object to
-      the environment; this is the Django cache, and allows you to carry out
-      caching operations from within your templates (such as `cache.get(key)`,
-      et cetera).
-    * `djanjinja.humanize`: This will add all of the filters contained within
-      the `django.contrib.humanize` app; consult the official Django docs for
-      more information on the filters provided.
-    * `djanjinja.site`: This will add two functions to the global environment:
-      `url`, and `setting`. The former acts like Django’s template tag, by
-      reversing URLconf names and views into URLs, but because Jinja2 supports a
-      richer syntax, it can be used via `{{ url(name, *args, **kwargs) }}`
-      instead. `setting` attempts to resolve a setting name into a value,
-      returning an optional default instead (i.e. `setting('MEDIA_URL',
-      '/media')`).
-
-## Extensions
-
-Jinja2 supports the concept of *environment extensions*; these are non-trivial
-plugins which enhance the Jinja2 templating engine itself. By default, the
-environment is configured with the `do` statement and the loop controls (i.e.
-`break` and `continue`), but if you want to add extensions to the environment
-then you can do so with the `JINJA_EXTENSIONS` setting. Just add this to your
-`settings.py` file:
-    
-    JINJA_EXTENSIONS = (
-        'jinja2.ext.i18n', # i18n Extension
-        ...
-    )
-
-For all the extensions you wish to load. This will be passed in directly to the
-`jinja2.Environment` constructor.
-
-If you have set `USE_I18N = True` in your settings file, then DjanJinja will
-automatically initialize the i18n machinery for the Jinja2 environment, loading
-your Django translations during the bootstrapping process. For more information
-on how to use the Jinja2 i18n extension, please consult the Jinja2
-documentation.
-
-### Cache
-
-DjanJinja also provides an extension for fragment caching using the Django cache
-system. The code for this borrows heavily from the example in the Jinja2
-documentation, but with a few extras thrown in. You can use the extension like
-this:
-    
-    {% cache (parameter1, param2, param3), timeout %}
-        ...
-    {% endcache %}
-
-The tuple of parameters is used to generate the cache key for this fragment. You
-can place any object here, so long as it is suitable for serialization by the
-standard library `marshal` module. The cache key for the fragment is generated
-by marshaling the parameters, hashing them and then using the digest with a
-prefix as the key. This allows you to specify cached fragments which vary
-depending on multiple variables. The timeout is optional, and should be given in
-seconds.
-
-## Shortcut Functions
-
-DjanJinja provides you with two shortcut functions for rendering templates,
-`render_to_response` and `render_to_string`. These are very similar to those
-provided by Django in the `django.shortcuts` module, except they use Jinja2
-instead of the Django templating system. To use them from your views, just do
-`from djanjinja.views import render_to_response, render_to_string` at the top of
-your views module.
-
-## `RequestContext`
-
-One of Django's most useful features is the `RequestContext` class, which allows
-you to specify several context processors which each add some information to the
-context before templates are rendered. Luckily, this feature is
-template-agnostic, and is therefore fully compatible with DjanJinja.
-
-However, DjanJinja also provides you with some very helpful shortcuts for using
-request contexts. Usually, without DjanJinja, you would use them like this:
-    
-    from django.shortcuts import render_to_response
-    from django.template import RequestContext
-    
-    def myview(request):
-        context = {'foo': bar, 'spam': eggs}
-        return render_to_response('template_name.html',
-            context, context_instance=RequestContext())
-
-To be honest,this doesn't look very much like a 'shortcut' at all. For this
-reason, DjanJinja contains a subclass of `RequestContext` specialised for
-Jinja2, which is used like this:
-
-    from djanjinja.views import RequestContext
-    
-    def myview(request):
-        context = RequestContext(request, {'foo': bar, 'spam': eggs})
-        return context.render_response('template_name.html')
-
-This code is much more concise, but loses none of the flexibility of the
-previous example. The main changes made are the addition of `render_response`
-and `render_string` methods to the context object itself. This is highly
-specialised to rendering Jinja2 templates, so it may not be a very reusable
-approach (indeed, other code which does not use Jinja2 will need to use the full
-Django syntax), but it works for the problem domain it was designed for.
-
-## Middleware
-
-One important thing to note from before is that each time a `RequestContext`
-instance is constructed, it is necessary to explicitly pass the request. In
-object-oriented programming, and Python expecially, when we have functions to
-which we must always pass an object of a certain type, it makes sense to make
-that function a *method* of the type. When that function is not, in fact, a
-function, but a constructor, this seems more difficult. However, thanks to a
-feature of Python known as metaprogramming, we can do this very easily. Because
-it's not exactly obvious how to do so, DjanJinja includes a special piece of
-middleware which can help make your code a lot shorter yet *still* retain all
-the functionality and flexibility of the previous two examples.
-
-To use this middleware, simply add
-`'djanjinja.middleware.RequestContextMiddleware'` to your `MIDDLEWARE_CLASSES`
-list in the settings module of your project. Then, you can write view code like
-this:
-
-    def myview(request):
-        return request.Context({'foo': bar, 'spam': eggs}).render_response(
-            'template_name.html')
-
-As you can see, we've greatly reduced the verbosity of the previous code, but
-it's still obvious what this code does. The middleware attaches a `Context`
-attribute to each request object. This attribute is in fact a fully-fledged
-Python class, which may itself be subclassed and modified later on. When
-constructed, it behaves almost exactly the same as the usual `RequestContext`,
-only it uses the request object to which it has been attached, so you don't have
-to pass it in to the constructor every time.
-
-## Template Loading
-
-DjanJinja hooks directly into the Django template loader machinery to load
-templates. This means you can mix Jinja2 templates freely with Django templates,
-in your `TEMPLATE_DIRS` and your applications, and render each type
-independently and seamlessly. If you want more information on how it actually
-works, please consult the `djanjinja/environment.py` file.
-
-## License
-
-This software is licensed under the following MIT-style license:
-    
-    Copyright (c) 2009 Zachary Voase
-
-    Permission is hereby granted, free of charge, to any person
-    obtaining a copy of this software and associated documentation
-    files (the "Software"), to deal in the Software without
-    restriction, including without limitation the rights to use,
-    copy, modify, merge, publish, distribute, sublicense, and/or sell
-    copies of the Software, and to permit persons to whom the
-    Software is furnished to do so, subject to the following
-    conditions:
-
-    The above copyright notice and this permission notice shall be
-    included in all copies or substantial portions of the Software.
-
-    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-    OTHER DEALINGS IN THE SOFTWARE.
-
-## Author
-
-Zachary Voase can be found on `Twitter <http://twitter.com/zacharyvoase>`_.

File README.mdown

+# DjanJinja v0.5
+
+DjanJinja: the sound you make when you've got peanut butter stuck to the roof of
+your mouth. Incidentally, it also happens to be the name of a new re-usable
+Django app. This one, in fact.
+
+DjanJinja exists to help you leverage the power of
+[Jinja2](http://jinja.pocoo.org/2/) templates in your Django projects. It's
+simple to get started.
+
+## Installing and Using DjanJinja
+
+### Installing DjanJinja
+
+1. Install DjanJinja using `easy_install djanjinja`, `pip install djanjinja`, or
+   by grabbing a copy of the Mercurial repo and running `python setup.py
+   install`.
+2. Add `'djanjinja'` to your `INSTALLED_APPS` list.
+3. (Optionally) add `'djanjinja.middleware.RequestContextMiddleware'` to your
+   `MIDDLEWARE_CLASSES` list.
+
+It’s assumed that you have fairly recent versions of Jinja2 and Django
+installed. The author recommends the *most recent* stable versions of each,
+which should be installable via PyPI (i.e. a simple `easy_install` or `pip
+install`). A lot of people have their own ways of installing things, so the
+author hasn’t put any explicit requirements in the `setup.py` file. DjanJinja
+just expects to find `jinja2` and `django` on the import path.
+
+### Using DjanJinja
+
+* Instead of using `django.shortcuts.render_to_response`, use one of the
+  Jinja2-based functions provided.
+* Instead of using the Django loaders to load templates, get them from the
+  Jinja2 environment created for you by DjanJinja.
+* Instead of using Django’s provided generic views, use those contained within
+  `djanjinja.generic` (at the moment the only one is `direct_to_template()`).
+
+## Bundles
+
+A Jinja2 environment can contain additional filters, tests and global variables
+which will be available in all templates rendered through that environment.
+Since individual Django apps will have their own set of things to add to the
+environment, DjanJinja adds the concept of ‘bundles’; small objects containing
+some global variables, filters and tests. Each app may define any number of
+these bundles which can then be loaded as required.
+
+### Defining Bundles
+
+It’s relatively easy to define a bundle; an example is shown below:
+    
+    from djanjinja.loader import Bundle
+    
+    foo = Bundle()
+    foo.globals['myvar'] = 12345
+    
+    @foo.envfilter
+    def myenvfilter(environment, value):
+        pass # do something here...
+    
+    @foo.ctxfunction
+    def mycontextfunction(context, value):
+        pass # do something here...
+
+Here we define a bundle called `foo`, with a global variable of `myvar`
+containing the value `12345`, an environment filter and a context function (for
+more information on each of these please consult the Jinja2 documentation). The
+`Bundle` class also supplies these handy decorators (the full list can be found
+as `djanjinja.loader.Bundle.TYPES`) to define various components.
+
+DjanJinja expects to find bundles in a `bundles` submodule of your Django app.
+You can lay things out in one of two ways:
+    
+    * Add a file called `bundles.py` to your app, and within this define
+      multiple `Bundle` instances.
+    * Add a package called `bundles` to your app (i.e. a `bundles` directory
+      containing an empty file called `__init__.py`), and within this define
+      submodules for each of your bundles. Each submodule should have a
+      top-level `bundle` variable which is an instance of the `Bundle` class.
+
+You can actually mix and match these; you could add some bundle instances to the
+`bundles/__init__.py` file with different names, in addition to having the
+submodules. These are loaded lazily, so DjanJinja sees no real difference. It
+doesn’t scour the `bundles` module for definitions, it just loads what you ask
+it to.
+
+### Addressing Bundles
+
+In order to use the functions, filters and tests defined in a bundle, you first
+have to load it into the environment. Bundles are specified in two parts: the
+‘app label’ and the ‘bundle name’. The app label is simply the name of the app
+which contains it. For example, it may be `django.contrib.auth`, or simply
+`auth`, since you may just give the last part of the full name and DjanJinja
+will figure it out from looking at the `INSTALLED_APPS` setting.
+
+If a bundle is defined within a `bundles.py` or a `bundles/__init__.py` file,
+then the bundle name will be the name in the module with which it was defined.
+For example:
+    
+    # in the file `myapp/bundles.py`
+    foo = Bundle()
+    foo.globals['myvar'] = 12345
+
+In this case, the app label will be `myapp`, and the bundle name will be `foo`.
+If the bundles are defined in submodules, then the bundle name will be the name
+of the submodule.
+
+### Loading Bundles
+
+In order to load any bundles into the Jinja2 environment, you need to specify a
+`DJANJINJA_BUNDLES` setting in your `settings.py` file. This is a list or tuple
+of bundle specifiers in an `'app_label.bundle_name'` format. For example:
+
+    DJANJINJA_BUNDLES = (
+        'djanjinja.cache',
+        'djanjinja.humanize',
+        'djanjinja.site',
+    )
+
+You can also add bundles to the environment programmatically. This is useful
+when:
+
+* Your app needs to do some initial setup before a bundle is loaded.
+* Your app relies on a particular bundle being present in the environment
+  anyway, and you don’t want the user to have to add the bundle to
+  `DJANJINJA_BUNDLES` manually.
+* Your app needs to load bundles dynamically.
+
+You can load a bundle into an environment like this:
+
+    import djanjinja
+    env = djanjinja.get_env()
+    env.load('app_label', 'bundle_name', reload=False)
+
+This will load the bundle into the environment, passing through if it’s already
+loaded. If you specify `reload=True`, you can make it reload a bundle even if
+it’s been loaded.
+
+You should put this code somewhere where it will get executed when you want it
+to. If you want it to be executed immediately, as Django starts up, put it in
+`myapp/__init__.py`.
+
+### Caveats and Limitations
+
+Jinja2 does not yet support scoped filters and tests; as a result of this, the
+contents of bundles will be loaded into the global environment. It is important
+to make sure that definitions in your bundle do not override those in another
+bundle. This is especially important with threaded web applications, as multiple
+bundles overriding one another could cause unpredictable behavior in the
+templates.
+
+### Included Bundles
+
+DjanJinja provides three bundles already which either replace Django
+counterparts or add some useful functionality to your Jinja2 templates:
+    
+    * `djanjinja.cache`: Loading this bundle will add a global `cache` object to
+      the environment; this is the Django cache, and allows you to carry out
+      caching operations from within your templates (such as `cache.get(key)`,
+      et cetera).
+    * `djanjinja.humanize`: This will add all of the filters contained within
+      the `django.contrib.humanize` app; consult the official Django docs for
+      more information on the filters provided.
+    * `djanjinja.site`: This will add two functions to the global environment:
+      `url`, and `setting`. The former acts like Django’s template tag, by
+      reversing URLconf names and views into URLs, but because Jinja2 supports a
+      richer syntax, it can be used via `{{ url(name, *args, **kwargs) }}`
+      instead. `setting` attempts to resolve a setting name into a value,
+      returning an optional default instead (i.e. `setting('MEDIA_URL',
+      '/media')`).
+
+## Extensions
+
+Jinja2 supports the concept of *environment extensions*; these are non-trivial
+plugins which enhance the Jinja2 templating engine itself. By default, the
+environment is configured with the `do` statement and the loop controls (i.e.
+`break` and `continue`), but if you want to add extensions to the environment
+then you can do so with the `JINJA_EXTENSIONS` setting. Just add this to your
+`settings.py` file:
+    
+    JINJA_EXTENSIONS = (
+        'jinja2.ext.i18n', # i18n Extension
+        ...
+    )
+
+For all the extensions you wish to load. This will be passed in directly to the
+`jinja2.Environment` constructor.
+
+If you have set `USE_I18N = True` in your settings file, then DjanJinja will
+automatically initialize the i18n machinery for the Jinja2 environment, loading
+your Django translations during the bootstrapping process. For more information
+on how to use the Jinja2 i18n extension, please consult the Jinja2
+documentation.
+
+### Cache
+
+DjanJinja also provides an extension for fragment caching using the Django cache
+system. The code for this borrows heavily from the example in the Jinja2
+documentation, but with a few extras thrown in. You can use the extension like
+this:
+    
+    {% cache (parameter1, param2, param3), timeout %}
+        ...
+    {% endcache %}
+
+The tuple of parameters is used to generate the cache key for this fragment. You
+can place any object here, so long as it is suitable for serialization by the
+standard library `marshal` module. The cache key for the fragment is generated
+by marshaling the parameters, hashing them and then using the digest with a
+prefix as the key. This allows you to specify cached fragments which vary
+depending on multiple variables. The timeout is optional, and should be given in
+seconds.
+
+## Shortcut Functions
+
+DjanJinja provides you with two shortcut functions for rendering templates,
+`render_to_response` and `render_to_string`. These are very similar to those
+provided by Django in the `django.shortcuts` module, except they use Jinja2
+instead of the Django templating system. To use them from your views, just do
+`from djanjinja.views import render_to_response, render_to_string` at the top of
+your views module.
+
+## `RequestContext`
+
+One of Django's most useful features is the `RequestContext` class, which allows
+you to specify several context processors which each add some information to the
+context before templates are rendered. Luckily, this feature is
+template-agnostic, and is therefore fully compatible with DjanJinja.
+
+However, DjanJinja also provides you with some very helpful shortcuts for using
+request contexts. Usually, without DjanJinja, you would use them like this:
+    
+    from django.shortcuts import render_to_response
+    from django.template import RequestContext
+    
+    def myview(request):
+        context = {'foo': bar, 'spam': eggs}
+        return render_to_response('template_name.html',
+            context, context_instance=RequestContext())
+
+To be honest,this doesn't look very much like a 'shortcut' at all. For this
+reason, DjanJinja contains a subclass of `RequestContext` specialised for
+Jinja2, which is used like this:
+
+    from djanjinja.views import RequestContext
+    
+    def myview(request):
+        context = RequestContext(request, {'foo': bar, 'spam': eggs})
+        return context.render_response('template_name.html')
+
+This code is much more concise, but loses none of the flexibility of the
+previous example. The main changes made are the addition of `render_response`
+and `render_string` methods to the context object itself. This is highly
+specialised to rendering Jinja2 templates, so it may not be a very reusable
+approach (indeed, other code which does not use Jinja2 will need to use the full
+Django syntax), but it works for the problem domain it was designed for.
+
+## Middleware
+
+One important thing to note from before is that each time a `RequestContext`
+instance is constructed, it is necessary to explicitly pass the request. In
+object-oriented programming, and Python expecially, when we have functions to
+which we must always pass an object of a certain type, it makes sense to make
+that function a *method* of the type. When that function is not, in fact, a
+function, but a constructor, this seems more difficult. However, thanks to a
+feature of Python known as metaprogramming, we can do this very easily. Because
+it's not exactly obvious how to do so, DjanJinja includes a special piece of
+middleware which can help make your code a lot shorter yet *still* retain all
+the functionality and flexibility of the previous two examples.
+
+To use this middleware, simply add
+`'djanjinja.middleware.RequestContextMiddleware'` to your `MIDDLEWARE_CLASSES`
+list in the settings module of your project. Then, you can write view code like
+this:
+
+    def myview(request):
+        return request.Context({'foo': bar, 'spam': eggs}).render_response(
+            'template_name.html')
+
+As you can see, we've greatly reduced the verbosity of the previous code, but
+it's still obvious what this code does. The middleware attaches a `Context`
+attribute to each request object. This attribute is in fact a fully-fledged
+Python class, which may itself be subclassed and modified later on. When
+constructed, it behaves almost exactly the same as the usual `RequestContext`,
+only it uses the request object to which it has been attached, so you don't have
+to pass it in to the constructor every time.
+
+## Template Loading
+
+DjanJinja hooks directly into the Django template loader machinery to load
+templates. This means you can mix Jinja2 templates freely with Django templates,
+in your `TEMPLATE_DIRS` and your applications, and render each type
+independently and seamlessly. If you want more information on how it actually
+works, please consult the `djanjinja/environment.py` file.
+
+## License
+
+This software is licensed under the following MIT-style license:
+    
+    Copyright (c) 2009 Zachary Voase
+
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use,
+    copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following
+    conditions:
+
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    OTHER DEALINGS IN THE SOFTWARE.
+
+## Author
+
+Zachary Voase can be found on `Twitter <http://twitter.com/zacharyvoase>`_.