Revision 8afc06d1
b/astakos/im/static/im/cloudbar/README.rst | ||
---|---|---|
1 |
Cloudbar |
|
2 |
======== |
|
3 |
|
|
4 |
Cloudbar is a project to provide common navigation user experience |
|
5 |
between services that share common authentication mechanism and user |
|
6 |
entries but get deployed on different domains and may not share |
|
7 |
common frontend themes/templates. |
|
8 |
|
|
9 |
The project consists of a javascript file which once imported in a |
|
10 |
html page handles the automatic creation and styling of a bar that |
|
11 |
is placed on top of the page (first body element absolutely |
|
12 |
positioned on top). Since the addition of the bar may break the |
|
13 |
current layout of the site once imported the script tries to load an |
|
14 |
additional css located in the same url as the script itself named by |
|
15 |
the ``CLOUDBAR_ACTIVE_SERVICE`` configuration and prefixed by *service_* so |
|
16 |
that css changes can be applied without touching the page native styles. |
|
17 |
|
|
18 |
The bar contains links to the refered services application urls, and |
|
19 |
depending on if the user is authenticated links to account pages |
|
20 |
(login, change profile, logout etc.). |
|
21 |
|
|
22 |
To identify if a user is authenticated the script checks of a |
|
23 |
specific cookie which can be configured using ``CLOUDBAR_COOKIE_NAME`` setting |
|
24 |
contains valid data which should match the following format:: |
|
25 |
|
|
26 |
<username or email>|<authentication token> |
|
27 |
|
|
28 |
|
|
29 |
Usage |
|
30 |
----- |
|
31 |
|
|
32 |
Each page that wants to display the navigation bar should: |
|
33 |
|
|
34 |
- Include one of the latest jquery builds. |
|
35 |
- Set the ``CLOUDBAR_COOKIE_NAME`` variable containing info about the username |
|
36 |
and the authentication status of the current visitor of the page. |
|
37 |
- Set the ``CLOUDBAR_ACTIVE_SERVICE`` to the id of the service the current |
|
38 |
page refers to so that script cat set the appropriate active styles to |
|
39 |
the services menu for services ids see ``SERVICES_LINK`` |
|
40 |
object in cloudbar.js. |
|
41 |
- Set the ``CLOUDBAR_LOCATION`` to the url where bar files are served from. |
|
42 |
- Include the servicesbar.js script. |
|
43 |
|
|
44 |
|
|
45 |
Example |
|
46 |
******* |
|
47 |
|
|
48 |
.. codeblock:: javascript |
|
49 |
|
|
50 |
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> |
|
51 |
<script> |
|
52 |
var CLOUDBAR_COOKIE_NAME = '_pithos2_a'; |
|
53 |
var CLOUDBAR_ACTIVE_SERVICE = 'cloud'; |
|
54 |
var CLOUDBAR_LOCATION = "http://accounts.cloud.grnet.gr/cloudbar/"; |
|
55 |
|
|
56 |
$(document).ready(function(){ |
|
57 |
$.getScript(CLOUDBAR_LOC + 'cloudbar.js'); |
|
58 |
}) |
|
59 |
</script> |
|
60 |
|
|
61 |
|
|
62 |
Build styles |
|
63 |
------------ |
|
64 |
|
|
65 |
Cloudbar uses `less-css <http://www.lesscss.org>`_ for css styles |
|
66 |
definitions. To build the less file you need the bootstrap less files |
|
67 |
available on |
|
68 |
`bootstrap github repository <https://github.com/twitter/bootstrap/>`. |
|
69 |
|
|
70 |
You can build the styles using the following command:: |
|
71 |
|
|
72 |
$ lessc --include-path=<path/to/bootstrap> cloudbar.less > cloudbar.css |
|
73 |
|
b/astakos/im/static/im/cloudbar/cloudbar.css | ||
---|---|---|
1 |
/*! |
|
2 |
* Bootstrap @VERSION |
|
3 |
* |
|
4 |
* Copyright 2011 Twitter, Inc |
|
5 |
* Licensed under the Apache License v2.0 |
|
6 |
* http://www.apache.org/licenses/LICENSE-2.0 |
|
7 |
* |
|
8 |
* Designed and built with all the love in the world @twitter by @mdo and @fat. |
|
9 |
* Date: @DATE |
|
10 |
*/ |
|
11 |
/* Variables.less |
|
12 |
* Variables to customize the look and feel of Bootstrap |
|
13 |
* ----------------------------------------------------- */ |
|
14 |
/* Mixins.less |
|
15 |
* Snippets of reusable CSS to develop faster and keep code readable |
|
16 |
* ----------------------------------------------------------------- */ |
|
17 |
.servicesbar { |
|
18 |
font-family: arial, sans-serif; |
|
19 |
font-size: 13px !important; |
|
20 |
line-height: 13px; |
|
21 |
letter-spacing: 0px; |
|
22 |
zoom: 1; |
|
23 |
color: #ccc; |
|
24 |
z-index: 1000; |
|
25 |
border-bottom: 1px solid #444; |
|
26 |
background-color: #000000; |
|
27 |
position: relative; |
|
28 |
} |
|
29 |
.servicesbar ol, .servicesbar ul { |
|
30 |
list-style: none; |
|
31 |
margin: 0; |
|
32 |
padding: 0; |
|
33 |
} |
|
34 |
.servicesbar li { |
|
35 |
margin: 0; |
|
36 |
padding: 0; |
|
37 |
} |
|
38 |
.servicesbar:before, .servicesbar:after { |
|
39 |
display: table; |
|
40 |
content: ""; |
|
41 |
zoom: 1; |
|
42 |
} |
|
43 |
.servicesbar:after { |
|
44 |
clear: both; |
|
45 |
} |
|
46 |
.servicesbar a { |
|
47 |
border: none !important; |
|
48 |
font-size: inherit !important; |
|
49 |
color: #e6e6e6; |
|
50 |
text-decoration: none; |
|
51 |
display: block; |
|
52 |
float: left; |
|
53 |
padding: 11px; |
|
54 |
height: 13px; |
|
55 |
} |
|
56 |
.servicesbar a:hover { |
|
57 |
background-color: #444; |
|
58 |
} |
|
59 |
.servicesbar a.active { |
|
60 |
font-weight: bold; |
|
61 |
background-color: #333; |
|
62 |
} |
|
63 |
.servicesbar .services { |
|
64 |
zoom: 1; |
|
65 |
} |
|
66 |
.servicesbar .services:before, .servicesbar .services:after { |
|
67 |
display: table; |
|
68 |
content: ""; |
|
69 |
zoom: 1; |
|
70 |
} |
|
71 |
.servicesbar .services:after { |
|
72 |
clear: both; |
|
73 |
} |
|
74 |
.servicesbar .profile { |
|
75 |
margin-top: -35px; |
|
76 |
zoom: 1; |
|
77 |
text-align: right; |
|
78 |
min-width: 200px; |
|
79 |
background-color: #000000; |
|
80 |
zoom: 1; |
|
81 |
position: absolute; |
|
82 |
right: 0; |
|
83 |
float: right; |
|
84 |
} |
|
85 |
.servicesbar .profile:before, .servicesbar .profile:after { |
|
86 |
display: table; |
|
87 |
content: ""; |
|
88 |
zoom: 1; |
|
89 |
} |
|
90 |
.servicesbar .profile:after { |
|
91 |
clear: both; |
|
92 |
} |
|
93 |
.servicesbar .profile a { |
|
94 |
float: none; |
|
95 |
} |
|
96 |
.servicesbar .profile ul { |
|
97 |
display: none; |
|
98 |
} |
|
99 |
.servicesbar .profile ul li { |
|
100 |
width: 100%; |
|
101 |
border-bottom: 1px solid #444; |
|
102 |
background-color: #333; |
|
103 |
} |
|
104 |
.servicesbar .profile ul li a { |
|
105 |
float: none; |
|
106 |
display: block; |
|
107 |
} |
|
108 |
.servicesbar .profile:hover { |
|
109 |
background-color: #222; |
|
110 |
} |
|
111 |
.servicesbar .profile:hover ul { |
|
112 |
display: block; |
|
113 |
} |
|
114 |
.servicesbar .profile:before, .servicesbar .profile:after { |
|
115 |
display: table; |
|
116 |
content: ""; |
|
117 |
zoom: 1; |
|
118 |
} |
|
119 |
.servicesbar .profile:after { |
|
120 |
clear: both; |
|
121 |
} |
b/astakos/im/static/im/cloudbar/cloudbar.js | ||
---|---|---|
1 |
$(document).ready(function(){ |
|
2 |
|
|
3 |
/* |
|
4 |
* LINKS CONFIGURATION |
|
5 |
*/ |
|
6 |
|
|
7 |
var PROFILE_URL = "https://accounts.cloud.grnet.gr"; |
|
8 |
var SERVICES_LINKS = window.CLOUDBAR_SERVICES_LINKS || { |
|
9 |
'cloud': { url:'http://pithos.dev.grnet.gr/im/', name:'grnet cloud', id:'cloud', icon:'home-icon.png' }, |
|
10 |
'okeanos': { url:'http://staging.okeanos.grnet.gr/ui/', name:'~okeanos', id:'okeanos' }, |
|
11 |
'pithos': { url:'http://pithos.dev.grnet.gr/ui/', name:'pithos+', id:'pithos' } |
|
12 |
}; |
|
13 |
|
|
14 |
var PROFILE_LINKS = window.CLOUDBAR_PROFILE_LINKS || { |
|
15 |
'login': { url: '/im/login?next=' + window.location.toString(), auth:false, name: "login...", visible:false }, |
|
16 |
'profile': { url: '/im/profile', auth:true, name: "change your profile..." }, |
|
17 |
'invitations': { url: '/im/invite', auth:true, name: "invite some friends..." }, |
|
18 |
'feedback': { url: '/im/feedback', auth:true, name: "feedback..." }, |
|
19 |
'logout': { url: '/im/logout', auth:true, name: "logout..." } |
|
20 |
}; |
|
21 |
|
|
22 |
|
|
23 |
// cookie plugin https://raw.github.com/carhartl/jquery-cookie/master/jquery.cookie.js |
|
24 |
// * Copyright (c) 2010 Klaus Hartl, @carhartl |
|
25 |
// * Dual licensed under the MIT and GPL licenses |
|
26 |
var cookie=function(key,value,options){if(arguments.length>1&&(!/Object/.test(Object.prototype.toString.call(value))||value===null||value===undefined)){options=$.extend({},options);if(value===null||value===undefined){options.expires=-1}if(typeof options.expires==='number'){var days=options.expires,t=options.expires=new Date();t.setDate(t.getDate()+days)}value=String(value);return(document.cookie=[encodeURIComponent(key),'=',options.raw?value:encodeURIComponent(value),options.expires?'; expires='+options.expires.toUTCString():'',options.path?'; path='+options.path:'',options.domain?'; domain='+options.domain:'',options.secure?'; secure':''].join(''))}options=value||{};var decode=options.raw?function(s){return s}:decodeURIComponent;var pairs=document.cookie.split('; ');for(var i=0,pair;pair=pairs[i]&&pairs[i].split('=');i++){if(decode(pair[0])===key)return decode(pair[1]||'')}return null}; |
|
27 |
|
|
28 |
var ACTIVE_MENU = window.CLOUDBAR_ACTIVE_SERVICE || 'cloud'; |
|
29 |
var USER_DATA = window.CLOUDBAR_USER_DATA || {'user': 'Not logged in', 'logged_in': false}; |
|
30 |
var COOKIE_NAME = window.CLOUDBAR_COOKIE_NAME || '_pithos2_a'; |
|
31 |
|
|
32 |
var cssloc = window.CLOUDBAR_LOCATION || "http://127.0.0.1:8989/"; |
|
33 |
|
|
34 |
// load css |
|
35 |
var css = $("<link />"); |
|
36 |
css.attr({rel:'stylesheet', type:'text/css', href:cssloc + 'cloudbar.css'}); |
|
37 |
$("head").append(css); |
|
38 |
|
|
39 |
// load service specific css |
|
40 |
var SKIP_ADDITIONAL_CSS = window.SKIP_ADDITIONAL_CSS == undefined ? false : window.SKIP_ADDITIONAL_CSS; |
|
41 |
|
|
42 |
if (!SKIP_ADDITIONAL_CSS) { |
|
43 |
var css = $("<link />"); |
|
44 |
css.attr({rel:'stylesheet', type:'text/css', href:cssloc + 'service_' + ACTIVE_MENU + '.css'}); |
|
45 |
$("head").append(css); |
|
46 |
} |
|
47 |
|
|
48 |
var root = $('body'); |
|
49 |
var bar = $('<div class="servicesbar"></div>'); |
|
50 |
var services = $('<div class="services"></div>'); |
|
51 |
var profile = $('<div class="profile"></div>'); |
|
52 |
|
|
53 |
|
|
54 |
// create services links and set the active class to the current service |
|
55 |
$.each(SERVICES_LINKS, function(i, el){ |
|
56 |
var slink = $("<a>"); |
|
57 |
if (el.icon) { |
|
58 |
slink.append($('<img src="'+cssloc+el.icon+'"/>')); |
|
59 |
} else { |
|
60 |
slink.text(el.name); |
|
61 |
} |
|
62 |
slink.attr('href', el.url); |
|
63 |
slink.attr('title', el.name); |
|
64 |
services.append(slink); |
|
65 |
if (el.id == ACTIVE_MENU) { |
|
66 |
slink.addClass("active"); |
|
67 |
} |
|
68 |
}); |
|
69 |
|
|
70 |
var USERNAME, LOGGED_IN; |
|
71 |
var authcookie = cookie(COOKIE_NAME); |
|
72 |
var anonymous = {'user': 'Login...', 'logged_in': false}; |
|
73 |
|
|
74 |
if (authcookie && authcookie.indexOf("|") > -1) { |
|
75 |
USER_DATA.logged_in = true; |
|
76 |
USER_DATA.user = authcookie.split("|")[0]; |
|
77 |
} else { |
|
78 |
USER_DATA = anonymous; |
|
79 |
} |
|
80 |
|
|
81 |
USERNAME = USER_DATA.user; |
|
82 |
LOGGED_IN = USER_DATA.logged_in; |
|
83 |
|
|
84 |
// clear username |
|
85 |
USERNAME = USERNAME.replace(/\\'/g,''); |
|
86 |
USERNAME = USERNAME.replace(/\"/g,''); |
|
87 |
|
|
88 |
var user = $('<div class="user"></div>'); |
|
89 |
var username = $('<a href="#"></a>'); |
|
90 |
username.text(USERNAME); |
|
91 |
|
|
92 |
// create profile links |
|
93 |
var usermenu = $("<ul>"); |
|
94 |
$.each(PROFILE_LINKS, function(i,el) { |
|
95 |
if (!LOGGED_IN && el.auth) { return } |
|
96 |
if (LOGGED_IN && !el.auth) { return } |
|
97 |
var li = $("<li />"); |
|
98 |
var link = $("<a />"); |
|
99 |
link.text(el.name); |
|
100 |
link.attr({href:el.url}); |
|
101 |
li.append(link); |
|
102 |
if (el.visible == false) { |
|
103 |
li.hide(); |
|
104 |
} |
|
105 |
usermenu.append(li); |
|
106 |
}); |
|
107 |
|
|
108 |
//profile.filter(".user a").attr("href", |
|
109 |
//profile.find("li a").get(0).attr("href")) |
|
110 |
|
|
111 |
|
|
112 |
|
|
113 |
user.append(username); |
|
114 |
user.append(usermenu); |
|
115 |
profile.append(user); |
|
116 |
bar.append(services).append(profile); |
|
117 |
|
|
118 |
|
|
119 |
root.prepend(bar); |
|
120 |
var firstlink = profile.find("ul li:first-child a").attr("href"); |
|
121 |
profile.find(".user > a").attr("href", firstlink); |
|
122 |
}); |
b/astakos/im/static/im/cloudbar/cloudbar.less | ||
---|---|---|
1 |
@import "less/bootstrap.less"; |
|
2 |
|
|
3 |
@toolbarBg: #222; |
|
4 |
@toolbarColor: darken(@white, 10%); |
|
5 |
@toolbarHeight: 30px; |
|
6 |
|
|
7 |
.servicesbar { |
|
8 |
|
|
9 |
// mini reset |
|
10 |
ol, ul { list-style:none; margin:0; padding:0;} |
|
11 |
li {margin:0; padding:0;} |
|
12 |
font-family: arial, sans-serif; |
|
13 |
font-size: 13px !important; |
|
14 |
line-height: 13px; |
|
15 |
letter-spacing: 0px; |
|
16 |
.clearfix(); |
|
17 |
color: #ccc; |
|
18 |
z-index: 1000; |
|
19 |
border-bottom: 1px solid #444; |
|
20 |
|
|
21 |
background-color: darken(@toolbarBg, 40%); |
|
22 |
|
|
23 |
a { |
|
24 |
border: none !important; |
|
25 |
font-size: inherit !important; |
|
26 |
color: @toolbarColor; |
|
27 |
text-decoration: none; |
|
28 |
display: block; |
|
29 |
float: left; |
|
30 |
padding: 11px; |
|
31 |
height: 13px; |
|
32 |
&:hover { |
|
33 |
background-color: #444; |
|
34 |
} |
|
35 |
&.active { |
|
36 |
font-weight: bold; |
|
37 |
background-color: #333; |
|
38 |
} |
|
39 |
} |
|
40 |
|
|
41 |
.services { |
|
42 |
.clearfix(); |
|
43 |
} |
|
44 |
|
|
45 |
position: relative; |
|
46 |
|
|
47 |
.profile { |
|
48 |
margin-top: -35px; |
|
49 |
.clearfix(); |
|
50 |
text-align: right; |
|
51 |
min-width: 200px; |
|
52 |
a { |
|
53 |
float: none; |
|
54 |
} |
|
55 |
ul { |
|
56 |
display: none; |
|
57 |
li { |
|
58 |
width: 100%; |
|
59 |
border-bottom: 1px solid #444; |
|
60 |
background-color: #333; |
|
61 |
a { |
|
62 |
float: none; |
|
63 |
display: block; |
|
64 |
} |
|
65 |
} |
|
66 |
} |
|
67 |
&:hover { |
|
68 |
background-color: #222; |
|
69 |
ul { |
|
70 |
display: block; |
|
71 |
} |
|
72 |
} |
|
73 |
background-color: @black; |
|
74 |
.clearfix(); |
|
75 |
position: absolute; |
|
76 |
right: 0; |
|
77 |
float: right; |
|
78 |
} |
|
79 |
} |
b/astakos/im/static/im/cloudbar/service_okeanos.css | ||
---|---|---|
1 |
body { |
|
2 |
background-color: #4085A5; |
|
3 |
background-position: 20px 34px; |
|
4 |
} |
b/astakos/im/static/im/cloudbar/service_pithos.css | ||
---|---|---|
1 |
.gwt-HTML.pithos-logo { |
|
2 |
top: 65px !important; |
|
3 |
} |
|
4 |
|
|
5 |
.pithos-usernameMenu { |
|
6 |
display: none; |
|
7 |
} |
Also available in: Unified diff