Migrate from Cheetah to Django template system

Compiled templates are an unnecessary pain in maintance and
packaging. If each module is to bring its own templates, compiling
them in the build process becomes unnecessarily more complex. The
current state of template mess can somewhat be attributed to this.

Cheetah only partially supports dynamic templates. It does not support
inheritence of dynamic templates. From its documentation: "There is no
support for extending from a class that is not imported; e.g., from a
template dynamically created from a string. Since the most practical
way to get a parent template into a module is to precompile it, all
parent templates essentially have to be precompiled."
This commit is contained in:
Sunil Mohan Adapa 2014-05-04 16:01:17 +05:30
parent d7a3235120
commit 9239d2c627
9 changed files with 122 additions and 158 deletions

View File

@ -3,6 +3,7 @@
import os, stat, sys, argparse import os, stat, sys, argparse
from gettext import gettext as _ from gettext import gettext as _
import cfg import cfg
import django.conf
if not os.path.join(cfg.file_root, "vendor") in sys.path: if not os.path.join(cfg.file_root, "vendor") in sys.path:
sys.path.append(os.path.join(cfg.file_root, "vendor")) sys.path.append(os.path.join(cfg.file_root, "vendor"))
@ -183,6 +184,11 @@ def main():
setup() setup()
# Configure Django
directory = os.path.dirname(os.path.abspath(__file__))
templates_directory = os.path.join(directory, 'templates')
django.conf.settings.configure(TEMPLATE_DIRS=(templates_directory,))
cherrypy.engine.start() cherrypy.engine.start()
cherrypy.engine.block() cherrypy.engine.block()

View File

