===================================
Database template loader for Django
===================================

``dbtemplates`` is a Django app that comes with to parts: It allows you to
create templates that are saved in your database, and it provides a so called
`template loader`_, a function that enables Django to find the templates you
created in the database.

It also includes a extensible caching mechanism and supports version control
of the templates saved in the database.

.. _template loader: http://docs.djangoproject.com/en/dev/ref/templates/api/#loading-templates

.. contents:: Table of Contents
    :backlinks: none

Setup
=====

1. Get the source from the `Mercurial repository`_ or install it from the
   Python Package Index by running ``easy_install django-dbtemplates`` or
   ``pip django-dbtemplates``.
2. Follow the instructions in the INSTALL file
3. Edit the settings.py of your Django site:

   * Add ``dbtemplates`` to the ``INSTALLED_APPS`` setting

     Check if ``django.contrib.sites`` and ``django.contrib.admin`` are in
     ``INSTALLED_APPS`` and add if necessary.

     It should look something like this::

         INSTALLED_APPS = (
             'django.contrib.auth',
             'django.contrib.contenttypes',
             'django.contrib.sessions',
             'django.contrib.sites',
             'django.contrib.admin',
             'django.contrib.flatpages',
             # ..
             'dbtemplates',
         )

   * Add ``dbtemplates.loader.load_template_source`` to the
     ``TEMPLATE_LOADERS`` list in the settings.py of your Django project

     It should look something like this::

       TEMPLATE_LOADERS = (
           'django.template.loaders.filesystem.load_template_source',
           'django.template.loaders.app_directories.load_template_source',
           'dbtemplates.loader.load_template_source',
       )

4. Sync your database ``python manage.py syncdb``
5. Restart your Django server

.. _Mercurial repository: http://bitbucket.org/jezdez/django-dbtemplates/

Usage
=====

Creating database templates is pretty simple: Just open the admin interface
of your Django-based site in your browser and click on "Templates" in the
"Dbtemplates" section.

There you only need to fill in the ``name`` field with the identifier, Django
is supposed to use while searching for templates, e.g.
``blog/entry_list.html``. The ``content`` field should be filled with the
content of your template.

Optionally, by leaving the ``content`` field empty you are able to tell
``dbtemplates`` to look for a template with the ``name`` by using Django's
other template loaders. For example, if you have a template called
``blog/entry_list.html`` on your file system and want to save the templates
contents in the database, you just need to leave the content field empty to
automatically populate it. That's especially useful if you don't want to
copy and paste its content manually to the textarea.

Example
=======

``dbtemplates`` comes with an example Django project that let's you try it 
out. The example uses Django's own `flatpages app`_ to enable you to create
a simple page using ``dbtemplates``. Flat pages are a perfect fit to
dbtemplates since they come prepackaged and are simple to use.

Here is how it works:

1. Open your command line and change to the ``example`` directory in the
   directory with the extracted source distribution.
2. Run ``python manage.py syncdb`` and follow the instructions.
3. Run ``python manage.py runserver`` and open your favorite browser with the
   address http://127.0.0.1:8000/admin/.
4. Next add a new `Template` object in the ``dbtemplates`` section and use
   ``flatpages/default.html`` as the value for the ``name`` field. For the
   ``content`` field use this example::

        <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
            "http://www.w3.org/TR/REC-html40/loose.dtd">
        <html>
        <head>
        <title>{{ flatpage.title }}</title>
        </head>
        <body>
        {{ flatpage.content }}
        </body>
        </html>

5. Return to the home screen of the admin interface and add a new flat page.
   Use ``/`` (yep, just a forward slash) and whatever ``title`` and 
   ``content`` you prefer. Please make sure you select the default site
   ``example.com`` before you save the flat page.
6. Visit http://127.0.0.1:8000/ and see the flat page you just created 
   rendered with the ``flatpages/default.html`` template provided by  
   ``dbtemplates``.

.. _flatpages app: http://docs.djangoproject.com/en/dev/ref/contrib/flatpages/

Settings
========

* ``DBTEMPLATES_ADD_DEFAULT_SITE``

  ``dbtemplates`` adds the current site (``settings.SITE_ID``) to the database  
  template when it is created by default. You can disable this feature by   
  setting ``DBTEMPLATES_ADD_DEFAULT_SITE`` to ``False``.

* ``DBTEMPLATES_CACHE_BACKEND``

  The dotted Python path to the cache backend class. See `Caching`_ for 
  details.

* ``DBTEMPLATES_CACHE_DIR``

  A directory path that is used by the cache ``FileSystemBackend`` to store 
  the cached templates. See `Caching`_ for details.

