pakyow-presenter/lib/presenter/presenter.rb in pakyow-presenter-0.7.2 vs pakyow-presenter/lib/presenter/presenter.rb in pakyow-presenter-0.8rc1
- old
+ new
@@ -1,34 +1,79 @@
module Pakyow
module Presenter
class Presenter < PresenterBase
- attr_accessor :current_context
+ class << self
+ attr_accessor :proc
+ end
+ attr_accessor :current_context, :parser_store, :view_store
+
def initialize
- reset_state()
+ reset_state
+ reset_bindings
end
+ def scope(name, set = :default, &block)
+ @bindings[set] ||= {}
+
+ bs = Bindings.for(block)
+ @bindings[set][name] = bs
+ bs
+ end
+
+ def bindings(scope)
+ #TODO think about merging on launch instead
+ @bindings.inject(Bindings.new) { |bs, b| bs.merge(b[1][scope]) }
+ end
+
+ def reset_bindings(set = :default)
+ @bindings ||= {}
+ @bindings[set] = {}
+ end
+
+ def current_view_lookup_store
+ @view_stores[self.view_store]
+ end
+
#
# Methods that are called by core. This is the interface that core expects a Presenter to have
#
def load
load_views
+
+ self.reset_bindings
+ self.instance_eval(&Presenter.proc) if Presenter.proc
end
def prepare_for_request(request)
reset_state()
@request = request
+
+ if @request && @request.route_path && !@request.route_path.is_a?(Regexp) && @request.route_path.index(':')
+ @view_path = StringUtils.remove_route_vars(@request.route_path)
+ else
+ @view_path = @request && @request.working_path
+ end
+ @root_path = self.current_view_lookup_store.root_path(@view_path)
end
+ def reset
+ @request = nil
+ reset_state
+ end
+
def presented?
+ #TODO the right thing to do?
+ self.ensure_root_view_built
+
@presented
end
def content
return unless view
- request_container = @request.params[:_container]
+ request_container = @request.params[:_container] if @request
return view.to_html(request_container) if request_container
view.to_html(@container_name)
end
#
@@ -38,11 +83,11 @@
# Call these directly
#
def view_for_path(abstract_path, is_root_view=false, klass=View)
- real_path = @view_lookup_store.real_path(abstract_path)
+ real_path = self.current_view_lookup_store.real_path(abstract_path)
klass.new(real_path, is_root_view)
end
def view_for_class(view_class, path_override=nil)
return view_for_path(path_override, view_class.default_is_root_view, view_class) if path_override
@@ -52,80 +97,54 @@
def view
ensure_root_view_built
@root_view
end
- def set_view(view)
- @root_view = View.new(view)
+ def view=(v)
+ # TODO: Why is it important to dup here?
+ @root_view = View.new(v)
@root_view_is_built = true
@presented = true
+
+ # reset paths
@view_path = nil
@root_path = nil
end
- def limit_to_container(id)
- @container_name = id
+ def root
+ @is_compiled = false
+ @root ||= View.root_at_path(@root_path)
end
- def use_view_path(path)
- @view_path = path
- @root_view_is_built = false
+ def root=(v)
+ @is_compiled = false
+ @root = v
end
+ def limit_to_container(id)
+ @container_name = id
+ end
+
def view_path
@view_path
end
- def use_root_view_file(abstract_view_file)
- real_path = @view_lookup_store.real_path(abstract_view_file)
- @root_path = real_path
- @root_view_is_built = false
+ def view_path=(path)
+ @is_compiled = false
+ @view_path = path
end
- def use_root_view_at_view_path(abstract_view_dir)
- @root_path = @view_lookup_store.view_info(abstract_view_dir)[:root_view]
- @root_view_is_built = false
+ def root_path
+ @root_path
end
-
- # This is for creating views from within a controller using the route based lookup mechanism
- def view_for_view_path(v_p, name, deep = false)
- v = nil
- view_info = @view_lookup_store.view_info(v_p)
- vpath = view_info[:views][name] if view_info
- v = View.new(vpath) if vpath
- if v && deep
- populate_view(v, view_info[:views])
- end
- v
- end
- # This is also for creating views from within a controller using the route based lookup mechanism.
- # This method takes either a dir or file path and builds either a root_view or view, respectively.
- def view_for_full_view_path(f_v_p, deep = false)
- v = nil
- real_path_info = @view_lookup_store.real_path_info(f_v_p)
- if real_path_info
- if real_path_info[:file_or_dir] == :file
- v = View.new(real_path_info[:real_path])
- elsif real_path_info[:file_or_dir] == :dir
- root_view = @view_lookup_store.view_info(f_v_p)[:root_view]
- v = View.new(root_view)
- if v && deep
- populate_view(v, @view_lookup_store.view_info(f_v_p)[:views])
- end
- end
- end
- v
+ def root_path=(abstract_path)
+ @is_compiled = false
+ @root = nil
+ @root_path = abstract_path
end
- def populate_view_for_view_path(view, v_p)
- return view unless view_info = @view_lookup_store.view_info(v_p)
- views = view_info[:views]
- populate_view(view, views)
- view
- end
-
# Call as part of View DSL for DOM manipulation
#
def with_container(container, &block)
v = self.view.find("##{container}").first
@@ -143,10 +162,11 @@
#
protected
#
def reset_state
+ @view_store = :default
@presented = false
@root_path = nil
@root_view_is_built = false
@root_view = nil
@view_path = nil
@@ -154,22 +174,13 @@
end
def build_root_view
@root_view_is_built = true
- if @view_path
- v_p = @view_path
- elsif @request && @request.restful
- v_p = restful_view_path(@request.restful)
- elsif @request && @request.route_spec && !@request.route_spec.is_a?(Regexp) && @request.route_spec.index(':')
- v_p = StringUtils.remove_route_vars(@request.route_spec)
- else
- v_p = @request && @request.working_path
- end
- return unless v_p
+ return unless v_p = @view_path
- return unless view_info = @view_lookup_store.view_info(v_p)
+ return unless view_info = self.current_view_lookup_store.view_info(v_p)
@root_path ||= view_info[:root_view]
if Configuration::Base.presenter.view_caching
r_v = @populated_root_view_cache.get([v_p, @root_path]) {
populate_view(LazyView.new(@root_path, true), view_info[:views])
@@ -189,13 +200,17 @@
StringUtils.remove_route_vars(@request.route_spec)
end
end
def load_views
- @view_lookup_store = ViewLookupStore.new("#{Configuration::Presenter.view_dir}")
+ @view_stores = {}
+ Configuration::Presenter.view_stores.each_pair {|name, path|
+ @view_stores[name] = ViewLookupStore.new(path)
+ }
+
if Configuration::Base.presenter.view_caching then
- @populated_root_view_cache = build_root_view_cache(@view_lookup_store.view_info)
+ @populated_root_view_cache = build_root_view_cache(self.current_view_lookup_store.view_info)
end
end
def build_root_view_cache(view_info)
cache = Pakyow::Cache.new
@@ -209,20 +224,31 @@
end
# populates the top_view using view_store data by recursively building
# and substituting in child views named in the structure
def populate_view(top_view, views)
- containers = top_view.elements_with_ids
- containers.each {|e|
- name = e.attr("id")
- path = views[name]
- if path
- v = populate_view(View.new(path), views)
- top_view.reset_container(name) # TODO revisit how this is implemented; assumes all LazyViews are root views
- top_view.add_content_to_container(v, name)
- end
+ top_view.containers.each {|e|
+ next unless path = views[e[:name]]
+
+ v = populate_view(View.new(path), views)
+ self.reset_container(e[:doc])
+ self.add_content_to_container(v, e[:doc])
}
top_view
+ end
+
+ def parser(format, &block)
+ @parser_store ||= {}
+ @parser_store[format.to_sym] = block
+ end
+
+ def add_content_to_container(content, container)
+ content = content.doc unless content.class == String || content.class == Nokogiri::HTML::DocumentFragment || content.class == Nokogiri::XML::Element
+ container.add_child(content)
+ end
+
+ def reset_container(container)
+ container.inner_html = ''
end
end
end
end