lib/lolita/controllers/component_helpers.rb in lolita-3.4.3 vs lib/lolita/controllers/component_helpers.rb in lolita-4.0.0
- old
+ new
@@ -1,157 +1,157 @@
-module Lolita
- module Controllers
- # Helper that add #render_component method. That is shortstand for render :partial for lolita
- # partial files. Also it provide view hooks for Lolita.
- # For any component there may be helper module. Modules are include in current view or
- # controller instance when component is rendered.
- # All components ar placed in "app/helpers/components/[your component path]".
- # Component should have fallowing module structure Components::[NameSpace]::[Component name]Component
- # Components::Lolita::ListComponent
- # ====Example
- # render_component :"lolita/configuration/list", :dispaly
- # # try to find /helpers/components/lolita/list_component.rb in every directory in $: that
- # # ends with /helpers
- # # require this file if found and extend self with Components::Lolita::ListComponent.
- # Component helpers is loaded in same order as views or controller.
- module ComponentHelpers
- # Render partial template.
- # Accept:
- # <tt>name</tt> - name for component in '/components' directory,
- # can be full name too.
- # Example 'lolita/list'
- # <tt>state</tt> - name for partial. Example 'row'.
- # <tt>options</tt> - any options to pass as <code>:locals</code> to partial,
- # also available through <code>@opts</code> variable.
- # =====Example
- # render_component "lolita/list", :display
- # render_component "lolita/list/display"
- def render_component *args
- @rendering_components ||= []
- name,state,options=get_render_options(*args)
- format=options.delete(:format)
- raise "Can't render component without name!" unless name
- will_use_component name
- component_name=File.join(name.to_s,state ? "#{!Lolita.rails? && "_" || ""}#{state}" : "")
- partial_name=File.join("/components",component_name)
-
- @rendering_components.push(component_name)
- @current_component_name = component_name
- output = output_component(partial_name,component_name,:format=>format ,:locals=>options)
- @rendering_components.pop
- @current_component_name = @rendering_components.last
- self.respond_to?(:raw) ? raw(output) : output
- end
-
- def get_render_options *args
- options=args.extract_options!
- if args.first.respond_to?(:build)
- name,state,options=args[0].build("",args[1],options)
- elsif args.first.class.ancestors.include?(Lolita::Configuration)
- raise ArgumentError, "Include Lolita::Builder in #{args.first.class}"
- else
- name,state=args
- name = "/#{name}" unless name.to_s.match(/^\//)
- end
- return name,state,options
- end
-
- def output_component(partial_name,name,options={})
- output=""
- if options[:format]
- with_format(options[:format]) do
- output << output_with_callbacks(partial_name,name,options[:locals])
- end
- else
- output << output_with_callbacks(partial_name,name,options[:locals])
- end
- output
- end
-
- def output_with_callbacks(partial_name,name,locals)
- @component_locals ||={}
- @component_locals[name] = locals
- output = Lolita::Hooks.component(name).run(:before,:run_scope => self).to_s
- block_output = Lolita::Hooks.component(name).run(:around, :run_scope => self) do
- if Lolita.rails?
- render(:partial => partial_name, :locals => locals)
- else
- haml :"#{partial_name}.html", :locals => locals
- end
- end
- #FIXME does block_output raises error?
- output << block_output.to_s
- output << Lolita::Hooks.component(name).run(:after,:run_scope => self).to_s
- @component_locals[name] = nil
- output
- end
-
- def with_format(format, &block)
- old_formats = formats
- self.formats = [format]
- result=block.call
- self.formats = old_formats
- result
- end
-
- # Require component helper file and extend current instance with component helper module.
- # ====Example
- # will_use_component :"lolita/configuration/list"
- def will_use_component component_name
- helpers_for_component(component_name) do |possible_component_name|
- @used_component_helpers||={}
- unless @used_component_helpers.include?(possible_component_name)
- if path=component_helper_path(possible_component_name)
- self.class.class_eval do
- require path
- end
- class_name=possible_component_name.to_s.camelize
- helper_module = "Components::#{class_name}Component".constantize rescue nil
- if helper_module
- self.extend(helper_module)
- end
- end
- @used_component_helpers[possible_component_name] = helper_module
- else
- if helper_module = @used_component_helpers[possible_component_name]
- self.extend(helper_module)
- end
- end
- end
- end
-
- def helpers_for_component component_name
- names=component_name.to_s.gsub(/^\//,"").split("/")
- start_index=1 # first is lolita
- start_index.upto(names.size) do |index|
- yield names.slice(0..index).join("/")
- end
- end
-
- # Find path for given component.
- #
- # component_helper_path :"lolita/list" #=> [path_to_lolita]/app/helpers/components/lolita/list_component.rb
- def component_helper_path component_name
- @helper_paths||=$:.reject{|p| !p.match(/\/helpers$/) rescue nil}
- get_path=lambda{|paths|
- extra_path=component_name.to_s.split("/")
- component=extra_path.pop
- paths.each do |path|
- new_path=File.join(path,"components",*extra_path,"#{component}_component.rb")
- if File.exist?(new_path)
- return new_path
- end
- end
- nil
- }
- path=get_path.call(@helper_paths)
- path
- end
-
- # Return locals for component that will be rendered next. Very useful in hook views, where is no locals.
- def component_locals
- @component_locals[@current_component_name]
- end
-
- end
- end
+module Lolita
+ module Controllers
+ # Helper that add #render_component method. That is shortstand for render :partial for lolita
+ # partial files. Also it provide view hooks for Lolita.
+ # For any component there may be helper module. Modules are include in current view or
+ # controller instance when component is rendered.
+ # All components ar placed in "app/helpers/components/[your component path]".
+ # Component should have fallowing module structure Components::[NameSpace]::[Component name]Component
+ # Components::Lolita::ListComponent
+ # ====Example
+ # render_component :"lolita/configuration/list", :dispaly
+ # # try to find /helpers/components/lolita/list_component.rb in every directory in $: that
+ # # ends with /helpers
+ # # require this file if found and extend self with Components::Lolita::ListComponent.
+ # Component helpers is loaded in same order as views or controller.
+ module ComponentHelpers
+ # Render partial template.
+ # Accept:
+ # <tt>name</tt> - name for component in '/components' directory,
+ # can be full name too.
+ # Example 'lolita/list'
+ # <tt>state</tt> - name for partial. Example 'row'.
+ # <tt>options</tt> - any options to pass as <code>:locals</code> to partial,
+ # also available through <code>@opts</code> variable.
+ # =====Example
+ # render_component "lolita/list", :display
+ # render_component "lolita/list/display"
+ def render_component *args
+ @rendering_components ||= []
+ name,state,options=get_render_options(*args)
+ format=options.delete(:format)
+ raise "Can't render component without name!" unless name
+ will_use_component name
+ component_name=File.join(name.to_s,state ? "#{!Lolita.rails? && "_" || ""}#{state}" : "")
+ partial_name=File.join("/components",component_name)
+
+ @rendering_components.push(component_name)
+ @current_component_name = component_name
+ output = output_component(partial_name,component_name,:format=>format ,:locals=>options)
+ @rendering_components.pop
+ @current_component_name = @rendering_components.last
+ self.respond_to?(:raw) ? raw(output) : output
+ end
+
+ def get_render_options *args
+ options=args.extract_options!
+ if args.first.respond_to?(:build)
+ name,state,options=args[0].build("",args[1],options)
+ elsif args.first.class.ancestors.include?(Lolita::Configuration)
+ raise ArgumentError, "Include Lolita::Builder in #{args.first.class}"
+ else
+ name,state=args
+ name = "/#{name}" unless name.to_s.match(/^\//)
+ end
+ return name,state,options
+ end
+
+ def output_component(partial_name,name,options={})
+ output=""
+ if options[:format]
+ with_format(options[:format]) do
+ output << output_with_callbacks(partial_name,name,options[:locals])
+ end
+ else
+ output << output_with_callbacks(partial_name,name,options[:locals])
+ end
+ output
+ end
+
+ def output_with_callbacks(partial_name,name,locals)
+ @component_locals ||={}
+ @component_locals[name] = locals
+ output = Lolita::Hooks.component(name).run(:before,:run_scope => self).to_s
+ block_output = Lolita::Hooks.component(name).run(:around, :run_scope => self) do
+ if Lolita.rails?
+ render(:partial => partial_name, :locals => locals)
+ else
+ haml :"#{partial_name}.html", :locals => locals
+ end
+ end
+ #FIXME does block_output raises error?
+ output << block_output.to_s
+ output << Lolita::Hooks.component(name).run(:after,:run_scope => self).to_s
+ @component_locals[name] = nil
+ output
+ end
+
+ def with_format(format, &block)
+ old_formats = formats
+ self.formats = [format]
+ result=block.call
+ self.formats = old_formats
+ result
+ end
+
+ # Require component helper file and extend current instance with component helper module.
+ # ====Example
+ # will_use_component :"lolita/configuration/list"
+ def will_use_component component_name
+ helpers_for_component(component_name) do |possible_component_name|
+ @used_component_helpers||={}
+ unless @used_component_helpers.include?(possible_component_name)
+ if path=component_helper_path(possible_component_name)
+ self.class.class_eval do
+ require path
+ end
+ class_name=possible_component_name.to_s.camelize
+ helper_module = "Components::#{class_name}Component".constantize rescue nil
+ if helper_module
+ self.extend(helper_module)
+ end
+ end
+ @used_component_helpers[possible_component_name] = helper_module
+ else
+ if helper_module = @used_component_helpers[possible_component_name]
+ self.extend(helper_module)
+ end
+ end
+ end
+ end
+
+ def helpers_for_component component_name
+ names=component_name.to_s.gsub(/^\//,"").split("/")
+ start_index=1 # first is lolita
+ start_index.upto(names.size) do |index|
+ yield names.slice(0..index).join("/")
+ end
+ end
+
+ # Find path for given component.
+ #
+ # component_helper_path :"lolita/list" #=> [path_to_lolita]/app/helpers/components/lolita/list_component.rb
+ def component_helper_path component_name
+ @helper_paths||=$:.reject{|p| !p.match(/\/helpers$/) rescue nil}
+ get_path=lambda{|paths|
+ extra_path=component_name.to_s.split("/")
+ component=extra_path.pop
+ paths.each do |path|
+ new_path=File.join(path,"components",*extra_path,"#{component}_component.rb")
+ if File.exist?(new_path)
+ return new_path
+ end
+ end
+ nil
+ }
+ path=get_path.call(@helper_paths)
+ path
+ end
+
+ # Return locals for component that will be rendered next. Very useful in hook views, where is no locals.
+ def component_locals
+ @component_locals[@current_component_name]
+ end
+
+ end
+ end
end
\ No newline at end of file