* ``DBTEMPLATES_USE_CODEMIRROR``

  A boolean, if enabled triggers the use of the CodeMirror based editor.
  Set to ``False`` by default.

* ``DBTEMPLATES_USE_REVERSION``

  A boolean, if enabled triggers the use of ``django-reversion``.

* ``DBTEMPLATES_MEDIA_PREFIX``

  The URL prefix for ``dbtemplates``' media -- CSS and JavaScript used by
  the CodeMirror based editor. Make sure to use a trailing
  slash, and to have this be different from the ``MEDIA_URL`` setting
  (since the same URL cannot be mapped onto two different sets of
  files).

Caching
=======

Using the default caching
-------------------------

Dbtemplates comes with different backends for caching that are automatically
created, updated and deleted when templates are saved in the database by
using Django's signal framework.

To enable one of them you need to specify a setting called
``DBTEMPLATES_CACHE_BACKEND`` to one of the following values:

* ``dbtemplates.cache.FileSystemBackend`` -- File system caching

  The ``FileSystemBackend`` is a simple way to store the templates you have
  in the database on the filesystem. That's especially useful if you don't
  use a full caching framework like Django is providing.

  To use this backend you need additionally create a setting
  ``DBTEMPLATES_CACHE_DIR`` that contains the full file system path to the
  directory where ``dbtemplates`` should create the cache files in.

* ``dbtemplates.cache.DjangoCacheBackend`` -- Django cache

  The ``DjangoCacheBackend`` is a thin wrapper around Django's caching
  framework that enables you to use advanced caching solutions like
  memcached or database caching. Please see the `cache documentation`_ if
  you want to know more about it.

.. _cache documentation: http://docs.djangoproject.com/en/dev/topics/cache/#setting-up-the-cache

Writing your own caching backends
---------------------------------

Writing your own cache backends is perfectly easy since ``dbtemplates``
includes a easy-to-use base class in ``dbtemplates.cache.BaseCacheBackend``.

Just subclass that base backend somewhere in your own code and provide the
follwing three reuqired methods:

* ``load``

  Loads a template from the cache with the given name and returns its
  contents. Return None if nothing found.
  
  Arguments:
    
  * ``name`` - name of the template

* ``save``
  
  Saves the passed template contents with the passed name in the cache.

  Arguments:

  * ``name`` - name of the template
  * ``content`` - contents of the template

* ``remove``

  Removes the template with the passed name from the cache.

  Arguments:
    
  * ``name`` - name of the template

Please see also the `source of the default backends`_ to see how it works.

.. _source of the default backends: http://bitbucket.org/jezdez/django-dbtemplates/src/tip/dbtemplates/cache.py

Versionizing your templates
===========================

``dbtemplates`` comes prepared to use the third party Django app
`django-reversion`_, that once installed besides ``dbtemplates`` allows you
to jump back to old versions of your templates. It automatically saves every
state when you save the template in your database and provides an easy to use
interface.

Please refer to `django-reversion's documentation`_ for more information
about how it works. ``dbtemplates`` uses ``django-reversion`` if the 
``DBTEMPLATES_USE_REVERSION`` setting is ``True``. Just visit the
"History" section of each template instance and browse its history.

Short installation howto
------------------------

1. Get the source from the `django-reversion`_ project site and put it
   somewhere on your `PYTHONPATH`.
2. Add ``reversion`` to the ``INSTALLED_APPS`` setting of your Django project
3. Sync your database with ``python manage.py syncdb``

.. _django-reversion: http://code.google.com/p/django-reversion/
.. _django-reversion's documentation: http://code.google.com/p/django-reversion/wiki/GettingStarted

Management commands
===================

``dbtemplates`` comes with two `Django management commands`_ to be used with
``django-admin.py`` or ``manage.py``:

* ``sync_templates``

  Enables you to sync your already existing file systems templates with the
  database. It will guide you through the whole process.

* ``create_error_templates``

  Tries to add the two templates ``404.html`` and ``500.html`` that are used
  by Django when a error occurs.

.. _Django management commands: http://docs.djangoproject.com/en/dev/ref/django-admin/

Admin actions
=============

``dbtemplates`` provides two `admin actions`_ to be used with Django>=1.1.

* ``invalidate_cache``

  Invalidates the cache of the selected templates by calling the appropriate
  cache backend methods.

* ``repopulate_cache``

  Repopulates the cache with selected templates by invalidating it first and
  filling then after that.

.. _admin actions: http://docs.djangoproject.com/en/1.1/ref/contrib/admin/actions/#ref-contrib-admin-actions

