themes_for_rails 0.2.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 (75) hide show
  1. data/.gitignore +3 -0
  2. data/.rvmrc +5 -0
  3. data/Gemfile +11 -0
  4. data/Gemfile.lock +108 -0
  5. data/README.textile +155 -0
  6. data/Rakefile +33 -0
  7. data/init.rb +1 -0
  8. data/lib/generators/theme_for_rails/install_generator.rb +11 -0
  9. data/lib/generators/theme_for_rails/templates/theme/images/.gitkeep +0 -0
  10. data/lib/generators/theme_for_rails/templates/theme/javascripts/.gitkeep +0 -0
  11. data/lib/generators/theme_for_rails/templates/theme/stylesheets/.gitkeep +0 -0
  12. data/lib/generators/theme_for_rails/templates/theme/views/layouts/.gitkeep +0 -0
  13. data/lib/generators/theme_for_rails/theme_generator.rb +17 -0
  14. data/lib/tasks/themes_for_rails.rake +21 -0
  15. data/lib/themes_for_rails.rb +23 -0
  16. data/lib/themes_for_rails/assets_controller.rb +37 -0
  17. data/lib/themes_for_rails/common_methods.rb +48 -0
  18. data/lib/themes_for_rails/controller_methods.rb +23 -0
  19. data/lib/themes_for_rails/railtie.rb +18 -0
  20. data/lib/themes_for_rails/routes.rb +15 -0
  21. data/lib/themes_for_rails/url_helpers.rb +23 -0
  22. data/lib/themes_for_rails/version.rb +3 -0
  23. data/lib/themes_for_rails/view_helpers.rb +37 -0
  24. data/test/assets_controller_test.rb +46 -0
  25. data/test/controller_methods_test.rb +78 -0
  26. data/test/dummy_app/.gitignore +4 -0
  27. data/test/dummy_app/Gemfile +30 -0
  28. data/test/dummy_app/Rakefile +7 -0
  29. data/test/dummy_app/app/controllers/application_controller.rb +3 -0
  30. data/test/dummy_app/app/helpers/application_helper.rb +2 -0
  31. data/test/dummy_app/app/views/layouts/application.html.erb +14 -0
  32. data/test/dummy_app/config.ru +4 -0
  33. data/test/dummy_app/config/application.rb +42 -0
  34. data/test/dummy_app/config/boot.rb +13 -0
  35. data/test/dummy_app/config/database.yml +18 -0
  36. data/test/dummy_app/config/environment.rb +5 -0
  37. data/test/dummy_app/config/environments/development.rb +26 -0
  38. data/test/dummy_app/config/environments/production.rb +49 -0
  39. data/test/dummy_app/config/environments/test.rb +35 -0
  40. data/test/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
  41. data/test/dummy_app/config/initializers/inflections.rb +10 -0
  42. data/test/dummy_app/config/initializers/mime_types.rb +5 -0
  43. data/test/dummy_app/config/initializers/secret_token.rb +7 -0
  44. data/test/dummy_app/config/initializers/session_store.rb +8 -0
  45. data/test/dummy_app/config/locales/en.yml +5 -0
  46. data/test/dummy_app/config/routes.rb +4 -0
  47. data/test/dummy_app/db/seeds.rb +7 -0
  48. data/test/dummy_app/lib/tasks/.gitkeep +0 -0
  49. data/test/dummy_app/public/404.html +26 -0
  50. data/test/dummy_app/public/422.html +26 -0
  51. data/test/dummy_app/public/500.html +26 -0
  52. data/test/dummy_app/public/favicon.ico +0 -0
  53. data/test/dummy_app/public/images/rails.png +0 -0
  54. data/test/dummy_app/public/index.html +239 -0
  55. data/test/dummy_app/public/javascripts/application.js +2 -0
  56. data/test/dummy_app/public/javascripts/controls.js +965 -0
  57. data/test/dummy_app/public/javascripts/dragdrop.js +974 -0
  58. data/test/dummy_app/public/javascripts/effects.js +1123 -0
  59. data/test/dummy_app/public/javascripts/prototype.js +6001 -0
  60. data/test/dummy_app/public/javascripts/rails.js +175 -0
  61. data/test/dummy_app/public/robots.txt +5 -0
  62. data/test/dummy_app/public/stylesheets/.gitkeep +0 -0
  63. data/test/dummy_app/script/rails +6 -0
  64. data/test/dummy_app/themes/default/images/logo.png +0 -0
  65. data/test/dummy_app/themes/default/javascripts/app.js +1 -0
  66. data/test/dummy_app/themes/default/stylesheets/style.css +0 -0
  67. data/test/dummy_app/themes/default/stylesheets/style2.css +3 -0
  68. data/test/dummy_app/themes/default/views/layouts/default.html.erb +10 -0
  69. data/test/dummy_app/themes/default/views/products/index.html.erb +0 -0
  70. data/test/routes_test.rb +33 -0
  71. data/test/support/extensions.rb +16 -0
  72. data/test/test_helper.rb +10 -0
  73. data/test/themes_for_rails_test.rb +7 -0
  74. data/themes_for_rails.gemspec +133 -0
  75. metadata +157 -0
