wicked-focused 0.2.0

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 (77) hide show
  1. data/.rvmrc +19 -0
  2. data/.travis.yml +4 -0
  3. data/CHANGELOG.md +3 -0
  4. data/Gemfile +22 -0
  5. data/Gemfile.lock +122 -0
  6. data/MIT-LICENSE +20 -0
  7. data/README.md +253 -0
  8. data/Rakefile +50 -0
  9. data/VERSION +1 -0
  10. data/lib/wicked/action.rb +64 -0
  11. data/lib/wicked/controller/concerns/path.rb +29 -0
  12. data/lib/wicked/controller/concerns/render_redirect.rb +49 -0
  13. data/lib/wicked/controller/concerns/steps.rb +87 -0
  14. data/lib/wicked/engine.rb +4 -0
  15. data/lib/wicked/macros.rb +23 -0
  16. data/lib/wicked/wizard.rb +26 -0
  17. data/lib/wicked-focused.rb +25 -0
  18. data/test/dummy/Rakefile +7 -0
  19. data/test/dummy/app/controllers/application_controller.rb +3 -0
  20. data/test/dummy/app/controllers/bar_controller.rb +18 -0
  21. data/test/dummy/app/controllers/foo_controller.rb +19 -0
  22. data/test/dummy/app/controllers/jump_controller.rb +26 -0
  23. data/test/dummy/app/controllers/steps_controller.rb +18 -0
  24. data/test/dummy/app/helpers/application_helper.rb +2 -0
  25. data/test/dummy/app/models/bar.rb +9 -0
  26. data/test/dummy/app/views/bar/first.html.erb +5 -0
  27. data/test/dummy/app/views/bar/last_step.html.erb +3 -0
  28. data/test/dummy/app/views/bar/second.html.erb +3 -0
  29. data/test/dummy/app/views/foo/first.html.erb +1 -0
  30. data/test/dummy/app/views/foo/last_step.html.erb +1 -0
  31. data/test/dummy/app/views/foo/second.html.erb +1 -0
  32. data/test/dummy/app/views/jump/first.html.erb +1 -0
  33. data/test/dummy/app/views/jump/last_step.html.erb +1 -0
  34. data/test/dummy/app/views/jump/second.html.erb +1 -0
  35. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  36. data/test/dummy/app/views/step_positions/_step_position.html.erb +9 -0
  37. data/test/dummy/app/views/step_positions/first.html.erb +1 -0
  38. data/test/dummy/app/views/step_positions/last_step.html.erb +1 -0
  39. data/test/dummy/app/views/step_positions/second.html.erb +1 -0
  40. data/test/dummy/config/application.rb +45 -0
  41. data/test/dummy/config/boot.rb +10 -0
  42. data/test/dummy/config/database.yml +22 -0
  43. data/test/dummy/config/environment.rb +5 -0
  44. data/test/dummy/config/environments/development.rb +26 -0
  45. data/test/dummy/config/environments/production.rb +49 -0
  46. data/test/dummy/config/environments/test.rb +35 -0
  47. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  48. data/test/dummy/config/initializers/inflections.rb +10 -0
  49. data/test/dummy/config/initializers/mime_types.rb +5 -0
  50. data/test/dummy/config/initializers/secret_token.rb +7 -0
  51. data/test/dummy/config/initializers/session_store.rb +8 -0
  52. data/test/dummy/config/initializers/wicked.rb +2 -0
  53. data/test/dummy/config/locales/en.yml +5 -0
  54. data/test/dummy/config/routes.rb +8 -0
  55. data/test/dummy/config.ru +4 -0
  56. data/test/dummy/public/404.html +26 -0
  57. data/test/dummy/public/422.html +26 -0
  58. data/test/dummy/public/500.html +26 -0
  59. data/test/dummy/public/favicon.ico +0 -0
  60. data/test/dummy/public/index.html +1 -0
  61. data/test/dummy/public/javascripts/application.js +2 -0
  62. data/test/dummy/public/javascripts/controls.js +965 -0
  63. data/test/dummy/public/javascripts/dragdrop.js +974 -0
  64. data/test/dummy/public/javascripts/effects.js +1123 -0
  65. data/test/dummy/public/javascripts/prototype.js +6001 -0
  66. data/test/dummy/public/javascripts/rails.js +202 -0
  67. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  68. data/test/dummy/script/rails +6 -0
  69. data/test/integration/helpers_test.rb +40 -0
  70. data/test/integration/jump_test.rb +16 -0
  71. data/test/integration/navigation_test.rb +88 -0
  72. data/test/integration/steps_test.rb +32 -0
  73. data/test/support/integration_case.rb +5 -0
  74. data/test/test_helper.rb +30 -0
  75. data/test/wicked_test.rb +7 -0
  76. data/wicked-focused.gemspec +138 -0
  77. metadata +270 -0