Changelog
=========

0.7.1 (07-07-10)
----------------

* Fixed problem with the CodeMirror textarea, which wasn't completely
  disabled before.

* Fixed problem with the ``DBTEMPLATES_MEDIA_PREFIX`` setting, which defaults
  now to ``os.path.join(settings.MEDIA_ROOT, 'dbtemplates')`` now.
  
  In other words, if you don't specify a ``DBTEMPLATES_MEDIA_PREFIX`` setting
  and have the CodeMirror textarea enabled, dbtemplates will look in a
  subdirectory of your site's ``MEDIA_ROOT`` for the CodeMirror media files.

0.7.0 (06-24-10)
----------------

* Added CodeMirror_-based syntax highlighting textarea, based on the amaxing
  work_ by `Nic Pottier`_. Set the ``DBTEMPLATES_USE_CODEMIRROR`` setting
  to ``True`` to enable it.

* Make use of the full width in plain textarea mode.

* Added Chinese translation

* Added support for Django 1.2

* Updated French translation

* Added ``DBTEMPLATES_USE_REVERSION`` setting to be able to explicitely enable
  reversion support. (Default: ``False``)

.. _CodeMirror: http://marijn.haverbeke.nl/codemirror/
.. _work: https://gist.github.com/368758/86bcafe53c438e2e2a0e3442c3b30f2c6011fbba
.. _`Nic Pottier`: http://github.com/nicpottier

0.6.1 (10-19-09):
-----------------

* Fixed issue with default site of a template, added ability to disable
  default site (``DBTEMPLATES_ADD_DEFAULT_SITE``).

0.6.0 (10-09-09):
-----------------

* Updated and added locales (Danish, Brazilian Portuguese)

* Fixes an ambiguity problem with the cache invalidation

* Added ``invalidate_cache`` and ``repopulate_cache`` admin actions

* Added Sphinx documentation

0.5.7
-----

* Updates to the docs

* switch back to Bitbucket

* fixed tests

* Added Italian translation

* list of sites the template is used on

* fixed bug in ``create_error_template`` command.

0.5.4
-----

* Made loader and cache backends site-aware.

* The filesystem cache backend now saves the files under
  ``<dir>/<site_domain>/<file_name>``.

* The Django cache backend the Site id in the cache key

* Template is now saved explicitly to backend if not existent in cache
  (e.g. if deleted manually or invalidated).

0.5.3
-----

* Removed automatic creation of 404.html and 500.html templates and added a
  new management command for those cases called ``create_error_templates``

* Also reverted move to Bitbucket

0.5.2
-----

* Fixed a problem with ``django.contrib.sites`` when its table hasn't been
  populated yet on initialization of dbtemplates. Thanks for the report,
  Kevin Fricovsky

* Added an example Django project and docs for it

0.5.1
-----

* Removed unneeded code that registered the model with reversion.

* Updated docs a bit.

* Moved codebase to Bitbucket.

* Removed legacy ``sync_templates.py`` script, use ``django-admin.py
  sync_templates`` from now on.

0.5.0
-----

* Added support for `django-reversion`_

* added feature that populates the content field automatically when left
  empty by using Django's other template loaders

* added caching backend system with two default backends:
  
  * ``FileSystemBackend``
  * ``DjangoCacheBackend``
  
  More about it in the `blog post`_ and in the docs.

.. _django-reversion: http://code.google.com/p/django-reversion/
.. _blog post: http://jannisleidel.com/2008/11/updates-to-django-dbtemplates-and-half-assed-promise/

0.4.7
-----

* Minor bugfix

0.4.6
-----

* Minor doc change and PyPI support

0.4.5
-----

* fixed the --force option of the sync_templates command

0.4.4
-----

* fixed error in custom model save() after changes in Django `r8670`_.

.. _r8670: http://code.djangoproject.com/changeset/8670

0.4.3
-----

* removed oldforms code

0.4.2
-----

* added Hebrew translation (by mkriheli)

0.4.1
-----

* added French (by Roland Frederic) and German locale

0.4.0
-----

* adds better support for newforms-admin

* don't forget to load the dbtemplates.admin, e.g. by using
  django.contrib.admin.autodiscover() in you urls.py

0.3.1
-----

* adds a new management command *sync_templates* for bidirectional syncing
  between filesystem and database (backwards-compatible) and
  FilesystemCaching (thanks, Arne Brodowski!)

0.2.5
-----

* adds support for newforms-admin

Support
=======

Please leave your questions and messages on the designated site:

http://bitbucket.org/jezdez/django-dbtemplates/issues/
