themes_for_rails4 1.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +2 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +117 -0
  7. data/LICENSE +21 -0
  8. data/README.textile +53 -0
  9. data/Rakefile +11 -0
  10. data/doc/README.textile +380 -0
  11. data/doc/REVIEW_NOTES +0 -0
  12. data/doc/RMU_REVIEW +26 -0
  13. data/doc/TODO.textile +3 -0
  14. data/lib/generators/themes_for_rails/install_generator.rb +16 -0
  15. data/lib/generators/themes_for_rails/templates/theme/images/.gitkeep +0 -0
  16. data/lib/generators/themes_for_rails/templates/theme/javascripts/.gitkeep +0 -0
  17. data/lib/generators/themes_for_rails/templates/theme/stylesheets/.gitkeep +0 -0
  18. data/lib/generators/themes_for_rails/templates/theme/views/layouts/.gitkeep +0 -0
  19. data/lib/generators/themes_for_rails/theme_generator.rb +14 -0
  20. data/lib/tasks/themes_for_rails.rake +40 -0
  21. data/lib/themes_for_rails/action_controller.rb +32 -0
  22. data/lib/themes_for_rails/action_mailer.rb +22 -0
  23. data/lib/themes_for_rails/action_view.rb +66 -0
  24. data/lib/themes_for_rails/assets_controller.rb +68 -0
  25. data/lib/themes_for_rails/common_methods.rb +98 -0
  26. data/lib/themes_for_rails/config.rb +79 -0
  27. data/lib/themes_for_rails/digested_action_view.rb +64 -0
  28. data/lib/themes_for_rails/interpolation.rb +11 -0
  29. data/lib/themes_for_rails/railtie.rb +42 -0
  30. data/lib/themes_for_rails/routes.rb +30 -0
  31. data/lib/themes_for_rails/url_helpers.rb +27 -0
  32. data/lib/themes_for_rails/version.rb +4 -0
  33. data/lib/themes_for_rails.rb +73 -0
  34. data/test/dummy_app/.gitignore +4 -0
  35. data/test/dummy_app/Gemfile +30 -0
  36. data/test/dummy_app/Rakefile +7 -0
  37. data/test/dummy_app/another_themes/another_default/images/logo.png +0 -0
  38. data/test/dummy_app/another_themes/another_default/images/nested/logo.png +0 -0
  39. data/test/dummy_app/another_themes/another_default/javascripts/app.js +1 -0
  40. data/test/dummy_app/another_themes/another_default/stylesheets/style.css +0 -0
  41. data/test/dummy_app/another_themes/another_default/stylesheets/style2.css +3 -0
  42. data/test/dummy_app/another_themes/another_default/views/layouts/default.html.erb +10 -0
  43. data/test/dummy_app/another_themes/another_default/views/products/index.html.erb +0 -0
  44. data/test/dummy_app/app/controllers/application_controller.rb +3 -0
  45. data/test/dummy_app/app/helpers/application_helper.rb +2 -0
  46. data/test/dummy_app/app/views/layouts/application.html.erb +14 -0
  47. data/test/dummy_app/config/application.rb +42 -0
  48. data/test/dummy_app/config/boot.rb +13 -0
  49. data/test/dummy_app/config/database.yml +18 -0
  50. data/test/dummy_app/config/environment.rb +5 -0
  51. data/test/dummy_app/config/environments/development.rb +26 -0
  52. data/test/dummy_app/config/environments/production.rb +49 -0
  53. data/test/dummy_app/config/environments/test.rb +35 -0
  54. data/test/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
  55. data/test/dummy_app/config/initializers/inflections.rb +10 -0
  56. data/test/dummy_app/config/initializers/mime_types.rb +5 -0
  57. data/test/dummy_app/config/initializers/secret_token.rb +7 -0
  58. data/test/dummy_app/config/initializers/session_store.rb +8 -0
  59. data/test/dummy_app/config/locales/en.yml +5 -0
  60. data/test/dummy_app/config/routes.rb +4 -0
  61. data/test/dummy_app/config.ru +4 -0
  62. data/test/dummy_app/db/seeds.rb +7 -0
  63. data/test/dummy_app/empty_themes/.gitkeep +0 -0
  64. data/test/dummy_app/lib/tasks/.gitkeep +0 -0
  65. data/test/dummy_app/public/404.html +26 -0
  66. data/test/dummy_app/public/422.html +26 -0
  67. data/test/dummy_app/public/500.html +26 -0
  68. data/test/dummy_app/public/favicon.ico +0 -0
  69. data/test/dummy_app/public/images/rails.png +0 -0
  70. data/test/dummy_app/public/index.html +239 -0
  71. data/test/dummy_app/public/javascripts/application.js +2 -0
  72. data/test/dummy_app/public/javascripts/controls.js +965 -0
  73. data/test/dummy_app/public/javascripts/dragdrop.js +974 -0
  74. data/test/dummy_app/public/javascripts/effects.js +1123 -0
  75. data/test/dummy_app/public/javascripts/prototype.js +6001 -0
  76. data/test/dummy_app/public/javascripts/rails.js +175 -0
  77. data/test/dummy_app/public/robots.txt +5 -0
  78. data/test/dummy_app/public/stylesheets/.gitkeep +0 -0
  79. data/test/dummy_app/script/rails +6 -0
  80. data/test/dummy_app/themes/default/images/logo.png +0 -0
  81. data/test/dummy_app/themes/default/images/nested/logo.png +0 -0
  82. data/test/dummy_app/themes/default/javascripts/app.js +1 -0
  83. data/test/dummy_app/themes/default/javascripts/app.min.js +0 -0
  84. data/test/dummy_app/themes/default/stylesheets/images/logo.png +0 -0
  85. data/test/dummy_app/themes/default/stylesheets/style.css +0 -0
  86. data/test/dummy_app/themes/default/stylesheets/style2.css +3 -0
  87. data/test/dummy_app/themes/default/views/layouts/default.html.erb +10 -0
  88. data/test/dummy_app/themes/default/views/products/index.html.erb +0 -0
  89. data/test/lib/action_controller_test.rb +170 -0
  90. data/test/lib/action_mailer_test.rb +35 -0
  91. data/test/lib/action_view_test.rb +54 -0
  92. data/test/lib/assets_controller_test.rb +73 -0
  93. data/test/lib/common_methods_test.rb +28 -0
  94. data/test/lib/config_test.rb +26 -0
  95. data/test/lib/integration_test.rb +12 -0
  96. data/test/lib/routes_test.rb +40 -0
  97. data/test/lib/themes_for_rails_test.rb +18 -0
  98. data/test/support/extensions.rb +19 -0
  99. data/test/test_helper.rb +12 -0
  100. data/themes_for_rails.gemspec +25 -0
  101. metadata +280 -0
