active_theme 0.5.0.pre

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 (99) hide show
  1. data/.gitignore +8 -0
  2. data/.rspec +2 -0
  3. data/.rvmrc +1 -0
  4. data/.travis.yml +2 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +91 -0
  7. data/LICENSE +21 -0
  8. data/README.textile +3 -0
  9. data/Rakefile +11 -0
  10. data/active_theme.gemspec +25 -0
  11. data/doc/README.textile +332 -0
  12. data/doc/REVIEW_NOTES +0 -0
  13. data/doc/TODO.textile +3 -0
  14. data/lib/active_theme.rb +58 -0
  15. data/lib/active_theme/action_controller.rb +32 -0
  16. data/lib/active_theme/action_mailer.rb +22 -0
  17. data/lib/active_theme/action_view.rb +59 -0
  18. data/lib/active_theme/assets_controller.rb +66 -0
  19. data/lib/active_theme/common_methods.rb +66 -0
  20. data/lib/active_theme/config.rb +74 -0
  21. data/lib/active_theme/interpolation.rb +11 -0
  22. data/lib/active_theme/railtie.rb +32 -0
  23. data/lib/active_theme/routes.rb +27 -0
  24. data/lib/active_theme/url_helpers.rb +27 -0
  25. data/lib/active_theme/version.rb +4 -0
  26. data/lib/generators/active_theme/create_generator.rb +14 -0
  27. data/lib/generators/active_theme/install_generator.rb +16 -0
  28. data/lib/generators/active_theme/templates/theme/images/.gitkeep +0 -0
  29. data/lib/generators/active_theme/templates/theme/javascripts/.gitkeep +0 -0
  30. data/lib/generators/active_theme/templates/theme/stylesheets/.gitkeep +0 -0
  31. data/lib/generators/active_theme/templates/theme/views/layouts/.gitkeep +0 -0
  32. data/lib/tasks/active_theme.rake +22 -0
  33. data/test/dummy_app/.gitignore +4 -0
  34. data/test/dummy_app/Gemfile +30 -0
  35. data/test/dummy_app/Rakefile +7 -0
  36. data/test/dummy_app/another_themes/another_default/images/logo.png +0 -0
  37. data/test/dummy_app/another_themes/another_default/images/nested/logo.png +0 -0
  38. data/test/dummy_app/another_themes/another_default/javascripts/app.js +1 -0
  39. data/test/dummy_app/another_themes/another_default/stylesheets/style.css +0 -0
  40. data/test/dummy_app/another_themes/another_default/stylesheets/style2.css +3 -0
  41. data/test/dummy_app/another_themes/another_default/views/layouts/default.html.erb +10 -0
  42. data/test/dummy_app/another_themes/another_default/views/products/index.html.erb +0 -0
  43. data/test/dummy_app/app/controllers/application_controller.rb +3 -0
  44. data/test/dummy_app/app/helpers/application_helper.rb +2 -0
  45. data/test/dummy_app/app/views/layouts/application.html.erb +14 -0
  46. data/test/dummy_app/config.ru +4 -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/db/seeds.rb +7 -0
  62. data/test/dummy_app/empty_themes/.gitkeep +0 -0
  63. data/test/dummy_app/lib/tasks/.gitkeep +0 -0
  64. data/test/dummy_app/public/404.html +26 -0
  65. data/test/dummy_app/public/422.html +26 -0
  66. data/test/dummy_app/public/500.html +26 -0
  67. data/test/dummy_app/public/favicon.ico +0 -0
  68. data/test/dummy_app/public/images/rails.png +0 -0
  69. data/test/dummy_app/public/index.html +239 -0
  70. data/test/dummy_app/public/javascripts/application.js +2 -0
  71. data/test/dummy_app/public/javascripts/controls.js +965 -0
  72. data/test/dummy_app/public/javascripts/dragdrop.js +974 -0
  73. data/test/dummy_app/public/javascripts/effects.js +1123 -0
  74. data/test/dummy_app/public/javascripts/prototype.js +6001 -0
  75. data/test/dummy_app/public/javascripts/rails.js +175 -0
  76. data/test/dummy_app/public/robots.txt +5 -0
  77. data/test/dummy_app/public/stylesheets/.gitkeep +0 -0
  78. data/test/dummy_app/script/rails +6 -0
  79. data/test/dummy_app/themes/default/images/logo.png +0 -0
  80. data/test/dummy_app/themes/default/images/nested/logo.png +0 -0
  81. data/test/dummy_app/themes/default/javascripts/app.js +1 -0
  82. data/test/dummy_app/themes/default/javascripts/app.min.js +0 -0
  83. data/test/dummy_app/themes/default/stylesheets/images/logo.png +0 -0
  84. data/test/dummy_app/themes/default/stylesheets/style.css +0 -0
  85. data/test/dummy_app/themes/default/stylesheets/style2.css +3 -0
  86. data/test/dummy_app/themes/default/views/layouts/default.html.erb +10 -0
  87. data/test/dummy_app/themes/default/views/products/index.html.erb +0 -0
  88. data/test/lib/action_controller_test.rb +170 -0
  89. data/test/lib/action_mailer_test.rb +35 -0
  90. data/test/lib/action_view_test.rb +54 -0
  91. data/test/lib/assets_controller_test.rb +73 -0
  92. data/test/lib/common_methods_test.rb +28 -0
  93. data/test/lib/config_test.rb +26 -0
  94. data/test/lib/integration_test.rb +12 -0
  95. data/test/lib/routes_test.rb +40 -0
  96. data/test/lib/themes_for_rails_test.rb +18 -0
  97. data/test/support/extensions.rb +19 -0
  98. data/test/test_helper.rb +12 -0
  99. metadata +276 -0
