context_exposer 0.3.0 → 0.4.0

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cff7846013a27d16f62e455b571af3336ea88531
4
- data.tar.gz: d7b782a83befc4da2b8ffa9a145eff505734d303
3
+ metadata.gz: 636d3dfdd4dc2b214e8f8b4b21be110979c458b2
4
+ data.tar.gz: 1ee51b21d57d43d0320a7096445c6bfe1609b6a1
5
5
  SHA512:
6
- metadata.gz: 47926e8db084652454e11b10b82e949618809ed3a1b9141c98b5830dae93a5e771fe79aca837a7a1520062710b9c3fe5f4a7cf63366942048db414391b7e1f36
7
- data.tar.gz: 191e35391a9271b9cc3a3dea8e2429fee8ebb0c6788ade0feb2f9c449303c280fc6bcf26c3d2bf3151db1dcc94db809fff341c87fcd9a91a0717a885785e7553
6
+ metadata.gz: 093d90e0c742c7516b8dfd3caba617758a0d7ba7febcd5ea129b9552e262c8a9583cd8b4a6652ff514039557bafb96b6565baf69f81f19117846706ad801fb82
7
+ data.tar.gz: 5607a5cacf2b0ba969b498dd61d4a0e4b2a6dc6debe90b000907dd6bc05c32470f648e4b7d80999210a2cbc605e61e731637325653d40d9a4f47545e44998ac1
data/README.md CHANGED
@@ -12,6 +12,7 @@ The gem comes with integrations ready for easy migration or symbiosis with exist
12
12
  * exposing of instance variables (Rails default strategy)
13
13
  * decent_exposure gem (expose methods)
14
14
  * decorates_before_rendering gem (expose decorated instance vars)
15
+ * draper
15
16
 
16
17
  For more on integration (and migration path) see below ;)
17
18
 
@@ -98,7 +99,7 @@ class PostsController < ActionController::Base
98
99
  exposed(:posts) { Post.all }
99
100
 
100
101
  # Array of model instances
101
- exposed(:posts_list) { Post.all.to_a }
102
+ exposed(:post_list) { Post.all.to_a }
102
103
  end
103
104
  ```
104
105
 
@@ -148,7 +149,7 @@ The `ResourceController` automatically sets up the typical singular and plural-f
148
149
 
149
150
  * `post` - one Post instance
150
151
  * `posts` - Search Relatation (for lazy load or further scoping)
151
- * `posts_list` - Array of Post instances
152
+ * `post_list` - Array of Post instances
152
153
 
153
154
  This simplifies the above `PostsController` example to this:
154
155
 
@@ -161,7 +162,7 @@ class PostsController < ActionController::Base
161
162
  end
162
163
  ```
163
164
 
164
- The macro `expose_resources` optionally takes a list of the types of resource you want to expose. Valid types are `:one`, `:many` and `:list` respectively (for fx: `post`, `posts` and `posts_list`).
165
+ The macro `expose_resources` optionally takes a list of the types of resource you want to expose. Valid types are `:one`, `:many` and `:list` respectively (for fx: `post`, `posts` and `post_list`).
165
166
 
166
167
  `ContextExposer::ResourceController` uses the following internal logic for its default functionality. You can override these methods to customize your behavior as needed.
167
168
 
@@ -264,6 +265,23 @@ HAML view example
264
265
  %h2 = post.name