@@ -0,0 +1,3 @@
1
+ .bundle
2
+ pkg
3
+ tmp
data/.rvmrc ADDED
@@ -0,0 +1,5 @@
1
+ if [[ -n "$rvm_environments_path" && -s "$rvm_environments_path/ruby-1.9.2-p0@theme_support" ]] ; then
2
+ \. "$rvm_environments_path/ruby-1.9.2-p0@theme_support"
3
+ else
4
+ rvm --create use "ruby-1.9.2-p0@theme_support"
5
+ fi
data/Gemfile ADDED
@@ -0,0 +1,11 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem 'sqlite3-ruby', :require => 'sqlite3'
4
+ gem "rails", "3.0.0"
5
+ gem 'test-unit', :require => 'test/unit'
6
+ gem "rspec-rails", ">= 2.0.0.beta.20"
7
+ gem 'themes_for_rails', :path => '.'
8
+ gem 'jeweler'
9
+ gem "contest"
10
+ gem 'mocha'
11
+
@@ -0,0 +1,108 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ themes_for_rails (0.2.0)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ abstract (1.0.0)
10
+ actionmailer (3.0.0)
11
+ actionpack (= 3.0.0)
12
+ mail (~> 2.2.5)
13
+ actionpack (3.0.0)
14
+ activemodel (= 3.0.0)
15
+ activesupport (= 3.0.0)
16
+ builder (~> 2.1.2)
17
+ erubis (~> 2.6.6)
18
+ i18n (~> 0.4.1)
19
+ rack (~> 1.2.1)
20
+ rack-mount (~> 0.6.12)
21
+ rack-test (~> 0.5.4)
22
+ tzinfo (~> 0.3.23)
23
+ activemodel (3.0.0)
24
+ activesupport (= 3.0.0)
25
+ builder (~> 2.1.2)
26
+ i18n (~> 0.4.1)
27
+ activerecord (3.0.0)
28
+ activemodel (= 3.0.0)
29
+ activesupport (= 3.0.0)
30
+ arel (~> 1.0.0)
31
+ tzinfo (~> 0.3.23)
32
+ activeresource (3.0.0)
33
+ activemodel (= 3.0.0)
34
+ activesupport (= 3.0.0)
35
+ activesupport (3.0.0)
36
+ arel (1.0.1)
37
+ activesupport (~> 3.0.0)
38
+ builder (2.1.2)
39
+ contest (0.1.2)
40
+ diff-lcs (1.1.2)
41
+ erubis (2.6.6)
42
+ abstract (>= 1.0.0)
43
+ gemcutter (0.6.1)
44
+ git (1.2.5)
45
+ i18n (0.4.1)
46
+ jeweler (1.4.0)
47
+ gemcutter (>= 0.1.0)
48
+ git (>= 1.2.5)
49
+ rubyforge (>= 2.0.0)
50
+ json_pure (1.4.6)
51
+ mail (2.2.5)
52
+ activesupport (>= 2.3.6)
53
+ mime-types
54
+ treetop (>= 1.4.5)
55
+ mime-types (1.16)
56
+ mocha (0.9.8)
57
+ rake
58
+ polyglot (0.3.1)
59
+ rack (1.2.1)
60
+ rack-mount (0.6.13)
61
+ rack (>= 1.0.0)
62
+ rack-test (0.5.4)
63
+ rack (>= 1.0)
64
+ rails (3.0.0)
65
+ actionmailer (= 3.0.0)
66
+ actionpack (= 3.0.0)
67
+ activerecord (= 3.0.0)
68
+ activeresource (= 3.0.0)
69
+ activesupport (= 3.0.0)
70
+ bundler (~> 1.0.0)
71
+ railties (= 3.0.0)
72
+ railties (3.0.0)
73
+ actionpack (= 3.0.0)
74
+ activesupport (= 3.0.0)
75
+ rake (>= 0.8.4)
76
+ thor (~> 0.14.0)
77
+ rake (0.8.7)
78
+ rspec (2.0.0.beta.20)
79
+ rspec-core (= 2.0.0.beta.20)
80
+ rspec-expectations (= 2.0.0.beta.20)
81
+ rspec-mocks (= 2.0.0.beta.20)
82
+ rspec-core (2.0.0.beta.20)
83
+ rspec-expectations (2.0.0.beta.20)
84
+ diff-lcs (>= 1.1.2)
85
+ rspec-mocks (2.0.0.beta.20)
86
+ rspec-rails (2.0.0.beta.20)
87
+ rspec (= 2.0.0.beta.20)
88
+ rubyforge (2.0.4)
89
+ json_pure (>= 1.1.7)
90
+ sqlite3-ruby (1.3.1)
91
+ test-unit (2.1.1)
92
+ thor (0.14.0)
93
+ treetop (1.4.8)
94
+ polyglot (>= 0.3.1)
95
+ tzinfo (0.3.23)
96
+
97
+ PLATFORMS
98
+ ruby
99
+
100
+ DEPENDENCIES
101
+ contest
102
+ jeweler
103
+ mocha
104
+ rails (= 3.0.0)
105
+ rspec-rails (>= 2.0.0.beta.20)
106
+ sqlite3-ruby
107
+ test-unit
108
+ themes_for_rails!
@@ -0,0 +1,155 @@
1
+ h1. Theme For Rails (3 and hopefully later)
2
+
3
+ h2. Features list / Wish list
4
+
5
+ * Support for adding themes which includes stylesheets, javascripts, views and layouts.
6
+
7
+ <pre>
8
+ $app_root
9
+ themes/
10
+ [theme_name]
11
+ images/
12
+ stylesheets/
13
+ javascripts/
14
+ views/ <- you can override application views
15
+ layouts/ <- layout .rhtml or .liquid templates
16
+ </pre>
17
+
18
+ h2. Instructions
19
+
20
+ Add themes_for_rails to your Gemfile.
21
+
22
+ <pre>
23
+ gem 'themes_for_rails'
24
+ </pre>
25
+
26
+ Add themes_for_rails to your config/routes.rb
27
+
28
+ <pre>
29
+ MySuperDuperApp::Application.routes.draw do
30
+ # ...
31
+ themes_for_rails
32
+ # ...
33
+ end
34
+ </pre>
35
+
36
+ h3. And then?
37
+
38
+ Now you'll be able to use themes like this:
39
+
40
+ Inside method, for some explicit action:
41
+
42
+ <pre>
43
+ class MyController < ApplicationController
44
+ def show
45
+ theme "purple"
46
+ end
47
+ end
48
+ </pre>
49
+
50
+ Or at class level definition, in order to set a theme for more than one action. I think this is is prettier, and less invasive.
51
+
52
+ <pre>
53
+ class MyController < ApplicationController
54
+ theme "purple" # all actions will use this theme
55
+ def show
56
+ ...
57
+ end
58
+ end
59
+ </pre>
60
+
61
+ You could also enable a theme for some actions only
62
+
63
+ <pre>
64
+ class MyController < ApplicationController
65
+ theme "purple", :only => :show
66
+ def show
67
+ # with theme
68
+ end
69
+ def edit
70
+ # no theme
71
+ end
72
+ end
73
+ </pre>
74
+
75
+ As a plus, you could do this to defer theme name resolution to a method:
76
+
77
+ <pre>
78
+ class MyController < ApplicationController
79
+ theme :theme_resolver
80
+ # ...
81
+ private
82
+ def theme_resolver
83
+ current_user.theme # or anything else that return a string.
84
+ end
85
+ end
86
+ </pre>
87
+
88
+ As a general rule, when passing a String, that becomes the theme name, but when a Symbol is sent, it gets treated as method message.
89
+
90
+ h3. Url Helpers
91
+
92
+ In your views you should be able to access your assets like this (given the theme 'default' is set):
93
+
94
+ <pre>
95
+ current_theme_image_path('logo.png') # => /themes/default/images/logo.png
96
+ current_theme_stylesheet_path('style') # => /themes/default/stylesheets/logo.css
97
+ current_theme_javascript_path('app') # => /themes/default/stylesheets/app.js
98
+ </pre>
99
+
100
+ Or a given theme:
101
+
102
+ <pre>
103
+ current_theme_image_path('logo.png', 'purple') # => /themes/purple/images/logo.png
104
+ </pre>
105
+
106
+ In your application views, there are theme specific helper tags
107
+ available to you. For ERb templates they are:
108
+
109
+ <pre>
110
+ theme_image_tag
111
+ theme_image_path
112
+ theme_javascript_include_tag
113
+ theme_javascript_path
114
+ theme_stylesheet_link_tag
115
+ theme_stylesheet_path
116
+ </pre>
117
+
118
+ h2. Generators
119
+
120
+ For now, it only creates the theme folder.
121
+
122
+ <pre>
123
+ rails generate theme_for_rails:install
124
+ </pre>
125
+
126
+ Inside the themes folder, it create a structure for my_theme.
127
+
128
+ <pre>
129
+ rails generate theme_for_rails:theme my_theme
130
+ </pre>
131
+
132
+ h2. Ideas
133
+
134
+ * Add ThemesForRails::Railtie for configuration, so we selectively set the plugin on or off. Also to be able to change several settings.
135
+ * Add routes to allow access to the theme's static resources (js and cs), unless cached on public folder by capistrano / rake.
136
+ * -Extend Action View path in order to make the views accessible. Same for the layouts.-
137
+ * More tests ford edge cases. Now I am only testing the happy paths.
138
+
139
+ h2. Things to remember.
140
+
141
+ * -Final version should be a gem. Initialization hooks doesn't work when using this as a plugin (vendor/plugins).-
142
+ * -Research about testing this kind of gem. I really don't have a clue.- Testing in place!
143
+ * I should probably load the theme list at start time, to be able to consult it as needed. I am gonna need that when dealing with runtime theme selection. Many themes are going to be used simultaneously, so I have to be able to switch view paths as fast as I can.
144
+
145
+ h2. Running tests
146
+
147
+ <pre>
148
+ gem install bundler
149
+ bundle install
150
+ rake
151
+ </pre>
152
+
153
+ h2. Authors and contributors
154
+
155
+ * lucasefe
@@ -0,0 +1,33 @@
1
+ # require File.join(File.dirname(__FILE__), 'lib', 'themes_for_rails')
2
+ require File.dirname(__FILE__) + "/lib/themes_for_rails/version.rb"
3
+
4
+ require 'rake'
5
+ require 'rake/testtask'
6
+ require 'rake/rdoctask'
7
+
8
+ desc 'Default: run tests for all ORMs.'
9
+ task :default => :test
10
+
11
+ desc 'Run unit tests.'
12
+ Rake::TestTask.new(:test) do |t|
13
+ t.libs << 'lib'
14
+ t.libs << 'test'
15
+ t.pattern = 'test/**/*_test.rb'
16
+ t.verbose = true
17
+ end
18
+
19
+ begin
20
+ require 'jeweler'
21
+ Jeweler::Tasks.new do |gemspec|
22
+ gemspec.name = "themes_for_rails"
23
+ gemspec.summary = "Themes support for rails (3)"
24
+ gemspec.description = "It allows an application to have many different ways of rendering static assets and dynamic views. "
25
+ gemspec.email = "lucasefe@gmail.com"
26
+ gemspec.homepage = "http://github.com/lucasefe/themes_for_rails"
27
+ gemspec.authors = ["Lucas Florio"]
28
+ gemspec.version = ThemesForRails::VERSION
29
+ end
30
+ rescue LoadError
31
+ puts "Jeweler not available. Install it with: gem install jeweler"
32
+ end
33
+
data/init.rb ADDED
@@ -0,0 +1 @@
1
+ require "themes_for_rails"
@@ -0,0 +1,11 @@
1
+ module ThemeForRails
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ desc "Creates a ThemeForRails basic structure."
5
+
6
+ def create_themes_folder
7
+ empty_directory(File.join(Rails.root, 'themes'))
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,17 @@
1
+ module ThemeForRails
2
+ module Generators
3
+ class ThemeGenerator < Rails::Generators::NamedBase
4
+ source_root File.expand_path("../templates", __FILE__)
5
+ desc "Creates an empty theme."
6
+
7
+ def create_theme
8
+ theme_dir = File.join(themes_path, name)
9
+ directory 'theme', theme_dir
10
+ end
11
+ private
12
+ def themes_path
13
+ File.join(Rails.root, "themes")
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
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
+ puts "Creating #{Rails.public_path}/themes/#{theme_name}"
7
+
8
+ FileUtils.mkdir_p "#{Rails.public_path}/themes/#{theme_name}"
9
+ FileUtils.cp_r "#{theme}/images", "#{Rails.public_path}/themes/#{theme_name}/images", :verbose => true
10
+ FileUtils.cp_r "#{theme}/stylesheets", "#{Rails.public_path}/themes/#{theme_name}/stylesheets", :verbose => true
11
+ FileUtils.cp_r "#{theme}/javascripts", "#{Rails.public_path}/themes/#{theme_name}/javascripts", :verbose => true
12
+ end
13
+ end
14
+ desc "Removes the cached (public) theme folders"
15
+ task :remove_cache => :environment do
16
+ puts "Removing #{Rails.public_path}/themes"
17
+ FileUtils.rm_r "#{Rails.public_path}/themes", :force => true
18
+ end
19
+ desc "Updates the cached (public) theme folders"
20
+ task :update_cache => [:remove_cache, :create_cache]
21
+ end
@@ -0,0 +1,23 @@
1
+ module ThemesForRails
2
+ class << self
3
+ def theme_base_dir
4
+ Rails.root
5
+ end
6
+ def available_themes
7
+ Dir.glob("#{theme_base_dir}/themes/*")
8
+ end
9
+ def available_theme_names
10
+ @available_theme_names ||= available_themes.map {|theme| File.basename(theme) }
11
+ end
12
+ end
13
+ end
14
+
15
+ require 'active_support/dependencies'
16
+ require 'themes_for_rails/common_methods'
17
+ require 'themes_for_rails/url_helpers'
18
+ require 'themes_for_rails/view_helpers'
19
+ require 'themes_for_rails/assets_controller'
20
+ require 'themes_for_rails/controller_methods'
21
+ require 'themes_for_rails/railtie'
22
+ require 'themes_for_rails/routes'
23
+ require 'themes_for_rails/version'
@@ -0,0 +1,37 @@
1
+ require "action_controller/metal"
2
+
3
+ module ThemesForRails
4
+ class AssetsController < ActionController::Base
5
+ include ThemesForRails::CommonMethods
6
+ include ThemesForRails::UrlHelpers
7
+ def stylesheets
8
+ render_asset theme_stylesheet_path_for(params[:theme], params[:asset]), 'text/css'
9
+ end
10
+ def javascripts
11
+ render_asset theme_javascript_path_for(params[:theme], params[:asset]), 'text/javascript'
12
+ end
13
+ def images
14
+ render_asset theme_image_path_for(params[:theme], params[:asset], params[:extension]), "image/#{params[:extension]}"
15
+ end
16
+ private
17
+ def render_asset(asset, mime_type)
18
+ unless File.exists?(asset)
19
+ render :text => 'not found', :status => 404
20
+ else
21
+ send_file asset, :type => mime_type
22
+ end
23
+ end
24
+ # Physical paths
25
+ def theme_stylesheet_path_for(name, asset)
26
+ File.join(theme_path_for(name), 'stylesheets', "#{asset}.css")
27
+ end
28
+ def theme_javascript_path_for(name, asset)
29
+ File.join(theme_path_for(name), 'javascripts', "#{asset}.js")
30
+ end
31
+ def theme_image_path_for(name, asset, extension = nil)
32
+ extension ||= "png"
33
+ extension = ".#{extension}"
34
+ File.join(theme_path_for(name), 'images', "#{asset}#{extension}")
35
+ end
36
+ end
37
+ end