瀏覽代碼

clean user interface + add js calculator tool

damien 11 年之前
父節點
當前提交
bbebe8ed6a

+ 4 - 41
pboard/pboard/controllers/root.py 查看文件

@@ -5,7 +5,6 @@ from tg import expose, flash, require, url, lurl, request, redirect, tmpl_contex
5 5
 from tg.i18n import ugettext as _, lazy_ugettext as l_
6 6
 from tg import predicates
7 7
 from pboard import model
8
-from pboard.controllers.secure import SecureController
9 8
 from pboard.model import DBSession, metadata
10 9
 from tgext.admin.tgadminconfig import TGAdminConfig
11 10
 from tgext.admin.controller import AdminController
@@ -17,6 +16,7 @@ import pboard.model as pbm
17 16
 import pboard.controllers as pbc
18 17
 from pboard.lib import dbapi as pld
19 18
 from pboard.controllers import api as pbca
19
+from pboard.controllers import debug as pbcd
20 20
 
21 21
 import pboard.model.data as pbmd
22 22
 
@@ -37,13 +37,12 @@ class RootController(BaseController):
37 37
     must be wrapped around with :class:`tg.controllers.WSGIAppController`.
38 38
 
39 39
     """
40
-    secc = SecureController()
41 40
     admin = AdminController(model, DBSession, config_type=TGAdminConfig)
42 41
 
42
+    api   = pbca.PODApiController()
43
+    debug = pbcd.DebugController()
43 44
     error = ErrorController()
44 45
 
45
-    api = pbca.PODApiController()
46
-    
47 46
     def _before(self, *args, **kw):
48 47
         tmpl_context.project_name = "pboard"
49 48
 
@@ -52,39 +51,6 @@ class RootController(BaseController):
52 51
         """Handle the front-page."""
53 52
         return dict()
54 53
 
55
-    @expose('pboard.templates.about')
56
-    def about(self):
57
-        """Handle the 'about' page."""
58
-        return dict(page='about')
59
-
60
-    @expose('pboard.templates.environ')
61
-    def environ(self):
62
-        """This method showcases TG's access to the wsgi environment."""
63
-        return dict(page='environ', environment=request.environ)
64
-
65
-    @expose('pboard.templates.data')
66
-    @expose('json')
67
-    def data(self, **kw):
68
-        """This method showcases how you can use the same controller for a data page and a display page"""
69
-        return dict(page='data', params=kw)
70
-        
71
-    @expose('pboard.templates.iconset')
72
-    def iconset(self, **kw):
73
-        """This method showcases how you can use the same controller for a data page and a display page"""
74
-        return dict(page='data', params=kw)
75
-        
76
-        
77
-    @expose('pboard.templates.index')
78
-    @require(predicates.has_permission('manage', msg=l_('Only for managers')))
79
-    def manage_permission_only(self, **kw):
80
-        """Illustrate how a page for managers only works."""
81
-        return dict(page='managers stuff')
82
-
83
-    @expose('pboard.templates.index')
84
-    @require(predicates.is_user('editor', msg=l_('Only for the editor')))
85
-    def editor_user_only(self, **kw):
86
-        """Illustrate how a page exclusive for the editor works."""
87
-        return dict(page='editor stuff')
88 54
 
89 55
     @expose('pboard.templates.login')
90 56
     def login(self, came_from=lurl('/')):
@@ -121,18 +87,15 @@ class RootController(BaseController):
121 87
         redirect(came_from)
122 88
         
123 89
     @expose('pboard.templates.document')
90
+    @require(predicates.in_group('user', msg=l_('Please login to access this page')))
124 91
     def document(self, node=0, came_from=lurl('/')):
125 92
         """show the user dashboard"""
126 93
         import pboard.model.data as pbmd
127 94
         
128 95
         # loRootNodeList   = pbm.DBSession.query(pbmd.PBNode).filter(pbmd.PBNode.parent_id==None).order_by(pbmd.PBNode.node_order).all()
