mirror of
https://github.com/jazzband/django-dbtemplates.git
synced 2026-03-16 22:20:28 +00:00
again: refactoring as a standalone application
git-svn-id: https://django-dbtemplates.googlecode.com/svn/trunk@12 cfb8ba98-e953-0410-9cff-959ffddf5974 committer: leidel <leidel@cfb8ba98-e953-0410-9cff-959ffddf5974> --HG-- extra : convert_revision : 5fc12102108671ddb3b9890c9091bd39cb446728
This commit is contained in:
parent
590a0efbc1
commit
bbc00a779b
7 changed files with 278 additions and 0 deletions
28
LICENSE
Normal file
28
LICENSE
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
Copyright (c) 2007, Jannis Leidel
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following
|
||||
disclaimer in the documentation and/or other materials provided
|
||||
with the distribution.
|
||||
* Neither the name of the author nor the names of other
|
||||
contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
55
README
Normal file
55
README
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
Database template loader for Django
|
||||
===================================
|
||||
|
||||
This is a basic database template loader for Django which uses a m2m
|
||||
relationship to provide a site centric template loading.
|
||||
|
||||
How to use it in your own django application
|
||||
============================================
|
||||
|
||||
0. Get the source from the subversion repository
|
||||
1. Copy the "template" directory to your django project directory
|
||||
2. Edit your settings.py:
|
||||
|
||||
# Add ``myapp.template`` to the ``INSTALLED_APPS`` where "myapp" is the
|
||||
name of your django project
|
||||
|
||||
# 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',
|
||||
'myapp.blog',
|
||||
'myapp.template',
|
||||
)
|
||||
|
||||
# Add ``myapp.template.loaders.database.load_template_source`` to the
|
||||
``TEMPLATE_LOADERS`` where "myapp" is the name 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',
|
||||
'myapp.template.loaders.database.load_template_source',
|
||||
)
|
||||
|
||||
3. Sync your database via shell (hint: "./manage.py syncdb" within project dir)
|
||||
4. Restart your Django server
|
||||
5. Go to the admin interface and add templates by filling the ``name`` field
|
||||
with filename like identifiers, for example "blog/entry_list.html"
|
||||
6. Use it with ``Flatpages``, ``Generic views`` and your own custom views
|
||||
|
||||
What? Hm, doesn't work here. || Aaah nice, BUT...
|
||||
=================================================
|
||||
|
||||
Please leave your questions and messages on the designated Google Code site:
|
||||
|
||||
http://code.google.com/p/django-databasetemplateloader/
|
||||
0
dbtemplates/__init__.py
Normal file
0
dbtemplates/__init__.py
Normal file
23
dbtemplates/loader.py
Normal file
23
dbtemplates/loader.py
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
from django.conf import settings
|
||||
from django.template import TemplateDoesNotExist
|
||||
from django.contrib.dbtemplates.models import Template
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
try:
|
||||
site = Site.objects.get_current()
|
||||
except:
|
||||
site = None
|
||||
|
||||
def load_template_source(template_name, template_dirs=None):
|
||||
"""
|
||||
Loads templates from the database by querying the database field ``name``
|
||||
with a template path and ``sites`` with the current site.
|
||||
"""
|
||||
if site is not None:
|
||||
try:
|
||||
t = Template.objects.get(name__exact=template_name, sites__pk=site.id)
|
||||
return (t.content, 'db:%s:%s' % (settings.DATABASE_ENGINE, template_name))
|
||||
except:
|
||||
pass
|
||||
raise TemplateDoesNotExist, template_name
|
||||
load_template_source.is_usable = True
|
||||
36
dbtemplates/management.py
Normal file
36
dbtemplates/management.py
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
"""
|
||||
Creates the default database template objects.
|
||||
Don't know if it works.
|
||||
"""
|
||||
|
||||
from django.dispatch import dispatcher
|
||||
from django.db.models import signals
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
from template.models import Template
|
||||
from template import models as template_app
|
||||
|
||||
def create_default_templates(app, created_models, verbosity):
|
||||
try:
|
||||
site = Site.objects.get_current()
|
||||
except Site.DoesNotExist:
|
||||
site = None
|
||||
|
||||
if site is not None:
|
||||
if Template in created_models:
|
||||
if verbosity >= 2:
|
||||
print "Creating example database templates for error 404 and error 500"
|
||||
|
||||
template404 = Template(name="404.html",content="""
|
||||
{% load i18n %}<h2>{% trans 'Page not found' %}</h2>
|
||||
<p>{% trans "We're sorry, but the requested page could not be found." %}</p>""")
|
||||
template404.save()
|
||||
template404.sites.add(site)
|
||||
|
||||
template500 = Template(name="500.html",content="""{% load i18n %}
|
||||
<h1>{% trans 'Server Error <em>(500)</em>' %}</h1>
|
||||
<p>{% trans "There's been an error." %}</p>""")
|
||||
template500.save()
|
||||
template500.sites.add(site)
|
||||
|
||||
dispatcher.connect(create_default_templates, sender=template_app, signal=signals.post_syncdb)
|
||||
56
dbtemplates/models.py
Normal file
56
dbtemplates/models.py
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from django.db import models
|
||||
from django.template import loader, Context
|
||||
from django.core import validators
|
||||
from django.contrib.sites.models import Site
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
class Template(models.Model):
|
||||
"""
|
||||
Defines a template model for use with the database template loader.
|
||||
The field ``name`` is the equivalent to the filename of a static template.
|
||||
"""
|
||||
name = models.CharField(_('name'), unique=True, maxlength=100, help_text=_("Example: 'flatpages/default.html'"))
|
||||
content = models.TextField(_('content'))
|
||||
sites = models.ManyToManyField(Site)
|
||||
creation_date = models.DateTimeField(_('creation date'), auto_now_add=True)
|
||||
last_changed = models.DateTimeField(_('last changed'), auto_now=True)
|
||||
class Meta:
|
||||
db_table = 'django_template'
|
||||
verbose_name = _('template')
|
||||
verbose_name_plural = _('templates')
|
||||
ordering = ('name',)
|
||||
class Admin:
|
||||
fields = ((None, {'fields': ('name', 'content', 'sites')}),)
|
||||
list_display = ('name', 'creation_date', 'last_changed')
|
||||
list_filter = ('sites',)
|
||||
search_fields = ('name','content')
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
__test__ = {'API_TESTS':"""
|
||||
>>> test_site = Site.objects.get(pk=1)
|
||||
>>> test_site
|
||||
<Site: example.com>
|
||||
>>> t1 = Template(name='base.html', content="<html><head></head><body>{% block content %}Welcome at {{ title }}{% endblock %}</body></html>")
|
||||
>>> t1.save()
|
||||
>>> t1.sites.add(test_site)
|
||||
>>> t1
|
||||
<Template: base.html>
|
||||
>>> t2 = Template(name='sub.html', content='{% extends "base.html" %}{% block content %}This is {{ title }}{% endblock %}')
|
||||
>>> t2.save()
|
||||
>>> t2.sites.add(test_site)
|
||||
>>> t2
|
||||
<Template: sub.html>
|
||||
>>> Template.objects.filter(sites=test_site)
|
||||
[<Template: base.html>, <Template: sub.html>]
|
||||
>>> t2.sites.all()
|
||||
[<Site: example.com>]
|
||||
>>> from django.contrib.dbtemplates.loader import load_template_source
|
||||
>>> loader.template_source_loaders = [load_template_source]
|
||||
>>> loader.get_template("base.html").render(Context({'title':'MainPage'}))
|
||||
'<html><head></head><body>Welcome at MainPage</body></html>'
|
||||
>>> loader.get_template("sub.html").render(Context({'title':'SubPage'}))
|
||||
'<html><head></head><body>This is SubPage</body></html>'
|
||||
"""}
|
||||
80
dbtemplates/sync_templates.py
Normal file
80
dbtemplates/sync_templates.py
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
"""
|
||||
Helper function for syncing templates in TEMPLATES_DIRS with the dbtemplates
|
||||
contrib app.
|
||||
"""
|
||||
|
||||
from django.conf import settings
|
||||
from django.template import TemplateDoesNotExist
|
||||
from django.contrib.dbtemplates.models import Template
|
||||
from django.contrib.sites.models import Site
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
try:
|
||||
site = Site.objects.get_current()
|
||||
except:
|
||||
site = None
|
||||
|
||||
def synctemplates(extension=".html", overwrite=False):
|
||||
"""
|
||||
Helper function for syncing templates in TEMPLATES_DIRS with the
|
||||
dbtemplates contrib app.
|
||||
"""
|
||||
tried = []
|
||||
synced = []
|
||||
existing = []
|
||||
overwritten = []
|
||||
|
||||
if site is not None:
|
||||
for template_dir in settings.TEMPLATE_DIRS:
|
||||
if os.path.isdir(template_dir):
|
||||
for dirpath, subdirs, filenames in os.walk(template_dir):
|
||||
for file in filenames:
|
||||
if file.endswith(extension) and not file.startswith("."):
|
||||
filepath = os.path.join(dirpath, file)
|
||||
filename = filepath.split(template_dir)[1][1:]
|
||||
try:
|
||||
try:
|
||||
t = Template.objects.get(name__exact=filename)
|
||||
except Template.DoesNotExist:
|
||||
filecontent = open(filepath, "r").read()
|
||||
t = Template(name=filename, content=filecontent)
|
||||
t.save()
|
||||
t.sites.add(site)
|
||||
synced.append(filename)
|
||||
else:
|
||||
if overwrite:
|
||||
t.content = open(filepath, "r").read()
|
||||
t.save()
|
||||
t.sites.add(site)
|
||||
overwritten.append(t.name)
|
||||
else:
|
||||
existing.append(t.name)
|
||||
except IOError:
|
||||
tried.append(filepath)
|
||||
except:
|
||||
raise TemplateDoesNotExist
|
||||
|
||||
if len(existing) > 0:
|
||||
print "\nAlready existing templates:"
|
||||
for _existing in existing:
|
||||
print _existing
|
||||
|
||||
if len(overwritten) > 0:
|
||||
print "\nOverwritten existing templates:"
|
||||
for _replaced in overwritten:
|
||||
print _replaced
|
||||
|
||||
if len(synced) > 0:
|
||||
print "\nSuccessfully synced templates:"
|
||||
for _synced in synced:
|
||||
print _synced
|
||||
|
||||
if len(tried) > 0:
|
||||
print "\nTried to sync but failed:"
|
||||
for _tried in tried:
|
||||
print _tried
|
||||
|
||||
if __name__ == "__main__":
|
||||
synctemplates()
|
||||
Loading…
Reference in a new issue