data/.rvmrc ADDED
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env bash
2
+
3
+ ruby_string="ruby-1.9.3-p125"
4
+ gemset_name="wicked"
5
+
6
+ if rvm list strings | grep -q "${ruby_string}" ; then
7
+
8
+ rvm use "${ruby_string}@${gemset_name}" --create
9
+
10
+ # Complain if bundler isn't installed
11
+ if [[ -z "`gem which bundler 2>&1 | grep -v ERROR`" ]]; then
12
+ echo "You need bundler:"
13
+ echo ""
14
+ echo " gem install bundler"
15
+ echo ""
16
+ fi
17
+ else
18
+ echo "${ruby_string} was not found, please run 'rvm install ${ruby_string}' and then cd back into the project directory."
19
+ fi
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 0.2.0 (08/06/2012)
2
+
3
+ @kristianmandrup: Redesigned for use with Focused Controller. All tests pass :)
data/Gemfile ADDED
@@ -0,0 +1,22 @@
1
+ source "http://rubygems.org"
2
+
3
+ gem "activesupport" , ">= 3.0.7"
4
+ gem "rails" , ">= 3.0.7"
5
+
6
+ # with Action macros
7
+ gem 'focused_controller', :git => 'git://github.com/kristianmandrup/focused_controller.git'
8
+
9
+
10
+ group :development, :test do
11
+ gem 'rake'
12
+ gem 'jeweler', "~> 1.8.4"
13
+ gem "rcov", ">= 0"
14
+ gem "capybara", ">= 1.0.0"
15
+ gem "sqlite3"
16
+ gem "launchy"
17
+ end
18
+
19
+
20
+ # To use debugger (ruby-debug for Ruby 1.8.7+, ruby-debug19 for Ruby 1.9.2+)
21
+ # gem 'ruby-debug'
22
+ # gem 'ruby-debug19'
data/Gemfile.lock ADDED
@@ -0,0 +1,122 @@
1
+ GIT
2
+ remote: git://github.com/kristianmandrup/focused_controller.git
3
+ revision: 729d753a62abf4eadcfd76123f643973392bec3a
4
+ specs:
5
+ focused_controller (0.1.0)
6
+ actionpack (~> 3.0)
7
+
8
+ GEM
9
+ remote: http://rubygems.org/
10
+ specs:
11
+ abstract (1.0.0)
12
+ actionmailer (3.0.11)
13
+ actionpack (= 3.0.11)
14
+ mail (~> 2.2.19)
15
+ actionpack (3.0.11)
16
+ activemodel (= 3.0.11)
17
+ activesupport (= 3.0.11)
18
+ builder (~> 2.1.2)
19
+ erubis (~> 2.6.6)
20
+ i18n (~> 0.5.0)
21
+ rack (~> 1.2.1)
22
+ rack-mount (~> 0.6.14)
23
+ rack-test (~> 0.5.7)
24
+ tzinfo (~> 0.3.23)
25
+ activemodel (3.0.11)
26
+ activesupport (= 3.0.11)
27
+ builder (~> 2.1.2)
28
+ i18n (~> 0.5.0)
29
+ activerecord (3.0.11)
30
+ activemodel (= 3.0.11)
31
+ activesupport (= 3.0.11)
32
+ arel (~> 2.0.10)
33
+ tzinfo (~> 0.3.23)
34
+ activeresource (3.0.11)
35
+ activemodel (= 3.0.11)
36
+ activesupport (= 3.0.11)
37
+ activesupport (3.0.11)
38
+ addressable (2.2.7)
39
+ arel (2.0.10)
40
+ builder (2.1.2)
41
+ capybara (1.1.2)
42
+ mime-types (>= 1.16)
43
+ nokogiri (>= 1.3.3)
44
+ rack (>= 1.0.0)
45
+ rack-test (>= 0.5.4)
46
+ selenium-webdriver (~> 2.0)
47
+ xpath (~> 0.1.4)
48
+ childprocess (0.2.4)
49
+ ffi (~> 1.0.6)
50
+ erubis (2.6.6)
51
+ abstract (>= 1.0.0)
52
+ ffi (1.0.11)
53
+ git (1.2.5)
54
+ i18n (0.5.0)
55
+ jeweler (1.8.4)
56
+ bundler (~> 1.0)
57
+ git (>= 1.2.5)
58
+ rake
59
+ rdoc
60
+ json (1.6.4)
61
+ launchy (2.0.5)
62
+ addressable (~> 2.2.6)
63
+ mail (2.2.19)
64
+ activesupport (>= 2.3.6)
65
+ i18n (>= 0.4.0)
66
+ mime-types (~> 1.16)
67
+ treetop (~> 1.4.8)
68
+ mime-types (1.17.2)
69
+ multi_json (1.0.4)
70
+ nokogiri (1.5.0)
71
+ polyglot (0.3.3)
72
+ rack (1.2.5)
73
+ rack-mount (0.6.14)
74
+ rack (>= 1.0.0)
75
+ rack-test (0.5.7)
76
+ rack (>= 1.0)
77
+ rails (3.0.11)
78
+ actionmailer (= 3.0.11)
79
+ actionpack (= 3.0.11)
80
+ activerecord (= 3.0.11)
81
+ activeresource (= 3.0.11)
82
+ activesupport (= 3.0.11)
83
+ bundler (~> 1.0)
84
+ railties (= 3.0.11)
85
+ railties (3.0.11)
86
+ actionpack (= 3.0.11)
87
+ activesupport (= 3.0.11)
88
+ rake (>= 0.8.7)
89
+ rdoc (~> 3.4)
90
+ thor (~> 0.14.4)
91
+ rake (0.9.2.2)
92
+ rcov (0.9.11)
93
+ rdoc (3.12)
94
+ json (~> 1.4)
95
+ rubyzip (0.9.5)
96
+ selenium-webdriver (2.15.0)
97
+ childprocess (>= 0.2.1)
98
+ ffi (~> 1.0.9)
99
+ multi_json (~> 1.0.4)
100
+ rubyzip
101
+ sqlite3 (1.3.5)
102
+ thor (0.14.6)
103
+ treetop (1.4.10)
104
+ polyglot
105
+ polyglot (>= 0.3.1)
106
+ tzinfo (0.3.33)
107
+ xpath (0.1.4)
108
+ nokogiri (~> 1.3)
109
+
110
+ PLATFORMS
111
+ ruby
112
+
113
+ DEPENDENCIES
114
+ activesupport (>= 3.0.7)
115
+ capybara (>= 1.0.0)
116
+ focused_controller!
117
+ jeweler (~> 1.8.4)
118
+ launchy
119
+ rails (>= 3.0.7)
120
+ rake
121
+ rcov
122
+ sqlite3
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2011 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # Wicked Focused
2
+
3
+ This gem is [wicked](https://github.com/schneems/wicked) tweaked for use with [focused controller](https://github.com/jonleighton/focused_controller).
4
+
5
+ [![Build Status](https://secure.travis-ci.org/schneems/wicked.png)](http://travis-ci.org/schneems/wicked)
6
+
7
+ Use wicked to make your Rails controllers into step-by-step wizards. To see Wicked in action check out the example [Rails app](https://github.com/schneems/wicked_example) or [watch the screencast](http://schneems.com/post/18437886598/wizard-ify-your-rails-controllers-with-wicked).
8
+
9
+ ## Why
10
+
11
+ Many times I'm left wanting a RESTful way to display a step by step process that may or not be associated with a resource. Wicked gives the flexibility to do what I want while hiding all the really nasty stuff you shouldn't do in a controller to make this possible. At it's core Wicked is a RESTful(ish) state machine, but you don't need to know that, just use it.
12
+
13
+ ## Install
14
+
15
+ Add this to your Gemfile
16
+
17
+ ```ruby
18
+ gem 'wicked-focused'
19
+ ```
20
+
21
+ Then run `bundle install` and you're ready to start
22
+
23
+ ## Quicklinks
24
+
25
+ * Build an object step-by-step using [Partial Validation of Active Record Objects](https://github.com/schneems/wicked/wiki/Partial-Validation-of-Active-Record-Objects)
26
+ * [Show Current Wizard Progress to User](https://github.com/schneems/wicked/wiki/Show-Current-Wizard-Progress-to-User)
27
+ * [Example App](https://github.com/schneems/wicked_example)
28
+ * [Screencast](http://schneems.com/post/18437886598/wizard-ify-your-rails-controllers-with-wicked)
29
+ * [Watch Railscasts episode: #346 Wizard Forms with Wicked](http://railscasts.com/episodes/346-wizard-forms-with-wicked)
30
+
31
+ ## How
32
+
33
+ We are going to build an 'after signup' wizard. First create a controller:
34
+
35
+ ```
36
+ rails g controller after_signup
37
+ ```
38
+
39
+ Add Routes into `config/routes.rb`:
40
+
41
+ ```ruby
42
+ resources :after_signup
43
+ ```
44
+
45
+ Next include `Wicked::Wizard` in your controller
46
+
47
+ ```ruby
48
+
49
+ class AfterSignupController
50
+ # base Wizard Action class of Controller must be called 'Action'
51
+ # and must include of Wizard::Action
52
+ class Action < FocusedAction
53
+ include Wizard::Action
54
+
55
+ steps :confirm_password, :confirm_profile, :find_friends
56
+ end
57
+
58
+ # creates Focused Action :index
59
+ include Wicked::Wizard
60
+
61
+ ```
62
+
63
+ The wizard is set to call steps in order in the show action, you can specify custom logic in your show using a case statement like below. To send someone to the first step in this wizard we can direct them to `after_signup_path(:confirm_password)`.
64
+
65
+ ```ruby
66
+ class AfterSignupController
67
+ class Action < FocusedAction
68
+ include Wizard::Action
69
+
70
+ steps :confirm_password, :confirm_profile, :find_friends
71
+ end
72
+ include Wicked::Wizard
73
+
74
+ class Show < Action
75
+ def run
76
+ wizard_redirect and return if super()
77
+ @user = current_user
78
+ case step
79
+ when :find_friends
80
+ @friends = @user.find_friends
81
+ end
82
+ render_wizard
83
+ end
84
+ end
85
+ end
86
+ ```
87
+
88
+ **Note:** Wicked uses the `:id` parameter to control the flow of steps, if you need to have an id parameter, please use nested routes see [Partial Validation of Active Record Objects](https://github.com/schneems/wicked/wiki/Partial-Validation-of-Active-Record-Objects) for an example. It will need to be prefixed, for example a Product's `:id` would be `:product_id`
89
+
90
+ You'll need to call `render_wizard` at the end of your action to get the correct views to show up.
91
+
92
+ By default the wizard will render a view with the same name as the step. So for our controller `AfterSignupController` with a view path of `/views/after_signup/` if call the :confirm_password step, our wizard will render `/views/after_signup/confirm_password.html.erb`
93
+
94
+ Then in your view you can use the helpers to get to the next step.
95
+
96
+ ```ruby
97
+ <%= link_to 'skip', next_wizard_path %>
98
+ ```
99
+
100
+ You can manually specify which wizard action you want to link to by using the wizard_path helper.
101
+
102
+ ```ruby
103
+ <%= link_to 'skip', wizard_path(:find_friends) %>
104
+ ```
105
+
106
+ In addition to showing sequential views we can update elements in our controller.
107
+ Note: Here we demonstrate the use of wicked macros.
108
+
109
+ ```ruby
110
+ class AfterSignupController
111
+ use_wicked_macros
112
+
113
+ wicked_base_action do
114
+ steps :confirm_password, :confirm_profile, :find_friends
115
+ end
116
+
117
+ wizard_action :update do
118
+ wizard do
119
+ @user = current_user
120
+ case step
121
+ when :confirm_password
122
+ @user.update_attributes(params[:user])
123
+ end
124
+ sign_in(@user, :bypass => true) # needed for devise
125
+ render_wizard @user
126
+ end
127
+ end
128
+ end
129
+ ```
130
+
131
+ We're passing `render_wizard` our `@user` object here. If you pass an object into `render_wizard` it will show the next step if the object saves or re-render the previous view if it does not save.
132
+
133
+ To get to this update action, you simply need to submit a form that PUT's to the same url
134
+
135
+ ```ruby
136
+
137
+ <%= form_for @user, :url => wizard_path, :method => :put do |f| %>
138
+ <%= f.password_field :password %>
139
+ <%= f.password_field :password_confirmation %>
140
+
141
+ <%= f.submit "Change Password" %>
142
+ <% end %>
143
+
144
+ ```
145
+
146
+ We explicitly tell the form to PUT above. If you forget this, you will get a warning about the create action not existing, or no route found for POST. Don't forget this.
147
+
148
+ In the controller if you find that you want to skip a step, you can do it simply by calling `skip_step`
149
+
150
+ ```ruby
151
+
152
+ wizard_action :show do
153
+ wizard do
154
+ @user = current_user
155
+ case step
156
+ when :find_friends
157
+ if @user.has_facebook_access_token?
158
+ @friends = @user.find_friends
159
+ else
160
+ skip_step
161
+ end
162
+ end
163
+ render_wizard
164
+ end
165
+ end
166
+
167
+ ```
168
+
169
+ Now you've got a fully functioning AfterSignup controller! If you have questions or if you struggled with something, let me know on [twitter](http://twitter.com/schneems), and i'll try to make it better or make the docs better.
170
+
171
+ ## Quick Reference
172
+
173
+ *Macros*
174
+
175
+ `use_wicked_macros` enables use of the Wicked macros. Otherwise you must explicitly create equivalent classes and methods.
176
+
177
+ `wicked_base_action name, &block`
178
+
179
+ Created the Focused Controller action base class, from which any Wizard Action class will inherit from.
180
+
181
+ `wizard_action name, &block`
182
+
183
+ Creates a Focused Controller action class inheriting from the base action class of the controller. The block contains the class definition.
184
+
185
+ `wizard`
186
+
187
+ Creates a `#run` method as "required" by a Focused Controller action class. The run method generated calls super which calls `setup_wizard` and also auto-handles redirects.
188
+
189
+ *View/URL Helpers*
190
+
191
+ ```ruby
192
+
193
+ wizard_path # Grabs the current path in the wizard
194
+ wizard_path(:specific_step) # Url of the :specific_step
195
+ next_wizard_path # Url of the next step
196
+ previous_wizard_path # Url of the previous step
197
+
198
+ # These only work while in a Wizard, and are not absolute paths
199
+ # You can have multiple wizards in a project with multiple `wizard_path` calls
200
+ ```
201
+
202
+ *Controller Tidbits:*
203
+
204
+ ```ruby
205
+ steps :first, :second # Sets the order of steps
206
+ step # Gets symbol of current step
207
+ next_step # Gets symbol of next step
208
+ skip_step # Tells render_wizard to skip to the next logical step
209
+ render_wizard # Renders the current step
210
+ render_wizard(@user) # Shows next_step if @user.save, otherwise renders current step
211
+ ```
212
+
213
+ Finally:
214
+
215
+ Don't forget to create your named views
216
+
217
+ ```
218
+ app/
219
+ views/
220
+ controller_name/
221
+ first.html.erb
222
+ second.html.erb
223
+ # ...
224
+ ```
225
+
226
+ # Finish Wizard Path
227
+
228
+ You can specify the url that your user goes to by over-riding the `finish_wizard_path` in your wizard controller action.
229
+
230
+
231
+ ```
232
+ def finish_wizard_path
233
+ user_path(current_user)
234
+ end
235
+ ```
236
+
237
+ ### Testing with RSpec
238
+
239
+ ```ruby
240
+ # Test find_friends block of show action
241
+ get :show, :id => :find_friends
242
+
243
+ # Test find_friends block of update action
244
+ put :update, {'id' => 'find_friends', "user" => { "id" => @user.id.to_s }}
245
+ ```
246
+
247
+ ## About
248
+
249
+ Please poke around the source code, if you see easier ways to get a Rails controller do do what I want, let me know.
250
+
251
+ If you have a question file an issue or, find me on the Twitters [@schneems](http://twitter.com/schneems).
252
+
253
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,50 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+
5
+ begin
6
+ Bundler.setup(:default, :development, :test)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+
13
+ require 'rake'
14
+ require 'rdoc/task'
15
+
16
+ require 'rake/testtask'
17
+
18
+ Rake::TestTask.new(:test) do |t|
19
+ t.libs << 'lib'
20
+ t.libs << 'test'
21
+ t.pattern = 'test/**/*_test.rb'
22
+ t.verbose = false
23
+ end
24
+
25
+ task :default => :test
26
+
27
+ Rake::RDocTask.new(:rdoc) do |rdoc|
28
+ rdoc.rdoc_dir = 'rdoc'
29
+ rdoc.title = 'Wicked Focused'
30
+ rdoc.options << '--line-numbers' << '--inline-source'
31
+ rdoc.rdoc_files.include('README.rdoc')
32
+ rdoc.rdoc_files.include('lib/**/*.rb')
33
+ end
34
+
35
+
36
+ require 'jeweler'
37
+ Jeweler::Tasks.new do |gem|
38
+ # gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
39
+ gem.name = "wicked-focused"
40
+ gem.homepage = "http://github.com/schneems/wicked"
41
+ gem.license = "MIT"
42
+ gem.summary = %Q{Use Wicked to turn your Focused Controller into a wizard}
43
+ gem.description = %Q{Rails engine for producing Focused Controller based wizards}
44
+ gem.email = "kmandrup@gmail.com"
45
+ gem.authors = ["kristianmandrup", "schneems"]
46
+ # dependencies defined in Gemfile
47
+ end
48
+ Jeweler::RubygemsDotOrgTasks.new
49
+
50
+
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.0
@@ -0,0 +1,64 @@
1
+ module Wicked
2
+ module Action
3
+ extend ActiveSupport::Concern
4
+
5
+ # Include the modules!!
6
+ include Wicked::Controller::Concerns::Path
7
+ include Wicked::Controller::Concerns::RenderRedirect
8
+ include Wicked::Controller::Concerns::Steps
9
+
10
+ included do
11
+ # Give our Views helper methods!
12
+ helper_method :wizard_path, :next_wizard_path, :previous_wizard_path,
13
+ :step, :wizard_steps, :current_step?,
14
+ :past_step?, :future_step?, :previous_step?,
15
+ :next_step?
16
+ end
17
+
18
+ # any subclass (Action class) should call super!
19
+ def run
20
+ setup_wizard
21
+ end
22
+
23
+ module ClassMethods
24
+ def wizard &block
25
+ define_method :run do
26
+ wizard_redirect and return if super()
27
+ instance_eval &block
28
+ end
29
+ end
30
+ end
31
+
32
+ protected
33
+
34
+ def setup_wizard
35
+ @redirect_path = wizard_path(steps.first) if first_step? && !on_first_step?
36
+ @redirect_path = wizard_path(steps.last) if last_step? && !on_last_step?
37
+
38
+ @step = params[:id].try(:to_sym) || steps.first
39
+ @previous_step = previous_step(@step)
40
+ @next_step = next_step(@step)
41
+ @redirect_path
42
+ end
43
+
44
+ def wizard_redirect
45
+ redirect_to @redirect_path if @redirect_path
46
+ end
47
+
48
+ def on_first_step?
49
+ step == steps.first
50
+ end
51
+
52
+ def on_last_step?
53
+ step == steps.first
54
+ end
55
+
56
+ def first_step?
57
+ params[:id].try(:to_sym) == :wizard_first
58
+ end
59
+
60
+ def last_step?
61
+ params[:id].try(:to_sym) == :wizard_last
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,29 @@
1
+ module Wicked::Controller::Concerns::Path
2
+ extend ActiveSupport::Concern
3
+
4
+ def next_wizard_path(options = {})
5
+ wizard_path(@next_step, options)
6
+ end
7
+
8
+ def previous_wizard_path(options = {})
9
+ wizard_path(@previous_step, options)
10
+ end
11
+
12
+ def wicked_controller
13
+ self.class.name.sub(/::\w+$/, '')
14
+ end
15
+
16
+ def wicked_controller_name
17
+ wicked_controller.sub(/Controller$/, '').gsub('::', '_').underscore
18
+ end
19
+
20
+ def wicked_action
21
+ params[:action]
22
+ end
23
+
24
+ def wizard_path(goto_step = nil, options = {})
25
+ id = goto_step || params[:id]
26
+ path_method = "#{wicked_controller_name}_path"
27
+ send path_method, id, options
28
+ end
29
+ end
@@ -0,0 +1,49 @@
1
+ module Wicked::Controller::Concerns::RenderRedirect
2
+ extend ActiveSupport::Concern
3
+
4
+
5
+ def render_wizard(resource = nil, options = {})
6
+ process_resource!(resource)
7
+ if @skip_to
8
+ redirect_to wizard_path(@skip_to), options
9
+ else
10
+ render_step @step, options
11
+ end
12
+ end
13
+
14
+ def process_resource!(resource)
15
+ if resource
16
+ if resource.save
17
+ @skip_to ||= @next_step
18
+ else
19
+ @skip_to = nil
20
+ end
21
+ end
22
+ end
23
+
24
+ def render_step(the_step, options = {})
25
+ if the_step.nil? || the_step == :finish
26
+ redirect_to_finish_wizard options
27
+ else
28
+ render the_step, options
29
+ end
30
+ end
31
+
32
+ def redirect_to_next(next_step)
33
+ if next_step.nil?
34
+ redirect_to_finish_wizard
35
+ else
36
+ redirect_to wizard_path(next_step)
37
+ end
38
+ end
39
+
40
+ # TODO redirect to resource if one is passed to render_wizard
41
+ def finish_wizard_path
42
+ '/'
43
+ end
44
+
45
+ def redirect_to_finish_wizard(options = nil)
46
+ redirect_to finish_wizard_path, options
47
+ end
48
+
49
+ end