129
-        print "===> AAA"
130 96
         loRootNodeList = pld.buildTreeListForMenu()
131
-        print "===> BBB"
132 97
         liNodeId         = max(int(node), 1) # show node #1 if no selected node
133 98
         loCurrentNode    = pbm.DBSession.query(pbmd.PBNode).filter(pbmd.PBNode.node_id==liNodeId).one()
134
-        print "===> CCC"
135 99
         loNodeStatusList = pbmd.PBNodeStatus.getList()
136
-        print "===> DDD"
137 100
         return dict(root_node_list=loRootNodeList, current_node=loCurrentNode, node_status_list = loNodeStatusList)
138 101
 

+ 0 - 190
pboard/pboard/templates/about.mak 查看文件

@@ -1,190 +0,0 @@
1
-<%inherit file="local:templates.master"/>
2
-
3
-<%def name="title()">
4
-Learning TurboGears 2.3: Quick guide to the Quickstart pages.
5
-</%def>
6
-
7
-   <div class="row">
8
-      <div class="span12">
9
-        <div class="page-header">
10
-          <h2>Architectural basics of a quickstart TG2 site.</h2>
11
-        </div>
12
-
13
-        <p>The TG2 quickstart command produces this basic TG site. Here's how it works.</p>
14
-      </div>
15
-
16
-      <div class="span4">
17
-        <div class="well" style="padding: 8px 0;">
18
-          <ul class="nav nav-list">
19
-            <li class="nav-header">About Architecture</li>
20
-            <li><a href="#data-model">Data Model</a></li>
21
-            <li><a href="#url-structure">URL Structure</a></li>
22
-            <li><a href="#template-reuse">Web page element's reuse</a></li>
23
-            <li py:if="tg.auth_stack_enabled" class="nav-header">Authentication</li>
24
-            <li py:if="tg.auth_stack_enabled"><a href="#authentication">Authorization and Authentication</a></li>
25
-          </ul>
26
-        </div>
27
-
28
-        <div class="well" id="data-model">
29
-          <h3>Code my data model</h3>
30
-
31
-          <p>When you want a model for storing favorite links or wiki content, the
32
-          <code>/model</code> folder in your site is ready to go.</p>
33
-
34
-          <p>You can build a dynamic site without any data model at all. There still be a
35
-          default data-model template for you if you didn't enable authentication and
36
-          authorization in quickstart. If you have enabled authorization, the auth
37
-          data-model is ready-made.</p>
38
-        </div>
39
-
40
-        <div class="well" id="url-structure">
41
-          <h3>Design my URL structure</h3>
42
-
43
-          <p>The "<code>root.py</code>" file under the <code>/controllers</code> folder has
44
-          your URLs. When you called this url (<code><a href=
45
-          "${tg.url('/about')}">about</a></code>), the command went through the
46
-          RootController class to the <code>about()</code> method.</p>
47
-
48
-          <p>Those Python methods are responsible to create the dictionary of variables
49
-          that will be used in your web views (template).</p>
50
-        </div>
51
-      </div>
52
-
53
-      <div class="span8"><img src=
54
-      "http://www.turbogears.org/2.1/docs/_images/tg2_files.jpg" alt=
55
-      "TurboGears2 quickstarted project" /></div>
56
-    </div>
57
-
58
-    <div class="row">
59
-      <div class="span12" id="template-reuse">
60
-        <h3>Reuse the web page elements</h3>
61
-
62
-        <p>A web page viewed by user could be constructed by single or several reusable
63
-        templates under <code>/templates</code>. Take 'about' page for example, each
64
-        reusable templates generating a part of the page. We'll cover them in the order of
65
-        where they are found, listed near the top of the about.html template</p>
66
-
67
-        <div class="row">
68
-          <div class="span6">
69
-            <p><strong><span class="label label-info">header.html</span></strong> - The
70
-            "header.html" template contains the HTML code to display the 'header': The div,
71
-            the h1 tag, and the subtitle are there, and the the blue gradient, TG2 logo,
72
-            are placed by way of the .css file (from style.css) are all at the top of every
73
-            page it is included on. When the "about.html" template is called, it includes
74
-            this "header.html" template (and the others) with a <code>&lt;xi:include
75
-            /&gt;</code> tag, part of the Genshi templating system. The "header.html"
76
-            template is not a completely static HTML -- it also includes (via
77
-            <code>&lt;xi:include/&gt;</code> tag) "master.html", which dynamically displays
78
-            the current page name with a Genshi template method called "replace" with the
79
-            code: <code>&lt;span py:replace="page"/&gt;</code>. It means replace this
80
-            <code>&lt;span /&gt;</code> region with the contents found in the variable
81
-            'page' that has been sent in the dictionary to this "about.html" template, and
82
-            is available through that namespace for use by this "header.html" template.
83
-            That's how it changes in the header depending on what page you are
84
-            visiting.</p>
85
-
86
-            <p><strong><span class="label label-info">sidebars.html</span></strong> - The
87
-            sidebars (navigation areas on the right side of the page) are generated as two
88
-            separate <code>py:def</code> blocks in the "sidebars.html" template. The
89
-            <code>py:def</code> construct is best thought of as a "macro" code... a simple
90
-            way to separate and reuse common code snippets. All it takes to include these
91
-            on the "about.html" page template is to write</p>
92
-            <pre><span>$</span>{sidebar_top()}
93
-<span>$</span>{sidebar_bottom()}
94
-  </pre>in the page where they are wanted. CSS styling (in "/public/css/style.css") floats
95
-  them off to the right side. You can remove a sidebar or add more of them, and the CSS
96
-  will place them one atop the other.
97
-
98
-            <p>This is, of course, also exactly how the header and footer templates are
99
-            also displayed in their proper places, but we'll cover that in the
100
-            "master.html" template below.</p>
101
-
102
-            <p>Oh, and in sidebar_top we've added a dynamic menu that shows the link to
103
-            this page at the top when you're at the "index" page, and shows a link to the
104
-            Home (index) page when you're here. Study the "sidebars.html" template to see
105
-            how we used <code>py:choose</code> for that.</p>
106
-          </div>
107
-
108
-          <div class="span6">
109
-            <p><strong><span class="label label-info">footer.html</span></strong> - The
110
-            "footer.html" block is simple, but also utilizes a special "replace" method to
111
-            set the current YEAR in the footer copyright message. The code is:</p>
112
-            <pre>
113
-  &lt;span py:replace="now.strftime('%Y')"&gt;
114
-  </pre>and it uses the variable "now" that was passed in with the dictionary of variables.
115
-  But because "now" is a datetime object, we can use the Python <code>"strftime()"</code>
116
-  method with the "replace" call to say "Just Display The Year Here". Simple, elegant; we
117
-  format the date display in the template (the View in the Model/View/Controller
118
-  architecture) rather than formatting it in the Controller method and sending it to the
119
-  template as a string variable.
120
-
121
-            <p><strong><span class="label label-info">master.html</span></strong> - The
122
-            "master.html" template is called last, by design. The "master.html" template
123
-            controls the overall design of the page we're looking at, calling first the
124
-            "header" py:def macro, then the putting everything from this "about.html"
125
-            template into the "main_content" div, and then calling the "footer" macro at
126
-            the end. Thus the "master.html" template provides the overall architecture for
127
-            each page in this site.</p>
128
-
129
-            <p>But why then shouldn't we call it first? Isn't it the most important?
130
-            Perhaps, but that's precisely why we call it LAST. The "master.html" template
131
-            needs to know where to find everything else, everything that it will use in
132
-            py:def macros to build the page. So that means we call the other templates
133
-            first, and then call "master.html".</p>
134
-
135
-            <p>There's more to the "master.html" template... study it to see how the
136
-            &lt;title&gt; tags and static JS and CSS files are brought into the page.
137
-            Templating with Genshi is a powerful tool and we've only scratched the surface.
138
-            There are also a few little CSS tricks hidden in these pages, like the use of a
139
-            "clearingdiv" to make sure that your footer stays below the sidebars and always
140
-            looks right. That's not TG2 at work, just CSS. You'll need all your skills to
141
-            build a fine web app, but TG2 will make the hard parts easier so that you can
142
-            concentrate more on good design and content rather than struggling with
143
-            mechanics.</p>
144
-          </div>
145
-
146
-          <div class="span12" id="authentication" py:if="tg.auth_stack_enabled">
147
-            <h3>Authentication &amp; Authorization in a TG2 site.</h3>
148
-
149
-            <p>If you have access to this page, this means you have enabled authentication
150
-            and authorization in the quickstart to create your project.</p>
151
-
152
-            <p>The paster command will have created a few specific controllers for you. But
153
-            before you go to play with those controllers you'll need to make sure your
154
-            application has been properly bootstapped. This is dead easy, here is how to do
155
-            this:</p>
156
-            <pre>paster setup-app development.ini</pre>
157
-
158
-            <p>inside your application's folder and you'll get a database setup (using the
159
-            preferences you have set in your development.ini file). This database will also
160
-            have been prepopulated with some default logins/passwords so that you can test
161
-            the secured controllers and methods.</p>
162
-
163
-            <p>To change the comportement of this setup-app command you just need to edit
164
-            the <code>websetup.py</code> file.</p>
165
-
166
-            <p>Now try to visiting the <a href=
167
-            "${tg.url('/manage_permission_only')}">manage_permission_only</a> URL. You will
168
-            be challenged with a login/password form.</p>
169
-
170
-            <p>Only managers are authorized to visit this method. You will need to log-in
171
-            using:</p>
172
-            <pre>login: manager
173
-password: managepass</pre>
174
-
175
-            <p>Another protected resource is <a href=
176
-            "${tg.url('/editor_user_only')}">editor_user_only</a>. This one is protected by
177
-            a different set of permissions. You will need to be <code>editor</code> with a
178
-            password of <code>editpass</code> to be able to access it.</p>
179
-
180
-            <p>The last kind of protected resource in this quickstarted app is a full so
181
-            called <a href="${tg.url('/secc')}">secure controller</a>. This controller is
182
-            protected globally. Instead of having a @require decorator on each method, we
183
-            have set an allow_only attribute at the class level. All the methods in this
184
-            controller will require the same level of access. You need to be manager to
185
-            access <a href="${tg.url('/secc')}">secc</a> or <a href=
186
-            "${tg.url('/secc/some_where')}">secc/some_where</a>.</p>
187
-          </div>
188
-        </div>
189
-      </div>
190
-    </div>

