require 'builder' module Merb module MerbAdmin module MainHelper def to_model_name(param) param.split("::").map{|x| x.camel_case}.join("::") end def object_label(object) if object.nil? nil elsif object.respond_to?(:name) && object.name object.name elsif object.respond_to?(:title) && object.title object.title else "#{object.class.to_s} ##{object.id}" end end def object_property(object, property) property_type = property[:type] property_name = property[:name] case property_type when :boolean if object.send(property_name) == true Builder::XmlMarkup.new.img(:src => image_path("icon-yes.gif"), :alt => "True") else Builder::XmlMarkup.new.img(:src => image_path("icon-no.gif"), :alt => "False") end when :datetime value = object.send(property_name) value.respond_to?(:strftime) ? value.strftime("%b. %d, %Y, %I:%M%p") : nil when :date value = object.send(property_name) value.respond_to?(:strftime) ? value.strftime("%b. %d, %Y") : nil when :time value = object.send(property_name) value.respond_to?(:strftime) ? value.strftime("%I:%M%p") : nil when :string if property_name.to_s =~ /(image|logo|photo|photograph|picture|thumb|thumbnail)_ur(i|l)/i Builder::XmlMarkup.new.img(:src => object.send(property_name), :width => 10, :height => 10) else object.send(property_name).to_s.truncate(50) end when :text object.send(property_name).to_s.truncate(50) when :integer association = @abstract_model.belongs_to_associations.select{|a| a[:child_key].first == property_name}.first if association object_label(object.send(association[:name])) else object.send(property_name) end else object.send(property_name) end end # Given a page count and the current page, we generate a set of pagination # links. # # * We use an inner and outer window into a list of links. For a set of # 20 pages with the current page being 10: # outer_window: # 1 2 ..... 19 20 # inner_window # 5 6 7 8 9 10 11 12 13 14 # # This is totally adjustable, or can be turned off by giving the # :inner_window setting a value of nil. # # * Options # :left_cut_label => text_for_cut:: # Used when the page numbers need to be cut off to prevent the set of # pagination links from being too long. # Defaults to '…' # :right_cut_label => text_for_cut:: # Same as :left_cut_label but for the right side of numbers. # Defaults to '…' # :outer_window => number_of_pages:: # Sets the number of pages to include in the outer 'window' # Defaults to 2 # :inner_window => number_of_pages:: # Sets the number of pags to include in the inner 'window' # Defaults to 7 # :page_param => name_of_page_paramiter # Sets the name of the paramiter the paginator uses to return what # page is being requested. # Defaults to 'page' # :url => url_for_links # Provides the base url to use in the page navigation links. # Defaults to '' def paginate(current_page, page_count, options = {}) options[:left_cut_label] ||= '…' options[:right_cut_label] ||= '…' options[:outer_window] ||= 2 options[:inner_window] ||= 7 options[:page_param] ||= 'page' options[:url] ||= '' url = options.delete(:url) url << (url.include?('?') ? '&' : '?') << options[:page_param] pages = { :all => (1..page_count).to_a, :left => [], :center => [], :right => [] } # Only worry about using our 'windows' if the page count is less then # our windows combined. if options[:inner_window].nil? || ((options[:outer_window] * 2) + options[:inner_window] + 2) >= page_count pages[:center] = pages[:all] else pages[:left] = pages[:all][0, options[:outer_window]] pages[:right] = pages[:all][page_count - options[:outer_window], options[:outer_window]] pages[:center] = case current_page # allow the inner 'window' to shift to right when close to the left edge # Ex: 1 2 [3] 4 5 6 7 8 9 ... 20 when -infinity .. (options[:inner_window] / 2) + 3 pages[:all][options[:outer_window], options[:inner_window]] + [options[:right_cut_label]] # allow the inner 'window' to shift left when close to the right edge # Ex: 1 2 ... 12 13 14 15 16 [17] 18 19 20 when (page_count - (options[:inner_window] / 2.0).ceil) - 1 .. infinity [options[:left_cut_label]] + pages[:all][page_count - options[:inner_window] - options[:outer_window], options[:inner_window]] # Display the unshifed window # ex: 1 2 ... 5 6 7 [8] 9 10 11 ... 19 20 else [options[:left_cut_label]] + pages[:all][current_page - (options[:inner_window] / 2) - 1, options[:inner_window]] + [options[:right_cut_label]] end end b = [] [pages[:left], pages[:center], pages[:right]].each do |p| p.each do |page_number| case page_number when String b << page_number when current_page b << Builder::XmlMarkup.new.span(page_number, :class => "this-page") when page_count b << Builder::XmlMarkup.new.a(page_number, :class => "end", :href => "#{url}=#{page_number}") else b << Builder::XmlMarkup.new.a(page_number, :href => "#{url}=#{page_number}") end end end b.join(" ") end private def infinity 1.0 / 0 end end end end