@ -1,10 +1,3 @@
#def default($text, $default)
#if $text
$text
#else
$default
#end if
#end def
<!doctype html> <!doctype html>
<!--[if lt IE 7 ]> <html class="ie ie6 no-js" lang="en"> <![endif]--> <!--[if lt IE 7 ]> <html class="ie ie6 no-js" lang="en"> <![endif]-->
<!--[if IE 7 ]> <html class="ie ie7 no-js" lang="en"> <![endif]--> <!--[if IE 7 ]> <html class="ie ie7 no-js" lang="en"> <![endif]-->
@ -31,22 +24,22 @@
<meta name="msnbot" content="noindex, nofollow, noarchive, noodp" /> <meta name="msnbot" content="noindex, nofollow, noarchive, noodp" />
<meta name="slurp" content="noindex, nofollow, noarchive, noodp, noydir" /> <meta name="slurp" content="noindex, nofollow, noarchive, noodp, noydir" />
<meta name="title" content="$default($title, 'FreedomBox Dashboard')" /> <meta name="title" content="{% if title %} {{ title }} {% else %} FreedomBox Dashboard {% endif %}" />
<meta name="description" content="Plinth administrative interface for the FreedomBox" /> <meta name="description" content="Plinth administrative interface for the FreedomBox" />
<title>$default($title, "FreedomBox Dashboard")</title> <title>{% if title %} {{ title }} {% else %} FreedomBox Dashboard {% endif %}</title>
<!-- This is the traditional favicon. Size: 16x16 or 32x32, transparency is OK --> <!-- This is the traditional favicon. Size: 16x16 or 32x32, transparency is OK -->
<link rel="shortcut icon" href="$basehref/static/theme/img/favicon.ico" /> <link rel="shortcut icon" href="{{ basehref }}/static/theme/img/favicon.ico" />
<!-- The is the icon for iOS's Web Clip. Size: 57x57 for older iPhones, 72x72 for iPads, 114x114 for iPhone4 <!-- The is the icon for iOS's Web Clip. Size: 57x57 for older iPhones, 72x72 for iPads, 114x114 for iPhone4
- To prevent iOS from applying its styles to the icon name it thusly: apple-touch-icon-precomposed.png - To prevent iOS from applying its styles to the icon name it thusly: apple-touch-icon-precomposed.png
- Transparency is not recommended (iOS will put a black BG behind the icon) --> - Transparency is not recommended (iOS will put a black BG behind the icon) -->
<link rel="apple-touch-icon" sizes="57x57" href="$basehref/static/theme/img/apple-touch-icon-57px-precomposed.png" /> <link rel="apple-touch-icon" sizes="57x57" href="{{ basehref }}/static/theme/img/apple-touch-icon-57px-precomposed.png" />
<link rel="apple-touch-icon" sizes="72x72" href="$basehref/static/theme/img/apple-touch-icon-72px-precomposed.png" /> <link rel="apple-touch-icon" sizes="72x72" href="{{ basehref }}/static/theme/img/apple-touch-icon-72px-precomposed.png" />
<link rel="apple-touch-icon" sizes="114x114" href="$basehref/static/theme/img/apple-touch-icon-114px-precomposed.png" /> <link rel="apple-touch-icon" sizes="114x114" href="{{ basehref }}/static/theme/img/apple-touch-icon-114px-precomposed.png" />
<!-- Bootstrap base CSS --> <!-- Bootstrap base CSS -->
<link rel="stylesheet" href="$basehref/static/theme/css/bootstrap.css" /> <link rel="stylesheet" href="{{ basehref }}/static/theme/css/bootstrap.css" />
<style type="text/css"> <style type="text/css">
/* custom styles, load before bootstrap responsive styles */ /* custom styles, load before bootstrap responsive styles */
body { body {
@ -58,7 +51,7 @@
} }
</style> </style>
<!-- Bootstrap responsive CSS --> <!-- Bootstrap responsive CSS -->
<link rel="stylesheet" href="$basehref/static/theme/css/bootstrap-responsive.css" /> <link rel="stylesheet" href="{{ basehref }}/static/theme/css/bootstrap-responsive.css" />
<style type="text/css"> <style type="text/css">
/* custom styles, load after all bootstrap styles */ /* custom styles, load after all bootstrap styles */
.super-hero { .super-hero {
@ -91,16 +84,16 @@
} }
</style> </style>
<!-- CSS from previous Plinth template, not sure what to keep yet --> <!-- CSS from previous Plinth template, not sure what to keep yet -->
$css {{ css|safe }}
<!-- End Plinth CSS --> <!-- End Plinth CSS -->
<!-- JS from previous Plinth template, not sure what to keep yet --> <!-- JS from previous Plinth template, not sure what to keep yet -->
<script type="text/javascript" src="$basehref/static/theme/js/menu.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/menu.js"></script>
<script type="text/javascript" src="$basehref/static/theme/js/plinth.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/plinth.js"></script>
$main_menu_js {{ main_menu_js|safe }}
$sub_menu_js {{ sub_menu_js|safe }}
<script type="text/javascript"> <script type="text/javascript">
<!-- <!--
$onload {{ onload|safe }}
// --> // -->
</script> </script>
</head> </head>
@ -114,9 +107,9 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</a> </a>
<a href="$basehref/" class="logo-top"><img src="$basehref/static/theme/img/freedombox-logo-32px.png" alt="FreedomBox" /></a><a class="brand" href="$basehref/">FreedomBox Dashboard</a> <a href="{{ basehref }}/" class="logo-top"><img src="{{ basehref }}/static/theme/img/freedombox-logo-32px.png" alt="FreedomBox" /></a><a class="brand" href="{{ basehref }}/">FreedomBox Dashboard</a>
#block add_nav_and_login {% block add_nav_and_login %}
#end block add_nav_and_login {% endblock %}
</div><!--/.nav-collapse --> </div><!--/.nav-collapse -->
</div> </div>
</div> </div>
@ -124,35 +117,35 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row-fluid"> <div class="row-fluid">
#if $nav or $sidebar_right or $sidebar_left {% if nav or sidebar_right or sidebar_left %}
<div class="span3"> <div class="span3">
#if $nav {% if nav %}
<div class="well sidebar-nav"> <div class="well sidebar-nav">
$nav {{ nav|safe }}
</div><!--/.well --> </div><!--/.well -->
#end if {% endif %}
#if $sidebar_left {% if sidebar_left %}
<div class="well sidebar-nav"> <div class="well sidebar-nav">
left $sidebar_left {{ sidebar_left|safe }}
</div><!--/.well --> </div><!--/.well -->
#end if {% endif %}
#if $sidebar_right {% if sidebar_right %}
<div class="well sidebar-nav"> <div class="well sidebar-nav">
$sidebar_right {{ sidebar_right|safe }}
</div><!--/.well --> </div><!--/.well -->
#end if {% endif %}
</div> </div>
#end if {% endif %}
<div class="span9"> <div class="span9">
<div class="hero-unit" class="pull-left"> <div class="hero-unit" class="pull-left">
<h2> <h2>
#block title_block {% block title_block %}
$title {{ title }}
#end block title_block {% endblock %}
</h2> </h2>
#block main_block {% block main_block %}
$main {{ main|safe }}
#end block main_block {% endblock %}
</div> </div>
</div><!--/span--> </div><!--/span-->
</div><!--/row--> </div><!--/row-->
@ -160,44 +153,44 @@
<hr> <hr>
<footer> <footer>
<p>#block footer_block <p>{% block footer_block %}
<p> <p>
Plinth is &copy; Copyright 2012 <a href="http://hackervisions.org" target="_blank">James Vasile</a>. It is Plinth is &copy; Copyright 2012 <a href="http://hackervisions.org" target="_blank">James Vasile</a>. It is
free software offered to you under the terms of free software offered to you under the terms of
the <a href="http://www.gnu.org/licenses/agpl.html" target="_blank">GNU Affero General Public the <a href="http://www.gnu.org/licenses/agpl.html" target="_blank">GNU Affero General Public
License</a>, Version 3 or later. This Plinth theme was built by <a href="http://seandiggity.com" target="_blank">Sean &quot;Diggity&quot; O&apos;Brien</a>. License</a>, Version 3 or later. This Plinth theme was built by <a href="http://seandiggity.com" target="_blank">Sean &quot;Diggity&quot; O&apos;Brien</a>.
</p> </p>
<p>Current page: $current_url</p> <p>Current page: {{ current_url }}</p>
<p> <p>
</p> </p>
#end block footer_block</p> {% endblock %}</p>
</footer> </footer>
</div><!--/.fluid-container--> </div><!--/.fluid-container-->
<!-- JavaScript <script> tags are placed at the end of the document to speed up initial page loads--> <!-- JavaScript <script> tags are placed at the end of the document to speed up initial page loads-->
<!-- Local link to system Modernizr (includes HTML5 Shiv) --> <!-- Local link to system Modernizr (includes HTML5 Shiv) -->
<script type="text/javascript" src="$basehref/static/theme/js/libs/modernizr.min.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/modernizr.min.js"></script>
<!-- Local link to system jQuery --> <!-- Local link to system jQuery -->
<script type="text/javascript" src="$basehref/static/theme/js/libs/jquery.min.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/jquery.min.js"></script>
<!-- Bootstrap JS, most files commented out until we know what we need --> <!-- Bootstrap JS, most files commented out until we know what we need -->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/bootstrap.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/bootstrap.js"></script>-->
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/bootstrap.min.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/bootstrap.min.js"></script>
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/button.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/button.js"></script>
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/dropdown.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/dropdown.js"></script>
<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/collapse.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/collapse.js"></script>
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/transition.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/transition.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/alert.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/alert.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/modal.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/modal.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/scrollspy.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/scrollspy.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/tab.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/tab.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/tooltip.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/tooltip.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/popover.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/popover.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/carousel.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/carousel.js"></script>-->
<!--<script type="text/javascript" src="$basehref/static/theme/js/libs/bootstrap/typeahead.js"></script>--> <!--<script type="text/javascript" src="{{ basehref }}/static/theme/js/libs/bootstrap/typeahead.js"></script>-->
<!-- JS plugins --> <!-- JS plugins -->
<script type="text/javascript" src="$basehref/static/theme/js/plugins.js"></script> <script type="text/javascript" src="{{ basehref }}/static/theme/js/plugins.js"></script>
$js {{ js|safe }}
</body> </body>
</html> </html>

