Skip to content

Commit

Permalink
moving all building code to Cell::Building for better overrideability.
Browse files Browse the repository at this point in the history
  • Loading branch information
apotonick committed Dec 5, 2011
1 parent 6b0f8c9 commit 56bc56d
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 59 deletions.
60 changes: 1 addition & 59 deletions lib/cell.rb
@@ -1,6 +1,6 @@
module Cell
autoload :Caching, 'cell/caching'

extend ActiveSupport::Concern

DEFAULT_VIEW_PATHS = [File.join('app', 'cells')]
Expand All @@ -18,63 +18,5 @@ def render_cell_for(controller, name, state, *args)

cell.render_state(state, *args)
end

# Creates a cell instance. Note that this method calls builders which were attached to the
# class with Cell::Base.build - this might lead to a different cell being returned.
def create_cell_for(controller, name, *args)
class_from_cell_name(name).build_for(controller, *args)
end

def build_for(controller, *args)
build_class_for(controller, *args).
new(controller)
end

# Adds a builder to the cell class. Builders are used in #render_cell to find out the concrete
# class for rendering. This is helpful if you frequently want to render subclasses according
# to different circumstances (e.g. login situations) and you don't want to place these deciders in
# your view code.
#
# Passes the opts hash from #render_cell into the block. The block is executed in controller context.
# Multiple build blocks are ORed, if no builder matches the building cell is used.
#
# Example:
#
# Consider two different user box cells in your app.
#
# class AuthorizedUserBox < UserInfoBox
# end
#
# class AdminUserBox < UserInfoBox
# end
#
# Now you don't want to have deciders all over your views - use a declarative builder.
#
# UserInfoBox.build do |opts|
# AuthorizedUserBox if user_signed_in?
# AdminUserBox if admin_signed_in?
# end
#
# In your view #render_cell will instantiate the right cell for you now.
def build(&block)
builders << block
end

# The cell class constant for +cell_name+.
def class_from_cell_name(cell_name)
"#{cell_name}_cell".classify.constantize
end

protected
def build_class_for(controller, *args)
builders.each do |blk|
klass = controller.instance_exec(*args, &blk) and return klass
end
self
end

def builders
@builders ||= []
end
end
end
2 changes: 2 additions & 0 deletions lib/cell/base.rb
@@ -1,9 +1,11 @@
require 'abstract_controller'
require 'cell'
require 'cell/builder'

module Cell
class Base < AbstractController::Base
include Cell
extend Builder
include AbstractController
include Rendering, Layouts, Helpers, Callbacks, Translation, Logger

Expand Down
65 changes: 65 additions & 0 deletions lib/cell/builder.rb
@@ -0,0 +1,65 @@
module Cell
module Builder
# Creates a cell instance. Note that this method calls builders which were attached to the
# class with Cell::Base.build - this might lead to a different cell being returned.
def create_cell_for(controller, name, *args)
class_from_cell_name(name).build_for(controller, *args)
end

def build_for(controller, *args)
build_class_for(controller, *args).
new(controller)
end

# Adds a builder to the cell class. Builders are used in #render_cell to find out the concrete
# class for rendering. This is helpful if you frequently want to render subclasses according
# to different circumstances (e.g. login situations) and you don't want to place these deciders in
# your view code.
#
# Passes the opts hash from #render_cell into the block. The block is executed in controller context.
# Multiple build blocks are ORed, if no builder matches the building cell is used.
#
# Example:
#
# Consider two different user box cells in your app.
#
# class AuthorizedUserBox < UserInfoBox
# end
#
# class AdminUserBox < UserInfoBox
# end
#
# Now you don't want to have deciders all over your views - use a declarative builder.
#
# UserInfoBox.build do |opts|
# AuthorizedUserBox if user_signed_in?
# AdminUserBox if admin_signed_in?
# end
#
# In your view #render_cell will instantiate the right cell for you now.
def build(&block)
builders << block
end

# The cell class constant for +cell_name+.
def class_from_cell_name(cell_name)
"#{cell_name}_cell".classify.constantize
end

protected
def build_class_for(controller, *args)
builders.each do |blk|
klass = run_builder_block(blk, controller, *args) and return klass
end
self
end

def run_builder_block(blk, controller, *args)
controller.instance_exec(*args, &blk)
end

def builders
@builders ||= []
end
end
end

0 comments on commit 56bc56d

Please sign in to comment.