265
266
  ```
266
267
 
268
+ ## Draper
269
+
270
+ The `draper` gem adds a `decorates_assigned` method since version *1.1* (see [pull request](https://github.com/drapergem/draper/pull/461)).
271
+
272
+ ```ruby
273
+ decorates_assigned :article, with: FancyArticleDecorator
274
+ decorates_assigned :articles, with: PaginatingCollectionDecorator
275
+ ```
276
+
277
+ Since this functionality is very similar to fx `decent_exposure`, it can be used with `ctx` in a similar way. Simply use the `context_expose_assigned` macro.
278
+
279
+ `context_expose_assigned :post, :posts`
280
+
281
+ In the near future there should be even better integration, so you don't have to specify the method names to expose all, just like for `context_expose_decently` ;)
282
+
283
+ See [commit comment](https://github.com/haines/draper/commit/afa97bb401666f47ef380d7c9e8e94a8b472597d#commitcomment-2844631)
284
+
267
285
  ## Decorates before rendering
268
286
 
269
287
  A patch for the `decorates_before_render` gem is currently made available.
@@ -306,6 +324,78 @@ end
306
324
 
307
325
  If the auto-decoration can't find a decorator for an exposed variable (or method), it will either ignore it (not decorate it) or call `__handle_decorate_error_(error)` which by default will log a Rails warning. Override this error handler as it suits you.
308
326
 
327
+ ## Globalizing the page context
328
+
329
+ As you have the `ctx` object encapsulate all the view state in one place, you can simplify
330
+ your partial calls to `render partial: 'my/partial/template', locals: {ctx: ctx}`.
331
+ However, if you use nested partials it quickly feels repetitive...
332
+
333
+ Which is why this pattern is now encapsulated in the view helper `render_ctx` which auto-populates the `:locals` hash with a local `page_context` variable that points to a `ContextExposer::PageContext.instance` which contains the `ctx` object :)
334
+
335
+ Furthermore, a delegation of `ctx` to `page_context.ctx` is defined so you can still access `ctx` directly from within the views.
336
+
337
+ So you then only have to use the locals hash if you want to pass on variables not part of `ctx`.
338
+
339
+ ```ruby
340
+ render_ctx partial: 'my/partial/template'
341
+ ```
342
+
343
+ ### Page object
344
+
345
+ To further help in making page rendering decissions, a `ContextExposer::Page` instance is
346
+ created and populated on each request, which can contain the following data:
347
+
348
+ `:name, :id, :action, :mode, :controller_name, :type, :resource`
349
+
350
+ The Page instance will attempt to calculate the resource name from the `normalized_resource_name` method of the `ContextExposer::BaseController`. Override this method to calculate a custom resource name for the controller.
351
+
352
+ The page name will normally be calculated by concatenating action, resource name and type, so a `PostController#show` action will have the default name `'show_post_item'`. Resource `type` is either `:list` or `:item` and will be attempted calculated using the action name and looking up in the `list_actions` and `item_actions` class methods on the controller.
353
+
354
+ By default these methods will use the `base_list_actions` (index) and `base_item_actions` (show, new, edit). You can override/extend these conventions and provide your own `list_actions` and `item_actions` class methods for each controller. Macros are provided to generate these methods from a simple list.
355
+
356
+ ```ruby
357
+ class Admin::BirdLocationController < ActionController::Base
358
+ # expose, decorate etc left out
359
+
360
+ # use macros to configure extra REST-like actions
361
+ list_actions :manage
362
+ item_actions :map
363
+
364
+ # custom page object config just before render
365
+ after_filter :set_page_mode
366
+
367
+ # manage many birds
368
+ def manage
369
+ Bird.all
370
+ end
371
+
372
+ # show a single bird location on the map
373
+ def map
374
+ Bird.find params[:id]
375
+ end
376
+
377
+ protected
378
+
379
+ def set_page_mode
380
+ ctx.page.mode = mode
381
+ end
382
+
383
+ # custom calculated page name using fx action_name method and params etc
384
+ def page_name
385
+ "#{action_name}_#{mode}"
386
+ end
387
+
388
+ # map, details or normal mode ?
389
+ def mode
390
+ params[:mode]
391
+ end
392
+
393
+ def self.normalized_resource_name
394
+ :bird
395
+ end
396
+ end
397
+ ```
398
+
309
399
  ## Testing
310
400
 
311
401
  The tests have been written in rspec 2 and capybara.
@@ -8,6 +8,8 @@ module ContextExposer::BaseController
8
8
  # before_filter :configure_exposed_context
9
9
  set_callback :process_action, :before, :configure_exposed_context
10
10
 
11
+ set_callback :process_action, :after, :save_exposed_context
12
+
11
13
  expose_context :ctx
12
14
  end
13
15
 
@@ -17,6 +19,10 @@ module ContextExposer::BaseController
17
19
  alias_method :ctx, :view_ctx
18
20
 
19
21
  module ClassMethods
22
+ def normalized_resource_name
23
+ self.to_s.demodulize.sub(/Controller$/, '').underscore.singularize
24
+ end
25
+
20
26
  def exposed name, options = {}, &block
21
27
  _exposure_storage[name.to_sym] = {options: options, proc: block}
22
28
  end
@@ -31,6 +37,30 @@ module ContextExposer::BaseController
31
37
  end