+ 0 - 91
pboard/pboard/templates/data.mak 查看文件

@@ -1,91 +0,0 @@
1
-<%inherit file="local:templates.master"/>
2
-
3
-<%def name="title()">
4
-  Welcome to TurboGears 2.3, standing on the shoulders of giants, since 2007
5
-</%def>
6
-
7
-<h2>Content Type Dispatch</h2>
8
-<p>
9
-This page shows how you can provide multiple pages
10
-directly from the same controller method.  This page is generated 
11
-from the expose decorator with the template defintion provided.
12
-You can provide a url with parameters and this page will display
13
-the parameters as html, and the json version will express
14
-the entries as JSON.  Here, try it out: <a href="/data.html?a=1&b=2">/data.html?a=1&b=2</a>
15
-</p>
16
-
17
-<p>Click here for the <a href="${tg.url('/data.json', params=params)}">JSON Version of this page.</a></p>
18
-<p>The data provided in the template call is: 
19
-    <table>
20
-        %for key, value in params.items():
21
-            <tr>
22
-                <td>${key}</td>
23
-                <td>${value}</td>
24
-            </tr>
25
-        %endfor
26
-    </table>
27
-
28
-  <div class="well span3 text-center">
29
-    <div>
30
-    </div>
31
-    <table id='keyboard'>
32
-      <tr>
33
-        <td colspan="5">
34
-          <input type='text' class="text-right" id='calculation'/><br/>
35
-          <input type='text' class="text-right" readonly id='result'/>
36
-        </td>
37
-      </tr>
38
-      <tr>
39
-        <td><span class='btn'>7</span></td>
40
-        <td><span class='btn'>8</span></td>
41
-        <td><span class='btn'>9</span></td>
42
-        <td><span class='btn'>(</span></td>
43
-        <td><span class='btn'>)</span></td>
44
-      </tr>
45
-      <tr>
46
-        <td><span class='btn'>4</span></td>
47
-        <td><span class='btn'>5</span></td>
48
-        <td><span class='btn'>6</span></td>
49
-        <td><span class='btn'>-</span></td>
50
-        <td><span class='btn'>+</span></td>
51
-      </tr>
52
-      <tr>
53
-        <td><span class='btn'>1</span></td>
54
-        <td><span class='btn'>2</span></td>
55
-        <td><span class='btn'>3</span></td>
56
-        <td><span class='btn'>/</span></td>
57
-        <td><span class='btn'>*</span></td>
58
-      </tr>
59
-      <tr>
60
-        <td><span class='btn'>.</span></td>
61
-        <td><span class='btn'>0</span></td>
62
-        <td><span class='btn'>%</span></td>
63
-        <td><span class='btn btn-success'>=</span></td>
64
-        <td><span class='btn btn-danger'>C</span></td>
65
-      </tr>
66
-    </table>
67
-    <script src="http://code.jquery.com/jquery.js"></script>
68
-    <script src="${tg.url('/javascript/bootstrap.min.js')}"></script>
69
-
70
-    <script>
71
-      $(document).ready(function() {
72
-        $('#keyboard span').on('click', function (e) {
73
-          current_value = $(this).text()
74
-          if(current_value=='C') {
75
-            $('#calculation').val('');
76
-            $('#result').val('');
77
-          } else if(current_value=='=') {
78
-            string = $('#calculation').val().replace(/[^0-9+-/\*\%\(\)]/gi, ''); // replace('/[^0-9()*/-+]/g', "");
79
-            console.log("Compute value of "+string)
80
-            calculation = eval(string);
81
-            console.log("Result is: "+calculation)
82
-            $('#result').val(calculation)
83
-          } else {
84
-            field = $('#calculation')
85
-            field.oldval = field.val();
86
-            field.val(field.oldval+current_value)
87
-          }
88
-        });
89
-      });
90
-    </script>
91
-  </div>