7
templates/err.html Normal file
View File

@ -0,0 +1,7 @@
{% extends "login_nav.html" %}
{% block title_block %}
<span class="label label-important error-large">Error: {{ title }}</span>
<br />
<br />
{% endblock %}

View File

@ -1,23 +0,0 @@
#extends templates.login_nav
#def title_block
<span class="label label-important error-large">Error: $title</span>
<br />
<br />
#end def
#def sidebar_left_block
$sidebar_left
#end def
#def main_block
$main
#end def
#def sidebar_right_block
$sidebar_right
#end def
#def nav_block
$nav
#end def

13
templates/login_nav.html Normal file
View File

@ -0,0 +1,13 @@
{% extends "base.html" %}
{% block add_nav_and_login %}
<div class="nav-collapse">
<script type="text/javascript">
main_menu(main_menu_items);
</script>
{% if username %}
<p class="navbar-text pull-right"><i class="icon-user icon-white nav-icon"></i>Logged in as <a href="{{ username }}">{{ username }}</a>. <a href="{{ basehref }}/auth/logout" title="Log out">Log out</a>.</p>
{% else %}
<p class="navbar-text pull-right">Not logged in. <i class="icon-user icon-white nav-icon"></i><a href="{{ basehref }}/auth/login" title="Log in">Log in</a>.</p>
{% endif %}
{% endblock %}