32
38
  end
33
39
 
40
+ def base_list_actions
41
+ [:index]
42
+ end
43
+
44
+ def base_item_actions
45
+ [:show, :new, :edit]
46
+ end
47
+
48
+ def list_actions *names
49
+ return if names.blank?
50
+ names = names.flatten.map(&:to_sym)
51
+ (class << self; end).define_method :list_actions do
52
+ names | base_list_actions
53
+ end
54
+ end
55
+
56
+ def item_actions *names
57
+ return if names.blank?
58
+ names = names.flatten.map(&:to_sym)
59
+ (class << self; end).define_method :item_actions do
60
+ names | base_item_actions
61
+ end
62
+ end
63
+
34
64
  def integrate_with *names
35
65
  names.flatten.compact.each do |name|
36
66
  self.send :include, "ContextExposer::Integrations::With#{name.to_s.camelize}".constantize
@@ -83,6 +113,56 @@ module ContextExposer::BaseController
83
113
  @configured_exposed_context = true
84
114
  end
85
115
 
116
+ def save_exposed_context
117
+ ContextExposer::PageContext.instance.configure ctx, page_obj
118
+ end
119
+
120
+ def page_obj
121
+ @page ||= build_page_obj
122
+ end
123
+
124
+ # TODO: cleanup!
125
+ def build_page_obj
126
+ return @page if @page
127
+ @page = ContextExposer::Page.instance
128
+ @page.clear!
129
+ clazz = self.class
130
+
131
+ # single or list resource ?
132
+ @page.resource.type = calc_resource_type if calc_resource_type
133
+
134
+ # also attempts to auto-caluclate resource.type if not set
135
+ @page.resource.name = if clazz.respond_to?(:normalized_resource_name, true)
136
+ clazz.normalized_resource_name
137
+ else
138
+ clazz.resource_name if clazz.respond_to?(:resource_name, true)
139
+ end
140
+
141
+ @page.controller = self
142
+
143
+ @page.name = if respond_to?(:page_name, true)
144
+ page_name
145
+ else
146
+ @page_name if @page_name
147
+ end
148
+
149
+ @page
150
+ end
151
+
152
+ def calc_resource_type
153
+ return @resource_type if @resource_type
154
+ clazz = self.class
155
+
156
+ if clazz.respond_to?(:list_actions, true) && !clazz.list_actions.blank?
157
+ resource_type = :list if clazz.list_actions[action_name.to_sym]
158
+ end
159
+
160
+ if !resource_type && clazz.respond_to?(:item_actions, true) && !clazz.item_actions.blank?
161
+ resource_type = :item if clazz.item_actions[action_name.to_sym]
162
+ end
163
+ @resource_type = resource_type
164
+ end
165
+
86
166
  def configured_exposed_context?
87
167
  @configured_exposed_context == true
88
168
  end