pboard/pboard/templates/iconset.mak → pboard/pboard/templates/debug/iconset.mak 查看文件

@@ -1,35 +1,25 @@
1 1
 <%inherit file="local:templates.master"/>
2 2
 
3
+<%def name="title()">
4
+  debug: icon set
5
+</%def>
3 6
 
4
-        <style>
5
-            body{
6
-                padding-top: 60px;
7
-            }
8
-            #icon_grid li{
9
-                width: 23%;
10
-            }
11
-        </style>
12
-
13
-        <div class="navbar navbar-inverse navbar-fixed-top">
14
-            <div class="navbar-inner">
15
-                <div class="container">
16
-                    <a class="brand" href="./index.html">Glyphicons</a>
17
-                </div>
18
-            </div>
19
-        </div>
20
-        
21
-        <div class="container">
22
-            
23
-            <div class="hero-unit">
24
-                List Of icons
25
-            </div>
26
-            
27
-            <div id="icon_grid">
28
-                <ul class="inline">
29
-
30
-                </ul>
31
-            </div>
32
-        </div>
7
+    <style>
8
+        body{
9
+            padding-top: 60px;
10
+        }
11
+        #icon_grid li{
12
+            width: 23%;
13
+        }
14
+    </style>
15
+
16
+    <div class="container">
17
+      <h1>List of icons</h1>
18
+      <div id="icon_grid">
19
+        <ul class="inline">
20
+        </ul>
21
+      </div>
22
+    </div>
33 23
 
