Cleanup menu generation using templates

This commit is contained in:
Sunil Mohan Adapa 2014-05-13 01:00:38 +05:30
parent 218fc37e8f
commit 994199f096
7 changed files with 61 additions and 124 deletions

View File

@ -108,7 +108,6 @@ specified and linked otherwise.
- themes/default/img/glyphicons-halflings.png :: -
- themes/default/img/glyphicons-halflings-white.png :: -
- themes/default/js/functions.js :: -
- themes/default/js/menu.js :: -
- themes/default/js/plinth.js :: -
- themes/default/js/plugins.js :: [[file:themes/default/js/plugins.js::/%20paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/][CC0]]
- themes/default/js/libs/jquery.min.js :: Symlink to external target: [[file:themes/default/js/libs/jquery.min.js::*%20Dual%20licensed%20under%20the%20MIT%20or%20GPL%20Version%202%20licenses.][MIT/GPL2]]

39
menu.py
View File

@ -1,19 +1,16 @@
from urlparse import urlparse
try:
import simplejson as json
except ImportError:
import json
import cherrypy
import cfg
class Menu():
"""One menu item."""
def __init__(self, label="", icon="", url="#", order=50):
"""label is the text that is displayed on the menu.
icon is the icon to be displayed next to the label.
Choose from the Glyphicon set:
http://twitter.github.com/bootstrap/base-css.html#icons
icon is the icon to be displayed next to the label.
Choose from the Glyphicon set:
http://twitter.github.com/bootstrap/base-css.html#icons
url is the url location that will be activated when the menu
item is selected.
@ -35,11 +32,13 @@ class Menu():
def sort_items(self):
"""Sort the items in self.items by order."""
self.items = sorted(self.items, key=lambda x: x.order, reverse=False)
def add_item(self, label, icon, url, order=50, basehref=True):
"""This method creates a menu item with the parameters, adds
that menu item to this menu, and returns the item.
If BASEHREF is true and url start with a slash, prepend the cfg.server_dir to it"""
If BASEHREF is true and url start with a slash, prepend the
cfg.server_dir to it"""
if basehref and url.startswith("/"):
url = cfg.server_dir + url
@ -62,27 +61,3 @@ class Menu():
for item in self.items:
if path.startswith(item.url):
return item
def serializable(self, render_subs=False):
"""Return the items in self.items as a serializable object we can pass to json.
Note: this doesn't serialize all the data in this object."""
so = []
for item in self.items:
i = { 'label':item.label, 'icon':item.icon, 'url':item.url}
if item.active_p():
i['active']=True
if item.items and render_subs:
i['subs'] = item.serializable()
so.append(i)
return so
def encode(self, name="", render_subs=False):
"""return a string containing a javascript data structure
assigned to the menu name
if render_subs is True, we render submenus too"""
return ('<script type="text/javascript">\n <!--\n var %s_items=' % name
#+ json.dumps(self.serializable(render_subs=render_subs), separators=(',',':')) # compact
+ "\n"+ json.dumps(self.serializable(render_subs=render_subs), sort_keys=True, indent=4) # pretty print
+ ';\n // -->\n </script>')

View File

@ -47,10 +47,7 @@
{{ css|safe }}
<!-- End Plinth CSS -->
<!-- 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/plinth.js"></script>
{{ main_menu_js|safe }}
{{ sub_menu_js|safe }}
</head>
<body>
<!--[if lt IE 7]><p class=chromeframe>Your browser is <em>ancient!</em> <a href="http://mozilla.org/firefox">Upgrade to a modern version of Firefox</a> to experience this site.</p><![endif]-->
@ -72,13 +69,13 @@
<div class="container-fluid">
<div class="row-fluid">
{% if nav or sidebar_right or sidebar_left %}
{% if submenu or sidebar_right or sidebar_left %}
<div class="span3">
{% if nav %}
{% if submenu %}
<div class="well sidebar-nav">
{{ nav|safe }}
{% include "menu.html" with menu=submenu %}
</div><!--/.well -->
{% endif %}
{% endif %}
{% if sidebar_left %}
<div class="well sidebar-nav">
{{ sidebar_left|safe }}