@@ -0,0 +1,13 @@
1
+ module PluralTester
2
+ def singular?
3
+ self.pluralize.singularize == self
4
+ end
5
+
6
+ def plural?
7
+ self.singularize.pluralize == self
8
+ end
9
+ end
10
+
11
+ class String
12
+ include PluralTester
13
+ end
@@ -0,0 +1,22 @@
1
+ module ContextExposer::Integrations
2
+ module WithDecentExposure
3
+ extend ActiveSupport::Concern
4
+
5
+ module ClassMethods
6
+ # expose all exposures exposed by decent_exposure to context
7
+ def context_expose_assigned *names
8
+ options = names.extract_options!
9
+ expose_keys = names
10
+ expose_keys = _assigned.keys if expose_keys.empty? && respond_to? :_assigned
11
+ return if expose_keys.blank?
12
+
13
+ _exposure_filter(expose_keys, options).each do |exposure|
14
+ exposed exposure do
15
+ send(exposure)
16
+ end
17
+ end
18
+ end
19
+ alias_method :expose_decently, :context_expose_decently
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ module ContextExposer
2
+ class Page
3
+ class Resource
4
+ attr_accessor :name, :type, :controller
5
+
6
+ def initialize name = nil, type = nil
7
+ self.name = name
8
+ self.type = type if type
9
+ end
10
+
11
+ def type= type
12
+ validate_type! type
13
+ @type = type.to_sym
14
+ end
15
+
16
+ def name= name
17
+ @name = name.to_s
18
+ unless @type
19
+ @type = calc_type
20
+ end
21
+ end
22
+
23
+ protected
24
+
25
+ def page_context
26
+ ContextExposer::PageContext.instance
27
+ end
28
+
29
+ def calc_type
30
+ return nil if name.blank?
31
+ name.to_s.plural? ? :list : :item
32
+ end
33
+
34
+ def validate_type! type
35
+ unless valid_type? type
36
+ raise ArgumentError, "type must be one of: #{valid_types}, was: #{type}"
37
+ end
38
+ end
39
+
40
+ def valid_type? type
41
+ valid_types.include? type.to_sym
42
+ end
43
+
44
+ def valid_types
45
+ [:list, :item]
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,44 @@
1
+ require 'context_exposer/page/resource'
2
+
3
+ module ContextExposer
4
+ class Page
5
+ include Singleton
6
+
7
+ attr_accessor :name, :id, :action, :mode, :controller_name, :type, :resource
8
+
9
+ def configure name = nil, options = {}
10
+ self.name = name
11
+ self.type = options[:type]
12
+ self.resource.name = options[:resource_name]
13
+ self.resource.type = options[:resource_type]
14
+ end
15
+
16
+ def clear!
17
+ instance_variables.each do |inst_var|
18
+ var = inst_var.to_s.sub('@', '')
19
+ self.send("#{var}=", nil)
20
+ end
21
+ end
22
+
23
+ # action= 'show', resource.name = 'post' and resource.type = :item
24
+ # show_post_item
25
+ # action= 'manage', resource.name = 'post' and resource.type = :list
26
+ # manage_post_list
27
+ def name
28
+ @name ||= [action, resource.name, resource.type].compact.map(&:to_s).join('_').underscore
29
+ end
30
+
31
+ def controller= controller
32
+ @action = controller.action_name
33
+ @controller_name = controller.controller_name
34
+ end
35
+
36
+ def resource
37
+ @resource ||= Resource.new
38
+ end
39
+
40
+ def map?
41
+ false
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,27 @@
1
+ module ContextExposer
2
+ class PageContext
3
+ include Singleton
4
+
5
+ attr_accessor :ctx
6
+
7
+ def configure ctx, page = nil
8
+ self.ctx = ctx
9
+ self.page = page if page
10
+ end
11
+
12
+ def ctx= ctx
13
+ unless ctx.kind_of? ContextExposer::ViewContext
14
+ raise ArgumentErorr, "Must be a kind of ContextExposer::ViewContext, was: #{ctx}"
15
+ end
16
+ @ctx = ctx
17
+ end
18
+
19
+ def page= page
20
+ ctx.page = page
21
+ end
22
+
23
+ def page
24
+ ctx.page if ctx
25
+ end
26
+ end
27
+ end
@@ -2,11 +2,15 @@ module DecoratesBeforeRendering
2
2
  class FindModelError < StandardError; end
3
3
  class DecoratorError < StandardError; end
4
4
 
5
- def render *args
6
- __auto_decorate_exposed_ones_
7
- super(*args)
5
+ included do
6
+ after_filter :__auto_decorate_exposed_ones_
8
7
  end
9
8
 
9
+ # def render *args
10
+ # __auto_decorate_exposed_ones_
11
+ # super(*args)
12
+ # end
13
+
10
14
  def __auto_decorate_exposed_ones_
11
15
  __decorate_ivars__
12
16
  __decorate_exposed_ones_
@@ -17,27 +21,41 @@ module DecoratesBeforeRendering
17
21
 
18
22
  def __handle_decorate_error_ e
19
23
  # puts "Error: #{e}"
20
-
21
24
  if defined?(::Rails) && (Rails.respond_to? :logger)
22
25
  Rails.logger.warn 'decorates_before_render: auto_decorate error: #{e}'
23
26
  end
24
27
  end
25
28
 
26
29
  def __exposed_ones_
27
- return [] unless self.class.respond_to? :_exposures
28
- @__exposed_ones_ ||= self.class._exposures.keys
30
+ return [] unless _has_exposures?
31
+ @__exposed_ones_ ||= _exposure_keys
32
+ end
33
+
34
+ def _exposure_keys
35
+ self.class._exposures.keys
36
+ end
37
+
38
+ def _has_exposures?
39
+ self.class.respond_to? :_exposures
29
40
  end