@@ -0,0 +1,40 @@
1
+ namespace :themes do
2
+ desc "Creates the cached theme folder"
3
+ task :create_cache => :environment do
4
+ for theme in ThemesForRails.available_themes
5
+ theme_name = File.basename(theme)
6
+ theme_dir = ThemesForRails.config.themes_dir
7
+ theme_base = "#{Rails.public_path}/#{theme_dir}/#{theme_name}"
8
+ puts "Creating #{theme_base}"
9
+
10
+ FileUtils.mkdir_p "#{theme_base}"
11
+ FileUtils.cp_r Dir["#{theme}/{images,stylesheets,javascripts}"], theme_base, :verbose => true
12
+ end
13
+ end
14
+ desc "Removes the cached (public) theme folders"
15
+ task :remove_cache => :environment do
16
+ theme_dir = ThemesForRails.config.themes_dir
17
+ puts "Removing #{Rails.public_path}/#{theme_dir}"
18
+ FileUtils.rm_r "#{Rails.public_path}/#{theme_dir}", :force => true
19
+ end
20
+ desc "Updates the cached (public) theme folders"
21
+ task :update_cache => [:remove_cache, :create_cache]
22
+
23
+ desc "Add theme view paths to ActionView PathSet"
24
+ task :add_theme_to_view_paths => :environment do
25
+ raise 'you must provide THEME for theme support to work' unless theme = ENV['THEME']
26
+ puts "adding theme [#{theme}] to view path"
27
+ require 'themes_for_rails/common_methods'
28
+ include ThemesForRails::CommonMethods
29
+
30
+ theme_view_path=theme_view_path_for(theme)
31
+ ActionController::Base.view_paths.paths.prepend(theme_view_path) if theme
32
+ end
33
+ end
34
+
35
+ namespace :cache_digests do
36
+ puts "patching cache_digests with themes_for_rails support"
37
+ # Add themes support to cache_digest gem rake tasks
38
+ task :nested_dependencies => ['themes:add_theme_to_view_paths']
39
+ task :dependencies => ['themes:add_theme_to_view_paths']
40
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+
4
+ module ActionController
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ include ThemesForRails::CommonMethods
11
+ include ThemesForRails::UrlHelpers
12
+
13
+ end
14
+
15
+ module ClassMethods
16
+
17
+ def theme(name, options = {})
18
+ before_filter(options) do |controller|
19
+ controller.set_theme(name)
20
+ end
21
+ end
22
+
23
+ end
24
+
25
+ def theme(name)
26
+ set_theme(name)
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,22 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+
4
+ module ActionMailer
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include ThemesForRails::ActionController
10
+ alias_method_chain :mail, :theme
11
+ end
12
+
13
+ def mail_with_theme(headers = {}, &block)
14
+ theme_opts = headers[:theme] || headers['X-theme'] || self.class.default[:theme]
15
+ theme(theme_opts) if theme_opts
16
+
17
+ mail_without_theme(headers, &block)
18
+ end
19
+
20
+ end
21
+
22
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+
4
+ module ActionView
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include ThemesForRails::CommonMethods
10
+ end
11
+
12
+ def current_theme_stylesheet_path(asset)
13
+ base_theme_stylesheet_path(:theme => self.theme_name, :asset => digest_for_stylesheet("#{asset}.css", self.theme_name))
14
+ end
15
+
16
+ def current_theme_javascript_path(asset)
17
+ base_theme_javascript_path(:theme => self.theme_name, :asset => digest_for_javascript("#{asset}.js", self.theme_name))
18
+ end
19
+
20
+ def current_theme_image_path(asset)
21
+ image, extension = name_ext(asset)
22
+ base_theme_image_path(:theme => self.theme_name, :asset => digest_for_image("#{image}.#{extension}", self.theme_name))
23
+ end
24
+
25
+ def theme_stylesheet_path(asset, new_theme_name = self.theme_name)
26
+ base_theme_stylesheet_path(:theme => new_theme_name, :asset => digest_for_stylesheet("#{asset}.css", new_theme_name))
27
+ end
28
+
29
+ def theme_javascript_path(asset, new_theme_name = self.theme_name)
30
+ base_theme_javascript_path(:theme => new_theme_name, :asset => digest_for_javascript("#{asset}.js", new_theme_name))
31
+ end
32
+
33
+ def theme_image_path(asset, new_theme_name = self.theme_name)
34
+ image, extension = name_ext(asset)
35
+ base_theme_image_path(:theme => new_theme_name, :asset => digest_for_image("#{image}.#{extension}", new_theme_name))
36
+ end
37
+
38
+ def theme_image_tag(source, options = {})
39
+ image, extension = name_ext(source)
40
+ image_tag(theme_image_path(digest_for_image("#{image}.#{extension}", self.theme_name)), options)
41
+ end
42
+
43
+ def theme_image_submit_tag(source, options = {})
44
+ image, extension = name_ext(source)
45
+ image_submit_tag(theme_image_path(digest_for_image("#{image}.#{extension}", self.theme_name)), options)
46
+ end
47
+
48
+ def theme_javascript_include_tag(*files)
49
+ options = files.extract_options!
50
+ options.merge!({ :type => "text/javascript" })
51
+ files_with_options = files.collect {|file| theme_javascript_path(file) }
52
+ files_with_options += [options]
53
+
54
+ javascript_include_tag(*files_with_options)
55
+ end
56
+
57
+ def theme_stylesheet_link_tag(*files)
58
+ options = files.extract_options!
59
+ options.merge!({ :type => "text/css" })
60
+ files_with_options = files.collect {|file| theme_stylesheet_path(file) }
61
+ files_with_options += [options]
62
+
63
+ stylesheet_link_tag(*files_with_options)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,68 @@
1
+ # encoding: utf-8
2
+ require "action_controller/metal"
3
+
4
+ module ThemesForRails
5
+ class AssetsController < ActionController::Base
6
+
7
+ def stylesheets
8
+ handle_asset("stylesheets")
9
+ end
10
+
11
+ def javascripts
12
+ handle_asset("javascripts")
13
+ end
14
+
15
+ def images
16
+ handle_asset("images")
17
+ end
18
+
19
+ private
20
+
21
+ def handle_asset(prefix)
22
+ asset, theme = params[:asset], params[:theme]
23
+ find_themed_asset(asset, theme, prefix) do |path, mime_type|
24
+ response.headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(File.mtime(path).to_s + path))}")
25
+ response.headers['Cache-Control'] = "public, max-age=2592000"
26
+ send_file path, :type => mime_type, :disposition => "inline"
27
+ end
28
+ end
29
+
30
+ def find_themed_asset(asset_name, asset_theme, asset_type, &block)
31
+ path = asset_path(asset_name, asset_theme, asset_type)
32
+ if File.exists?(path)
33
+ yield path, mime_type_for(request)
34
+ elsif File.extname(path).blank?
35
+ asset_name = "#{asset_name}.#{extension_from(request.path_info)}"
36
+ return find_themed_asset(asset_name, asset_theme, asset_type, &block)
37
+ else
38
+ render_not_found
39
+ end
40
+ end
41
+
42
+ def asset_path(asset_name, asset_theme, asset_type)
43
+ File.join(theme_asset_path_for(asset_theme), asset_type, asset_name)
44
+ end
45
+
46
+ def render_not_found
47
+ render :text => 'Not found', :status => 404
48
+ end
49
+
50
+ def mime_type_for(request)
51
+ existing_mime_type = mime_type_from_uri(request.path_info)
52
+ unless existing_mime_type.nil?
53
+ existing_mime_type.to_s
54
+ else
55
+ "image/#{extension_from(request.path_info)}"
56
+ end
57
+ end
58
+
59
+ def mime_type_from_uri(path)
60
+ extension = extension_from(path)
61
+ Mime::Type.lookup_by_extension(extension)
62
+ end
63
+
64
+ def extension_from(path)
65
+ File.extname(path).to_s[1..-1]
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,98 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+ module CommonMethods
4
+
5
+ include ThemesForRails::Interpolation
6
+
7
+ def theme_name
8
+ @cached_theme_name ||= begin
9
+ case @theme_name
10
+ when Symbol then
11
+ self.respond_to?(@theme_name, true) ? self.send(@theme_name) : @theme_name.to_s
12
+ when String then @theme_name
13
+ else
14
+ nil
15
+ end
16
+ end
17
+ end
18
+
19
+ def theme_name=(name)
20
+ @theme_name = name
21
+ end
22
+
23
+ def set_theme(name)
24
+ self.theme_name = name
25
+ if valid_theme?
26
+ add_theme_view_path
27
+ end
28
+ end
29
+
30
+ public
31
+
32
+ def valid_theme?
33
+ !self.theme_name.nil?
34
+ end
35
+
36
+ # will add the view path for the current theme
37
+ def add_theme_view_path
38
+ add_theme_view_path_for(self.theme_name)
39
+ end
40
+
41
+ # will add the view path for a given theme name
42
+ def add_theme_view_path_for(name)
43
+ self.view_paths.insert 0, ::ActionView::FileSystemResolver.new(theme_view_path_for(name))
44
+ end
45
+
46
+ def digest_for_image(asset, theme_context)
47
+ if ThemesForRails.config.asset_digests_enabled?
48
+ asset_paths.digest_for("#{theme_context}/images/#{asset}") || asset
49
+ else
50
+ asset
51
+ end
52
+ end
53
+
54
+ def digest_for_javascript(asset, theme_context)
55
+ if ThemesForRails.config.asset_digests_enabled?
56
+ asset_paths.digest_for("#{theme_context}/javascripts/#{asset}") || asset
57
+ else
58
+ asset
59
+ end
60
+ end
61
+
62
+ def digest_for_stylesheet(asset, theme_context)
63
+ if ThemesForRails.config.asset_digests_enabled?
64
+ #Rails.application.config.assets.digests["#{theme_context}/stylesheets/#{asset}"] || asset
65
+ asset_paths.digest_for("#{theme_context}/stylesheets/#{asset}") || asset
66
+ else
67
+ asset
68
+ end
69
+ end
70
+
71
+ def name_ext(file_name)
72
+ ext = File.extname(file_name)
73
+ name = File.basename(file_name, ext)
74
+ ext.slice!(0) if ext.length > 0
75
+ return name, ext
76
+ end
77
+
78
+ def public_theme_path
79
+ theme_view_path("/")
80
+ end
81
+
82
+ def theme_asset_path
83
+ theme_asset_path_for(theme_name)
84
+ end
85
+
86
+ def theme_view_path
87
+ theme_view_path_for(theme_name)
88
+ end
89
+
90
+ def theme_view_path_for(theme_name)
91
+ interpolate(ThemesForRails.config.views_dir, theme_name)
92
+ end
93
+
94
+ def theme_asset_path_for(theme_name)
95
+ interpolate(ThemesForRails.config.assets_dir, theme_name)
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,79 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+ class Config
4
+
5
+ attr_writer :base_dir, :themes_dir, :assets_dir, :views_dir, :themes_routes_dir
6
+ attr_accessor :use_sass, :default_theme, :asset_digests_enabled
7
+
8
+ include Interpolation
9
+
10
+ def initialize(&block)
11
+ @use_sass = true
12
+ @default_theme = 'default'
13
+ @asset_digests_enabled = nil
14
+ yield if block_given?
15
+ end
16
+
17
+ def base_dir
18
+ @base_dir ||= Rails.root.to_s
19
+ end
20
+
21
+ # relative assets dir for view overloading support
22
+ # used for theme_view_path_for method to get theme path and add to view paths.
23
+ # Defaults to themes_dir for non asset pipeline users
24
+ #
25
+ # If you are using the Rails Asset Pipeline, this should be changed to the
26
+ # path of your assets in your app. For example, if you store your themes
27
+ # under /app/assets/themes - {Rails.root}/app/assets/themes
28
+ # you would need to set this to 'app/assets/themes' in your initializer config
29
+ def assets_dir
30
+ @assets_dir ||= ":root/themes/:name"
31
+ end
32
+
33
+ # relative views directory for theme views to be separated from assets
34
+ # used for Asset Pipeline support. Defaults to match {assets_dir}/views
35
+ def views_dir
36
+ @views_dir ||= ":root/themes/:name/views"
37
+ end
38
+
39
+ def themes_dir
40
+ @themes_dir ||= ":root/themes"
41
+ end
42
+
43
+ # Full path to themes
44
+ def themes_path
45
+ interpolate(themes_dir)
46
+ end
47
+
48
+ # This is the base themes dir that is used for mapping URL paths.
49
+ #
50
+ # If you are using the Rails Asset Pipeline, this should be changed to the
51
+ # prefix dir of your assets path. For example, if you store your themes
52
+ # under /app/assets/themes - {Rails.root}/app/assets/themes
53
+ # you would need to set this value to 'assets' to match up with the Sprockets
54
+ # path resolution process.
55
+
56
+ def themes_routes_dir
57
+ @themes_routes_dir ||= "themes"
58
+ end
59
+
60
+ def clear
61
+ @base_dir = nil
62
+ @themes_dir = nil
63
+ @assets_dir = nil
64
+ @views_dir = nil
65
+ end
66
+
67
+ def use_sass?
68
+ @use_sass and sass_is_available?
69
+ end
70
+
71
+ def sass_is_available?
72
+ !!defined?Sass::Plugin
73
+ end
74
+
75
+ def asset_digests_enabled?
76
+ @asset_digests_enabled
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+
4
+ module DigestedActionView
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include ThemesForRails::CommonMethods
10
+ end
11
+
12
+ def current_theme_stylesheet_path(asset)
13
+ digest_for_stylesheet("#{asset}.css", self.theme_name)
14
+ end
15
+
16
+ def current_theme_javascript_path(asset)
17
+ digest_for_javascript("#{asset}.js", self.theme_name)
18
+ end
19
+
20
+ def current_theme_image_path(asset)
21
+ image, extension = name_ext(asset)
22
+ digest_for_image("#{image}.#{extension}", self.theme_name)
23
+ end
24
+
25
+ def theme_stylesheet_path(asset, new_theme_name = self.theme_name)
26
+ digest_for_stylesheet("#{asset}.css", new_theme_name)
27
+ end
28
+
29
+ def theme_javascript_path(asset, new_theme_name = self.theme_name)
30
+ digest_for_javascript("#{asset}.js", new_theme_name)
31
+ end
32
+
33
+ def theme_image_path(asset, new_theme_name = self.theme_name)
34
+ path_to_image(digest_for_image(asset, new_theme_name))
35
+ end
36
+
37
+ def theme_image_tag(source, options = {})
38
+ image_tag(theme_image_path("#{source}", self.theme_name), options)
39
+ end
40
+
41
+ def theme_image_submit_tag(source, options = {})
42
+ image, extension = name_ext(source)
43
+ image_submit_tag(theme_image_path("#{image}.#{extension}", self.theme_name), options)
44
+ end
45
+
46
+ def theme_javascript_include_tag(*files)
47
+ options = files.extract_options!
48
+ options.merge!({ :type => "text/javascript" })
49
+ files_with_options = files.collect {|file| theme_javascript_path(file) }
50
+ files_with_options += [options]
51
+
52
+ javascript_include_tag(*files_with_options)
53
+ end
54
+
55
+ def theme_stylesheet_link_tag(*files)
56
+ options = files.extract_options!
57
+ options.merge!({ :type => "text/css" })
58
+ files_with_options = files.collect {|file| theme_stylesheet_path(file) }
59
+ files_with_options += [options]
60
+
61
+ stylesheet_link_tag(*files_with_options)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,11 @@
1
+ module ThemesForRails
2
+
3
+ module Interpolation
4
+
5
+ def interpolate(pattern, name = nil)
6
+ pattern.gsub(":root", ThemesForRails.config.base_dir.to_s).gsub(":name", name.to_s)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ config.themes_for_rails = ActiveSupport::OrderedOptions.new
6
+
7
+ config.to_prepare do
8
+ ThemesForRails::Railtie.config.themes_for_rails.each do |key, value|
9
+ ThemesForRails.config.send "#{key}=".to_sym, value
10
+ end
11
+
12
+ # Adding theme stylesheets path to sass, automatically.
13
+ ThemesForRails.add_themes_path_to_sass if ThemesForRails.config.use_sass?
14
+
15
+ # Check if asset pipeline enabled
16
+ ThemesForRails.check_asset_pipeline
17
+
18
+ # Adding theme assets to the asset pipeline, automatically.
19
+ ThemesForRails.add_themes_assets_to_asset_pipeline if ThemesForRails.config.asset_digests_enabled?
20
+
21
+ ActiveSupport.on_load(:action_view) do
22
+ include ThemesForRails::ActionView
23
+ if ThemesForRails.config.asset_digests_enabled?
24
+ require 'themes_for_rails/digested_action_view'
25
+ include ThemesForRails::DigestedActionView
26
+ end
27
+ end
28
+
29
+ ActiveSupport.on_load(:action_controller) do
30
+ include ThemesForRails::ActionController
31
+ end
32
+
33
+ ActiveSupport.on_load(:action_mailer) do
34
+ include ThemesForRails::ActionMailer
35
+ end
36
+ end
37
+
38
+ rake_tasks do
39
+ load "tasks/themes_for_rails.rake"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+ module Routes
4
+
5
+ def themes_for_rails
6
+ theme_dir = ThemesForRails.config.themes_routes_dir
7
+ constraints = { :theme => /[\w\.]*/ }
8
+
9
+ # Lets not pollute the routes if they aren't being used.
10
+ unless ThemesForRails.config.asset_digests_enabled?
11
+ get "#{theme_dir}/:theme/stylesheets/*asset" => 'themes_for_rails/assets#stylesheets',
12
+ :as => :base_theme_stylesheet, :constraints => constraints
13
+ get "#{theme_dir}/:theme/javascripts/*asset" => 'themes_for_rails/assets#javascripts',
14
+ :as => :base_theme_javascript, :constraints => constraints
15
+ get "#{theme_dir}/:theme/images/*asset" => 'themes_for_rails/assets#images',
16
+ :as => :base_theme_image, :constraints => constraints
17
+ end
18
+ end
19
+
20
+ end
21
+ end
22
+
23
+ module ActionDispatch::Routing
24
+ class Mapper #:nodoc:
25
+
26
+ include ThemesForRails::Routes
27
+
28
+ end
29
+ end
30
+
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+ module UrlHelpers
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ helper_method :current_theme_stylesheet_path,
9
+ :current_theme_javascript_path,
10
+ :current_theme_image_path
11
+ end
12
+
13
+ def current_theme_stylesheet_path(asset)
14
+ base_theme_stylesheet_path(:theme => self.theme_name, :asset => digest_for_stylesheet("#{asset}.css", self.theme_name))
15
+ end
16
+
17
+ def current_theme_javascript_path(asset)
18
+ base_theme_javascript_path(:theme => self.theme_name, :asset => digest_for_javascript("#{asset}.js", self.theme_name))
19
+ end
20
+
21
+ def current_theme_image_path(asset)
22
+ image, extension = name_ext(asset)
23
+ base_theme_image_path(:theme => self.theme_name, :asset => digest_for_image("#{image}.#{extension}", self.theme_name))
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,4 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+ VERSION = "1.5.1"
4
+ end
@@ -0,0 +1,73 @@
1
+ # encoding: utf-8
2
+ module ThemesForRails
3
+
4
+ class << self
5
+
6
+ def config
7
+ @config ||= ThemesForRails::Config.new
8
+ yield(@config) if block_given?
9
+ @config
10
+ end
11
+
12
+ def available_themes(&block)
13
+ Dir.glob(File.join(config.themes_path, "*"), &block)
14
+ end
15
+ alias each_theme_dir available_themes
16
+
17
+ def available_theme_names
18
+ available_themes.map {|theme| File.basename(theme) }
19
+ end
20
+
21
+ def add_themes_path_to_sass
22
+ if ThemesForRails.config.sass_is_available?
23
+ each_theme_dir do |dir|
24
+ if File.directory?(dir) # Need to get rid of the '.' and '..'
25
+
26
+ sass_dir = "#{dir}/stylesheets/sass"
27
+ css_dir = "#{dir}/stylesheets"
28
+
29
+ unless already_configured_in_sass?(sass_dir)
30
+ Sass::Plugin.add_template_location sass_dir, css_dir
31
+ end
32
+ end
33
+ end
34
+ else
35
+ raise "Sass is not available. What are you trying to do?"
36
+ end
37
+ end
38
+
39
+ def check_asset_pipeline
40
+ config.asset_digests_enabled ||= Rails.application.config.respond_to?(:assets) && Rails.application.config.assets.digest == true
41
+ end
42
+
43
+ def add_themes_assets_to_asset_pipeline
44
+ Rails.logger.info "Start adding themes to assets [#{ThemesForRails.config.asset_digests_enabled?}]"
45
+ if ThemesForRails.config.asset_digests_enabled?
46
+ available_theme_names.each do |theme_name|
47
+ theme_asset_path = ThemesForRails.config.assets_dir.gsub(":root", ThemesForRails.config.base_dir).gsub(":name", theme_name.to_s)
48
+ Rails.logger.info "== Adding theme [#{theme_name}] asset dir [#{theme_asset_path}] to asset pipeline"
49
+ Rails.application.config.assets.paths.prepend(theme_asset_path) unless Rails.application.config.assets.paths.include?(theme_asset_path)
50
+ end unless ThemesForRails.config.base_dir =~ %r!/app/assets/!
51
+ end
52
+ end
53
+
54
+ def already_configured_in_sass?(sass_dir)
55
+ Sass::Plugin.template_location_array.map(&:first).include?(sass_dir)
56
+ end
57
+
58
+ end
59
+ end
60
+
61
+ require 'active_support/dependencies'
62
+ require 'themes_for_rails/interpolation'
63
+ require 'themes_for_rails/config'
64
+ require 'themes_for_rails/common_methods'
65
+ require 'themes_for_rails/url_helpers'
66
+
67
+ require 'themes_for_rails/action_view'
68
+ require 'themes_for_rails/assets_controller'
69
+ require 'themes_for_rails/action_controller'
70
+ require 'themes_for_rails/action_mailer'
71
+ require 'themes_for_rails/railtie'
72
+ require 'themes_for_rails/routes'
73
+
@@ -0,0 +1,4 @@
1
+ .bundle
2
+ db/*.sqlite3
3
+ log/*.log
4
+ tmp/**/*