edk-wizardly 0.1.8.9
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/CHANGELOG.rdoc +38 -0
- data/LICENSE +20 -0
- data/README.rdoc +645 -0
- data/init.rb +1 -0
- data/lib/jeffp-wizardly.rb +1 -0
- data/lib/validation_group.rb +147 -0
- data/lib/wizardly/action_controller.rb +36 -0
- data/lib/wizardly/wizard/button.rb +35 -0
- data/lib/wizardly/wizard/configuration/methods.rb +414 -0
- data/lib/wizardly/wizard/configuration.rb +194 -0
- data/lib/wizardly/wizard/dsl.rb +27 -0
- data/lib/wizardly/wizard/page.rb +62 -0
- data/lib/wizardly/wizard/text_helpers.rb +16 -0
- data/lib/wizardly/wizard/utils.rb +11 -0
- data/lib/wizardly/wizard.rb +16 -0
- data/lib/wizardly.rb +31 -0
- data/rails_generators/wizardly_app/USAGE +6 -0
- data/rails_generators/wizardly_app/templates/wizardly.rake +37 -0
- data/rails_generators/wizardly_app/wizardly_app_generator.rb +41 -0
- data/rails_generators/wizardly_controller/USAGE +3 -0
- data/rails_generators/wizardly_controller/templates/controller.rb.erb +34 -0
- data/rails_generators/wizardly_controller/templates/helper.rb.erb +14 -0
- data/rails_generators/wizardly_controller/wizardly_controller_generator.rb +57 -0
- data/rails_generators/wizardly_scaffold/USAGE +4 -0
- data/rails_generators/wizardly_scaffold/templates/form.html.erb +23 -0
- data/rails_generators/wizardly_scaffold/templates/form.html.haml.erb +22 -0
- data/rails_generators/wizardly_scaffold/templates/helper.rb.erb +30 -0
- data/rails_generators/wizardly_scaffold/templates/images/back.png +0 -0
- data/rails_generators/wizardly_scaffold/templates/images/cancel.png +0 -0
- data/rails_generators/wizardly_scaffold/templates/images/finish.png +0 -0
- data/rails_generators/wizardly_scaffold/templates/images/next.png +0 -0
- data/rails_generators/wizardly_scaffold/templates/images/skip.png +0 -0
- data/rails_generators/wizardly_scaffold/templates/layout.html.erb +15 -0
- data/rails_generators/wizardly_scaffold/templates/layout.html.haml.erb +10 -0
- data/rails_generators/wizardly_scaffold/templates/style.css +54 -0
- data/rails_generators/wizardly_scaffold/wizardly_scaffold_generator.rb +109 -0
- metadata +100 -0
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
require 'wizardly/wizard/utils'
|
|
2
|
+
require 'wizardly/wizard/dsl'
|
|
3
|
+
require 'wizardly/wizard/button'
|
|
4
|
+
require 'wizardly/wizard/page'
|
|
5
|
+
require 'wizardly/wizard/configuration/methods'
|
|
6
|
+
|
|
7
|
+
module Wizardly
|
|
8
|
+
module Wizard
|
|
9
|
+
class Configuration
|
|
10
|
+
include TextHelpers
|
|
11
|
+
attr_reader :pages, :completed_redirect, :canceled_redirect, :controller_path, :controller_class_name, :controller_name, :page_order
|
|
12
|
+
|
|
13
|
+
#enum_attr :persistance, %w(sandbox session database)
|
|
14
|
+
|
|
15
|
+
def initialize(controller, opts) #completed_redirect = nil, canceled_redirect = nil)
|
|
16
|
+
@controller_class_name = controller.to_s.camelcase
|
|
17
|
+
@controller_class_name += 'Controller' unless @controller_class_name =~ /Controller$/
|
|
18
|
+
@controller_path = @controller_class_name.sub(/Controller$/,'').underscore
|
|
19
|
+
@controller_name = @controller_class_name.demodulize.sub(/Controller$/,'').underscore
|
|
20
|
+
@completed_redirect = opts[:completed] || opts[:when_completed] || opts[:redirect] #format_redirect(completed_redirect)
|
|
21
|
+
@canceled_redirect = opts[:canceled] || opts[:when_canceled] || opts[:redirect]
|
|
22
|
+
@include_skip_button = opts[:skip] || opts[:allow_skip] || opts[:allow_skipping] || false
|
|
23
|
+
@include_cancel_button = opts.key?(:cancel) ? opts[:cancel] : true
|
|
24
|
+
@guard_entry = opts.key?(:guard) ? opts[:guard] : true
|
|
25
|
+
@password_fields = opts[:mask_fields] || opts[:mask_passwords] || [:password, :password_confirmation]
|
|
26
|
+
@persist_model = opts[:persist_model] || :per_page
|
|
27
|
+
@form_data = opts[:form_data] || :session
|
|
28
|
+
raise(ArgumentError, ":persist_model option must be one of :once or :per_page", caller) unless [:once, :per_page].include?(@persist_model)
|
|
29
|
+
raise(ArgumentError, ":form_data option must be one of :sandbox or :session", caller) unless [:sandbox, :session].include?(@form_data)
|
|
30
|
+
@page_order = []
|
|
31
|
+
@pages = {}
|
|
32
|
+
@buttons = nil
|
|
33
|
+
@default_buttons = Hash[*[:next, :back, :cancel, :finish, :skip].collect {|default| [default, Button.new(default)] }.flatten]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def guard?; @guard_entry; end
|
|
37
|
+
def persist_model_per_page?; @persist_model == :per_page; end
|
|
38
|
+
def form_data_keep_in_session?; @form_data == :session; end
|
|
39
|
+
def model; @wizard_model_sym; end
|
|
40
|
+
def model_instance_variable; "@#{@wizard_model_sym.to_s}"; end
|
|
41
|
+
def model_class_name; @wizard_model_class_name; end
|
|
42
|
+
def model_const; @wizard_model_const; end
|
|
43
|
+
|
|
44
|
+
def first_page?(name); @page_order.first == name; end
|
|
45
|
+
def last_page?(name); @page_order.last == name; end
|
|
46
|
+
def next_page(name)
|
|
47
|
+
index = @page_order.index(name)
|
|
48
|
+
index += 1 unless self.last_page?(name)
|
|
49
|
+
@page_order[index]
|
|
50
|
+
end
|
|
51
|
+
def previous_page(name)
|
|
52
|
+
index = @page_order.index(name)
|
|
53
|
+
index -= 1 unless self.first_page?(name)
|
|
54
|
+
@page_order[index]
|
|
55
|
+
end
|
|
56
|
+
def button_for_function(name); @default_buttons[name]; end
|
|
57
|
+
def buttons
|
|
58
|
+
return @buttons if @buttons
|
|
59
|
+
# reduce buttons
|
|
60
|
+
@buttons = Hash[*@default_buttons.collect{|k,v|[v.id, v]}.flatten]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def self.create(controller_name, model_name, opts={}, &block)
|
|
64
|
+
# controller_name = controller_name.to_s.underscore.sub(/_controller$/, '').to_sym
|
|
65
|
+
model_name = model_name.to_s.underscore.to_sym
|
|
66
|
+
config = Wizardly::Wizard::Configuration.new(controller_name, opts)
|
|
67
|
+
config.inspect_model!(model_name)
|
|
68
|
+
Wizardly::Wizard::DSL.new(config).instance_eval(&block) if block_given?
|
|
69
|
+
config
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def inspect_model!(model)
|
|
74
|
+
# first examine the model symbol, transform and see if the constant
|
|
75
|
+
# exists
|
|
76
|
+
begin
|
|
77
|
+
@wizard_model_sym = model.to_sym
|
|
78
|
+
@wizard_model_class_name = model.to_s.camelize
|
|
79
|
+
@wizard_model_const = @wizard_model_class_name.constantize
|
|
80
|
+
rescue Exception=>e
|
|
81
|
+
raise ModelNotFoundError, "Cannot convert :#{@wizard_model_sym} to model constant for #{@wizard_model_class_name}: " + e.message, caller
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
begin
|
|
85
|
+
@page_order = @wizard_model_const.validation_group_order
|
|
86
|
+
rescue Exception => e
|
|
87
|
+
raise ValidationGroupError, "Unable to read validation groups from #{@wizard_model_class_name}: " + e.message, caller
|
|
88
|
+
end
|
|
89
|
+
raise(ValidationGroupError, "No validation groups defined for model #{@wizard_model_class_name}", caller) unless (@page_order && !@page_order.empty?)
|
|
90
|
+
|
|
91
|
+
begin
|
|
92
|
+
groups = @wizard_model_const.validation_groups
|
|
93
|
+
enum_attrs = @wizard_model_const.respond_to?(:enumerated_attributes) ? @wizard_model_const.enumerated_attributes.collect {|k,v| k } : []
|
|
94
|
+
model_inst = @wizard_model_const.new
|
|
95
|
+
last_index = @page_order.size-1
|
|
96
|
+
@page_order.each_with_index do |p, index|
|
|
97
|
+
fields = groups[p].map do |f|
|
|
98
|
+
column = model_inst.column_for_attribute(f)
|
|
99
|
+
type = case
|
|
100
|
+
when enum_attrs.include?(f) then :enum
|
|
101
|
+
when (@password_fields && @password_fields.include?(f)) then :password
|
|
102
|
+
else
|
|
103
|
+
column ? column.type : :string
|
|
104
|
+
end
|
|
105
|
+
PageField.new(f, type)
|
|
106
|
+
end
|
|
107
|
+
page = Page.new(self, p, fields)
|
|
108
|
+
|
|
109
|
+
# default button settings based on order, can be altered by
|
|
110
|
+
# set_page(@id).buttons_to []
|
|
111
|
+
buttons = []
|
|
112
|
+
buttons << @default_buttons[:next] unless index >= last_index
|
|
113
|
+
buttons << @default_buttons[:finish] if index == last_index
|
|
114
|
+
buttons << @default_buttons[:back] unless index == 0
|
|
115
|
+
buttons << @default_buttons[:skip] if (@include_skip_button && index != last_index)
|
|
116
|
+
buttons << @default_buttons[:cancel] if (@include_cancel_button)
|
|
117
|
+
page.buttons = buttons
|
|
118
|
+
@pages[page.id] = page
|
|
119
|
+
end
|
|
120
|
+
rescue Exception => e
|
|
121
|
+
raise ValidationGroupError, "Failed to configure wizard from #{@wizard_model_class_name} validation groups: " + e.message, caller
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
public
|
|
126
|
+
# internal DSL method handlers
|
|
127
|
+
def _when_completed_redirect_to(redir); @completed_redirect = redir; end
|
|
128
|
+
def _when_canceled_redirect_to(redir); @canceled_redirect = redir; end
|
|
129
|
+
def _change_button(name)
|
|
130
|
+
raise(WizardConfigurationError, "Button :#{name} in _change_button() call does not exist", caller) unless self.buttons.key?(name)
|
|
131
|
+
_buttons = self.buttons
|
|
132
|
+
@buttons = nil # clear the buttons for regeneration after change in next line
|
|
133
|
+
_buttons[name]
|
|
134
|
+
end
|
|
135
|
+
def _create_button(name, opts)
|
|
136
|
+
id = opts[:id] || button_name_to_symbol(name)
|
|
137
|
+
raise(WizardConfigurationError, "Button '#{name}' with id :#{id} cannot be created. The ID already exists.", caller) if self.buttons.key?(id)
|
|
138
|
+
@buttons=nil
|
|
139
|
+
@default_buttons[id] = UserDefinedButton.new(id, name)
|
|
140
|
+
end
|
|
141
|
+
def _set_page(name); @pages[name]; end
|
|
142
|
+
def _mask_passwords(passwords)
|
|
143
|
+
case passwords
|
|
144
|
+
when String
|
|
145
|
+
passwords = [passwords.to_sym]
|
|
146
|
+
when Symbol
|
|
147
|
+
passwords = [passwords]
|
|
148
|
+
when Array
|
|
149
|
+
else
|
|
150
|
+
raise(WizardlyConfigurationError, "mask_passwords method only accepts string, symbol or array of password fields")
|
|
151
|
+
end
|
|
152
|
+
@password_fields.push(*passwords).uniq!
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def print_config
|
|
156
|
+
io = StringIO.new
|
|
157
|
+
class_name = controller_name.to_s.camelize
|
|
158
|
+
class_name += 'Controller' unless class_name =~ /Controller$/
|
|
159
|
+
io.puts "#{class_name} wizard configuration"
|
|
160
|
+
io.puts
|
|
161
|
+
io.puts "model: #{model_class_name}"
|
|
162
|
+
io.puts "instance: @#{model}"
|
|
163
|
+
io.puts
|
|
164
|
+
io.puts "pages:"
|
|
165
|
+
self.page_order.each do |pid|
|
|
166
|
+
page = pages[pid]
|
|
167
|
+
# io.puts " #{index+1}. '#{page.title}' page (:#{page.id}) has"
|
|
168
|
+
io.puts " '#{page.title}' page (:#{page.id}) has"
|
|
169
|
+
io.puts " --fields: #{page.fields.inject([]){|a, f| a << '"'+f.name.to_s.titleize+'" [:'+f.column_type.to_s+']'}.join(', ')}"
|
|
170
|
+
io.puts " --buttons: #{page.buttons.inject([]){|a, b| a << b.name.to_s }.join(', ')}"
|
|
171
|
+
end
|
|
172
|
+
io.puts
|
|
173
|
+
io.puts "redirects:"
|
|
174
|
+
io.puts " when completed: #{completed_redirect ? completed_redirect.inspect : 'redirects to initial referer by default (specify :completed=>url to override)'}"
|
|
175
|
+
io.puts " when canceled: #{canceled_redirect ? canceled_redirect.inspect : 'redirects to initial referer by default (specify :canceled=>url to override)'}"
|
|
176
|
+
io.puts
|
|
177
|
+
io.puts "buttons:"
|
|
178
|
+
self.buttons.each do |k, b|
|
|
179
|
+
bs = StringIO.new
|
|
180
|
+
bs << " #{b.name} (:#{b.id}) "
|
|
181
|
+
if (b.user_defined?)
|
|
182
|
+
bs << "-- user defined button and function"
|
|
183
|
+
else
|
|
184
|
+
dk = @default_buttons.index(b)
|
|
185
|
+
bs << "-- used for internal <#{dk}> functionality"
|
|
186
|
+
end
|
|
187
|
+
io.puts bs.string
|
|
188
|
+
end
|
|
189
|
+
io.puts
|
|
190
|
+
io.string
|
|
191
|
+
end
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
module Wizardly
|
|
2
|
+
module Wizard
|
|
3
|
+
class DSL
|
|
4
|
+
|
|
5
|
+
def initialize(config)
|
|
6
|
+
@config = config
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# DSL methods
|
|
10
|
+
def when_completed_redirect_to(redir); @config._when_completed_redirect_to(redir); end
|
|
11
|
+
def when_canceled_redirect_to(redir); @config._when_canceled_redirect_to(redir); end
|
|
12
|
+
def change_button(name)
|
|
13
|
+
@config._change_button(name)
|
|
14
|
+
end
|
|
15
|
+
def create_button(name, opts)
|
|
16
|
+
@config._create_button(name, opts)
|
|
17
|
+
end
|
|
18
|
+
def set_page(name);
|
|
19
|
+
@config._set_page(name)
|
|
20
|
+
end
|
|
21
|
+
def mask_passwords(passwords)
|
|
22
|
+
@config._mask_passwords(passwords)
|
|
23
|
+
end
|
|
24
|
+
alias_method :mask_password, :mask_passwords
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'wizardly/wizard/text_helpers'
|
|
2
|
+
|
|
3
|
+
module Wizardly
|
|
4
|
+
module Wizard
|
|
5
|
+
class Page
|
|
6
|
+
include TextHelpers
|
|
7
|
+
|
|
8
|
+
attr_reader :id, :title, :description
|
|
9
|
+
attr_accessor :buttons, :fields
|
|
10
|
+
|
|
11
|
+
def initialize(config, id, fields)
|
|
12
|
+
@buttons = []
|
|
13
|
+
@title = symbol_to_button_name(id)
|
|
14
|
+
@id = id
|
|
15
|
+
@description = ''
|
|
16
|
+
@fields = fields
|
|
17
|
+
@config = config
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def name; id.to_s; end
|
|
21
|
+
|
|
22
|
+
def buttons_to(*args)
|
|
23
|
+
buttons = @config.buttons
|
|
24
|
+
@buttons = args.map do |button_id|
|
|
25
|
+
raise(WizardConfigurationError, ":#{button_id} not defined as a button id in :button_to() call", caller) unless buttons.key?(button_id)
|
|
26
|
+
buttons[button_id]
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
def title_to(name)
|
|
30
|
+
@title = name.strip.squeeze(' ')
|
|
31
|
+
end
|
|
32
|
+
def description_to(name)
|
|
33
|
+
@description = name.strip.squeeze(' ')
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
class PageField
|
|
38
|
+
attr_reader :name, :column_type
|
|
39
|
+
|
|
40
|
+
def initialize(name, type)
|
|
41
|
+
@name = name
|
|
42
|
+
@column_type = type.to_sym
|
|
43
|
+
@field_type = nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def field_type
|
|
47
|
+
@field_type ||= case @column_type
|
|
48
|
+
when :string then :text_field
|
|
49
|
+
when :password then :password_field
|
|
50
|
+
when :enum then :enum_select
|
|
51
|
+
when :text then :text_area
|
|
52
|
+
when :boolean then :check_box
|
|
53
|
+
when :integer, :float, :decimal then :text_field
|
|
54
|
+
when :datetime, :timestamp, :time then :datetime_select
|
|
55
|
+
when :date then :date_select
|
|
56
|
+
else
|
|
57
|
+
:text_field
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Wizardly
|
|
2
|
+
module Wizard
|
|
3
|
+
module TextHelpers
|
|
4
|
+
private
|
|
5
|
+
def underscore_button_name(name)
|
|
6
|
+
name.to_s.strip.squeeze(' ').gsub(/ /, '_').downcase
|
|
7
|
+
end
|
|
8
|
+
def button_name_to_symbol(str)
|
|
9
|
+
underscore_button_name(str).to_sym
|
|
10
|
+
end
|
|
11
|
+
def symbol_to_button_name(sym)
|
|
12
|
+
sym.to_s.gsub(/_/, ' ').squeeze(' ').titleize
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'wizardly/wizard/configuration'
|
|
2
|
+
|
|
3
|
+
module Wizardly
|
|
4
|
+
class WizardlyError < StandardError; end
|
|
5
|
+
class ModelNotFoundError < WizardlyError; end
|
|
6
|
+
class ValidationGroupError < WizardlyError; end
|
|
7
|
+
class CallbackError < WizardlyError; end
|
|
8
|
+
class MissingCallbackError < WizardlyError; end
|
|
9
|
+
class WizardConfigurationError < WizardlyError; end
|
|
10
|
+
class RedirectNotDefinedError < WizardlyError; end
|
|
11
|
+
|
|
12
|
+
class WizardlyGeneratorError < WizardlyError; end
|
|
13
|
+
class WizardlyScaffoldError < WizardlyGeneratorError; end
|
|
14
|
+
class WizardlyControllerGeneratorError < WizardlyGeneratorError; end
|
|
15
|
+
|
|
16
|
+
end
|
data/lib/wizardly.rb
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'validation_group'
|
|
2
|
+
require 'wizardly/action_controller'
|
|
3
|
+
|
|
4
|
+
module Wizardly
|
|
5
|
+
module ActionController
|
|
6
|
+
module MacroMethods
|
|
7
|
+
def wizard_for_model(model, opts={}, &block)
|
|
8
|
+
include Wizardly::ActionController
|
|
9
|
+
#check for validation group gem
|
|
10
|
+
configure_wizard_for_model(model, opts, &block)
|
|
11
|
+
end
|
|
12
|
+
alias_method :act_wizardly_for, :wizard_for_model
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
begin
|
|
18
|
+
ActiveRecord::Base.class_eval do
|
|
19
|
+
class << self
|
|
20
|
+
alias_method :wizardly_page, :validation_group
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
rescue
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
ActionController::Base.send(:extend, Wizardly::ActionController::MacroMethods)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
|
|
2
|
+
namespace :wizardly do
|
|
3
|
+
desc "Display wizard configuration details"
|
|
4
|
+
task :config => :environment do
|
|
5
|
+
name = ENV['name']
|
|
6
|
+
return print_usage unless name
|
|
7
|
+
begin
|
|
8
|
+
name = name.strip.camelize
|
|
9
|
+
name += 'Controller' unless name.match('Controller$')
|
|
10
|
+
controller = name.constantize
|
|
11
|
+
begin
|
|
12
|
+
c = controller.wizard_config
|
|
13
|
+
begin
|
|
14
|
+
puts
|
|
15
|
+
puts c.print_config
|
|
16
|
+
rescue Exception=>e
|
|
17
|
+
puts "Problem printing configuration."
|
|
18
|
+
puts "#{e.class.name} -- #{e.message}"
|
|
19
|
+
puts
|
|
20
|
+
end
|
|
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}"
|
|
24
|
+
puts
|
|
25
|
+
end
|
|
26
|
+
rescue Exception=>e
|
|
27
|
+
puts "{#{name}} does not reference a controller class."
|
|
28
|
+
puts "#{e.class.name} -- #{e.message}"
|
|
29
|
+
puts
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def print_usage
|
|
34
|
+
puts "Usage: rake wizardly:config name={controller_name}"
|
|
35
|
+
puts
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#require 'wizardly'
|
|
2
|
+
|
|
3
|
+
class WizardlyAppGenerator < Rails::Generator::Base
|
|
4
|
+
|
|
5
|
+
def initialize(runtime_args, runtime_options = {})
|
|
6
|
+
super
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def manifest
|
|
10
|
+
record do |m|
|
|
11
|
+
m.directory "lib/tasks"
|
|
12
|
+
|
|
13
|
+
m.file "wizardly.rake", "lib/tasks/wizardly.rake"
|
|
14
|
+
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def controller_class_name
|
|
19
|
+
"#{controller_name.camelize}Controller"
|
|
20
|
+
end
|
|
21
|
+
def model_class_name
|
|
22
|
+
"#{model_name.camelize}"
|
|
23
|
+
end
|
|
24
|
+
def action_methods
|
|
25
|
+
@wizard_config.print_page_action_methods
|
|
26
|
+
end
|
|
27
|
+
def callback_methods
|
|
28
|
+
@wizard_config.print_callbacks
|
|
29
|
+
end
|
|
30
|
+
def helper_methods
|
|
31
|
+
@wizard_config.print_helpers
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
protected
|
|
35
|
+
# Override with your own usage banner.
|
|
36
|
+
def banner
|
|
37
|
+
"Usage: #{$0} wizardly_app"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
#
|
|
2
|
+
# <%= controller_class_name %> class generated by wizardly_controller
|
|
3
|
+
#
|
|
4
|
+
|
|
5
|
+
class <%= controller_class_name %> < ApplicationController
|
|
6
|
+
before_filter :guard_entry
|
|
7
|
+
|
|
8
|
+
<%= action_methods %>
|
|
9
|
+
|
|
10
|
+
<%= callback_methods %>
|
|
11
|
+
|
|
12
|
+
<%= helper_methods %>
|
|
13
|
+
|
|
14
|
+
<%= callback_macro_methods %>
|
|
15
|
+
|
|
16
|
+
public
|
|
17
|
+
def wizard_config; self.class.wizard_config; end
|
|
18
|
+
hide_action :wizard_config
|
|
19
|
+
|
|
20
|
+
private
|
|
21
|
+
|
|
22
|
+
def self.wizard_config; @wizard_config; end
|
|
23
|
+
@wizard_config = Wizardly::Wizard::Configuration.create(:<%=controller_name %>, :<%=model_name %>, :allow_skip=>true) do
|
|
24
|
+
<%= "when_completed_redirect_to #{Wizardly::Wizard::Utils.formatted_redirect(completed_redirect)}" if completed_redirect %>
|
|
25
|
+
<%= "when_canceled_redirect_to #{Wizardly::Wizard::Utils.formatted_redirect(canceled_redirect)}" if canceled_redirect %>
|
|
26
|
+
|
|
27
|
+
# other things you can configure
|
|
28
|
+
# change_button(:next).to('Next One')
|
|
29
|
+
# change_button(:back).to('Previous')
|
|
30
|
+
# create_button('Help')
|
|
31
|
+
# set_page(:init).buttons_to :next_one, :previous, :cancel, :help #this removes skip
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module <%=controller_name.camelize %>Helper
|
|
2
|
+
|
|
3
|
+
def wizardly_submit
|
|
4
|
+
@@wizardly_submit ||= {}
|
|
5
|
+
unless @@wizardly_submit[@step]
|
|
6
|
+
buttons = @wizard.pages[@step].buttons
|
|
7
|
+
@@wizardly_submit[@step] = buttons.inject(StringIO.new) do |io, button|
|
|
8
|
+
io << submit_tag(button.name)
|
|
9
|
+
end.string
|
|
10
|
+
end
|
|
11
|
+
@@wizardly_submit[@step]
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
require 'wizardly'
|
|
2
|
+
|
|
3
|
+
class WizardlyControllerGenerator < Rails::Generator::Base
|
|
4
|
+
attr_reader :controller_name, :model_name, :completed_redirect, :canceled_redirect
|
|
5
|
+
|
|
6
|
+
def initialize(runtime_args, runtime_options = {})
|
|
7
|
+
super
|
|
8
|
+
@controller_name = @args[0].sub(/^:/,'')
|
|
9
|
+
@model_name = @args[1].sub(/^:/, '').underscore
|
|
10
|
+
@completed_redirect = @args[2]
|
|
11
|
+
@canceled_redirect = @args[3]
|
|
12
|
+
opts = {}
|
|
13
|
+
opts[:completed] = @completed_redirect if @completed_redirect
|
|
14
|
+
opts[:canceled] = @canceled_redirect if @canceled_redirect
|
|
15
|
+
|
|
16
|
+
@wizard_config = Wizardly::Wizard::Configuration.new(@controller_name, opts)
|
|
17
|
+
@wizard_config.inspect_model!(@model_name.to_sym)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def manifest
|
|
21
|
+
record do |m|
|
|
22
|
+
m.directory "app/controllers"
|
|
23
|
+
|
|
24
|
+
m.template "controller.rb.erb", "app/controllers/#{controller_name}_controller.rb"
|
|
25
|
+
|
|
26
|
+
m.template "helper.rb.erb", "app/helpers/#{controller_name}_helper.rb"
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def controller_class_name
|
|
32
|
+
"#{controller_name.camelize}Controller"
|
|
33
|
+
end
|
|
34
|
+
def model_class_name
|
|
35
|
+
"#{model_name.camelize}"
|
|
36
|
+
end
|
|
37
|
+
def action_methods
|
|
38
|
+
@wizard_config.print_page_action_methods
|
|
39
|
+
end
|
|
40
|
+
def callback_methods
|
|
41
|
+
@wizard_config.print_callbacks
|
|
42
|
+
end
|
|
43
|
+
def helper_methods
|
|
44
|
+
@wizard_config.print_helpers
|
|
45
|
+
end
|
|
46
|
+
def callback_macro_methods
|
|
47
|
+
@wizard_config.print_callback_macros
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
protected
|
|
51
|
+
# Override with your own usage banner.
|
|
52
|
+
def banner
|
|
53
|
+
"Usage: #{$0} wizardly_controller controller_name model_name [completed_redirect canceled_redirect]"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<h1><%= page.title %></h1>
|
|
2
|
+
|
|
3
|
+
<%= "<p>#{page.description}<p>" if !page.description.blank? %>
|
|
4
|
+
<%%= "<p style=\"color: green\">#{flash[:notice]}<p>" if flash[:notice] %>
|
|
5
|
+
|
|
6
|
+
<%% form_for :<%= model_name %>, :url=>{:action=>:<%= page.name %>} do |f| %>
|
|
7
|
+
<%%= f.error_messages %>
|
|
8
|
+
|
|
9
|
+
<% for field in page.fields -%>
|
|
10
|
+
<% first_field_id ||= "#{model_name}_#{field.name}" %>
|
|
11
|
+
<p>
|
|
12
|
+
<%%= f.label :<%= field.name %> %><br />
|
|
13
|
+
<%%= f.<%= field.field_type %> :<%= field.name %> %>
|
|
14
|
+
</p>
|
|
15
|
+
<% end -%>
|
|
16
|
+
<p>
|
|
17
|
+
<%%= <%= submit_tag %> %>
|
|
18
|
+
</p>
|
|
19
|
+
<%% end %>
|
|
20
|
+
|
|
21
|
+
<script type='text/javascript'>
|
|
22
|
+
document.getElementById('<%=first_field_id %>').focus()
|
|
23
|
+
</script>
|
|
@@ -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= <%= submit_tag %>
|
|
20
|
+
|
|
21
|
+
%script{:type=>'text/javascript'}
|
|
22
|
+
document.getElementById('<%=first_field_id %>').focus()
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
module <%=controller_name.camelize %>Helper
|
|
2
|
+
|
|
3
|
+
def wizardly_submit
|
|
4
|
+
@@wizardly_submit ||= {}
|
|
5
|
+
step_id = "#{controller_name}_#{@step}".to_sym
|
|
6
|
+
unless @@wizardly_submit[step_id]
|
|
7
|
+
buttons = @wizard.pages[@step].buttons
|
|
8
|
+
@@wizardly_submit[step_id] = buttons.inject(StringIO.new) do |io, button|
|
|
9
|
+
io << submit_tag(button.name, :name=>button.id.to_s)
|
|
10
|
+
end.string
|
|
11
|
+
end
|
|
12
|
+
@@wizardly_submit[step_id]
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def wizardly_image_submit(asset_dir = nil, opts = {})
|
|
16
|
+
@@wizardly_image_submit ||={}
|
|
17
|
+
step_id = "#{controller_name}_#{@step}".to_sym
|
|
18
|
+
unless @@wizardly_image_submit[step_id]
|
|
19
|
+
asset_dir = asset_dir ? "#{asset_dir}/".squeeze("/").sub(/^\//,'') : "wizardly/"
|
|
20
|
+
buttons = @wizard.pages[@step].buttons
|
|
21
|
+
@@wizardly_image_submit[step_id] = buttons.inject(StringIO.new) do |io, button|
|
|
22
|
+
opts[:value] = button.name
|
|
23
|
+
opts[:name] = button.id.to_s
|
|
24
|
+
io << image_submit_tag("#{asset_dir}#{button.id}.png", opts)
|
|
25
|
+
end.string
|
|
26
|
+
end
|
|
27
|
+
@@wizardly_image_submit[step_id]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
end
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
|
2
|
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
|
3
|
+
|
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
5
|
+
<head>
|
|
6
|
+
<meta http-equiv="content-type" content="text/html;charset=UTF-8" />
|
|
7
|
+
<title><%= controller_class_name %>: <%%= controller.action_name %></title>
|
|
8
|
+
<%%= stylesheet_link_tag 'scaffold' %>
|
|
9
|
+
</head>
|
|
10
|
+
<body>
|
|
11
|
+
|
|
12
|
+
<%%= yield %>
|
|
13
|
+
|
|
14
|
+
</body>
|
|
15
|
+
</html>
|