34 24
 
35 25
     <script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>

+ 0 - 23
pboard/pboard/templates/environ.mak 查看文件

@@ -1,23 +0,0 @@
1
-<%inherit file="local:templates.master"/>
2
-
3
-<%def name="title()">
4
-  Learning TurboGears 2.3: Information about TG and WSGI
5
-</%def>
6
-
7
-<h2>The WSGI nature of the framework</h2>
8
-  <p>In this page you can see all the WSGI variables your request object has, 
9
-     the ones in capital letters are required by the spec, then a sorted by
10
-     component list of variables provided by the Components, and at last
11
-     the "wsgi." namespace with very useful information about your WSGI Server</p>
12
-  <p>The keys in the environment are: 
13
-  <table class="table">
14
-      %for key in sorted(environment):
15
-      <tr>
16
-          <td>${key}</td>
17
-          <td>${environment[key]}</td>
18
-      </tr>
19
-      %endfor
20
-  </table>
21
-
22
-  </p>
23
-

+ 120 - 23
pboard/pboard/templates/master.mak 查看文件

@@ -39,6 +39,11 @@
39 39
         }
40 40
       }
41 41
       
42
+      /* vertical align icons in legend nodes */
43
+      legend > i {
44
+        vertical-align: baseline !important;
45
+      }
46
+      
42 47
 
