hobo 1.3.0.pre31 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES-1.1.txt +5253 -0
- data/CHANGES.txt +255 -5095
- data/VERSION +1 -1
- data/hobo.gemspec +1 -2
- data/lib/generators/hobo/admin_subsite/USAGE +25 -0
- data/lib/generators/hobo/admin_subsite/admin_subsite_generator.rb +2 -1
- data/lib/generators/hobo/assets/USAGE +5 -0
- data/lib/generators/hobo/assets/templates/application.dryml.erb +1 -1
- data/lib/generators/hobo/controller/USAGE +3 -0
- data/lib/generators/hobo/i18n/USAGE +3 -0
- data/lib/generators/hobo/i18n/templates/app.fr.yml +26 -0
- data/lib/generators/hobo/i18n/templates/app.nb.yml +25 -0
- data/lib/generators/hobo/i18n/templates/hobo.de.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.en.yml +3 -2
- data/lib/generators/hobo/i18n/templates/hobo.es.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.fr.yml +195 -0
- data/lib/generators/hobo/i18n/templates/hobo.it.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.nb.yml +198 -0
- data/lib/generators/hobo/i18n/templates/hobo.pt-PT.yml +1 -0
- data/lib/generators/hobo/i18n/templates/hobo.ru.yml +1 -0
- data/lib/generators/hobo/model/USAGE +2 -2
- data/lib/generators/hobo/rapid/templates/hobo-rapid.js +15 -30
- data/lib/generators/hobo/rapid/templates/themes/clean/public/stylesheets/clean.css +1 -0
- data/lib/generators/hobo/resource/USAGE +39 -0
- data/lib/generators/hobo/routes/router.rb +2 -2
- data/lib/generators/hobo/setup_wizard/setup_wizard_generator.rb +23 -9
- data/lib/generators/hobo/subsite.rb +13 -2
- data/lib/generators/hobo/subsite/USAGE +24 -0
- data/lib/generators/hobo/subsite_taglib/USAGE +4 -0
- data/lib/generators/hobo/subsite_taglib/templates/taglib.dryml.erb +1 -1
- data/lib/generators/hobo/test_framework/USAGE +2 -0
- data/lib/generators/hobo/user_controller/USAGE +3 -0
- data/lib/generators/hobo/user_controller/templates/controller.rb.erb +3 -0
- data/lib/generators/hobo/user_mailer/USAGE +2 -0
- data/lib/generators/hobo/user_model/USAGE +2 -9
- data/lib/generators/hobo/user_resource/USAGE +10 -0
- data/lib/hobo.rb +1 -1
- data/lib/hobo/controller/authentication_support.rb +0 -22
- data/lib/hobo/controller/model.rb +15 -13
- data/lib/hobo/controller/{user.rb → user_base.rb} +43 -32
- data/lib/hobo/extensions/action_controller/hobo_methods.rb +25 -1
- data/lib/hobo/extensions/active_record/associations/collection.rb +12 -3
- data/lib/hobo/extensions/active_record/associations/reflection.rb +1 -1
- data/lib/hobo/extensions/active_record/relation_with_origin.rb +4 -0
- data/lib/hobo/helper.rb +6 -1
- data/lib/hobo/helper/translations.rb +1 -1
- data/lib/hobo/model.rb +55 -19
- data/lib/hobo/model/lifecycles.rb +3 -3
- data/lib/hobo/model/lifecycles/lifecycle.rb +7 -3
- data/lib/hobo/model/permissions.rb +1 -0
- data/lib/hobo/model/scopes/automatic_scopes.rb +0 -2
- data/lib/hobo/model/view_hints.rb +1 -0
- data/lib/hobo/rapid/generators/rapid/forms.dryml.erb +2 -1
- data/lib/hobo/rapid/generators/rapid/pages.dryml.erb +10 -11
- data/lib/hobo/rapid/helper.rb +4 -3
- data/lib/hobo/rapid/taglibs/rapid_core.dryml +92 -67
- data/lib/hobo/rapid/taglibs/rapid_editing.dryml +35 -15
- data/lib/hobo/rapid/taglibs/rapid_forms.dryml +46 -22
- data/lib/hobo/rapid/taglibs/rapid_i18n.dryml +103 -37
- data/lib/hobo/rapid/taglibs/rapid_lifecycles.dryml +3 -1
- data/lib/hobo/rapid/taglibs/rapid_pages.dryml +3 -3
- data/lib/hobo/rapid/taglibs/rapid_plus.dryml +49 -45
- data/test/irt/generators/partials/_subsite_taglib_variables.rb +1 -1
- metadata +38 -33
@@ -1,6 +1,6 @@
|
|
1
1
|
module Hobo
|
2
2
|
module Controller
|
3
|
-
|
3
|
+
module UserBase
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def included(base)
|
@@ -12,7 +12,7 @@ module Hobo
|
|
12
12
|
alias_method_chain :def_auto_actions, :user_actions
|
13
13
|
end
|
14
14
|
|
15
|
-
skip_before_filter :login_required, :only => [:login, :signup, :forgot_password, :reset_password, :do_reset_password,
|
15
|
+
skip_before_filter :login_required, :only => [:login, :signup, :do_signup, :forgot_password, :reset_password, :do_reset_password,
|
16
16
|
:accept_invitation, :do_accept_invitation]
|
17
17
|
|
18
18
|
include_taglib "rapid_user_pages", :plugin => "hobo"
|
@@ -52,7 +52,7 @@ module Hobo
|
|
52
52
|
|
53
53
|
private
|
54
54
|
|
55
|
-
def hobo_login(options={})
|
55
|
+
def hobo_login(options={}, &block)
|
56
56
|
if logged_in?
|
57
57
|
respond_to do |wants|
|
58
58
|
wants.html { redirect_to home_page }
|
@@ -62,8 +62,7 @@ module Hobo
|
|
62
62
|
end
|
63
63
|
|
64
64
|
login_attr = model.human_attribute_name(model.login_attribute)
|
65
|
-
options.reverse_merge!(:
|
66
|
-
:failure_notice => ht(:"#{model.to_s.underscore}.messages.login.error", :login=>login_attr, :default=>["You did not provide a valid #{login_attr} and password."]))
|
65
|
+
options.reverse_merge!(:failure_notice => ht(:"#{model.to_s.underscore}.messages.login.error", :login=>login_attr, :default=>["You did not provide a valid #{login_attr} and password."]))
|
67
66
|
|
68
67
|
if request.post?
|
69
68
|
user = model.authenticate(params[:login], params[:password])
|
@@ -71,33 +70,7 @@ module Hobo
|
|
71
70
|
flash[:error] = options[:failure_notice]
|
72
71
|
hobo_ajax_response if request.xhr? && !performed?
|
73
72
|
else
|
74
|
-
|
75
|
-
self.current_user = user
|
76
|
-
|
77
|
-
yield if block_given?
|
78
|
-
|
79
|
-
if !user.account_active?
|
80
|
-
# account not activate - cancel this login
|
81
|
-
self.current_user = old_user
|
82
|
-
unless performed?
|
83
|
-
respond_to do |wants|
|
84
|
-
wants.html {render :action => :account_disabled}
|
85
|
-
wants.js {hobo_ajax_response}
|
86
|
-
end
|
87
|
-
end
|
88
|
-
else
|
89
|
-
if params[:remember_me].present?
|
90
|
-
current_user.remember_me
|
91
|
-
create_auth_cookie
|
92
|
-
end
|
93
|
-
flash[:notice] ||= options[:success_notice]
|
94
|
-
unless performed?
|
95
|
-
respond_to do |wants|
|
96
|
-
wants.html {redirect_back_or_default(options[:redirect_to] || home_page) }
|
97
|
-
wants.js {hobo_ajax_response}
|
98
|
-
end
|
99
|
-
end
|
100
|
-
end
|
73
|
+
self.sign_user_in(user, options){ yield if block_given?}
|
101
74
|
end
|
102
75
|
end
|
103
76
|
end
|
@@ -183,6 +156,44 @@ module Hobo
|
|
183
156
|
end
|
184
157
|
end
|
185
158
|
|
159
|
+
protected
|
160
|
+
# If you are authenticating user on your own call this method -
|
161
|
+
# hobo will remember signed-in user this way. Arguments:
|
162
|
+
# user - user that you want to sign in
|
163
|
+
# options - hash with messages (:success_notice, :redirect_to)
|
164
|
+
# block - (optional) will be called after assigning current_user
|
165
|
+
def sign_user_in(user, options={}, &block)
|
166
|
+
options.reverse_merge!(:success_notice => ht(:"#{model.to_s.underscore}.messages.login.success", :default=>["You have logged in."]))
|
167
|
+
|
168
|
+
old_user = current_user
|
169
|
+
self.current_user = user
|
170
|
+
|
171
|
+
yield if block_given?
|
172
|
+
|
173
|
+
if !user.account_active?
|
174
|
+
# account not activate - cancel this login
|
175
|
+
self.current_user = old_user
|
176
|
+
unless performed?
|
177
|
+
respond_to do |wants|
|
178
|
+
wants.html {render :action => :account_disabled}
|
179
|
+
wants.js {hobo_ajax_response}
|
180
|
+
end
|
181
|
+
end
|
182
|
+
else
|
183
|
+
if params[:remember_me].present?
|
184
|
+
current_user.remember_me
|
185
|
+
create_auth_cookie
|
186
|
+
end
|
187
|
+
flash[:notice] ||= options[:success_notice]
|
188
|
+
unless performed?
|
189
|
+
respond_to do |wants|
|
190
|
+
wants.html {redirect_back_or_default(options[:redirect_to] || home_page) }
|
191
|
+
wants.js {hobo_ajax_response}
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
196
|
+
|
186
197
|
end
|
187
198
|
end
|
188
199
|
end
|
@@ -2,7 +2,7 @@ ActionController::Base.class_eval do
|
|
2
2
|
|
3
3
|
def self.hobo_user_controller
|
4
4
|
include Hobo::Controller::Model
|
5
|
-
include Hobo::Controller::
|
5
|
+
include Hobo::Controller::UserBase
|
6
6
|
end
|
7
7
|
|
8
8
|
def self.hobo_model_controller
|
@@ -17,4 +17,28 @@ ActionController::Base.class_eval do
|
|
17
17
|
base_url
|
18
18
|
end
|
19
19
|
|
20
|
+
# moved here from authentication_support.rb for easy overriding
|
21
|
+
# Redirect as appropriate when an access request fails.
|
22
|
+
#
|
23
|
+
# The default action is to redirect to the login screen.
|
24
|
+
#
|
25
|
+
# Override this method in your controllers if you want to have special
|
26
|
+
# behavior in case the user is not authorized
|
27
|
+
# to access the requested action. For example, a popup window might
|
28
|
+
# simply close itself.
|
29
|
+
def access_denied(user_model)
|
30
|
+
respond_to do |accepts|
|
31
|
+
accepts.html do
|
32
|
+
store_location
|
33
|
+
redirect_to(login_url(user_model))
|
34
|
+
end
|
35
|
+
accepts.xml do
|
36
|
+
headers["Status"] = "Unauthorized"
|
37
|
+
headers["WWW-Authenticate"] = %(Basic realm="Web Password")
|
38
|
+
render :text => t("hobo.messages.unauthenticated", :default=>["Couldn't authenticate you"]), :status => '401 Unauthorized'
|
39
|
+
end
|
40
|
+
end
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
20
44
|
end
|
@@ -28,12 +28,17 @@ module ActiveRecord
|
|
28
28
|
# DO NOT call super here - AssociationProxy's version loads the collection, and that's bad.
|
29
29
|
# TODO: this really belongs in Rails; migrate it there ASAP
|
30
30
|
def respond_to?(*args)
|
31
|
-
|
31
|
+
return super if has_one_collection?
|
32
|
+
proxy_respond_to?(*args) || [].respond_to?(*args)
|
32
33
|
end
|
33
34
|
|
34
|
-
# TODO: send this patch into Rails. There's no reason to load the collection just to find out it acts like an array.
|
35
35
|
def is_a?(klass)
|
36
|
-
|
36
|
+
if has_one_collection?
|
37
|
+
load_target
|
38
|
+
@target.is_a?(klass)
|
39
|
+
else
|
40
|
+
[].is_a?(klass)
|
41
|
+
end
|
37
42
|
end
|
38
43
|
|
39
44
|
def member_class
|
@@ -52,6 +57,10 @@ module ActiveRecord
|
|
52
57
|
end
|
53
58
|
end
|
54
59
|
|
60
|
+
def has_one_collection?
|
61
|
+
proxy_reflection.macro == :has_one
|
62
|
+
end
|
63
|
+
|
55
64
|
end
|
56
65
|
end
|
57
66
|
end
|
@@ -9,7 +9,7 @@ module ActiveRecord
|
|
9
9
|
begin
|
10
10
|
klass_without_create_polymorphic_class
|
11
11
|
rescue NameError => e
|
12
|
-
Object.class_eval "class #{e.missing_name} < ActiveRecord::Base; set_table_name '#{active_record.name.tableize}'; end"
|
12
|
+
Object.class_eval "class #{e.missing_name} < ActiveRecord::Base; set_table_name '#{active_record.name.tableize}'; def self.hobo_shim?; true; end; end"
|
13
13
|
e.missing_name.constantize
|
14
14
|
end
|
15
15
|
else
|
data/lib/hobo/helper.rb
CHANGED
@@ -179,6 +179,10 @@ module Hobo
|
|
179
179
|
object.respond_to?(:typed_id) ? "model::#{typed_id(object, attribute).to_s.dasherize}" : ""
|
180
180
|
end
|
181
181
|
|
182
|
+
def update_elements_class(updates)
|
183
|
+
'update::'+comma_split(updates).join(':') unless updates.blank?
|
184
|
+
end
|
185
|
+
|
182
186
|
def can_create?(object=this)
|
183
187
|
if object.is_a?(Class) and object < ActiveRecord::Base
|
184
188
|
object = object.new
|
@@ -248,7 +252,8 @@ module Hobo
|
|
248
252
|
# TODO: Man does this need a big cleanup!
|
249
253
|
|
250
254
|
if args.empty?
|
251
|
-
if
|
255
|
+
# if we're repeating over an array, this_field ends up with the current index. Is this useful to anybody?
|
256
|
+
if this_parent && this_field && !this_field.is_a?(Integer)
|
252
257
|
object = this_parent
|
253
258
|
field = this_field
|
254
259
|
else
|
@@ -42,7 +42,7 @@ en:
|
|
42
42
|
raise Hobo::I18nError, %(wrong model name: "#{model_name}" (extracted from translation key: "#{key}"). You might want to use the translate/t tag/method instead.)
|
43
43
|
end
|
44
44
|
options[:default].unshift("hobo.#{keys.join(".")}".to_sym)
|
45
|
-
options[:model] = model_class.model_name.human(:count=>options[:count]||1)
|
45
|
+
options[:model] = model_class.model_name.human(:count=>(options[:count] || 1).to_i)
|
46
46
|
translate key.to_sym, options
|
47
47
|
end
|
48
48
|
alias_method :ht, :hobo_translate
|
data/lib/hobo/model.rb
CHANGED
@@ -33,17 +33,6 @@ module Hobo
|
|
33
33
|
alias_method_chain :attr_accessor, :creator_metadata
|
34
34
|
|
35
35
|
alias_method_chain :has_one, :new_method
|
36
|
-
|
37
|
-
# eval avoids the ruby 1.9.2 "super from singleton method ..." error
|
38
|
-
eval %(
|
39
|
-
def inherited(klass)
|
40
|
-
super
|
41
|
-
fields(false) do
|
42
|
-
Hobo.register_model(klass)
|
43
|
-
field(klass.inheritance_column, :string)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
)
|
47
36
|
end
|
48
37
|
|
49
38
|
base.fields(false) # force hobo_fields to load
|
@@ -56,18 +45,45 @@ module Hobo
|
|
56
45
|
|
57
46
|
WillPaginate::Collection.class_eval do
|
58
47
|
attr_accessor :member_class, :origin, :origin_attribute
|
48
|
+
|
49
|
+
# make paginate_by_sql, etc. carry metadata
|
50
|
+
def replace_with_hobo_metadata(array)
|
51
|
+
result = replace_without_hobo_metadata(array)
|
52
|
+
self.member_class = array.try.member_class
|
53
|
+
self.origin = array.try.origin
|
54
|
+
self.origin_attribute = array.try.origin_attribute
|
55
|
+
result
|
56
|
+
end
|
57
|
+
alias_method_chain :replace, :hobo_metadata
|
59
58
|
end
|
60
59
|
|
61
|
-
WillPaginate::
|
62
|
-
|
63
|
-
|
64
|
-
|
60
|
+
WillPaginate::ActiveRecord::Pagination.class_eval do
|
61
|
+
|
62
|
+
def apply_hobo_metadata(collection)
|
63
|
+
klass = Object.instance_method(:class).bind(self).call
|
64
|
+
is_relation = klass <= ActiveRecord::Relation
|
65
|
+
is_association_proxy = klass <= ActiveRecord::Associations::AssociationProxy
|
66
|
+
collection.member_class = (is_relation || is_association_proxy) ? member_class : self
|
65
67
|
collection.origin = try.proxy_owner
|
66
68
|
collection.origin_attribute = try.proxy_reflection._?.name
|
67
69
|
collection
|
68
70
|
end
|
71
|
+
|
72
|
+
# NOTE: as of will_paginate 3.0.0, the standard paginate method calls the page method.
|
73
|
+
# However, it converts an association proxy into a relation first (via adding a limit clause),
|
74
|
+
# which causes the proxy_owner and proxy_reflection methods to disappear.
|
75
|
+
def paginate_with_hobo_metadata(*args, &block)
|
76
|
+
collection = paginate_without_hobo_metadata(*args, &block)
|
77
|
+
apply_hobo_metadata(collection)
|
78
|
+
end
|
69
79
|
alias_method_chain :paginate, :hobo_metadata
|
70
80
|
|
81
|
+
def page_with_hobo_metadata(*args, &block)
|
82
|
+
collection = page_without_hobo_metadata(*args, &block)
|
83
|
+
apply_hobo_metadata(collection)
|
84
|
+
end
|
85
|
+
alias_method_chain :page, :hobo_metadata
|
86
|
+
|
71
87
|
end
|
72
88
|
|
73
89
|
end
|
@@ -116,7 +132,6 @@ module Hobo
|
|
116
132
|
end
|
117
133
|
end
|
118
134
|
|
119
|
-
|
120
135
|
module ClassMethods
|
121
136
|
|
122
137
|
# TODO: should this be an inheriting_cattr_accessor as well? Probably.
|
@@ -146,6 +161,18 @@ module Hobo
|
|
146
161
|
send(:login_attribute=, name.to_sym, validate) if options.delete(:login) && respond_to?(:login_attribute=)
|
147
162
|
end
|
148
163
|
|
164
|
+
# eval avoids the ruby 1.9.2 "super from singleton method ..." error
|
165
|
+
eval %(
|
166
|
+
def inherited(klass)
|
167
|
+
super
|
168
|
+
Hobo::Model.register_model(klass)
|
169
|
+
# TODO: figure out when this is needed, as Hobofields already does this
|
170
|
+
fields(false) do
|
171
|
+
field(klass.inheritance_column, :string)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
)
|
175
|
+
|
149
176
|
private
|
150
177
|
|
151
178
|
def attrib_names
|
@@ -162,22 +189,27 @@ module Hobo
|
|
162
189
|
def belongs_to_with_test_methods(name, options={}, &block)
|
163
190
|
belongs_to_without_test_methods(name, options, &block)
|
164
191
|
refl = reflections[name]
|
192
|
+
id_method = refl.options[:primary_key] || refl.klass.primary_key
|
165
193
|
if options[:polymorphic]
|
166
194
|
# TODO: the class lookup in _is? below is incomplete; a polymorphic association to an STI base class
|
167
195
|
# will fail to match an object of a derived type
|
168
196
|
# (ie X belongs_to Y (polymorphic), Z is a subclass of Y; @x.y_is?(some_z) will never pass)
|
169
197
|
class_eval %{
|
170
198
|
def #{name}_is?(target)
|
171
|
-
target.class.name == self.#{refl.options[:foreign_type]} && target
|
199
|
+
target.class.name == self.#{refl.options[:foreign_type]} && target.#{id_method} == self.#{refl.primary_key_name}
|
172
200
|
end
|
173
201
|
def #{name}_changed?
|
174
202
|
#{refl.primary_key_name}_changed? || #{refl.options[:foreign_type]}_changed?
|
175
203
|
end
|
176
204
|
}
|
177
205
|
else
|
206
|
+
id_method = refl.options[:primary_key] || refl.klass.primary_key
|
178
207
|
class_eval %{
|
179
208
|
def #{name}_is?(target)
|
180
|
-
|
209
|
+
our_id = self.#{refl.primary_key_name}
|
210
|
+
# if our_id is nil, only return true if target is nil
|
211
|
+
return target.nil? unless our_id
|
212
|
+
target.class <= ::#{refl.klass.name} && target.#{id_method} == our_id
|
181
213
|
end
|
182
214
|
def #{name}_changed?
|
183
215
|
#{refl.primary_key_name}_changed?
|
@@ -438,7 +470,11 @@ module Hobo
|
|
438
470
|
if parts.include?(0)
|
439
471
|
nil
|
440
472
|
else
|
441
|
-
|
473
|
+
begin
|
474
|
+
Date.new(*parts)
|
475
|
+
rescue ArgumentError => ex
|
476
|
+
Time.time_with_datetime_fallback(ActiveRecord::Base.default_timezone, *parts).to_date
|
477
|
+
end
|
442
478
|
end
|
443
479
|
else
|
444
480
|
value
|
@@ -103,9 +103,9 @@ module Hobo
|
|
103
103
|
end
|
104
104
|
|
105
105
|
def transition(name, change, options={}, &block)
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
change.each do |k,v|
|
107
|
+
@lifecycle.def_transition(name, Array(k), v, block, options)
|
108
|
+
end
|
109
109
|
end
|
110
110
|
|
111
111
|
def invariant(&block)
|
@@ -41,7 +41,7 @@ module Hobo
|
|
41
41
|
Creator.new(self, name.to_s, on_create, options)
|
42
42
|
end
|
43
43
|
|
44
|
-
def self.def_transition(name,
|
44
|
+
def self.def_transition(name, start_states, end_state, on_transition, options)
|
45
45
|
class_eval %{
|
46
46
|
def #{name}!(user, attributes=nil)
|
47
47
|
transition(:#{name}, user, attributes)
|
@@ -50,7 +50,7 @@ module Hobo
|
|
50
50
|
can_transition?(:#{name}, user)
|
51
51
|
end
|
52
52
|
}
|
53
|
-
Transition.new(self, name.to_s,
|
53
|
+
Transition.new(self, name.to_s, start_states, end_state, on_transition, options)
|
54
54
|
end
|
55
55
|
|
56
56
|
def self.state_names
|
@@ -149,7 +149,11 @@ module Hobo
|
|
149
149
|
end
|
150
150
|
|
151
151
|
def publishable_transitions_for(user)
|
152
|
-
|
152
|
+
record.with_acting_user(user) do
|
153
|
+
available_transitions_for(user).select do |t|
|
154
|
+
t.publishable_by(user, t.available_to, record)
|
155
|
+
end
|
156
|
+
end
|
153
157
|
end
|
154
158
|
|
155
159
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
<% each_controller do -%>
|
2
2
|
<%
|
3
|
+
next unless @controller < Hobo::Controller::Model
|
3
4
|
form_fields = standard_fields :belongs_to, :has_many
|
4
5
|
|
5
6
|
cancel_to_show_page = linkable?(:show)
|
@@ -29,7 +30,7 @@ model_key = model.to_s.underscore
|
|
29
30
|
</def>
|
30
31
|
<% end -%>
|
31
32
|
|
32
|
-
<% transitions.each do |transition| -%>
|
33
|
+
<% transitions.uniq{|s| s.name}.each do |transition| -%>
|
33
34
|
<def tag="<%= transition.name.to_s.dasherize %>-form" polymorphic/>
|
34
35
|
<def tag="<%= transition.name.to_s.dasherize %>-form" for="<%= model.name %>">
|
35
36
|
<form lifecycle="<%= transition.name %>" merge param="default">
|