jeffp-wizardly 0.1.5 → 0.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +29 -24
- data/lib/jeffp-wizardly.rb +1 -0
- data/lib/validation_group.rb +18 -3
- data/lib/wizardly/action_controller.rb +0 -1
- data/lib/wizardly/wizard.rb +1 -0
- data/lib/wizardly/wizard/configuration.rb +11 -3
- data/lib/wizardly/wizard/configuration/methods.rb +77 -68
- data/lib/wizardly/wizard/page.rb +1 -0
- data/rails_generators/wizardly_app/templates/wizardly.rake +9 -5
- data/rails_generators/wizardly_app/wizardly_app_generator.rb +1 -1
- data/rails_generators/wizardly_scaffold/templates/form.html.haml.erb +22 -0
- data/rails_generators/wizardly_scaffold/templates/layout.html.haml.erb +10 -0
- data/rails_generators/wizardly_scaffold/wizardly_scaffold_generator.rb +18 -10
- metadata +5 -2
data/README.rdoc
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
= wizardly
|
2
2
|
|
3
|
-
+wizardly+
|
3
|
+
+wizardly+ creates a multi-step wizard for any ActiveRecord model in three steps.
|
4
4
|
|
5
5
|
== Resources
|
6
6
|
|
@@ -14,13 +14,13 @@ Source
|
|
14
14
|
|
15
15
|
Install
|
16
16
|
|
17
|
-
* sudo gem install jeffp-wizardly --source=http://gems.github.com
|
17
|
+
* sudo gem install jeffp-wizardly --source=http://http://gems.github.com
|
18
18
|
|
19
19
|
== Description
|
20
20
|
|
21
21
|
+wizardly+ builds on Alex Kira's +validation_group+ plugin code to
|
22
22
|
DRY up the Rails MVC implementation of a wizard. In three easy steps, +wizardly+
|
23
|
-
produces the scaffolding and controller of a
|
23
|
+
produces the scaffolding and controller of a multi-step wizard.
|
24
24
|
|
25
25
|
Features include:
|
26
26
|
* Model-based definition
|
@@ -32,11 +32,15 @@ Features include:
|
|
32
32
|
|
33
33
|
== Setup
|
34
34
|
|
35
|
-
|
35
|
+
Put the following in your application's config block in config/environment.rb
|
36
36
|
|
37
|
-
|
37
|
+
config.gem 'jeffp-wizardly', :lib=>'wizardly'
|
38
38
|
|
39
|
-
|
39
|
+
and run the install gems rake task on your application
|
40
|
+
|
41
|
+
rake gems:install
|
42
|
+
|
43
|
+
For any rails app, run the following to install wizardly rake tasks (optional)
|
40
44
|
|
41
45
|
./script/generate wizardly_app
|
42
46
|
|
@@ -55,7 +59,7 @@ Step 1: Define validation groups for your model.
|
|
55
59
|
|
56
60
|
Step 2: Tell your controller to act 'wizardly'.
|
57
61
|
|
58
|
-
class SignupController <
|
62
|
+
class SignupController < ApplicationController
|
59
63
|
act_wizardly_for :user
|
60
64
|
end
|
61
65
|
|
@@ -100,16 +104,16 @@ uses the HTTP_REFERER for both cases. What if there is no referer? The control
|
|
100
104
|
raises a RedirectNotDefined error. Let's remedy this problem with some options
|
101
105
|
in the macro.
|
102
106
|
|
103
|
-
class SignupController <
|
107
|
+
class SignupController < ApplicationController
|
104
108
|
act_wizardly_for :user, :completed=>'/main/finished',
|
105
|
-
:canceled=>
|
109
|
+
:canceled=>{:controller=>:main, :action=>:canceled}
|
106
110
|
end
|
107
111
|
|
108
112
|
Now whether the user completes or cancels the wizard, the controller knows
|
109
113
|
how to redirect. Alternately, if you want to redirect to the same page
|
110
114
|
for both cases
|
111
115
|
|
112
|
-
class SignupController <
|
116
|
+
class SignupController < ApplicationController
|
113
117
|
act_wizardly_for :user, :redirect=>'/main'
|
114
118
|
end
|
115
119
|
|
@@ -119,11 +123,11 @@ Here's a list of options you can use in the macro
|
|
119
123
|
|
120
124
|
:completed => '/main/finished'
|
121
125
|
:canceled => {:controller=>'main', :action=>'canceled'}
|
122
|
-
:skip =>
|
126
|
+
:skip => true
|
123
127
|
:mask_fields => [:password, :password_confirmation] (by default)
|
124
128
|
|
125
|
-
|
126
|
-
The :mask_fields options tells the scaffold generator which fields
|
129
|
+
Setting the :skip option to +true+ tells the scaffold helpers to include or exclude a skip button on each page.
|
130
|
+
The :mask_fields options tells the scaffold generator which fields to generate as 'type=password' fields.
|
127
131
|
|
128
132
|
=== Buttons
|
129
133
|
|
@@ -131,7 +135,7 @@ The wizardly controller defines five default button functions: next, back, skip,
|
|
131
135
|
cancel, and finish. All but :skip are used in the scaffolding by default. You
|
132
136
|
can add :skip functionality to all pages by adding an option to the macro
|
133
137
|
|
134
|
-
class SignupController <
|
138
|
+
class SignupController < ApplicationController
|
135
139
|
act_wizardly_for :user, :redirect=>'/main', :skip=>true
|
136
140
|
end
|
137
141
|
|
@@ -147,10 +151,10 @@ for the developer to change the processing. Here's an example. Say our model
|
|
147
151
|
declares a :step4 validation_group with :username, :password, and
|
148
152
|
:password_confirmation fields. We'd like to handle this step specifically.
|
149
153
|
|
150
|
-
class SignupController <
|
154
|
+
class SignupController < ApplicationController
|
151
155
|
act_wizardly_for :user, :redirect=>'/main'
|
152
156
|
|
153
|
-
def
|
157
|
+
def on_invalid_step4_form
|
154
158
|
#clear the password field if errors
|
155
159
|
@user[:password] = ''
|
156
160
|
@user[:password_confirmation] = ''
|
@@ -162,13 +166,14 @@ validation_group.
|
|
162
166
|
|
163
167
|
Every page has a set of callbacks. Here's the list for our :step1 page.
|
164
168
|
|
165
|
-
def
|
166
|
-
def
|
167
|
-
def
|
168
|
-
def
|
169
|
-
def
|
170
|
-
def
|
171
|
-
def
|
169
|
+
def on_get_step1_form; end
|
170
|
+
def on_post_step1_form; end
|
171
|
+
def on_invalid_step1_form; end
|
172
|
+
def on_step1_form_next; end
|
173
|
+
def on_step1_form_back; end
|
174
|
+
def on_step1_form_cancel; end
|
175
|
+
def on_step1_form_finish; end
|
176
|
+
def on_step1_form_skip; end
|
172
177
|
|
173
178
|
Each callback is defined for the controller object, thus giving it access to all
|
174
179
|
controller variables and methods just as any other action method. Each callback
|
@@ -190,7 +195,7 @@ of the button. For general use, this is not an issue. See the Advanced Configu
|
|
190
195
|
For anyone needing to handle rendering in a special way, wizardly provides a render
|
191
196
|
call back for this.
|
192
197
|
|
193
|
-
class SignupController <
|
198
|
+
class SignupController < ApplicationController
|
194
199
|
act_wizardly_for :user, :redirect=>'/main'
|
195
200
|
|
196
201
|
def render_wizard_page
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'wizardly'
|
data/lib/validation_group.rb
CHANGED
@@ -23,13 +23,20 @@ module ValidationGroup
|
|
23
23
|
|
24
24
|
def validation_group(name, options={})
|
25
25
|
self_groups = (self.validation_group_classes[self] ||= {})
|
26
|
-
self_groups[name.to_sym] = options[:fields]
|
27
|
-
|
28
|
-
|
26
|
+
self_groups[name.to_sym] = case options[:fields]
|
27
|
+
when Array then options[:fields]
|
28
|
+
when Symbol, String then [options[:fields].to_sym]
|
29
|
+
else []
|
30
|
+
end
|
31
|
+
# jeffp: capture the declaration order for this class only (no
|
32
|
+
# superclasses)
|
33
|
+
(@validation_group_order ||= []) << name.to_sym
|
29
34
|
|
30
35
|
unless included_modules.include?(InstanceMethods)
|
36
|
+
# jeffp: added reader for current_validation_fields
|
31
37
|
attr_reader :current_validation_group, :current_validation_fields
|
32
38
|
include InstanceMethods
|
39
|
+
# jeffp: add valid?(group = nil), see definition below
|
33
40
|
alias_method_chain :valid?, :validation_group
|
34
41
|
end
|
35
42
|
end
|
@@ -47,6 +54,7 @@ module ValidationGroup
|
|
47
54
|
end
|
48
55
|
if found
|
49
56
|
@current_validation_group = group
|
57
|
+
# jeffp: capture current fields for performance optimization
|
50
58
|
@current_validation_fields = group_classes[found][group]
|
51
59
|
else
|
52
60
|
raise ArgumentError, "No validation group of name :#{group}"
|
@@ -55,9 +63,13 @@ module ValidationGroup
|
|
55
63
|
|
56
64
|
def disable_validation_group
|
57
65
|
@current_validation_group = nil
|
66
|
+
# jeffp: delete fields
|
58
67
|
@current_validation_fields = nil
|
59
68
|
end
|
60
69
|
|
70
|
+
# jeffp: optimizer for someone writing custom :validate method -- no need
|
71
|
+
# to validate fields outside the current validation group note: could also
|
72
|
+
# use in validation modules to improve performance
|
61
73
|
def should_validate?(attribute)
|
62
74
|
!self.validation_group_enabled? || (@current_validation_fields && @current_validation_fields.include?(attribute.to_sym))
|
63
75
|
end
|
@@ -78,6 +90,7 @@ module ValidationGroup
|
|
78
90
|
def add_with_validation_group(attribute,
|
79
91
|
msg = @@default_error_messages[:invalid], *args,
|
80
92
|
&block)
|
93
|
+
# jeffp: setting @current_validation_fields and use of should_validate? optimizes code
|
81
94
|
add_error = @base.respond_to?(:should_validate?) ? @base.should_validate?(attribute.to_sym) : true
|
82
95
|
add_without_validation_group(attribute, msg, *args, &block) if add_error
|
83
96
|
end
|
@@ -106,5 +119,7 @@ module ValidationGroup
|
|
106
119
|
end
|
107
120
|
end
|
108
121
|
|
122
|
+
# jeffp: moved from init.rb for gemification purposes --
|
123
|
+
# require 'validation_group' loads everything now, init.rb requires 'validation_group' only
|
109
124
|
ActiveRecord::Base.send(:extend, ValidationGroup::ActiveRecord::ActsMethods)
|
110
125
|
ActiveRecord::Errors.send :include, ValidationGroup::ActiveRecord::Errors
|
@@ -20,7 +20,6 @@ module Wizardly
|
|
20
20
|
|
21
21
|
# controller_name = self.name.sub(/Controller$/, '').underscore.to_sym
|
22
22
|
@wizard_config = Wizardly::Wizard::Configuration.create(controller_name, model, opts, &block)
|
23
|
-
|
24
23
|
# define methods
|
25
24
|
self.class_eval @wizard_config.print_page_action_methods
|
26
25
|
self.class_eval @wizard_config.print_callbacks
|
data/lib/wizardly/wizard.rb
CHANGED
@@ -4,6 +4,7 @@ module Wizardly
|
|
4
4
|
class WizardlyError < StandardError; end
|
5
5
|
class ModelNotFoundError < WizardlyError; end
|
6
6
|
class ValidationGroupError < WizardlyError; end
|
7
|
+
class CallbackError < WizardlyError; end
|
7
8
|
class MissingCallbackError < WizardlyError; end
|
8
9
|
class WizardConfigurationError < WizardlyError; end
|
9
10
|
class RedirectNotDefinedError < WizardlyError; end
|
@@ -14,6 +14,7 @@ module Wizardly
|
|
14
14
|
@completed_redirect = opts[:redirect] || opts[:completed] || opts[:when_completed] #format_redirect(completed_redirect)
|
15
15
|
@canceled_redirect = opts[:redirect] || opts[:canceled] || opts[:when_canceled]
|
16
16
|
@allow_skipping = opts[:skip] || opts[:allow_skip] || opts[:allow_skipping] || false
|
17
|
+
@guard = opts.key?(:guard) ? opts[:guard] : true
|
17
18
|
@password_fields = opts[:mask_fields] || opts[:mask_passwords] || [:password, :password_confirmation]
|
18
19
|
@page_order = []
|
19
20
|
@pages = {}
|
@@ -23,7 +24,8 @@ module Wizardly
|
|
23
24
|
@default_buttons[default] = Button.new(default)
|
24
25
|
end
|
25
26
|
end
|
26
|
-
|
27
|
+
|
28
|
+
def guard?; @guard; end
|
27
29
|
def model; @wizard_model_sym; end
|
28
30
|
def model_instance_variable; "@#{@wizard_model_sym.to_s}"; end
|
29
31
|
def model_class_name; @wizard_model_class_name; end
|
@@ -67,18 +69,24 @@ module Wizardly
|
|
67
69
|
begin
|
68
70
|
@page_order = @wizard_model_const.validation_group_order
|
69
71
|
rescue Exception => e
|
70
|
-
raise ValidationGroupError, "
|
72
|
+
raise ValidationGroupError, "Unable to read validation groups from #{@wizard_model_class_name}: " + e.message, caller
|
71
73
|
end
|
72
74
|
raise(ValidationGroupError, "No validation groups defined for model #{@wizard_model_class_name}", caller) unless (@page_order && !@page_order.empty?)
|
73
75
|
|
74
76
|
begin
|
75
77
|
groups = @wizard_model_const.validation_groups
|
78
|
+
enum_attrs = @wizard_model_const.respond_to?(:enumerated_attributes) ? @wizard_model_const.enumerated_attributes.collect {|k,v| k } : []
|
76
79
|
model_inst = @wizard_model_const.new
|
77
80
|
last_index = @page_order.size-1
|
78
81
|
@page_order.each_with_index do |p, index|
|
79
82
|
fields = groups[p].map do |f|
|
80
83
|
column = model_inst.column_for_attribute(f)
|
81
|
-
type =
|
84
|
+
type = case
|
85
|
+
when enum_attrs.include?(f) then :enum
|
86
|
+
when (@password_fields && @password_fields.include?(f)) then :password
|
87
|
+
else
|
88
|
+
column ? column.type : :string
|
89
|
+
end
|
82
90
|
PageField.new(f, type)
|
83
91
|
end
|
84
92
|
page = Page.new(p, fields)
|
@@ -25,52 +25,70 @@ module Wizardly
|
|
25
25
|
next_button = self.button_for_function(:next).id
|
26
26
|
(mb = StringIO.new) << <<-ONE
|
27
27
|
def #{page.name}
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
28
|
+
begin
|
29
|
+
@step = :#{id}
|
30
|
+
@wizard = wizard_config
|
31
|
+
@title = '#{page.title}'
|
32
|
+
@description = '#{page.description}'
|
33
|
+
h = (flash[:wizard_model]||{}).merge(params[:#{self.model}] || {})
|
34
|
+
@#{self.model} = #{self.model_class_name}.new(h)
|
35
|
+
if request.post? && callback_performs_action?(:on_post_#{id}_form)
|
36
|
+
raise CallbackError, "render or redirect not allowed in :filter_params_#{id}_page callback", caller
|
37
|
+
end
|
38
|
+
button_id = check_action_for_button
|
39
|
+
return if performed?
|
40
|
+
if request.get?
|
41
|
+
return if callback_performs_action?(:on_get_#{id}_form)
|
42
|
+
render_wizard_form
|
43
|
+
return
|
44
|
+
end
|
42
45
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
# @#{self.model}.enable_validation_group :#{id}
|
47
|
+
unless @#{self.model}.valid?(:#{id})
|
48
|
+
return if callback_performs_action?(:on_invalid_#{id}_form)
|
49
|
+
render_wizard_form
|
50
|
+
return
|
51
|
+
end
|
49
52
|
|
50
53
|
ONE
|
51
54
|
if self.last_page?(id)
|
52
55
|
mb << <<-TWO
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
+
return if callback_performs_action?(:on_#{id}_form_#{finish_button})
|
57
|
+
_on_wizard_#{finish_button}
|
58
|
+
redirect_to #{Utils.formatted_redirect(self.completed_redirect)} unless self.performed?
|
56
59
|
TWO
|
57
60
|
elsif self.first_page?(id)
|
58
61
|
mb << <<-THREE
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
62
|
+
if button_id == :#{finish_button}
|
63
|
+
return if callback_performs_action?(:on_#{id}_form_#{finish_button})
|
64
|
+
_on_wizard_#{finish_button} if button_id == :#{finish_button}
|
65
|
+
redirect_to #{Utils.formatted_redirect(self.completed_redirect)} unless self.performed?
|
66
|
+
return
|
67
|
+
end
|
68
|
+
session[:progression] = [:#{id}]
|
69
|
+
return if callback_performs_action?(:on_#{id}_form_#{next_button})
|
70
|
+
redirect_to :action=>:#{self.next_page(id)}
|
64
71
|
THREE
|
65
72
|
else
|
66
73
|
mb << <<-FOUR
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
74
|
+
if button_id == :#{finish_button}
|
75
|
+
return if callback_performs_action?(:on_#{id}_form_#{finish_button})
|
76
|
+
_on_wizard_#{finish_button} if button_id == :#{finish_button}
|
77
|
+
redirect_to #{Utils.formatted_redirect(self.completed_redirect)} unless self.performed?
|
78
|
+
return
|
79
|
+
end
|
80
|
+
session[:progression].push(:#{id})
|
81
|
+
return if callback_performs_action?(:on_#{id}_form_#{next_button})
|
82
|
+
redirect_to :action=>:#{self.next_page(id)}
|
72
83
|
FOUR
|
73
84
|
end
|
85
|
+
|
86
|
+
mb << <<-ENSURE
|
87
|
+
ensure
|
88
|
+
flash[:wizard_model] = h.merge(@#{self.model}.attributes)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
ENSURE
|
74
92
|
mb.string
|
75
93
|
end
|
76
94
|
|
@@ -83,26 +101,26 @@ module Wizardly
|
|
83
101
|
protected
|
84
102
|
def _on_wizard_#{finish}
|
85
103
|
@#{self.model}.save_without_validation!
|
86
|
-
flash.discard(:wizard_model)
|
87
104
|
_wizard_final_redirect_to(:completed)
|
88
105
|
end
|
89
106
|
def _on_wizard_#{skip}
|
90
|
-
redirect_to
|
91
|
-
true
|
107
|
+
redirect_to(:action=>wizard_config.next_page(@step)) unless self.performed?
|
92
108
|
end
|
93
109
|
def _on_wizard_#{back}
|
94
|
-
|
95
|
-
|
110
|
+
# TODO: fix progression management
|
111
|
+
redirect_to(:action=>((session[:progression]||[]).pop || :#{self.page_order.first})) unless self.performed?
|
96
112
|
end
|
97
113
|
def _on_wizard_#{cancel}
|
98
114
|
_wizard_final_redirect_to(:canceled)
|
99
|
-
true
|
100
115
|
end
|
101
116
|
def _wizard_final_redirect_to(which_redirect)
|
117
|
+
flash.discard(:wizard_model)
|
102
118
|
initial_referer = reset_wizard_session_vars
|
103
|
-
|
104
|
-
|
105
|
-
|
119
|
+
unless self.performed?
|
120
|
+
redir = (which_redirect == :completed ? wizard_config.completed_redirect : wizard_config.canceled_redirect) || initial_referer
|
121
|
+
return redirect_to(redir) if redir
|
122
|
+
raise Wizardly::RedirectNotDefinedError, "No redirect was defined for completion or canceling the wizard. Use :completed and :canceled options to define redirects.", caller
|
123
|
+
end
|
106
124
|
end
|
107
125
|
hide_action :_on_wizard_#{finish}, :_on_wizard_#{skip}, :_on_wizard_#{back}, :_on_wizard_#{cancel}, :_wizard_final_redirect_to
|
108
126
|
CALLBACKS
|
@@ -112,6 +130,7 @@ module Wizardly
|
|
112
130
|
next_id = self.button_for_function(:next).id
|
113
131
|
finish_id = self.button_for_function(:finish).id
|
114
132
|
first_page = self.page_order.first
|
133
|
+
guard_line = self.guard? ? '' : 'return #guard entry disabled'
|
115
134
|
<<-HELPERS
|
116
135
|
protected
|
117
136
|
def guard_entry
|
@@ -123,13 +142,14 @@ module Wizardly
|
|
123
142
|
session[:initial_referer] = nil
|
124
143
|
end
|
125
144
|
flash.discard(:wizard_model)
|
145
|
+
#{guard_line}
|
126
146
|
redirect_to :action=>:#{first_page} unless (params[:action] || '') == '#{first_page}'
|
127
147
|
end
|
128
148
|
hide_action :guard_entry
|
129
149
|
|
130
|
-
def
|
150
|
+
def render_wizard_form
|
131
151
|
end
|
132
|
-
hide_action :
|
152
|
+
hide_action :render_wizard_form
|
133
153
|
|
134
154
|
def performed?; super; end
|
135
155
|
hide_action :performed?
|
@@ -140,14 +160,13 @@ module Wizardly
|
|
140
160
|
unless (params[:commit] == nil)
|
141
161
|
button_name = methodize_button_name(params[:commit])
|
142
162
|
unless [:#{next_id}, :#{finish_id}].include?(button_id = button_name.to_sym)
|
143
|
-
action_method_name = "on_" + params[:action].to_s + "
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
end
|
163
|
+
action_method_name = "on_" + params[:action].to_s + "_form_" + button_name
|
164
|
+
callback_performs_action?(action_method_name)
|
165
|
+
method_name = "_on_wizard_" + button_name
|
166
|
+
if (self.method(method_name))
|
167
|
+
self.__send__(method_name)
|
168
|
+
else
|
169
|
+
raise MissingCallbackError, "Callback method either '" + action_method_name + "' or '" + method_name + "' not defined", caller
|
151
170
|
end
|
152
171
|
end
|
153
172
|
end
|
@@ -161,22 +180,12 @@ module Wizardly
|
|
161
180
|
attr_reader :wizard_callbacks
|
162
181
|
end
|
163
182
|
|
164
|
-
def callback_performs_action?(methId)
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
else #nil
|
171
|
-
unless self.class.method_defined?(methId)
|
172
|
-
wc[methId] = :none
|
173
|
-
return false
|
174
|
-
end
|
175
|
-
wc[methId] = :found
|
176
|
-
end
|
177
|
-
self.__send__(methId)
|
178
|
-
return self.performed?
|
179
|
-
end
|
183
|
+
def callback_performs_action?(methId, arg=nil)
|
184
|
+
return false unless self.methods.include?(methId.to_s)
|
185
|
+
#self.__send__(methId)
|
186
|
+
self.method(methId).call
|
187
|
+
self.performed?
|
188
|
+
end
|
180
189
|
hide_action :callback_performs_action?
|
181
190
|
|
182
191
|
HELPERS
|
data/lib/wizardly/wizard/page.rb
CHANGED
@@ -43,6 +43,7 @@ module Wizardly
|
|
43
43
|
@field_type ||= case @column_type
|
44
44
|
when :string then :text_field
|
45
45
|
when :password then :password_field
|
46
|
+
when :enum then :enum_select
|
46
47
|
when :text then :text_area
|
47
48
|
when :boolean then :check_box
|
48
49
|
when :integer, :float, :decimal then :text_field
|
@@ -14,14 +14,18 @@ namespace :wizardly do
|
|
14
14
|
puts
|
15
15
|
puts c.print_config
|
16
16
|
rescue Exception=>e
|
17
|
-
puts "Problem printing configuration
|
17
|
+
puts "Problem printing configuration."
|
18
|
+
puts "#{e.class.name} -- #{e.message}"
|
19
|
+
puts
|
18
20
|
end
|
19
|
-
rescue
|
20
|
-
puts "{#{name}} is not a 'wizardly' controller.\nMake sure 'wizard_for_model' is defined in the controller class."
|
21
|
+
rescue Exception=>e
|
22
|
+
puts "{#{name}} is not a 'wizardly' controller.\nMake sure 'wizard_for_model' is defined in the controller class."
|
23
|
+
puts "#{e.class.name} -- #{e.message}"
|
21
24
|
puts
|
22
25
|
end
|
23
|
-
rescue
|
24
|
-
puts "{#{name}} does not reference a controller class"
|
26
|
+
rescue Exception=>e
|
27
|
+
puts "{#{name}} does not reference a controller class."
|
28
|
+
puts "#{e.class.name} -- #{e.message}"
|
25
29
|
puts
|
26
30
|
end
|
27
31
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
%h1 <%= page.title %>
|
2
|
+
|
3
|
+
<% unless page.description.blank? %>
|
4
|
+
%p <%= page.description %>
|
5
|
+
<% end %>
|
6
|
+
- if flash[:notice]
|
7
|
+
%p{:style=>'color: green'}= flash[:notice]
|
8
|
+
|
9
|
+
- form_for :<%= model_name %>, :url=>{:action=>:<%= page.name %>} do |f|
|
10
|
+
= f.error_messages
|
11
|
+
|
12
|
+
<% for field in page.fields %>
|
13
|
+
<% first_field_id ||= "#{model_name}_#{field.name}" %>
|
14
|
+
%p
|
15
|
+
= f.label :<%= field.name %>
|
16
|
+
%br
|
17
|
+
= f.<%= field.field_type %> :<%= field.name %>
|
18
|
+
<% end %>
|
19
|
+
%p= wizardly_submit
|
20
|
+
|
21
|
+
%script{:type=>'text/javascript'}
|
22
|
+
document.getElementById('<%=first_field_id %>').focus()
|
@@ -0,0 +1,10 @@
|
|
1
|
+
!!! XML
|
2
|
+
!!!
|
3
|
+
%html{ :'xml:lang' => "en", :lang => "en" }
|
4
|
+
%head
|
5
|
+
%title= "<%=controller_class_name %>: " + controller.action_name
|
6
|
+
%meta{ :"http-equiv" => "Content-Type", :content => "text/html; charset-utf-8" }
|
7
|
+
%link{ :rel => "shortcut icon", :href => "/favicon.ico" }
|
8
|
+
= stylesheet_link_tag "scaffold", :media => "screen"
|
9
|
+
%body
|
10
|
+
= yield
|
@@ -13,10 +13,16 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
|
|
13
13
|
|
14
14
|
alias_method :controller_file_name, :controller_underscore_name
|
15
15
|
|
16
|
+
def add_options!(opt)
|
17
|
+
opt.on('--haml', 'Generate scaffold for haml wizard') { |v| options[:output] = :haml }
|
18
|
+
opt.on('--ajax', 'Generate scaffold for ajax wizard') { |v| options[:output] = :ajax }
|
19
|
+
end
|
20
|
+
|
21
|
+
|
16
22
|
def initialize(runtime_args, runtime_options = {})
|
17
23
|
super
|
18
24
|
name = @args[0].sub(/^:/, '').underscore.sub(/_controller$/, '').camelize + 'Controller'
|
19
|
-
|
25
|
+
|
20
26
|
base_name, @controller_class_path, @controller_file_path, @controller_class_nesting, @controller_class_nesting_depth = extract_modules(name)
|
21
27
|
@controller_class_name_without_nesting = base_name.camelize
|
22
28
|
@controller_underscore_name = base_name.underscore
|
@@ -26,7 +32,7 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
|
|
26
32
|
else
|
27
33
|
@controller_class_name = "#{@controller_class_nesting}::#{@controller_class_name_without_nesting}"
|
28
34
|
end
|
29
|
-
|
35
|
+
|
30
36
|
begin
|
31
37
|
@controller_class = @controller_class_name.constantize
|
32
38
|
rescue Exception => e
|
@@ -34,15 +40,17 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
|
|
34
40
|
end
|
35
41
|
begin
|
36
42
|
@wizard_config = @controller_class.wizard_config
|
37
|
-
rescue
|
38
|
-
raise Wizardly::WizardlyScaffoldError, "#{@controller_class_name} must
|
43
|
+
rescue Exception => e
|
44
|
+
raise Wizardly::WizardlyScaffoldError, "#{@controller_class_name} must contain a valid 'act_wizardly_for' or 'wizard_for_model' macro: " + e.message, caller
|
39
45
|
end
|
40
|
-
|
46
|
+
|
41
47
|
@pages = @wizard_config.pages
|
42
48
|
@model_name = @wizard_config.model
|
43
|
-
|
49
|
+
|
44
50
|
#based on options, default is --html, others --ajax, --haml
|
45
|
-
@view_file_ext = "html.erb"
|
51
|
+
@view_file_ext = ["html.erb", "html.erb"]
|
52
|
+
@view_file_ext = ["html.haml.erb", "html.haml"] if options[:output] == :haml
|
53
|
+
#ajax
|
46
54
|
end
|
47
55
|
|
48
56
|
def manifest
|
@@ -56,8 +64,8 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
|
|
56
64
|
|
57
65
|
pages.each do |id, page|
|
58
66
|
m.template(
|
59
|
-
"form.#{view_file_ext}",
|
60
|
-
File.join('app/views', controller_class_path, controller_name, "#{id}.#{view_file_ext}"),
|
67
|
+
"form.#{view_file_ext.first}",
|
68
|
+
File.join('app/views', controller_class_path, controller_name, "#{id}.#{view_file_ext.last}"),
|
61
69
|
:assigns=>{:id=>id, :page=>page}
|
62
70
|
)
|
63
71
|
end
|
@@ -65,7 +73,7 @@ class WizardlyScaffoldGenerator < Rails::Generator::Base
|
|
65
73
|
m.template("helper.rb.erb", File.join('app/helpers', controller_class_path, "#{controller_name}_helper.rb"))
|
66
74
|
|
67
75
|
# Layout and stylesheet.
|
68
|
-
m.template("layout.#{view_file_ext}", File.join('app/views/layouts', controller_class_path, "#{controller_name}.#{view_file_ext}"))
|
76
|
+
m.template("layout.#{view_file_ext.first}", File.join('app/views/layouts', controller_class_path, "#{controller_name}.#{view_file_ext.last}"))
|
69
77
|
m.template('style.css', 'public/stylesheets/scaffold.css')
|
70
78
|
|
71
79
|
#m.dependency 'model', [name] + @args, :collision => :skip
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jeffp-wizardly
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jeff Patmon
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-10 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -23,6 +23,7 @@ extra_rdoc_files: []
|
|
23
23
|
|
24
24
|
files:
|
25
25
|
- lib/generators
|
26
|
+
- lib/jeffp-wizardly.rb
|
26
27
|
- lib/validation_group.rb
|
27
28
|
- lib/wizardly
|
28
29
|
- lib/wizardly/action_controller.rb
|
@@ -51,8 +52,10 @@ files:
|
|
51
52
|
- rails_generators/wizardly_scaffold
|
52
53
|
- rails_generators/wizardly_scaffold/templates
|
53
54
|
- rails_generators/wizardly_scaffold/templates/form.html.erb
|
55
|
+
- rails_generators/wizardly_scaffold/templates/form.html.haml.erb
|
54
56
|
- rails_generators/wizardly_scaffold/templates/helper.rb.erb
|
55
57
|
- rails_generators/wizardly_scaffold/templates/layout.html.erb
|
58
|
+
- rails_generators/wizardly_scaffold/templates/layout.html.haml.erb
|
56
59
|
- rails_generators/wizardly_scaffold/templates/style.css
|
57
60
|
- rails_generators/wizardly_scaffold/USAGE
|
58
61
|
- rails_generators/wizardly_scaffold/wizardly_scaffold_generator.rb
|