43 48
 div.pod-toolbar {
44 49
   visibility: hidden;
@@ -78,6 +83,10 @@ body { padding-top: 60px; }
78 83
     body { padding-top: 0px; }
79 84
 }
80 85
 
86
+ul.nav li.dropdown:hover > ul.dropdown-menu {
87
+    display: block;    
88
+}
89
+
81 90
     </style>
82 91
 </head>
83 92
 <body class="${self.body_class()}">
@@ -447,6 +456,27 @@ tr:Hover td div.pod-toolbar {
447 456
 
448 457
 $('.item-with-data-popoverable').popover({ html: true});
449 458
 
459
+      /** Make calculator available on all pages */
460
+      $(document).ready(function() {
461
+        $('#keyboard span').on('click', function (e) {
462
+          current_value = $(this).text()
463
+          if(current_value=='C') {
464
+            $('#calculation').val('');
465
+            $('#result').val('');
466
+          } else if(current_value=='=') {
467
+            string = $('#calculation').val().replace(/[^0-9+-/\*\%\(\)]/gi, ''); // replace('/[^0-9()*/-+]/g', "");
468
+            console.log("Compute value of "+string)
469
+            calculation = eval(string);
470
+            console.log("Result is: "+calculation)
471
+            $('#result').val(calculation)
472
+          } else {
473
+            field = $('#calculation')
474
+            field.oldval = field.val();
475
+            field.val(field.oldval+current_value)
476
+          }
477
+        });
478
+      });
479
+
450 480
             </script>
451 481
 </body>
452 482
 
@@ -489,34 +519,94 @@ $('.item-with-data-popoverable').popover({ html: true});
489 519
                 Home
490 520
               </a>
491 521
             </li>
522
+          % if request.identity:
492 523
             <li>
493 524
               <a href="${tg.url('/document')}"><i class="icon-g-book-open"></i> ${_('Documents')}</a>
494 525
             </li>
495
-            <li>
496
-              <a title="${_('Toggle view mode: narrow')}" id='view-size-toggle-button-small' style="display: none;"><i class='icon-g-eye-open'></i> ${_('View mode')}</a>
497
-              <a title="${_('Toggle view mode: medium')}" id='view-size-toggle-button-medium'><i class='icon-g-eye-open'></i> ${_('View mode')}</a>
498
-              <a title="${_('Toggle view mode: large')}" id='view-size-toggle-button-large' style="display: none;"><i class='icon-g-eye-open'></i> ${_('View mode')}</a>
526
+
527
+            <li title=" ${_('Toggle view mode [narrow, medium, large]')}">
528
+              <a title="${_('Toggle view mode: narrow')}" id='view-size-toggle-button-small' style="display: none;"><i class='icon-g-eye-open'></i></a>
529
+              <a title="${_('Toggle view mode: medium')}" id='view-size-toggle-button-medium'><i class='icon-g-eye-open'></i></a>
530
+              <a title="${_('Toggle view mode: large')}" id='view-size-toggle-button-large' style="display: none;"><i class='icon-g-eye-open'></i></a>
499 531
             </li>
500 532
 
501
-            <li>
533
+            <li title="Rebuild document index">
502 534
             % if current_node is UNDEFINED:
503
-              <a href="${tg.url('/api/reindex_nodes?back_to_node_id=0')}"><i class="icon-g-refresh"></i> Reindex documents</a>
535
+              <a href="${tg.url('/api/reindex_nodes?back_to_node_id=0')}"><i class="icon-g-refresh"></i></a>
504 536
             % else:
505
-              <a href="${tg.url('/api/reindex_nodes?back_to_node_id=%i'%(current_node.node_id))}"><i class="icon-g-refresh"></i> Reindex documents</a>
537
+              <a href="${tg.url('/api/reindex_nodes?back_to_node_id=%i'%(current_node.node_id))}"><i class="icon-g-refresh"></i></a>
506 538
             % endif
507 539
             </li>
508 540
 
509
-          % if request.identity:
541
+            <li class="dropdown" title="Calculator">
542
+              <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-g-calculator"></i></a>
543
+              <ul class="dropdown-menu pull-left">
544
+                <li class="text-center">
545
+                  <fieldset>
546
+                    <legend><i class="icon-g-calculator"></i> Calculator</legend>
547
+                    <table id='keyboard' style="margin:0.2em;">
548
+                      <tr>
549
+                        <td colspan="5">
550
+                          <input type='text' class="text-right" id='calculation'/><br/>
551
+                          <input type='text' class="text-right" readonly id='result'/>
552
+                        </td>
553
+                      </tr>
554
+                      <tr>
555
+                        <td><span class='btn'>7</span></td>
556
+                        <td><span class='btn'>8</span></td>
557
+                        <td><span class='btn'>9</span></td>
558
+                        <td><span class='btn'>(</span></td>
559
+                        <td><span class='btn'>)</span></td>
560
+                      </tr>
561
+                      <tr>
562
+                        <td><span class='btn'>4</span></td>
563
+                        <td><span class='btn'>5</span></td>
564
+                        <td><span class='btn'>6</span></td>
565
+                        <td><span class='btn'>-</span></td>
566
+                        <td><span class='btn'>+</span></td>
567
+                      </tr>
568
+                      <tr>
569
+                        <td><span class='btn'>1</span></td>
570
+                        <td><span class='btn'>2</span></td>
571
+                        <td><span class='btn'>3</span></td>
572
+                        <td><span class='btn'>/</span></td>
573
+                        <td><span class='btn'>*</span></td>
574
+                      </tr>
575
+                      <tr>
576
+                        <td><span class='btn'>.</span></td>
577
+                        <td><span class='btn'>0</span></td>
578
+                        <td><span class='btn'>%</span></td>
579
+                        <td><span class='btn btn-success'>=</span></td>
580
+                        <td><span class='btn btn-danger'>C</span></td>
581
+                      </tr>
582
+                    </table>
583
+                  </fieldset>
584
+                  <p></p>
585
+               </ul>
586
+            </li>
587
+
588
+
589
+          % endif
590
+          
591
+          % if request.identity and request.identity['repoze.who.userid']=='damien@accorsi.info':
510 592
             <li class="dropdown">
511 593
               <a href="#" class="dropdown-toggle" data-toggle="dropdown">Admin <b class="caret"></b></a>
512 594
               <ul class="dropdown-menu">
513 595
                 <li><a href="${tg.url('/admin')}">Manage</a></li>
514
-                <li><a href="${tg.url('/about')}">About</a></li>
515
-                <li><a href="${tg.url('/data')}">Serving Data</a></li>
516
-                <li><a href="${tg.url('/environ')}">WSGI Environment</a></li>
517
-                <li><a href="${tg.url('/iconset')}"><i class="icon-g-show-thumbnails"></i> ${_('Icons')}</a></li>
518 596
               </ul>
519 597
             </li>
598
+            
599
+            <li class="dropdown">
600
+              <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-g-adjust"></i> Debug <b class="caret"></b></a>
601
+              <ul class="dropdown-menu">
602
+                <li><a href="${tg.url('/debug/iconset')}">icon set</a></li>
603
+                <li><a href="${tg.url('/debug/environ')}">request.environ</a></li>
604
+                <li><a href="${tg.url('/debug/identity')}">request.identity</a></li>
605
+              </ul>
606
+            </li>
607
+            
608
+            
609
+            
520 610
           % endif
521 611
           </ul>
522 612
           <ul class="nav pull-right">
@@ -527,23 +617,30 @@ $('.item-with-data-popoverable').popover({ html: true});
527 617
                   <li class="text-center">
528 618
                     <form action="${tg.url('/login_handler')}">
529 619
                       <fieldset>
530
-                        <legend>Sign in</legend>
531
-                      <input class="span2" type="text" id="login" name="login" placeholder="email...">
532
-                      <input class="span2" type="password" id="password" name="password" placeholder="password...">
533
-                      <div class="span2 control-group">
534
-                        Remember me <input type="checkbox" id="loginremember" name="remember" value="2252000"/>
535
-                      </div>
536
-                      <input type="submit" id="submit" value="Login" />
620
+                        <legend><i class="icon-g-keys" style="vertical-align: baseline !important;"></i> Login</legend>
621
+                        <input class="span2" type="text" id="login" name="login" placeholder="email...">
622
+                        <input class="span2" type="password" id="password" name="password" placeholder="password...">
623
+                        <div class="span2 control-group">
624
+                          Remember me <input type="checkbox" id="loginremember" name="remember" value="2252000"/>
625
+                        </div>
626
+                        <input type="submit" id="submit" value="Login" />
537 627
                       </fieldset>
538 628
                     </form>
539
-                   <li class="divider"></li>
540
-                   <li><a href="">Register</a></li>
541 629
                  </ul>
542 630
               </li>
543 631
             % else:
544
-              <li>
545
-                <a href="${tg.url('/logout_handler')}"><i class="icon-off"></i> Logout</a>
632
+              <li class="dropdown">
633
+                <a href="#" class="dropdown-toggle" data-toggle="dropdown"><i class="icon-user"></i> ${request.identity['user']}</a>
634
+                <ul class="dropdown-menu pull-right">
635
+                  <li class="text-center">
636
+                    <fieldset>
637
+                      <legend><i class="icon-g-keys"></i> Logout</legend>
638
+                      <a class="btn btn-danger" href="${tg.url('/logout_handler')}">Logout <i class="icon-off icon-white"></i> </a>
639
+                    </fieldset>
640
+                    <p></p>
641
+                 </ul>
546 642
               </li>
643
+              
547 644
             % endif
548 645
           </ul>
549 646