radiant-templates-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (122) hide show
  1. data/HELP_designer.textile +79 -0
  2. data/README.textile +123 -0
  3. data/Rakefile +136 -0
  4. data/VERSION +1 -0
  5. data/app/controllers/admin/part_types_controller.rb +8 -0
  6. data/app/controllers/admin/templates_controller.rb +38 -0
  7. data/app/helpers/admin/part_types_helper.rb +26 -0
  8. data/app/helpers/admin/templates_helper.rb +108 -0
  9. data/app/models/part_type.rb +14 -0
  10. data/app/models/template.rb +80 -0
  11. data/app/models/template_part.rb +21 -0
  12. data/app/views/admin/pages/_edit_template.html.haml +32 -0
  13. data/app/views/admin/pages/_edit_template_part.html.haml +20 -0
  14. data/app/views/admin/pages/_switch_templates.html.haml +23 -0
  15. data/app/views/admin/pages/_template_column.html.haml +3 -0
  16. data/app/views/admin/pages/_template_column_header.html.haml +1 -0
  17. data/app/views/admin/part_types/_form.html.haml +36 -0
  18. data/app/views/admin/part_types/_list.html.haml +23 -0
  19. data/app/views/admin/part_types/edit.html.haml +5 -0
  20. data/app/views/admin/part_types/index.html.haml +7 -0
  21. data/app/views/admin/part_types/new.html.haml +2 -0
  22. data/app/views/admin/part_types/remove.html.haml +15 -0
  23. data/app/views/admin/templates/_form.html.haml +65 -0
  24. data/app/views/admin/templates/_template_part.html.haml +21 -0
  25. data/app/views/admin/templates/_templates_css.html.haml +12 -0
  26. data/app/views/admin/templates/edit.html.haml +10 -0
  27. data/app/views/admin/templates/index.html.haml +47 -0
  28. data/app/views/admin/templates/new.html.haml +9 -0
  29. data/app/views/admin/templates/remove.html.haml +15 -0
  30. data/config/initializers/radiant_config.rb +3 -0
  31. data/config/locales/en.yml +32 -0
  32. data/config/routes.rb +7 -0
  33. data/db/migrate/001_create_templates.rb +17 -0
  34. data/db/migrate/002_create_template_parts.rb +15 -0
  35. data/db/migrate/003_rename_sublayout_column.rb +9 -0
  36. data/db/migrate/004_add_position_to_templates.rb +13 -0
  37. data/db/migrate/005_create_part_types.rb +17 -0
  38. data/db/migrate/006_add_description_to_template_parts.rb +9 -0
  39. data/db/migrate/007_add_page_class_name_to_templates.rb +9 -0
  40. data/db/migrate/008_add_index_to_templates.rb +9 -0
  41. data/db/migrate/009_create_default_part_types.rb +23 -0
  42. data/db/migrate/010_update_boolean_part_type.rb +9 -0
  43. data/db/migrate/011_add_timestamps.rb +19 -0
  44. data/lib/file_system/model/part_type_extensions.rb +19 -0
  45. data/lib/file_system/model/template_extensions.rb +52 -0
  46. data/lib/tasks/templates_extension_tasks.rake +28 -0
  47. data/lib/templates/associations.rb +7 -0
  48. data/lib/templates/controller_extensions.rb +20 -0
  49. data/lib/templates/helper.rb +75 -0
  50. data/lib/templates/page_extensions.rb +43 -0
  51. data/lib/templates/tags.rb +43 -0
  52. data/public/images/admin/menu_arrow.png +0 -0
  53. data/public/images/admin/move_higher.png +0 -0
  54. data/public/images/admin/move_lower.png +0 -0
  55. data/public/images/admin/move_to_bottom.png +0 -0
  56. data/public/images/admin/move_to_top.png +0 -0
  57. data/public/images/admin/part_type.png +0 -0
  58. data/public/images/admin/template.png +0 -0
  59. data/spec/controllers/admin_page_controller_extensions_spec.rb +61 -0
  60. data/spec/controllers/part_types_controller_spec.rb +89 -0
  61. data/spec/controllers/templates_controller_spec.rb +322 -0
  62. data/spec/datasets/part_types_dataset.rb +15 -0
  63. data/spec/datasets/templates_dataset.rb +34 -0
  64. data/spec/helpers/templates_helper_spec.rb +56 -0
  65. data/spec/models/page_extensions_spec.rb +9 -0
  66. data/spec/models/part_type_spec.rb +28 -0
  67. data/spec/models/tags_spec.rb +44 -0
  68. data/spec/models/template_part_spec.rb +37 -0
  69. data/spec/models/template_spec.rb +88 -0
  70. data/spec/spec.opts +6 -0
  71. data/spec/spec_helper.rb +39 -0
  72. data/templates_extension.rb +83 -0
  73. data/vendor/plugins/acts_as_list/README +23 -0
  74. data/vendor/plugins/acts_as_list/init.rb +3 -0
  75. data/vendor/plugins/acts_as_list/lib/active_record/acts/list.rb +256 -0
  76. data/vendor/plugins/acts_as_list/test/list_test.rb +332 -0
  77. data/vendor/plugins/make_resourceful/DEFAULTS +148 -0
  78. data/vendor/plugins/make_resourceful/LICENSE +7 -0
  79. data/vendor/plugins/make_resourceful/README +239 -0
  80. data/vendor/plugins/make_resourceful/Rakefile +42 -0
  81. data/vendor/plugins/make_resourceful/VERSION +1 -0
  82. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/resourceful_scaffold_generator.rb +87 -0
  83. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/controller.rb +5 -0
  84. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/fixtures.yml +10 -0
  85. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/functional_test.rb +57 -0
  86. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/helper.rb +2 -0
  87. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/migration.rb +13 -0
  88. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/model.rb +2 -0
  89. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/unit_test.rb +7 -0
  90. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/view__form.haml +5 -0
  91. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/view_edit.haml +11 -0
  92. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/view_index.haml +5 -0
  93. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/view_new.haml +9 -0
  94. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/view_partial.haml +12 -0
  95. data/vendor/plugins/make_resourceful/generators/resourceful_scaffold/templates/view_show.haml +14 -0
  96. data/vendor/plugins/make_resourceful/init.rb +3 -0
  97. data/vendor/plugins/make_resourceful/lib/resourceful/base.rb +52 -0
  98. data/vendor/plugins/make_resourceful/lib/resourceful/builder.rb +354 -0
  99. data/vendor/plugins/make_resourceful/lib/resourceful/default/accessors.rb +346 -0
  100. data/vendor/plugins/make_resourceful/lib/resourceful/default/actions.rb +92 -0
  101. data/vendor/plugins/make_resourceful/lib/resourceful/default/callbacks.rb +51 -0
  102. data/vendor/plugins/make_resourceful/lib/resourceful/default/responses.rb +118 -0
  103. data/vendor/plugins/make_resourceful/lib/resourceful/default/urls.rb +137 -0
  104. data/vendor/plugins/make_resourceful/lib/resourceful/maker.rb +83 -0
  105. data/vendor/plugins/make_resourceful/lib/resourceful/response.rb +33 -0
  106. data/vendor/plugins/make_resourceful/lib/resourceful/serialize.rb +181 -0
  107. data/vendor/plugins/make_resourceful/spec/accessors_spec.rb +473 -0
  108. data/vendor/plugins/make_resourceful/spec/actions_spec.rb +283 -0
  109. data/vendor/plugins/make_resourceful/spec/base_spec.rb +12 -0
  110. data/vendor/plugins/make_resourceful/spec/builder_spec.rb +332 -0
  111. data/vendor/plugins/make_resourceful/spec/callbacks_spec.rb +71 -0
  112. data/vendor/plugins/make_resourceful/spec/integration_spec.rb +396 -0
  113. data/vendor/plugins/make_resourceful/spec/maker_spec.rb +91 -0
  114. data/vendor/plugins/make_resourceful/spec/response_spec.rb +37 -0
  115. data/vendor/plugins/make_resourceful/spec/responses_spec.rb +314 -0
  116. data/vendor/plugins/make_resourceful/spec/rspec_on_rails/LICENSE +35 -0
  117. data/vendor/plugins/make_resourceful/spec/rspec_on_rails/redirect_to.rb +81 -0
  118. data/vendor/plugins/make_resourceful/spec/rspec_on_rails/render_template.rb +28 -0
  119. data/vendor/plugins/make_resourceful/spec/serialize_spec.rb +133 -0
  120. data/vendor/plugins/make_resourceful/spec/spec_helper.rb +279 -0
  121. data/vendor/plugins/make_resourceful/spec/urls_spec.rb +276 -0
  122. metadata +214 -0