File without changes
@@ -0,0 +1,3 @@
1
+ - Allow to change the way the view path is added. Before or after.
2
+
3
+ - Research how to integrate SASS to this scheme.
@@ -0,0 +1,58 @@
1
+ # encoding: utf-8
2
+ module ActiveTheme
3
+
4
+ class << self
5
+
6
+ def config
7
+ @config ||= ActiveTheme::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 ActiveTheme.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 already_configured_in_sass?(sass_dir)
40
+ Sass::Plugin.template_location_array.map(&:first).include?(sass_dir)
41
+ end
42
+
43
+ end
44
+ end
45
+
46
+ require 'active_support/dependencies'
47
+ require 'active_theme/interpolation'
48
+ require 'active_theme/config'
49
+ require 'active_theme/common_methods'
50
+ require 'active_theme/url_helpers'
51
+
52
+ require 'active_theme/action_view'
53
+ require 'active_theme/assets_controller'
54
+ require 'active_theme/action_controller'
55
+ require 'active_theme/action_mailer'
56
+ require 'active_theme/railtie'
57
+ require 'active_theme/routes'
58
+
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module ActiveTheme
3
+
4
+ module ActionController
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+
10
+ include ActiveTheme::CommonMethods
11
+ include ActiveTheme::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 ActiveTheme
3
+
4
+ module ActionMailer
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include ActiveTheme::ActionController
10
+ alias_method_chain :mail, :theme
11
+ end
12
+
13
+ def mail_with_theme(headers = {}, &block)
14
+ theme_opts = headers[: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,59 @@
1
+ # encoding: utf-8
2
+ module ActiveTheme
3
+
4
+ module ActionView
5
+
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ include ActiveTheme::CommonMethods
10
+ end
11
+
12
+ def current_theme_stylesheet_path(asset)
13
+ base_theme_stylesheet_path(:theme => self.theme_name, :asset => "#{asset}.css")
14
+ end
15
+
16
+ def current_theme_javascript_path(asset)
17
+ base_theme_javascript_path(:theme => self.theme_name, :asset => "#{asset}.js")
18
+ end
19
+
20
+ def current_theme_image_path(asset)
21
+ base_theme_image_path(:theme => self.theme_name, :asset => asset)
22
+ end
23
+
24
+ def theme_stylesheet_path(asset, new_theme_name = self.theme_name)
25
+ base_theme_stylesheet_path(:theme => new_theme_name, :asset => "#{asset}.css")
26
+ end
27
+
28
+ def theme_javascript_path(asset, new_theme_name = self.theme_name)
29
+ base_theme_javascript_path(:theme => new_theme_name, :asset => "#{asset}.js")
30
+ end
31
+
32
+ def theme_image_path(asset, new_theme_name = self.theme_name)
33
+ base_theme_image_path(:theme => new_theme_name, :asset => asset)
34
+ end
35
+
36
+ def theme_image_tag(source, options = {})
37
+ image_tag(theme_image_path(source), options)
38
+ end
39
+
40
+ def theme_image_submit_tag(source, options = {})
41
+ image_submit_tag(theme_image_path(source), options)
42
+ end
43
+
44
+ def theme_javascript_include_tag(*files)
45
+ options = files.extract_options!
46
+ options.merge!({ :type => "text/javascript" })
47
+ files.collect! {|file| theme_javascript_path(file) }
48
+ javascript_include_tag(*files, options)
49
+ end
50
+
51
+ def theme_stylesheet_link_tag(*files)
52
+ options = files.extract_options!
53
+ options.merge!({ :type => "text/css" })
54
+ files.collect! {|file| theme_stylesheet_path(file) }
55
+ stylesheet_link_tag(*files, options)
56
+ end
57
+ end
58
+ end
59
+
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ require "action_controller/metal"
3
+
4
+ module ActiveTheme
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
+ send_file path, :type => mime_type, :disposition => "inline"
25
+ end
26
+ end
27
+
28
+ def find_themed_asset(asset_name, asset_theme, asset_type, &block)
29
+ path = asset_path(asset_name, asset_theme, asset_type)
30
+ if File.exists?(path)
31
+ yield path, mime_type_for(request)
32
+ elsif File.extname(path).blank?
33
+ asset_name = "#{asset_name}.#{extension_from(request.path_info)}"
34
+ return find_themed_asset(asset_name, asset_theme, asset_type, &block)
35
+ else
36
+ render_not_found
37
+ end
38
+ end
39
+
40
+ def asset_path(asset_name, asset_theme, asset_type)
41
+ File.join(theme_asset_path_for(asset_theme), asset_type, asset_name)
42
+ end
43
+
44
+ def render_not_found
45
+ render :text => 'Not found', :status => 404
46
+ end
47
+
48
+ def mime_type_for(request)
49
+ existing_mime_type = mime_type_from_uri(request.path_info)
50
+ unless existing_mime_type.nil?
51
+ existing_mime_type.to_s
52
+ else
53
+ "image/#{extension_from(request.path_info)}"
54
+ end
55
+ end
56
+
57
+ def mime_type_from_uri(path)
58
+ extension = extension_from(path)
59
+ Mime::Type.lookup_by_extension(extension)
60
+ end
61
+
62
+ def extension_from(path)
63
+ File.extname(path).to_s[1..-1]
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,66 @@
1
+ # encoding: utf-8
2
+ module ActiveTheme
3
+ module CommonMethods
4
+
5
+ include ActiveTheme::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 public_theme_path
47
+ theme_view_path("/")
48
+ end
49
+
50
+ def theme_asset_path
51
+ theme_asset_path_for(theme_name)
52
+ end
53
+
54
+ def theme_view_path
55
+ theme_view_path_for(theme_name)
56
+ end
57
+
58
+ def theme_view_path_for(theme_name)
59
+ interpolate(ActiveTheme.config.views_dir, theme_name)
60
+ end
61
+
62
+ def theme_asset_path_for(theme_name)
63
+ interpolate(ActiveTheme.config.assets_dir, theme_name)
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ module ActiveTheme
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
7
+
8
+ include Interpolation
9
+
10
+ def initialize(&block)
11
+ @use_sass = true
12
+ @default_theme = 'default'
13
+ yield if block_given?
14
+ end
15
+
16
+ def base_dir
17
+ @base_dir ||= Rails.root.to_s
18
+ end
19
+
20
+ # relative assets dir for view overloading support
21
+ # used for theme_view_path_for method to get theme path and add to view paths.
22
+ # Defaults to themes_dir for non asset pipeline users
23
+ #
24
+ # If you are using the Rails Asset Pipeline, this should be changed to the
25
+ # path of your assets in your app. For example, if you store your themes
26
+ # under /app/assets/themes - {Rails.root}/app/assets/themes
27
+ # you would need to set this to 'app/assets/themes' in your initializer config
28
+ def assets_dir
29
+ @assets_dir ||= ":root/themes/:name"
30
+ end
31
+
32
+ # relative views directory for theme views to be separated from assets
33
+ # used for Asset Pipeline support. Defaults to match {assets_dir}/views
34
+ def views_dir
35
+ @views_dir ||= ":root/themes/:name/views"
36
+ end
37
+
38
+ def themes_dir
39
+ @themes_dir ||= ":root/themes"
40
+ end
41
+
42
+ # Full path to themes
43
+ def themes_path
44
+ interpolate(themes_dir)
45
+ end
46
+
47
+ # This is the base themes dir that is used for mapping URL paths.
48
+ #
49
+ # If you are using the Rails Asset Pipeline, this should be changed to the
50
+ # prefix dir of your assets path. For example, if you store your themes
51
+ # under /app/assets/themes - {Rails.root}/app/assets/themes
52
+ # you would need to set this value to 'assets' to match up with the Sprockets
53
+ # path resolution process.
54
+
55
+ def themes_routes_dir
56
+ @themes_routes_dir ||= "themes"
57
+ end
58
+
59
+ def clear
60
+ @base_dir = nil
61
+ @themes_dir = nil
62
+ @assets_dir = nil
63
+ @views_dir = nil
64
+ end
65
+
66
+ def use_sass?
67
+ @use_sass and sass_is_available?
68
+ end
69
+
70
+ def sass_is_available?
71
+ !!defined?Sass::Plugin
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,11 @@
1
+ module ActiveTheme
2
+
3
+ module Interpolation
4
+
5
+ def interpolate(pattern, name = nil)
6
+ pattern.gsub(":root", ActiveTheme.config.base_dir).gsub(":name", name.to_s)
7
+ end
8
+
9
+ end
10
+
11
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+ module ActiveTheme
3
+ class Railtie < ::Rails::Railtie
4
+
5
+ config.active_theme = ActiveSupport::OrderedOptions.new
6
+
7
+ config.to_prepare do
8
+ ActiveTheme::Railtie.config.active_theme.each do |key, value|
9
+ ActiveTheme.config.send "#{key}=".to_sym, value
10
+ end
11
+
12
+ # Adding theme stylesheets path to sass, automatically.
13
+ ActiveTheme.add_themes_path_to_sass if ActiveTheme.config.use_sass?
14
+
15
+ ActiveSupport.on_load(:action_view) do
16
+ include ActiveTheme::ActionView
17
+ end
18
+
19
+ ActiveSupport.on_load(:action_controller) do
20
+ include ActiveTheme::ActionController
21
+ end
22
+
23
+ ActiveSupport.on_load(:action_mailer) do
24
+ include ActiveTheme::ActionMailer
25
+ end
26
+ end
27
+
28
+ rake_tasks do
29
+ load "tasks/active_theme.rake"
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ module ActiveTheme
3
+ module Routes
4
+
5
+ def active_theme
6
+ theme_dir = ActiveTheme.config.themes_routes_dir
7
+ constraints = { :theme => /[\w\.]*/ }
8
+
9
+ match "#{theme_dir}/:theme/stylesheets/*asset" => 'active_theme/assets#stylesheets',
10
+ :as => :base_theme_stylesheet, :constraints => constraints
11
+ match "#{theme_dir}/:theme/javascripts/*asset" => 'active_theme/assets#javascripts',
12
+ :as => :base_theme_javascript, :constraints => constraints
13
+ match "#{theme_dir}/:theme/images/*asset" => 'active_theme/assets#images',
14
+ :as => :base_theme_image, :constraints => constraints
15
+ end
16
+
17
+ end
18
+ end
19
+
20
+ module ActionDispatch::Routing
21
+ class Mapper #:nodoc:
22
+
23
+ include ActiveTheme::Routes
24
+
25
+ end
26
+ end
27
+