30
41
 
31
42
  def __ctx_exposed_ones_
32
- return [] unless self.class.respond_to? :_exposure_storage
33
- @__ctx_exposed_ones_ ||= self.class._exposure_storage.keys
43
+ return [] unless _has_exposure_storage?
44
+ @__ctx_exposed_ones_ ||= _cxt_exposed_keys
45
+ end
46
+
47
+ def _cxt_exposed_keys
48
+ self.class._exposure_storage.keys
49
+ end
50
+
51
+ def _has_exposure_storage?
52
+ self.class.respond_to? :_exposure_storage
34
53
  end
35
54
 
36
55
  def __decorate_exposed_ones_
37
56
  __exposed_ones_.each do |name|
38
57
  ivar_name = "@#{name}"
39
- obj = send(name)
40
- decorated = __attempt_to_decorate_(obj)
58
+ objs = send(name)
41
59
 
42
60
  decorated = case objs
43
61
  when Array
@@ -73,6 +91,7 @@ module DecoratesBeforeRendering
73
91
  end
74
92
 
75
93
  def __attempt_to_decorate_ obj
94
+ return obj if obj.respond_to?(:decorate)
76
95
  if obj
77
96
  src = __src_for__(obj)
78
97
  decorator = __normalized_decorator_for__(src)
@@ -81,6 +100,8 @@ module DecoratesBeforeRendering
81
100
  end
82
101
 
83
102
  def __do_decoration_ decorator, obj
103
+ return obj if obj.respond_to?(:decorate)
104
+
84
105
  return if !decorator || !obj
85
106
  __validate_decorator!(decorator)
86
107
  decorator.decorate(obj)
@@ -136,18 +157,13 @@ module DecoratesBeforeRendering
136
157
  end
137
158
 
138
159
  def __decorate_ivars__
160
+ return unless __has_decorates?
139
161
  __validate_decorates_present_
140
162
  return if __decorates_blank?
141
163
  __decorates__ivars
142
164
  __decorates_collection_ivars__
143
165
  end
144
166
 
145
- def __validate_decorates_present_
146
- unless __has_decorates?
147
- raise "Internal method '__decorates__' not found. You need to include the 'decorates_before_render' gem "
148
- end
149
- end
150
-
151
167
  def __has_decorates?
152
168
  respond_to?(:__decorates__)
153
169
  end
@@ -14,15 +14,15 @@ module ContextExposer::ResourceController
14
14
  types = types.empty? ? [:all] : types
15
15
 
16
16
  unless expose_resource_method? :one, types
17
- _exposing(_normalized_resource_name.singularize) { find_single_resource }
17
+ _exposing(normalized_resource_name.singularize) { find_single_resource }
18
18
  end
19
19
 
20
20
  unless expose_resource_method? :many, types
21
- _exposing(_normalized_resource_name.pluralize) { find_all_resources }
21
+ _exposing(normalized_resource_name.pluralize) { find_all_resources }
22
22
  end
23
23
 
24
24
  unless expose_resource_method? :list, types
25
- _exposing(_normalized_resource_list) { find_all_resources.to_a }
25
+ _exposing(normalized_resource_list) { find_all_resources.to_a }
26
26
  end
27
27
  end
28
28
 
@@ -57,12 +57,8 @@ module ContextExposer::ResourceController
57
57
  raise "Resource #{clazz_name} is not defined. #{e}"
58
58
  end
59
59
 
60
- def _normalized_resource_list
61
- _normalized_resource_name.pluralize + '_list'
62
- end
63
-
64
- def _normalized_resource_name
65
- self.to_s.demodulize.sub(/Controller$/, '').underscore
60
+ def normalized_resource_list
61
+ normalized_resource_name.singularize + '_list'
66
62
  end
67
63
  end
68
64
  end
@@ -1,3 +1,3 @@
1
1
  module ContextExposer
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -1,12 +1,31 @@
1
1
  class ContextExposer::ViewContext
2
- attr_reader :controller
2
+ attr_reader :controller
3
+ attr_accessor :page
3
4
 
4
- def initialize controller = nil
5
+ def initialize controller = nil, page = nil
5
6
  @controller = controller
7
+ self.page = page if page
8
+ end
9
+
10
+ def page= page
11
+ validate_page! page
12
+ @page = page
6
13
  end
7
14
 
8
15
  protected
