Add template "theme" feature, albeit global
would be even better to let each user session have something different, but alas this is all-or-nothing for now
This commit is contained in:
parent
f05d50bce3
commit
ea0dc1ea19
8 changed files with 377 additions and 20 deletions
|
@ -2,12 +2,13 @@
|
|||
<%namespace file="/menu.mako" import="main_menu_items" />
|
||||
<%namespace file="/grids/nav.mako" import="grid_index_nav" />
|
||||
<%namespace file="/feedback_dialog.mako" import="feedback_dialog" />
|
||||
<%namespace name="base_meta" file="/base_meta.mako" />
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<title>${self.global_title()} » ${capture(self.title)|n}</title>
|
||||
${self.favicon()}
|
||||
<title>${base_meta.global_title()} » ${capture(self.title)|n}</title>
|
||||
${base_meta.favicon()}
|
||||
${self.header_core()}
|
||||
|
||||
% if not request.rattail_config.production():
|
||||
|
@ -16,7 +17,7 @@
|
|||
</style>
|
||||
% endif
|
||||
|
||||
${self.head_tags()}
|
||||
${base_meta.head_tags()}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -31,8 +32,8 @@
|
|||
|
||||
<div class="global">
|
||||
<a class="home" href="${url('home')}">
|
||||
${self.header_logo()}
|
||||
<span class="global-title">${self.global_title()}</span>
|
||||
${base_meta.header_logo()}
|
||||
<span class="global-title">${base_meta.global_title()}</span>
|
||||
</a>
|
||||
% if master:
|
||||
<span class="global">»</span>
|
||||
|
@ -63,6 +64,16 @@
|
|||
<button type="button" id="feedback">Feedback</button>
|
||||
</div>
|
||||
|
||||
% if expose_theme_picker and request.has_perm('common.change_app_theme'):
|
||||
<div class="after-feedback">
|
||||
${h.form(url('change_theme'), name="theme_changer", method="post")}
|
||||
${h.csrf_token(request)}
|
||||
Theme:
|
||||
${h.select('theme', theme, options=theme_picker_options, id='theme-picker')}
|
||||
${h.end_form()}
|
||||
</div>
|
||||
% endif
|
||||
|
||||
</div><!-- global -->
|
||||
|
||||
<div class="page">
|
||||
|
@ -107,7 +118,7 @@
|
|||
</div><!-- content-wrapper -->
|
||||
|
||||
<div id="footer">
|
||||
${self.footer()}
|
||||
${base_meta.footer()}
|
||||
</div>
|
||||
|
||||
</div><!-- body-wrapper -->
|
||||
|
@ -116,18 +127,12 @@
|
|||
</body>
|
||||
</html>
|
||||
|
||||
<%def name="app_title()">Rattail</%def>
|
||||
|
||||
<%def name="global_title()">${"[STAGE] " if not request.rattail_config.production() else ''}${self.app_title()}</%def>
|
||||
|
||||
<%def name="title()"></%def>
|
||||
|
||||
<%def name="content_title()">
|
||||
<h1>${self.title()}</h1>
|
||||
</%def>
|
||||
|
||||
<%def name="favicon()"></%def>
|
||||
|
||||
<%def name="header_core()">
|
||||
${self.core_javascript()}
|
||||
${self.extra_javascript()}
|
||||
|
@ -155,6 +160,13 @@
|
|||
var session_timeout = ${request.get_session_timeout() or 'null'};
|
||||
var logout_url = '${request.route_url('logout')}';
|
||||
var noop_url = '${request.route_url('noop')}';
|
||||
% if expose_theme_picker and request.has_perm('common.change_app_theme'):
|
||||
$(function() {
|
||||
$('#theme-picker').change(function() {
|
||||
$(this).parents('form:first').submit();
|
||||
});
|
||||
});
|
||||
% endif
|
||||
</script>
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.js') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.feedback.js') + '?ver={}'.format(tailbone.__version__))}
|
||||
|
@ -189,14 +201,6 @@
|
|||
|
||||
<%def name="extra_styles()"></%def>
|
||||
|
||||
<%def name="head_tags()"></%def>
|
||||
|
||||
<%def name="header_logo()"></%def>
|
||||
|
||||
<%def name="footer()">
|
||||
powered by ${h.link_to("Rattail", url('about'))}
|
||||
</%def>
|
||||
|
||||
<%def name="wtfield(form, name, **kwargs)">
|
||||
<div class="field-wrapper${' error' if form[name].errors else ''}">
|
||||
<label for="${name}">${form[name].label}</label>
|
||||
|
|
17
tailbone/templates/base_meta.mako
Normal file
17
tailbone/templates/base_meta.mako
Normal file
|
@ -0,0 +1,17 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
|
||||
<%def name="app_title()">Rattail</%def>
|
||||
|
||||
<%def name="global_title()">${"[STAGE] " if not request.rattail_config.production() else ''}${self.app_title()}</%def>
|
||||
|
||||
<%def name="favicon()">
|
||||
<link rel="icon" type="image/x-icon" href="${request.static_url('tailbone:static/img/rattail.ico')}" />
|
||||
</%def>
|
||||
|
||||
<%def name="head_tags()"></%def>
|
||||
|
||||
<%def name="header_logo()"></%def>
|
||||
|
||||
<%def name="footer()">
|
||||
powered by ${h.link_to("Rattail", url('about'))}
|
||||
</%def>
|
214
tailbone/templates/themes/bobcat/base.mako
Normal file
214
tailbone/templates/themes/bobcat/base.mako
Normal file
|
@ -0,0 +1,214 @@
|
|||
## -*- coding: utf-8; -*-
|
||||
<%namespace file="/menu.mako" import="main_menu_items" />
|
||||
<%namespace file="/grids/nav.mako" import="grid_index_nav" />
|
||||
<%namespace file="/feedback_dialog.mako" import="feedback_dialog" />
|
||||
<%namespace name="base_meta" file="/base_meta.mako" />
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
|
||||
<title>${base_meta.global_title()} » ${capture(self.title)|n}</title>
|
||||
${base_meta.favicon()}
|
||||
${self.header_core()}
|
||||
|
||||
% if not request.rattail_config.production():
|
||||
<style type="text/css">
|
||||
body { background-image: url(${request.static_url('tailbone:static/img/testing.png')}); }
|
||||
</style>
|
||||
% endif
|
||||
|
||||
${base_meta.head_tags()}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="body-wrapper">
|
||||
|
||||
<header>
|
||||
<nav>
|
||||
<ul class="menubar">
|
||||
${main_menu_items()}
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<div class="global">
|
||||
<a class="home" href="${url('home')}">
|
||||
${base_meta.header_logo()}
|
||||
<span class="global-title">${base_meta.global_title()}</span>
|
||||
</a>
|
||||
% if master:
|
||||
<span class="global">»</span>
|
||||
% if master.listing:
|
||||
<span class="global">${index_title}</span>
|
||||
% else:
|
||||
${h.link_to(index_title, index_url, class_='global')}
|
||||
% if parent_url is not Undefined:
|
||||
<span class="global">»</span>
|
||||
${h.link_to(parent_title, parent_url, class_='global')}
|
||||
% elif instance_url is not Undefined:
|
||||
<span class="global">»</span>
|
||||
${h.link_to(instance_title, instance_url, class_='global')}
|
||||
% endif
|
||||
% if master.viewing and grid_index:
|
||||
${grid_index_nav()}
|
||||
% endif
|
||||
% endif
|
||||
% elif index_title:
|
||||
<span class="global">»</span>
|
||||
<span class="global">${index_title}</span>
|
||||
% endif
|
||||
|
||||
<div class="feedback">
|
||||
% if help_url is not Undefined and help_url:
|
||||
${h.link_to("Help", help_url, target='_blank', class_='button')}
|
||||
% endif
|
||||
<button type="button" id="feedback">Feedback</button>
|
||||
</div>
|
||||
|
||||
% if expose_theme_picker and request.has_perm('common.change_app_theme'):
|
||||
<div class="after-feedback">
|
||||
${h.form(url('change_theme'), name="theme_changer", method="post")}
|
||||
${h.csrf_token(request)}
|
||||
Theme:
|
||||
${h.select('theme', theme, options=theme_picker_options, id='theme-picker')}
|
||||
${h.end_form()}
|
||||
</div>
|
||||
% endif
|
||||
|
||||
</div><!-- global -->
|
||||
|
||||
<div class="page">
|
||||
${self.content_title()}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div class="content-wrapper">
|
||||
|
||||
<div id="scrollpane">
|
||||
<div id="content">
|
||||
<div class="inner-content">
|
||||
|
||||
% if request.session.peek_flash('error'):
|
||||
<div class="error-messages">
|
||||
% for error in request.session.pop_flash('error'):
|
||||
<div class="ui-state-error ui-corner-all">
|
||||
<span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-alert"></span>
|
||||
${error}
|
||||
</div>
|
||||
% endfor
|
||||
</div>
|
||||
% endif
|
||||
|
||||
% if request.session.peek_flash():
|
||||
<div class="flash-messages">
|
||||
% for msg in request.session.pop_flash():
|
||||
<div class="ui-state-highlight ui-corner-all">
|
||||
<span style="float: left; margin-right: .3em;" class="ui-icon ui-icon-info"></span>
|
||||
${msg|n}
|
||||
</div>
|
||||
% endfor
|
||||
</div>
|
||||
% endif
|
||||
|
||||
${self.body()}
|
||||
|
||||
</div><!-- inner-content -->
|
||||
</div><!-- content -->
|
||||
</div><!-- scrollpane -->
|
||||
|
||||
</div><!-- content-wrapper -->
|
||||
|
||||
<div id="footer">
|
||||
${base_meta.footer()}
|
||||
</div>
|
||||
|
||||
</div><!-- body-wrapper -->
|
||||
|
||||
${feedback_dialog()}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
<%def name="title()"></%def>
|
||||
|
||||
<%def name="content_title()">
|
||||
<h1>${self.title()}</h1>
|
||||
</%def>
|
||||
|
||||
<%def name="header_core()">
|
||||
|
||||
## ${h.stylesheet_link('https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.2/css/bulma.min.css')}
|
||||
|
||||
${self.core_javascript()}
|
||||
${self.extra_javascript()}
|
||||
${self.core_styles()}
|
||||
${self.extra_styles()}
|
||||
|
||||
## TODO: should this be elsewhere / more customizable?
|
||||
% if dform is not Undefined:
|
||||
<% resources = dform.get_widget_resources() %>
|
||||
% for path in resources['js']:
|
||||
${h.javascript_link(request.static_url(path))}
|
||||
% endfor
|
||||
% for path in resources['css']:
|
||||
${h.stylesheet_link(request.static_url(path))}
|
||||
% endfor
|
||||
% endif
|
||||
</%def>
|
||||
|
||||
<%def name="core_javascript()">
|
||||
${self.jquery()}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/lib/jquery.ui.menubar.js'))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/lib/jquery.loadmask.min.js'))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/lib/jquery.ui.timepicker.js'))}
|
||||
<script type="text/javascript">
|
||||
var session_timeout = ${request.get_session_timeout() or 'null'};
|
||||
var logout_url = '${request.route_url('logout')}';
|
||||
var noop_url = '${request.route_url('noop')}';
|
||||
% if expose_theme_picker and request.has_perm('common.change_app_theme'):
|
||||
$(function() {
|
||||
$('#theme-picker').change(function() {
|
||||
$(this).parents('form:first').submit();
|
||||
});
|
||||
});
|
||||
% endif
|
||||
</script>
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.js') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/tailbone.feedback.js') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.javascript_link(request.static_url('tailbone:static/js/jquery.ui.tailbone.js') + '?ver={}'.format(tailbone.__version__))}
|
||||
</%def>
|
||||
|
||||
<%def name="jquery()">
|
||||
${h.javascript_link('https://code.jquery.com/jquery-1.12.4.min.js')}
|
||||
${h.javascript_link('https://code.jquery.com/ui/{}/jquery-ui.min.js'.format(request.rattail_config.get('tailbone', 'jquery_ui.version', default='1.11.4')))}
|
||||
</%def>
|
||||
|
||||
<%def name="extra_javascript()"></%def>
|
||||
|
||||
<%def name="core_styles()">
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/normalize.css'))}
|
||||
${self.jquery_theme()}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/jquery.ui.menubar.css'))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/jquery.loadmask.css'))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/jquery.ui.timepicker.css'))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/jquery.ui.tailbone.css') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/base.css') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/layout.css') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/grids.css') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/filters.css') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/forms.css') + '?ver={}'.format(tailbone.__version__))}
|
||||
${h.stylesheet_link(request.static_url('tailbone:static/css/diffs.css') + '?ver={}'.format(tailbone.__version__))}
|
||||
</%def>
|
||||
|
||||
<%def name="jquery_theme()">
|
||||
${h.stylesheet_link('https://code.jquery.com/ui/1.11.4/themes/excite-bike/jquery-ui.css')}
|
||||
</%def>
|
||||
|
||||
<%def name="extra_styles()"></%def>
|
||||
|
||||
<%def name="wtfield(form, name, **kwargs)">
|
||||
<div class="field-wrapper${' error' if form[name].errors else ''}">
|
||||
<label for="${name}">${form[name].label}</label>
|
||||
<div class="field">
|
||||
${form[name](**kwargs)}
|
||||
</div>
|
||||
</div>
|
||||
</%def>
|
Loading…
Add table
Add a link
Reference in a new issue