themes_for_rails 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rvmrc +5 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +108 -0
- data/README.textile +155 -0
- data/Rakefile +33 -0
- data/init.rb +1 -0
- data/lib/generators/theme_for_rails/install_generator.rb +11 -0
- data/lib/generators/theme_for_rails/templates/theme/images/.gitkeep +0 -0
- data/lib/generators/theme_for_rails/templates/theme/javascripts/.gitkeep +0 -0
- data/lib/generators/theme_for_rails/templates/theme/stylesheets/.gitkeep +0 -0
- data/lib/generators/theme_for_rails/templates/theme/views/layouts/.gitkeep +0 -0
- data/lib/generators/theme_for_rails/theme_generator.rb +17 -0
- data/lib/tasks/themes_for_rails.rake +21 -0
- data/lib/themes_for_rails.rb +23 -0
- data/lib/themes_for_rails/assets_controller.rb +37 -0
- data/lib/themes_for_rails/common_methods.rb +48 -0
- data/lib/themes_for_rails/controller_methods.rb +23 -0
- data/lib/themes_for_rails/railtie.rb +18 -0
- data/lib/themes_for_rails/routes.rb +15 -0
- data/lib/themes_for_rails/url_helpers.rb +23 -0
- data/lib/themes_for_rails/version.rb +3 -0
- data/lib/themes_for_rails/view_helpers.rb +37 -0
- data/test/assets_controller_test.rb +46 -0
- data/test/controller_methods_test.rb +78 -0
- data/test/dummy_app/.gitignore +4 -0
- data/test/dummy_app/Gemfile +30 -0
- data/test/dummy_app/Rakefile +7 -0
- data/test/dummy_app/app/controllers/application_controller.rb +3 -0
- data/test/dummy_app/app/helpers/application_helper.rb +2 -0
- data/test/dummy_app/app/views/layouts/application.html.erb +14 -0
- data/test/dummy_app/config.ru +4 -0
- data/test/dummy_app/config/application.rb +42 -0
- data/test/dummy_app/config/boot.rb +13 -0
- data/test/dummy_app/config/database.yml +18 -0
- data/test/dummy_app/config/environment.rb +5 -0
- data/test/dummy_app/config/environments/development.rb +26 -0
- data/test/dummy_app/config/environments/production.rb +49 -0
- data/test/dummy_app/config/environments/test.rb +35 -0
- data/test/dummy_app/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy_app/config/initializers/inflections.rb +10 -0
- data/test/dummy_app/config/initializers/mime_types.rb +5 -0
- data/test/dummy_app/config/initializers/secret_token.rb +7 -0
- data/test/dummy_app/config/initializers/session_store.rb +8 -0
- data/test/dummy_app/config/locales/en.yml +5 -0
- data/test/dummy_app/config/routes.rb +4 -0
- data/test/dummy_app/db/seeds.rb +7 -0
- data/test/dummy_app/lib/tasks/.gitkeep +0 -0
- data/test/dummy_app/public/404.html +26 -0
- data/test/dummy_app/public/422.html +26 -0
- data/test/dummy_app/public/500.html +26 -0
- data/test/dummy_app/public/favicon.ico +0 -0
- data/test/dummy_app/public/images/rails.png +0 -0
- data/test/dummy_app/public/index.html +239 -0
- data/test/dummy_app/public/javascripts/application.js +2 -0
- data/test/dummy_app/public/javascripts/controls.js +965 -0
- data/test/dummy_app/public/javascripts/dragdrop.js +974 -0
- data/test/dummy_app/public/javascripts/effects.js +1123 -0
- data/test/dummy_app/public/javascripts/prototype.js +6001 -0
- data/test/dummy_app/public/javascripts/rails.js +175 -0
- data/test/dummy_app/public/robots.txt +5 -0
- data/test/dummy_app/public/stylesheets/.gitkeep +0 -0
- data/test/dummy_app/script/rails +6 -0
- data/test/dummy_app/themes/default/images/logo.png +0 -0
- data/test/dummy_app/themes/default/javascripts/app.js +1 -0
- data/test/dummy_app/themes/default/stylesheets/style.css +0 -0
- data/test/dummy_app/themes/default/stylesheets/style2.css +3 -0
- data/test/dummy_app/themes/default/views/layouts/default.html.erb +10 -0
- data/test/dummy_app/themes/default/views/products/index.html.erb +0 -0
- data/test/routes_test.rb +33 -0
- data/test/support/extensions.rb +16 -0
- data/test/test_helper.rb +10 -0
- data/test/themes_for_rails_test.rb +7 -0
- data/themes_for_rails.gemspec +133 -0
- metadata +157 -0
data/.gitignore
ADDED
data/.rvmrc
ADDED
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
|
+
|
data/Gemfile.lock
ADDED
@@ -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!
|
data/README.textile
ADDED
@@ -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
|
data/Rakefile
ADDED
@@ -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"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
@@ -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
|