View File

@ -1,31 +0,0 @@
#extends templates.base
#def add_nav_and_login
<div class="nav-collapse">
<script type="text/javascript">
<!--
main_menu(main_menu_items);
// -->
</script>
#if $username
<p class="navbar-text pull-right"><i class="icon-user icon-white nav-icon"></i>Logged in as <a href="$username">$username</a>. <a href="$basehref/auth/logout" title="Log out">Log out</a>.</p>
#else
<p class="navbar-text pull-right">Not logged in. <i class="icon-user icon-white nav-icon"></i><a href="$basehref/auth/login" title="Log in">Log in</a>.</p>
#end if
#end def
#def sidebar_left_block
$sidebar_left
#end def
#def main_block
$main
#end def
#def sidebar_right_block
$sidebar_right
#end def
#def nav_block
$nav
#end def

24
templates/two_col.html Normal file
View File

@ -0,0 +1,24 @@
{{ extends "base.html" }}
{% block css %}
<!-- CSS from previous template, not sure what to keep yet -->
<!--<link rel="stylesheet" href="{{ basehref }}/static/theme/style-plinth-2col.css" />-->
{% endblock %}
{% block add_sidebar_left %}
<div class="span3">
<div class="well sidebar-nav">
{% block nav_block %}
{{ nav }}
{% endblock %}
{% block sidebar_left_block %}
{{ sidebar_left }}
{% endblock %}
</div><!--/.well -->
<div class="well sidebar-nav">
{% block sidebar_right_block %}
{{ sidebar_right }}
{% endblock %}
</div><!--/.well -->
</div><!--/span-->
{% endblock %}

View File

@ -1,25 +0,0 @@
#extends templates.base
#def css
<!-- CSS from previous template, not sure what to keep yet -->
<!--<link rel="stylesheet" href="$basehref/static/theme/style-plinth-2col.css" />-->
#end def
#def add_sidebar_left
<div class="span3">
<div class="well sidebar-nav">
#block nav_block
$nav
#end block nav_block
#block sidebar_left_block
$sidebar_left
#end block sidebar_left_block
</div><!--/.well -->
<div class="well sidebar-nav">
#block sidebar_right_block
$sidebar_right
#end block sidebar_right_block
</div><!--/.well -->
</div><!--/span-->
#end def

22
util.py
View File

@ -1,9 +1,10 @@
import os, sys import os
import sys
import cherrypy import cherrypy
import cfg import cfg
import importlib
import sqlite3 import sqlite3
from django.template.loader import render_to_string
from filedict import FileDict from filedict import FileDict
@ -60,18 +61,16 @@ class Message():
def add(self, text): def add(self, text):
self.text += "<br />%s" % text self.text += "<br />%s" % text
def page_template(template='login_nav', **kwargs): def page_template(template='login_nav', **kwargs):
for k in ['sidebar_left', 'sidebar_right', 'main', 'js', 'onload', 'nav', 'css', 'title', 'basehref']: for key in ['sidebar_left', 'sidebar_right', 'main', 'js', 'onload', 'nav',
if not k in kwargs: 'css', 'title', 'basehref']:
kwargs[k] = '' if not key in kwargs:
kwargs[key] = ''
if kwargs['basehref'] == '': if kwargs['basehref'] == '':
kwargs['basehref'] = cfg.server_dir kwargs['basehref'] = cfg.server_dir
#if template=='base' and kwargs['sidebar_right']=='':
# template='two_col'
if isinstance(template, basestring):
template_module = importlib.import_module('templates.' + template)
template = getattr(template_module, template)
try: try:
submenu = cfg.main_menu.active_item().encode("sub_menu", render_subs=True) submenu = cfg.main_menu.active_item().encode("sub_menu", render_subs=True)
except AttributeError: except AttributeError:
@ -90,7 +89,8 @@ def page_template(template='login_nav', **kwargs):
// --> // -->
</script>""" </script>"""
return str(template(searchList=[kwargs])) return render_to_string(template + '.html', kwargs)
def filedict_con(filespec=None, table='dict'): def filedict_con(filespec=None, table='dict'):
"""TODO: better error handling in filedict_con""" """TODO: better error handling in filedict_con"""