9
16
 
17
+ def validate_page! page
18
+ raise ArgumentError, "Must be a kind of #{valid_page_class}, was: #{page}" unless valid_page? page
19
+ end
20
+
21
+ def valid_page? page
22
+ page.kind_of? valid_page_class
23
+ end
24
+
25
+ def valid_page_class
26
+ ContextExposer::Page
27
+ end
28
+
10
29
  def define_singleton_method(name, &block)
11
30
  eigenclass = class<<self; self end
12
31
  eigenclass.class_eval {define_method name, block}
@@ -0,0 +1,15 @@
1
+ module ContextExposer
2
+ module ViewHelpers
3
+ def render_ctx *args
4
+ opts = args.last
5
+ if opts.kind_of?(Hash) && opts[:locals]
6
+ args.last[:locals].merge!(page_context: ContextExposer::PageContext.instance)
7
+ end
8
+ super *args
9
+ end
10
+
11
+ def ctx
12
+ page_context.ctx
13
+ end
14
+ end
15
+ end
@@ -16,9 +16,15 @@ module ContextExposer
16
16
  end
17
17
 
18
18
  require "active_support"
19
+ require "context_exposer/core_ext/string"
19
20
  require "context_exposer/base_controller"
20
21
  require "context_exposer/resource_controller"
21
22
  require "context_exposer/cached_resource_controller"
22
23
  require "context_exposer/view_context"
23
24
  require "context_exposer/macros"
24
25
  require "context_exposer/rails_config"
26
+
27
+ require 'singleton'
28
+ require "context_exposer/page_context"
29
+ require "context_exposer/page"
30
+ require "context_exposer/view_helpers"
@@ -14,6 +14,8 @@ class PostsController < ActionController::Base
14
14
  end
15
15
 
16
16
  def index
17
+ configure_exposed_context
18
+ render
17
19
  end
18
20
 
19
21
  protected
@@ -72,8 +74,8 @@ describe ContextExposer::ResourceController do
72
74
  expect(subject).to respond_to(:posts)
73
75
  end
74
76
 
75
- it "defines a method :posts_list" do
76
- expect(subject).to respond_to(:posts_list)
77
+ it "defines a method :post_list" do
78
+ expect(subject).to respond_to(:post_list)
77
79
  end
78
80
 
79
81
  context 'post' do
@@ -93,14 +95,22 @@ describe ContextExposer::ResourceController do
93
95
  subject { posts }
94
96
  let(:posts) { ctx.posts }
95
97
 
98
+ before :each do
99
+ controller.index
100
+ end
101
+
96
102
  it "calling method :posts returns all posts " do
97
103
  expect(subject).to eq [@post1, @post2]
98
104
  end
99
105
  end
100
106
 
101
- context 'posts_list' do
102
- subject { posts_list }
103
- let(:posts_list) { ctx.posts_list }
107
+ context 'post_list' do
108
+ subject { post_list }
109
+ let(:post_list) { ctx.post_list }
110
+
111
+ before :each do
112
+ controller.index
113
+ end
104
114
 
105
115
  it "calling method :posts_list returns all posts " do
106
116
  expect(subject).to eq [@post1, @post2]
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- class MyController < ActionController::Base
3
+ class BirdController < ActionController::Base
4
4
  include ContextExposer::BaseController
5
5
 
6
6
  exposed(:bird) { "Bird" }
@@ -16,9 +16,18 @@ class MyController < ActionController::Base
16
16
 
17
17
  def show
18
18
  configure_exposed_context
19
+ save_exposed_context
20
+ end
21
+
22
+ def action_name
23
+ 'show'
19
24
  end
20
25
 
21
26
  protected
27
+
28
+ def self.resource_name
29
+ :bird
30
+ end
22
31
  end
23
32
 
24
33
  class MyCoolController < ActionController::Base
@@ -30,10 +39,19 @@ class MyCoolController < ActionController::Base
30
39
 
31
40
  def show
32
41
  configure_exposed_context
42
+ save_exposed_context
43
+ end
44
+
45
+ def action_name
46
+ 'show'
33
47
  end
34
48
 
35
49
  protected
36
50
 
51
+ def self.resource_name
52
+ "MyCool"
53
+ end
54
+
37
55
  def params; end
38
56
  end
39
57
 
@@ -52,7 +70,7 @@ describe ContextExposer::BaseController do
52
70
  describe "controller" do
