jeffp-wizardly 0.1.5 → 0.1.6
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.
- 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
|