File: lib/redmine/themes.rb

Overview
Module Structure
Class Hierarchy
Code

Overview

Module Structure

  module: <Toplevel Module>
  module: ApplicationHelper#101
extends
  Forwardable   
includes
  PublicMethods ( GravatarHelper )
  I18n ( Redmine )
  Definitions ( Redmine::WikiFormatting::Macros )
has properties
method: current_theme #102
method: stylesheet_path / 1 #109
method: path_to_stylesheet / 1 #117
method: heads_for_theme #122
  module: Redmine#18
  module: Themes#19
has properties
module method: themes #22
module method: rescan #27
module method: theme / 2 #32
module method: scan_themes #91
  class: Theme#44
inherits from
  Object ( Builtin-Module )
has properties
attribute: path [R] #45
attribute: name [R] #45
attribute: dir [R] #45
method: initialize / 1 #47
method: id #56
method: == / 1 #58
method: <=> / 1 #62
method: stylesheets #66
method: javascripts #70
method: stylesheet_path / 1 #74
method: javascript_path / 1 #78
method: assets / 2 #84

Class Hierarchy

Object ( Builtin-Module )
  Theme ( Redmine::Themes ) #44

Code

   1  # Redmine - project management software
   2  # Copyright (C) 2006-2011  Jean-Philippe Lang
   3  #
   4  # This program is free software; you can redistribute it and/or
   5  # modify it under the terms of the GNU General Public License
   6  # as published by the Free Software Foundation; either version 2
   7  # of the License, or (at your option) any later version.
   8  #
   9  # This program is distributed in the hope that it will be useful,
  10  # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12  # GNU General Public License for more details.
  13  #
  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
  16  # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  17 
  18  module Redmine
  19    module Themes
  20 
  21      # Return an array of installed themes
  22      def self.themes
  23        @@installed_themes ||= scan_themes
  24      end
  25 
  26      # Rescan themes directory
  27      def self.rescan
  28        @@installed_themes = scan_themes
  29      end
  30 
  31      # Return theme for given id, or nil if it's not found
  32      def self.theme(id, options={})
  33        return nil if id.blank?
  34 
  35        found = themes.find {|t| t.id == id}
  36        if found.nil? && options[:rescan] != false
  37          rescan
  38          found = theme(id, :rescan => false)
  39        end
  40        found
  41      end
  42 
  43      # Class used to represent a theme
  44      class Theme
  45        attr_reader :path, :name, :dir
  46 
  47        def initialize(path)
  48          @path = path
  49          @dir = File.basename(path)
  50          @name = @dir.humanize
  51          @stylesheets = nil
  52          @javascripts = nil
  53        end
  54 
  55        # Directory name used as the theme id
  56        def id; dir end
  57 
  58        def ==(theme)
  59          theme.is_a?(Theme) && theme.dir == dir
  60        end
  61 
  62        def <=>(theme)
  63          name <=> theme.name
  64        end
  65 
  66        def stylesheets
  67          @stylesheets ||= assets("stylesheets", "css")
  68        end
  69 
  70        def javascripts
  71          @javascripts ||= assets("javascripts", "js")
  72        end
  73 
  74        def stylesheet_path(source)
  75          "/themes/#{dir}/stylesheets/#{source}"
  76        end
  77 
  78        def javascript_path(source)
  79          "/themes/#{dir}/javascripts/#{source}"
  80        end
  81 
  82        private
  83 
  84        def assets(dir, ext)
  85          Dir.glob("#{path}/#{dir}/*.#{ext}").collect {|f| File.basename(f).gsub(/\.#{ext}$/, '')}
  86        end
  87      end
  88 
  89      private
  90 
  91      def self.scan_themes
  92        dirs = Dir.glob("#{Rails.public_path}/themes/*").select do |f|
  93          # A theme should at least override application.css
  94          File.directory?(f) && File.exist?("#{f}/stylesheets/application.css")
  95        end
  96        dirs.collect {|dir| Theme.new(dir)}.sort
  97      end
  98    end
  99  end
 100 
 101  module ApplicationHelper
 102    def current_theme
 103      unless instance_variable_defined?(:@current_theme)
 104        @current_theme = Redmine::Themes.theme(Setting.ui_theme)
 105      end
 106      @current_theme
 107    end
 108 
 109    def stylesheet_path(source)
 110      if current_theme && current_theme.stylesheets.include?(source)
 111        super current_theme.stylesheet_path(source)
 112      else
 113        super
 114      end
 115    end
 116 
 117    def path_to_stylesheet(source)
 118      stylesheet_path source
 119    end
 120 
 121    # Returns the header tags for the current theme
 122    def heads_for_theme
 123      if current_theme && current_theme.javascripts.include?('theme')
 124        javascript_include_tag current_theme.javascript_path('theme')
 125      end
 126    end
 127  end