53
71
  subject { controller }
54
72
 
55
- let(:controller) { MyController.new }
73
+ let(:controller) { BirdController.new }
56
74
 
57
75
  # run action post
58
76
  before :each do
@@ -79,7 +97,7 @@ describe ContextExposer::BaseController do
79
97
  expect(subject.configured_exposed_context?).to be_true
80
98
  end
81
99
 
82
- context 'context' do
100
+ context 'ctx' do
83
101
  subject { controller.ctx }
84
102
 
85
103
  it "is an instance of ContextExposer::ViewContext" do
@@ -102,6 +120,54 @@ describe ContextExposer::BaseController do
102
120
  expect(subject.bird).to eq "Bird"
103
121
  end
104
122
  end
123
+
124
+ context 'PageContext' do
125
+ subject { page_context }
126
+
127
+ let(:page_context) { ContextExposer::PageContext.instance }
128
+
129
+ it "has a page" do
130
+ expect(subject.page).to be_a ContextExposer::Page
131
+ end
132
+
133
+ it "has a ctx" do
134
+ expect(subject.ctx).to be_a ContextExposer::ViewContext
135
+ end
136
+
137
+ context 'page' do
138
+ subject { page }
139
+
140
+ let(:page) { page_context.page }
141
+
142
+ it "has a name" do
143
+ expect(subject.name).to eq "show_bird_item"
144
+ end
145
+
146
+ it "has a type" do
147
+ expect(subject.type).to eq nil
148
+ end
149
+
150
+ it "has an action" do
151
+ expect(subject.action).to eq 'show'
152
+ end
153
+
154
+ it "has a resource" do
155
+ expect(subject.resource).to be_a ContextExposer::Page::Resource
156
+ end
157
+
158
+ context 'resource' do
159
+ subject { page.resource }
160
+
161
+ it "has a name" do
162
+ expect(subject.name).to eq 'bird'
163
+ end
164
+
165
+ it "has a type" do
166
+ expect(subject.type).to eq :item
167
+ end
168
+ end
169
+ end
170
+ end
105
171
  end
106
172
 
107
173
  describe 'MyCoolController' do
@@ -114,7 +180,7 @@ describe ContextExposer::BaseController do
114
180
  controller.show
115
181
  end
116
182
 
117
- context 'context' do
183
+ context 'ctx' do
118
184
  subject { controller.ctx }
119
185
 
120
186
  it "inherits from ContextExposer::ViewContext" do
@@ -1,2 +1,2 @@
1
1
  <h1>Items</h1>
2
- <%= ctx.items_list.map {|i| i.nice_name }.inspect %>
2
+ <%= ctx.item_list.map {|i| i.nice_name }.inspect %>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: context_exposer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristian Mandrup
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-03-17 00:00:00.000000000 Z
11
+ date: 2013-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -56,18 +56,24 @@ files:
56
56
  - lib/context_exposer.rb
57
57
  - lib/context_exposer/base_controller.rb
58
58
  - lib/context_exposer/cached_resource_controller.rb
59
+ - lib/context_exposer/core_ext/string.rb
59
60
  - lib/context_exposer/integrations.rb
60
61
  - lib/context_exposer/integrations/base.rb
61
62
  - lib/context_exposer/integrations/key_filter.rb
62
63
  - lib/context_exposer/integrations/with_decent_exposure.rb
63
64
  - lib/context_exposer/integrations/with_decorates_before.rb
65
+ - lib/context_exposer/integrations/with_draper.rb
64
66
  - lib/context_exposer/integrations/with_instance_vars.rb
65
67
  - lib/context_exposer/macros.rb
68
+ - lib/context_exposer/page.rb
69
+ - lib/context_exposer/page/resource.rb
70
+ - lib/context_exposer/page_context.rb
66
71
  - lib/context_exposer/patch/decorates_before_rendering.rb
67
72
  - lib/context_exposer/rails_config.rb
68
73
  - lib/context_exposer/resource_controller.rb
69
74
  - lib/context_exposer/version.rb
70
75
  - lib/context_exposer/view_context.rb
76
+ - lib/context_exposer/view_helpers.rb
71
77
  - spec/app/items_spec.rb
72
78
  - spec/app/posts_spec.rb
73
79
  - spec/context_exposer/expose_resource_spec.rb