##// END OF EJS Templates
Themes:...
Jean-Philippe Lang -
r909:0634591b3db0
parent child
Show More
@@ -0,0 +1,39
1 @import url(../../../stylesheets/application.css);
2
3 body{ color:#303030; background:#e8eaec; }
4
5 #top-menu { font-size: 80%; height: 2em; padding-top: 0.5em; background-color: #578bb8; }
6 #top-menu a { font-weight: bold; }
7 #header { background: #467aa7; height:5.8em; padding: 10px 0 0 0; }
8 #header h1 { margin-left: 6px; }
9 #quick-search { margin-right: 6px; }
10 #main-menu { background-color: #578bb8; left: 0; border-top: 1px solid #fff; width: 100%; }
11 #main-menu li { margin: 0; padding: 0; }
12 #main-menu li a { background-color: #578bb8; border-right: 1px solid #fff; font-size: 80%; padding: 4px 8px 4px 8px; font-weight: bold; }
13 #main-menu li a:hover { background-color: #80b0da; color: #ffffff; }
14
15 #footer { background-color: #578bb8; border: 0; color: #fff;}
16 #footer a { color: #fff; font-weight: bold; }
17
18 #main { font:90% Verdana,Tahoma,Arial,sans-serif; background: #e8eaec; }
19 #main a { font-weight: bold; color: #467aa7;}
20 #main a:hover { color: #2a5a8a; text-decoration: underline; }
21 #content { background: #fff; }
22
23 h2, h3, h4, .wiki h1, .wiki h2, .wiki h3 { border-bottom: 0px; color:#606060; font-family: Trebuchet MS,Georgia,"Times New Roman",serif; }
24 h2, .wiki h1 { letter-spacing:-1px; }
25 h4 { border-bottom: dotted 1px #c0c0c0; }
26
27 #top-menu a.home, #top-menu a.mypage, #top-menu a.projects, #top-menu a.admin, #top-menu a.help {
28 background-position: 0% 40%;
29 background-repeat: no-repeat;
30 padding-left: 20px;
31 padding-top: 2px;
32 padding-bottom: 3px;
33 }
34
35 #top-menu a.home { background-image: url(../../../images/home.png); }
36 #top-menu a.mypage { background-image: url(../../../images/user_page.png); }
37 #top-menu a.projects { background-image: url(../../../images/projects.png); }
38 #top-menu a.admin { background-image: url(../../../images/admin.png); }
39 #top-menu a.help { background-image: url(../../../images/help.png); }
@@ -1,79 +1,79
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
2 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
3 <head>
3 <head>
4 <title><%=h html_title %></title>
4 <title><%=h html_title %></title>
5 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
5 <meta http-equiv="content-type" content="text/html; charset=utf-8" />
6 <meta name="description" content="<%= Redmine::Info.app_name %>" />
6 <meta name="description" content="<%= Redmine::Info.app_name %>" />
7 <meta name="keywords" content="issue,bug,tracker" />
7 <meta name="keywords" content="issue,bug,tracker" />
8 <%= stylesheet_link_tag 'application', :media => 'all' %>
8 <%= stylesheet_link_tag 'application', :media => 'all' %>
9 <%= javascript_include_tag :defaults %>
9 <%= javascript_include_tag :defaults %>
10 <%= stylesheet_link_tag 'jstoolbar' %>
10 <%= stylesheet_link_tag 'jstoolbar' %>
11 <!--[if IE]>
11 <!--[if IE]>
12 <style type="text/css">
12 <style type="text/css">
13 * html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
13 * html body{ width: expression( document.documentElement.clientWidth < 900 ? '900px' : '100%' ); }
14 body {behavior: url(<%= stylesheet_path "csshover.htc" %>);}
14 body {behavior: url(<%= stylesheet_path "csshover.htc" %>);}
15 </style>
15 </style>
16 <![endif]-->
16 <![endif]-->
17
17
18 <!-- page specific tags --><%= yield :header_tags %>
18 <!-- page specific tags --><%= yield :header_tags %>
19 </head>
19 </head>
20 <body>
20 <body>
21 <div id="top-menu">
21 <div id="top-menu">
22 <div id="account">
22 <div id="account">
23 <% if User.current.logged? %>
23 <% if User.current.logged? %>
24 <%=l(:label_logged_as)%> <%= User.current.login %> -
24 <%=l(:label_logged_as)%> <%= User.current.login %> -
25 <%= link_to l(:label_my_account), { :controller => 'my', :action => 'account' } %>
25 <%= link_to l(:label_my_account), { :controller => 'my', :action => 'account' }, :class => 'myaccount' %>
26 <%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' } %>
26 <%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' }, :class => 'logout' %>
27 <% else %>
27 <% else %>
28 <%= link_to l(:label_login), { :controller => 'account', :action => 'login' } %>
28 <%= link_to l(:label_login), { :controller => 'account', :action => 'login' }, :class => 'signin' %>
29 <%= link_to(l(:label_register), :controller => 'account',:action => 'register') if Setting.self_registration? %>
29 <%= link_to(l(:label_register), { :controller => 'account',:action => 'register' }, :class => 'register') if Setting.self_registration? %>
30 <% end %>
30 <% end %>
31 </div>
31 </div>
32 <%= link_to l(:label_home), home_url %>
32 <%= link_to l(:label_home), home_url, :class => 'home' %>
33 <%= link_to l(:label_my_page), { :controller => 'my', :action => 'page'} if User.current.logged? %>
33 <%= link_to l(:label_my_page), { :controller => 'my', :action => 'page'}, :class => 'mypage' if User.current.logged? %>
34 <%= link_to l(:label_project_plural), { :controller => 'projects' } %>
34 <%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => 'projects' %>
35 <%= link_to l(:label_administration), { :controller => 'admin' } if User.current.admin? %>
35 <%= link_to l(:label_administration), { :controller => 'admin' }, :class => 'admin' if User.current.admin? %>
36 <%= link_to l(:label_help), Redmine::Info.help_url %>
36 <%= link_to l(:label_help), Redmine::Info.help_url, :class => 'help' %>
37 </div>
37 </div>
38
38
39 <div id="header">
39 <div id="header">
40 <div id="quick-search">
40 <div id="quick-search">
41 <% form_tag({:controller => 'search', :action => 'index', :id => @project}, :method => :get ) do %>
41 <% form_tag({:controller => 'search', :action => 'index', :id => @project}, :method => :get ) do %>
42 <%= link_to l(:label_search), {:controller => 'search', :action => 'index', :id => @project}, :accesskey => accesskey(:search) %>:
42 <%= link_to l(:label_search), {:controller => 'search', :action => 'index', :id => @project}, :accesskey => accesskey(:search) %>:
43 <%= text_field_tag 'q', @question, :size => 20, :class => 'small', :accesskey => accesskey(:quick_search) %>
43 <%= text_field_tag 'q', @question, :size => 20, :class => 'small', :accesskey => accesskey(:quick_search) %>
44 <% end %>
44 <% end %>
45 <%= render :partial => 'layouts/project_selector' if User.current.memberships.any? %>
45 <%= render :partial => 'layouts/project_selector' if User.current.memberships.any? %>
46 </div>
46 </div>
47
47
48 <h1><%= h(@project ? @project.name : Setting.app_title) %></h1>
48 <h1><%= h(@project ? @project.name : Setting.app_title) %></h1>
49
49
50 <div id="main-menu">
50 <div id="main-menu">
51 <ul>
51 <ul>
52 <% Redmine::MenuManager.allowed_items(:project_menu, User.current, @project).each do |item| %>
52 <% Redmine::MenuManager.allowed_items(:project_menu, User.current, @project).each do |item| %>
53 <% unless item.condition && !item.condition.call(@project) %>
53 <% unless item.condition && !item.condition.call(@project) %>
54 <li><%= link_to l(item.name), {item.param => @project}.merge(item.url) %></li>
54 <li><%= link_to l(item.name), {item.param => @project}.merge(item.url) %></li>
55 <% end %>
55 <% end %>
56 <% end if @project && !@project.new_record? %>
56 <% end if @project && !@project.new_record? %>
57 </ul>
57 </ul>
58 </div>
58 </div>
59 </div>
59 </div>
60
60
61 <%= tag('div', {:id => 'main', :class => (has_content?(:sidebar) ? '' : 'nosidebar')}, true) %>
61 <%= tag('div', {:id => 'main', :class => (has_content?(:sidebar) ? '' : 'nosidebar')}, true) %>
62 <div id="sidebar">
62 <div id="sidebar">
63 <%= yield :sidebar %>
63 <%= yield :sidebar %>
64 </div>
64 </div>
65
65
66 <div id="content">
66 <div id="content">
67 <%= content_tag('div', flash[:error], :class => 'flash error') if flash[:error] %>
67 <%= content_tag('div', flash[:error], :class => 'flash error') if flash[:error] %>
68 <%= content_tag('div', flash[:notice], :class => 'flash notice') if flash[:notice] %>
68 <%= content_tag('div', flash[:notice], :class => 'flash notice') if flash[:notice] %>
69 <%= yield %>
69 <%= yield %>
70 </div>
70 </div>
71 </div>
71 </div>
72
72
73 <div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
73 <div id="ajax-indicator" style="display:none;"><span><%= l(:label_loading) %></span></div>
74
74
75 <div id="footer">
75 <div id="footer">
76 Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> <%= Redmine::VERSION %> &copy 2006-2007 Jean-Philippe Lang
76 Powered by <%= link_to Redmine::Info.app_name, Redmine::Info.url %> <%= Redmine::VERSION %> &copy 2006-2007 Jean-Philippe Lang
77 </div>
77 </div>
78 </body>
78 </body>
79 </html>
79 </html>
@@ -1,72 +1,72
1 # redMine - project management software
1 # redMine - project management software
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 module Redmine
18 module Redmine
19 module Themes
19 module Themes
20
20
21 # Return an array of installed themes
21 # Return an array of installed themes
22 def self.themes
22 def self.themes
23 @@installed_themes ||= scan_themes
23 @@installed_themes ||= scan_themes
24 end
24 end
25
25
26 # Rescan themes directory
26 # Rescan themes directory
27 def self.rescan
27 def self.rescan
28 @@installed_themes = scan_themes
28 @@installed_themes = scan_themes
29 end
29 end
30
30
31 # Return theme for given id, or nil if it's not found
31 # Return theme for given id, or nil if it's not found
32 def self.theme(id)
32 def self.theme(id)
33 themes.find {|t| t.id == id}
33 themes.find {|t| t.id == id}
34 end
34 end
35
35
36 # Class used to represent a theme
36 # Class used to represent a theme
37 class Theme
37 class Theme
38 attr_reader :name, :dir, :stylesheets
38 attr_reader :name, :dir, :stylesheets
39
39
40 def initialize(path)
40 def initialize(path)
41 @dir = File.basename(path)
41 @dir = File.basename(path)
42 @name = @dir.humanize
42 @name = @dir.humanize
43 @stylesheets = Dir.glob("#{path}/stylesheets/*.css").collect {|f| File.basename(f).gsub(/\.css$/, '')}
43 @stylesheets = Dir.glob("#{path}/stylesheets/*.css").collect {|f| File.basename(f).gsub(/\.css$/, '')}
44 end
44 end
45
45
46 # Directory name used as the theme id
46 # Directory name used as the theme id
47 def id; dir end
47 def id; dir end
48
48
49 def <=>(theme)
49 def <=>(theme)
50 name <=> theme.name
50 name <=> theme.name
51 end
51 end
52 end
52 end
53
53
54 private
54 private
55
55
56 def self.scan_themes
56 def self.scan_themes
57 dirs = Dir.glob('public/themes/*').select do |f|
57 dirs = Dir.glob("#{RAILS_ROOT}/public/themes/*").select do |f|
58 # A theme should at least override application.css
58 # A theme should at least override application.css
59 File.directory?(f) && File.exist?("#{f}/stylesheets/application.css")
59 File.directory?(f) && File.exist?("#{f}/stylesheets/application.css")
60 end
60 end
61 dirs.collect {|dir| Theme.new(dir)}.sort
61 dirs.collect {|dir| Theme.new(dir)}.sort
62 end
62 end
63 end
63 end
64 end
64 end
65
65
66 module ApplicationHelper
66 module ApplicationHelper
67 def stylesheet_path(source)
67 def stylesheet_path(source)
68 @current_theme ||= Redmine::Themes.theme(Setting.ui_theme)
68 @current_theme ||= Redmine::Themes.theme(Setting.ui_theme)
69 super((@current_theme && @current_theme.stylesheets.include?(source)) ?
69 super((@current_theme && @current_theme.stylesheets.include?(source)) ?
70 "/themes/#{@current_theme.dir}/stylesheets/#{source}" : source)
70 "/themes/#{@current_theme.dir}/stylesheets/#{source}" : source)
71 end
71 end
72 end
72 end
General Comments 0
You need to be logged in to leave comments. Login now