View File

@ -2,9 +2,18 @@
{% block add_nav_and_login %}
<div class="nav-collapse">
<script type="text/javascript">
main_menu(main_menu_items);
</script>
<ul class="nav">
{% for item in main_menu.items %}
<li class="{{ item.active_p|yesno:"active," }}">
<a href="{{ item.url }}" class="{{ item.active_p|yesno:"active," }}">
<span class="{{ item.icon }} icon-white nav-icon"></span>
{{ item.label }}
</a>
</li>
{% endfor %}
</ul>
{% 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 %}

36
templates/menu.html Normal file
View File

@ -0,0 +1,36 @@
{% comment %}
#
# This file is part of Plinth.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
{% endcomment %}
<ul class="nav nav-list">
<li class="nav-header">Menu</li>
{% for item in menu.items %}
<li class="{{ item.active_p|yesno:"active," }}">
<a href="{{ item.url }}" class="{{ item.active_p|yesno:"active," }}">
<span class="{{ item.icon }} {{ item.active_p|yesno:"icon-white," }}
sidenav-icon"></span>
{{ item.label }}
</a>
{% if item.items %}
{% include "menu.html" with menu=item %}
{% endif %}
</li>
{% endfor %}
</ul>

View File

@ -1,67 +0,0 @@
function main_menu(items) {
output = '<ul class="nav">'
for (item in items) {
i = items[item];
// Handle active page
if (i["active"]) {
active = ' class="active"';
} else {
active = '';
}
// Line break labels
/*label = i["label"];
if (label.search(" ") != -1) {
label = label.replace(" ", "<br />");
} else {
label = "&nbsp;<br />" + label;
}*/
// Add icon before labels
icon = '<i class="' + i["icon"] + ' icon-white nav-icon"></i>';
label = icon + i["label"];
output = output +'<li' + active + '><a href="' + i["url"] + '"' + active + '>' + label + "</a></li>";
}
output = output + "</ul>";
document.write(output);
}
function render_items(items) {
output = '<ul class="nav nav-list"><li class="nav-header">Menu</li>';
for (item in items) {
i = items[item];
// Handle active page
if (i["active"]) {
active = ' class="active"';
// Add icon before labels
icon = '<i class="' + i["icon"] + ' icon-white sidenav-icon"></i>';
label = icon + i["label"];
} else {
active = '';
// Add icon before labels
icon = '<i class="' + i["icon"] + ' sidenav-icon"></i>';
label = icon + i["label"];
}
output = output +'<li' + active + '><a href="' + i["url"] + '"' + active + '>' + label + "</a></li>";
if (i['subs']) {
output += render_items(i['subs']);
}
}
output = output + "</ul>";
return output
}
function side_menu(items) {
if (items.length == 0) {
return 0;
}
output = render_items(items);
document.write(output);
}

16
util.py
View File

@ -71,25 +71,13 @@ def render_template(template='login_nav', **kwargs):
if kwargs['basehref'] == '':
kwargs['basehref'] = cfg.server_dir
try:
submenu = cfg.main_menu.active_item().encode("sub_menu", render_subs=True)
except AttributeError:
submenu = ""
kwargs['template'] = template
kwargs['main_menu_js'] = cfg.main_menu.encode("main_menu")
kwargs['sub_menu_js'] = submenu
kwargs['main_menu'] = cfg.main_menu
kwargs['submenu'] = cfg.main_menu.active_item()
kwargs['current_url'] = cherrypy.url()
kwargs['username'] = cherrypy.session.get(cfg.session_key)
kwargs['cfg'] = cfg
if not kwargs['nav'] and submenu:
kwargs['nav'] = """ <script type="text/javascript">
<!--
side_menu(sub_menu_items);
// -->
</script>"""
return render_to_string(template + '.html', kwargs)