@@ -0,0 +1,346 @@
1
+ module Resourceful
2
+ # This module contains various methods
3
+ # that are available from actions and callbacks.
4
+ # Default::Accessors and Default::URLs are the most useful to users;
5
+ # the rest are mostly used internally.
6
+ #
7
+ # However, if you want to poke around the internals a little,
8
+ # check out Default::Actions, which has the default Action definitions,
9
+ # and Default::Responses.included, which defines the default response_for[link:classes/Resourceful/Builder.html#M000061] blocks.
10
+ module Default
11
+ # This module contains all sorts of useful methods
12
+ # that allow access to the resources being worked with,
13
+ # metadata about the controller and action,
14
+ # and so forth.
15
+ #
16
+ # Many of these accessors call other accessors
17
+ # and are called by the default make_resourceful actions[link:classes/Resourceful/Default/Actions.html].
18
+ # This means that overriding one method
19
+ # can affect everything else.
20
+ #
21
+ # This can be dangerous, but it can also be very powerful.
22
+ # make_resourceful is designed to take advantage of overriding,
23
+ # so as long as the new methods accomplish the same purpose as the old ones,
24
+ # everything will just work.
25
+ # Even if you make a small mistake,
26
+ # it's hard to break the controller in any unexpected ways.
27
+ #
28
+ # For example, suppose your controller is called TagsController,
29
+ # but your model is called PhotoTag.
30
+ # All you have to do is override current_model_name:
31
+ #
32
+ # def current_model_name
33
+ # "PhotoTag"
34
+ # end
35
+ #
36
+ # Then current_model will return the PhotoTag model,
37
+ # current_object will call <tt>PhotoTag.find</tt>,
38
+ # and so forth.
39
+ #
40
+ # Overriding current_objects and current_object is particularly useful
41
+ # for providing customized model lookup logic.
42
+ module Accessors
43
+ # Returns an array of all the objects of the model corresponding to the controller.
44
+ # For UsersController, it essentially runs <tt>User.find(:all)</tt>.
45
+ #
46
+ # However, there are a few important differences.
47
+ # First, this method caches is results in the <tt>@current_objects</tt> instance variable.
48
+ # That way, multiple calls won't run multiple queries.
49
+ #
50
+ # Second, this method uses the current_model accessor,
51
+ # which provides a lot of flexibility
52
+ # (see the documentation for current_model for details).
53
+ def current_objects
54
+ @current_objects ||= current_model.find(:all)
55
+ end
56
+
57
+ # Calls current_objects and stores
58
+ # the result in an instance variable
59
+ # named after the controller.
60
+ #
61
+ # This is called automatically by the default make_resourceful actions.
62
+ # You shouldn't need to use it directly unless you're creating a new action.
63
+ #
64
+ # For example, in UsersController,
65
+ # calling +load_objects+ sets <tt>@users = current_objects</tt>.
66
+ def load_objects
67
+ instance_variable_set("@#{instance_variable_name}", current_objects)
68
+ end
69
+
70
+ # Returns the object referenced by the id parameter
71
+ # (or the newly-created object for the +new+ and +create+ actions).
72
+ # For UsersController, it essentially runs <tt>User.find(params[:id])</tt>.
73
+ #
74
+ # However, there are a few important differences.
75
+ # First, this method caches is results in the <tt>@current_objects</tt> instance variable.
76
+ # That way, multiple calls won't run multiple queries.
77
+ #
78
+ # Second, this method uses the current_model accessor,
79
+ # which provides a lot of flexibility
80
+ # (see the documentation for current_model for details).
81
+ #
82
+ # Note that this is different for a singleton controller,
83
+ # where there's only one resource per parent resource.
84
+ # Then this just returns that resource.
85
+ # For example, if Person has_one Hat,
86
+ # then in HatsController current_object essentially runs <tt>Person.find(params[:person_id]).hat</tt>.
87
+ def current_object
88
+ @current_object ||= if plural?
89
+ current_model.find(params[:id])
90
+ else
91
+ parent_object.send(instance_variable_name)
92
+ end
93
+ end
94
+
95
+
96
+ # Calls current_object and stores
97
+ # the result in an instance variable
98
+ # named after the controller.
99
+ #
100
+ # This is called automatically by the default make_resourceful actions.
101
+ # You shouldn't need to use it directly unless you're creating a new action.
102
+ #
103
+ # For example, in UsersController,
104
+ # calling +load_object+ sets <tt>@user = current_object</tt>.
105
+ def load_object
106
+ instance_variable_set("@#{instance_variable_name.singularize}", current_object)
107
+ end
108
+
109
+ # Creates a new object of the type of the current model
110
+ # with the current object's parameters.
111
+ # +current_object+ then returns this object for this action
112
+ # instead of looking up a new object.
113
+ #
114
+ # This is called automatically by the default make_resourceful actions.
115
+ # You shouldn't need to use it directly unless you're creating a new action.
116
+ #
117
+ # Note that if a parent object exists,
118
+ # the newly created object will automatically be a child of the parent object.
119
+ # For example, on POST /people/4/things,
120
+ #
121
+ # build_object
122
+ # current_object.person.id #=> 4
123
+ #
124
+ def build_object
125
+ @current_object = if current_model.respond_to? :build
126
+ current_model.build(object_parameters)
127
+ else
128
+ returning(current_model.new(object_parameters)) do |obj|
129
+ obj.send("#{parent_name}_id=", parent_object.id) if singular? && parent?
130
+ end
131
+ end
132
+ end
133
+
134
+ # The string name of the current model.
135
+ # By default, this is derived from the name of the controller.
136
+ def current_model_name
137
+ controller_name.singularize.camelize
138
+ end
139
+
140
+ # An array of namespaces under which the current controller is.
141
+ # For example, in Admin::Content::PagesController:
142
+ #
143
+ # namespaces #=> [:admin, :content]
144
+ #
145
+ def namespaces
146
+ @namespaces ||= self.class.name.split('::').slice(0...-1).map(&:underscore).map(&:to_sym)
147
+ end
148
+
149
+ # The name of the instance variable that load_object and load_objects should assign to.
150
+ def instance_variable_name
151
+ controller_name
152
+ end
153
+
154
+ # The class of the current model.
155
+ # Note that if a parent object exists,
156
+ # this instead returns the association object.
157
+ # For example, in HatsController where Person has_many :hats,
158
+ #
159
+ # current_model #=> Person.find(params[:person_id]).hats
160
+ #
161
+ # This is useful because the association object uses duck typing
162
+ # to act like a model class.
163
+ # It supplies a find method that's automatically scoped
164
+ # to ensure that the object returned is actually a child of the parent,
165
+ # and so forth.
166
+ def current_model
167
+ if !parent? || singular?
168
+ current_model_name.constantize
169
+ else
170
+ parent_object.send(instance_variable_name)
171
+ end
172
+ end
173
+
174
+ # Returns the hash passed as HTTP parameters
175
+ # that defines the new (or updated) attributes
176
+ # of the current object.
177
+ # This is only meaningful for +create+ or +update+.
178
+ def object_parameters
179
+ params[current_model_name.underscore]
180
+ end
181
+
182
+ # Returns a list of the names of all the potential parents of the current model.
183
+ # For a non-nested controller, this is <tt>[]</tt>.
184
+ # For example, in HatsController where Rack has_many :hats and Person has_many :hats,
185
+ #
186
+ # parents #=> ["rack", "person"]
187
+ #
188
+ # Note that the parents must be declared via Builder#belongs_to.
189
+ def parent_names
190
+ self.class.read_inheritable_attribute :parents
191
+ end
192
+
193
+ # Returns true if an appropriate parent id parameter has been supplied.
194
+ # For example, in HatsController where Rack has_many :hats and Person has_many :hats,
195
+ # if <tt>params[:rack_id]</tt> or <tt>params[:person_id]</tt> is given,
196
+ #
197
+ # parent? #=> true
198
+ #
199
+ # Otherwise, if both <tt>params[:rack_id]</tt> and <tt>params[:rack_id]</tt> are nil,
200
+ #
201
+ # parent? #=> false
202
+ #
203
+ # Note that parents must be declared via Builder#belongs_to.
204
+ def parent?
205
+ !!parent_name
206
+ end
207
+
208
+ # Returns the name of the current parent object if a parent id is given, or nil otherwise.
209
+ # For example, in HatsController where Rack has_many :hats and Person has_many :hats,
210
+ # if <tt>params[:rack_id]</tt> is given,
211
+ #
212
+ # parent_name #=> "rack"
213
+ #
214
+ # If <tt>params[:person_id]</tt> is given,
215
+ #
216
+ # parent_name #=> "person"
217
+ #
218
+ # If both <tt>params[:rack_id]</tt> and <tt>params[:rack_id]</tt> are nil,
219
+ #
220
+ # parent_name #=> nil
221
+ #
222
+ # There are several things to note about this method.
223
+ # First, make_resourceful only supports single-level model nesting.
224
+ # Thus, if neither <tt>params[:rack_id]</tt> nor <tt>params[:rack_id]</tt> are nil,
225
+ # the return value of +parent_name+ is undefined.
226
+ #
227
+ # Second, don't use parent_name to check whether a parent id is given.
228
+ # It's better to use the more semantic parent? method.
229
+ #
230
+ # Third, parent_name caches its return value in the <tt>@parent_name</tt> variable,
231
+ # which you should keep in mind if you're overriding it.
232
+ # However, because <tt>@parent_name == nil</tt> could mean that there is no parent
233
+ # _or_ that the method hasn't been run yet,
234
+ # it uses <tt>defined?(@parent_name)</tt> to do the caching
235
+ # rather than <tt>@parent_name ||=</tt>. See the source code.
236
+ #
237
+ # Finally, note that parents must be declared via Builder#belongs_to.
238
+ def parent_name
239
+ return @parent_name if defined?(@parent_name)
240
+ @parent_name = parent_names.find { |name| params["#{name}_id"] }
241
+ end
242
+
243
+ # Returns the model class of the current parent.
244
+ # For example, in HatsController where Person has_many :hats,
245
+ # if <tt>params[:person_id]</tt> is given,
246
+ #
247
+ # parent_models #=> Rack
248
+ #
249
+ # Note that parents must be declared via Builder#belongs_to.
250
+ def parent_model
251
+ parent_name.camelize.constantize
252
+ end
253
+
254
+ # Returns the current parent object for the current object.
255
+ # For example, in HatsController where Person has_many :hats,
256
+ # if <tt>params[:person_id]</tt> is given,
257
+ #
258
+ # parent_object #=> Person.find(params[:person_id])
259
+ #
260
+ # Note that parents must be declared via Builder#belongs_to.
261
+ #
262
+ # Note also that the results of this method are cached
263
+ # so that multiple calls don't result in multiple SQL queries.
264
+ def parent_object
265
+ @parent_object ||= parent_model.find(params["#{parent_name}_id"])
266
+ end
267
+
268
+ # Assigns the current parent object, as given by parent_objects,
269
+ # to its proper instance variable, as given by parent_name.
270
+ #
271
+ # This is automatically added as a before_filter.
272
+ # You shouldn't need to use it directly unless you're creating a new action.
273
+ def load_parent_object
274
+ instance_variable_set("@#{parent_name}", parent_object) if parent?
275
+ end
276
+
277
+ # Renders a 422 error if no parent id is given.
278
+ # This is meant to be used with before_filter
279
+ # to ensure that some actions are only called with a parent id.
280
+ # For example:
281
+ #
282
+ # before_filter :ensure_parent_exists, :only => [:create, :update]
283
+ #
284
+ def ensure_parent_exists
285
+ return true if parent?
286
+ render :text => 'No parent id given', :status => 422
287
+ return false
288
+ end
289
+
290
+ # Returns whether or not the database update in the +create+, +update+, and +destroy+
291
+ # was completed successfully.
292
+ def save_succeeded?
293
+ @save_succeeded
294
+ end
295
+
296
+ # Declares that the current databse update was completed successfully.
297
+ # Causes subsequent calls to <tt>save_succeeded?</tt> to return +true+.
298
+ #
299
+ # This is mostly meant to be used by the default actions,
300
+ # but it can be used by user-defined actions as well.
301
+ def save_succeeded!
302
+ @save_succeeded = true
303
+ end
304
+
305
+ # Declares that the current databse update was not completed successfully.
306
+ # Causes subsequent calls to <tt>save_succeeded?</tt> to return +false+.
307
+ #
308
+ # This is mostly meant to be used by the default actions,
309
+ # but it can be used by user-defined actions as well.
310
+ def save_failed!
311
+ @save_succeeded = false
312
+ end
313
+
314
+ # Returns whether or not the current action acts upon multiple objects.
315
+ # By default, the only such action is +index+.
316
+ def plural_action?
317
+ PLURAL_ACTIONS.include?(params[:action].to_sym)
318
+ end
319
+
320
+ # Returns whether or not the current action acts upon a single object.
321
+ # By default, this is the case for all actions but +index+.
322
+ def singular_action?
323
+ !plural_action?
324
+ end
325
+
326
+ # Returns whether the controller is a singleton,
327
+ # implying that there is only one such resource for each parent resource.
328
+ #
329
+ # Note that the way this is determined is based on the singularity of the controller name,
330
+ # so it may yield false positives for oddly-named controllers and need to be overridden.
331
+ def singular?
332
+ instance_variable_name.singularize == instance_variable_name
333
+ end
334
+
335
+ # Returns whether the controller is a normal plural controller,
336
+ # implying that there are multiple resources for each parent resource.
337
+ #
338
+ # Note that the way this is determined is based on the singularity of the controller name,
339
+ # so it may yield false negatives for oddly-named controllers.
340
+ # If this is the case, the singular? method should be overridden.
341
+ def plural?
342
+ !singular?
343
+ end
344
+ end
345
+ end
346
+ end
@@ -0,0 +1,92 @@
1
+ module Resourceful
2
+ module Default
3
+ # Contains the definitions of the default resourceful actions.
4
+ # These are made available with the Builder#actions method.
5
+ #
6
+ # These methods are very compact,
7
+ # so the best way to understand them is just to look at their source.
8
+ # Check out Resourceful::Accessors and Resourceful::Callbacks
9
+ # for the documentation of the methods called within the actions.
10
+ #
11
+ # Along with each action is listed the RESTful method
12
+ # which corresponds to the action.
13
+ # The controller in the examples is FoosController,
14
+ # and the id for single-object actions is 12.
15
+ module Actions
16
+ # GET /foos
17
+ def index
18
+ load_objects
19
+ before :index
20
+ response_for :index
21
+ end
22
+
23
+ # GET /foos/12
24
+ def show
25
+ load_object
26
+ before :show
27
+ response_for :show
28
+ rescue
29
+ response_for :show_fails
30
+ end
31
+
32
+ # POST /foos
33
+ def create
34
+ build_object
35
+ load_object
36
+ before :create
37
+ if current_object.save
38
+ save_succeeded!
39
+ after :create
40
+ response_for :create
41
+ else
42
+ save_failed!
43
+ after :create_fails
44
+ response_for :create_fails
45
+ end
46
+ end
47
+
48
+ # PUT /foos/12
49
+ def update
50
+ load_object
51
+ before :update
52
+ if current_object.update_attributes object_parameters
53
+ save_succeeded!
54
+ after :update
55
+ response_for :update
56
+ else
57
+ save_failed!
58
+ after :update_fails
59
+ response_for :update_fails
60
+ end
61
+ end
62
+
63
+ # GET /foos/new
64
+ def new
65
+ build_object
66
+ load_object
67
+ before :new
68
+ response_for :new
69
+ end
70
+
71
+ # GET /foos/12/edit
72
+ def edit
73
+ load_object
74
+ before :edit
75
+ response_for :edit
76
+ end
77
+
78
+ # DELETE /foos/12
79
+ def destroy
80
+ load_object
81
+ before :destroy
82
+ if current_object.destroy
83
+ after :destroy
84
+ response_for :destroy
85
+ else
86
+ after :destroy_fails
87
+ response_for :destroy_fails
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,51 @@
1
+ require 'resourceful/builder'
2
+
3
+ module Resourceful
4
+ module Default
5
+ # This module is mostly meant to be used by the make_resourceful default actions.
6
+ # It provides various methods that declare where callbacks set in the +make_resourceful+ block,
7
+ # like Builder#before and Builder#response_for,
8
+ # should be called.
9
+ module Callbacks
10
+ # Calls any +before+ callbacks set in the +make_resourceful+ block for the given event.
11
+ def before(event)
12
+ resourceful_fire(:before, event.to_sym)
13
+ end
14
+
15
+ # Calls any +after+ callbacks set in the +make_resourceful+ block for the given event.
16
+ def after(event)
17
+ resourceful_fire(:after, event.to_sym)
18
+ end
19
+
20
+ # Calls any +response_for+ callbacks set in the +make_resourceful+ block for the given event.
21
+ # Note that these aren't called directly,
22
+ # but instead passed along to Rails' respond_to method.
23
+ def response_for(event)
24
+ if responses = self.class.read_inheritable_attribute(:resourceful_responses)[event.to_sym]
25
+ respond_to do |format|
26
+ responses.each do |key, value|
27
+ format.send(key, &scope(value))
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ # Returns a block identical to the given block,
34
+ # but in the context of the current controller.
35
+ # The returned block accepts no arguments,
36
+ # even if the given block accepted them.
37
+ def scope(block)
38
+ lambda do
39
+ instance_eval(&(block || lambda {}))
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ def resourceful_fire(type, name)
46
+ callbacks = self.class.read_inheritable_attribute(:resourceful_callbacks)[type][name] || []
47
+ callbacks.each { |callback| scope(callback).call }
48
+ end
49
+ end
50
+ end
51
+ end