context_exposer 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
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