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 +33 -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.rb +31 -0
- data/lib/wizardly/action_controller.rb +36 -0
- data/lib/wizardly/wizard.rb +16 -0
- data/lib/wizardly/wizard/button.rb +35 -0
- data/lib/wizardly/wizard/configuration.rb +194 -0
- data/lib/wizardly/wizard/configuration/methods.rb +422 -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/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 +90 -0
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'wizardly'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'wizardly'
|
@@ -0,0 +1,147 @@
|
|
1
|
+
module ValidationGroup
|
2
|
+
module ActiveRecord
|
3
|
+
module ActsMethods # extends ActiveRecord::Base
|
4
|
+
def self.extended(base)
|
5
|
+
# Add class accessor which is shared between all models and stores
|
6
|
+
# validation groups defined for each model
|
7
|
+
base.class_eval do
|
8
|
+
cattr_accessor :validation_group_classes
|
9
|
+
self.validation_group_classes = {}
|
10
|
+
|
11
|
+
def self.validation_group_order; @validation_group_order; end
|
12
|
+
def self.validation_groups(all_classes = false)
|
13
|
+
return (self.validation_group_classes[self] || {}) unless all_classes
|
14
|
+
klasses = ValidationGroup::Util.current_and_ancestors(self).reverse
|
15
|
+
returning Hash.new do |hash|
|
16
|
+
klasses.each do |klass|
|
17
|
+
hash.merge! self.validation_group_classes[klass]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def validation_group(name, options={})
|
25
|
+
self_groups = (self.validation_group_classes[self] ||= {})
|
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
|
34
|
+
|
35
|
+
unless included_modules.include?(InstanceMethods)
|
36
|
+
# jeffp: added reader for current_validation_fields
|
37
|
+
attr_reader :current_validation_group, :current_validation_fields
|
38
|
+
include InstanceMethods
|
39
|
+
# jeffp: add valid?(group = nil), see definition below
|
40
|
+
alias_method_chain :valid?, :validation_group
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
module InstanceMethods # included in every model which calls validation_group
|
46
|
+
#needs testing
|
47
|
+
# def reset_fields_for_validation_group(group)
|
48
|
+
# group_classes = self.class.validation_group_classes
|
49
|
+
# found = ValidationGroup::Util.current_and_ancestors(self.class).find do |klass|
|
50
|
+
# group_classes[klass] && group_classes[klass].include?(group)
|
51
|
+
# end
|
52
|
+
# if found
|
53
|
+
# group_classes[found][group].each do |field|
|
54
|
+
# self[field] = nil
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
# end
|
58
|
+
def enable_validation_group(group)
|
59
|
+
# Check if given validation group is defined for current class or one of
|
60
|
+
# its ancestors
|
61
|
+
group_classes = self.class.validation_group_classes
|
62
|
+
found = ValidationGroup::Util.current_and_ancestors(self.class).
|
63
|
+
find do |klass|
|
64
|
+
group_classes[klass] && group_classes[klass].include?(group)
|
65
|
+
end
|
66
|
+
if found
|
67
|
+
@current_validation_group = group
|
68
|
+
# jeffp: capture current fields for performance optimization
|
69
|
+
@current_validation_fields = group_classes[found][group]
|
70
|
+
else
|
71
|
+
raise ArgumentError, "No validation group of name :#{group}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def disable_validation_group
|
76
|
+
@current_validation_group = nil
|
77
|
+
# jeffp: delete fields
|
78
|
+
@current_validation_fields = nil
|
79
|
+
end
|
80
|
+
|
81
|
+
def reject_non_validation_group_errors
|
82
|
+
return unless validation_group_enabled?
|
83
|
+
self.errors.remove_on(@current_validation_fields)
|
84
|
+
end
|
85
|
+
|
86
|
+
# jeffp: optimizer for someone writing custom :validate method -- no need
|
87
|
+
# to validate fields outside the current validation group note: could also
|
88
|
+
# use in validation modules to improve performance
|
89
|
+
def should_validate?(attribute)
|
90
|
+
!self.validation_group_enabled? || (@current_validation_fields && @current_validation_fields.include?(attribute.to_sym))
|
91
|
+
end
|
92
|
+
|
93
|
+
def validation_group_enabled?
|
94
|
+
respond_to?(:current_validation_group) && !current_validation_group.nil?
|
95
|
+
end
|
96
|
+
|
97
|
+
# eliminates need to use :enable_validation_group before :valid? call --
|
98
|
+
# nice
|
99
|
+
def valid_with_validation_group?(group=nil)
|
100
|
+
self.enable_validation_group(group) if group
|
101
|
+
valid_without_validation_group?
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
module Errors # included in ActiveRecord::Errors
|
106
|
+
def add_with_validation_group(attribute,
|
107
|
+
msg = @@default_error_messages[:invalid], *args,
|
108
|
+
&block)
|
109
|
+
# jeffp: setting @current_validation_fields and use of should_validate? optimizes code
|
110
|
+
add_error = @base.respond_to?(:should_validate?) ? @base.should_validate?(attribute.to_sym) : true
|
111
|
+
add_without_validation_group(attribute, msg, *args, &block) if add_error
|
112
|
+
end
|
113
|
+
|
114
|
+
def remove_on(attributes)
|
115
|
+
return unless attributes
|
116
|
+
attributes = [attributes] unless attributes.is_a?(Array)
|
117
|
+
@errors.reject!{|k,v| !attributes.include?(k.to_sym)}
|
118
|
+
end
|
119
|
+
|
120
|
+
def self.included(base) #:nodoc:
|
121
|
+
base.class_eval do
|
122
|
+
alias_method_chain :add, :validation_group
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
module Util
|
129
|
+
# Return array consisting of current and its superclasses down to and
|
130
|
+
# including base_class.
|
131
|
+
def self.current_and_ancestors(current)
|
132
|
+
returning [] do |klasses|
|
133
|
+
klasses << current
|
134
|
+
root = current.base_class
|
135
|
+
until current == root
|
136
|
+
current = current.superclass
|
137
|
+
klasses << current
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# jeffp: moved from init.rb for gemification purposes --
|
145
|
+
# require 'validation_group' loads everything now, init.rb requires 'validation_group' only
|
146
|
+
ActiveRecord::Base.send(:extend, ValidationGroup::ActiveRecord::ActsMethods)
|
147
|
+
ActiveRecord::Errors.send :include, ValidationGroup::ActiveRecord::Errors
|
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,36 @@
|
|
1
|
+
require 'wizardly/wizard'
|
2
|
+
|
3
|
+
module Wizardly
|
4
|
+
module ActionController
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
|
8
|
+
base.class_eval do
|
9
|
+
before_filter :guard_entry
|
10
|
+
class << self
|
11
|
+
attr_reader :wizard_config #note: reader for @wizard_config on the class (not the instance)
|
12
|
+
end
|
13
|
+
hide_action :reset_wizard_session_vars, :wizard_config, :methodize_button_name
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module ClassMethods
|
18
|
+
private
|
19
|
+
def configure_wizard_for_model(model, opts={}, &block)
|
20
|
+
|
21
|
+
# controller_name = self.name.sub(/Controller$/, '').underscore.to_sym
|
22
|
+
@wizard_config = Wizardly::Wizard::Configuration.create(controller_name, model, opts, &block)
|
23
|
+
# define methods
|
24
|
+
self.class_eval @wizard_config.print_page_action_methods
|
25
|
+
self.class_eval @wizard_config.print_callbacks
|
26
|
+
self.class_eval @wizard_config.print_helpers
|
27
|
+
self.class_eval @wizard_config.print_callback_macros
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# instance methods for controller
|
32
|
+
public
|
33
|
+
def wizard_config; self.class.wizard_config; end
|
34
|
+
|
35
|
+
end
|
36
|
+
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
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'wizardly/wizard/text_helpers'
|
2
|
+
|
3
|
+
module Wizardly
|
4
|
+
module Wizard
|
5
|
+
class Button
|
6
|
+
include TextHelpers
|
7
|
+
attr_reader :name
|
8
|
+
attr_reader :id
|
9
|
+
|
10
|
+
def initialize(id, name=nil)
|
11
|
+
@id = id
|
12
|
+
@name = name || symbol_to_button_name(id)
|
13
|
+
@user_defined = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def user_defined?; @user_defined; end
|
17
|
+
|
18
|
+
#used in the dsl
|
19
|
+
def name_to(name, opts={})
|
20
|
+
case name
|
21
|
+
when String then @name = name.strip.squeeze(' ')
|
22
|
+
when Symbol then @name = symbol_to_button_name(name)
|
23
|
+
end
|
24
|
+
@id = opts[:id] if (opts[:id] && opts[:id].is_a?(Symbol))
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class UserDefinedButton < Button
|
29
|
+
def initialize(id, name=nil)
|
30
|
+
super
|
31
|
+
@user_defined = true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -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
|