module Pageable extend ActiveSupport::Concern def page_to_sitemap_entries(controller, page) path = nil options = {} entries = [] if page.resourceful? page.resource_class.find_each do |object| path = Rails.application.routes.url_helpers.url_for({ :only_path => true, :controller => controller, :action => page.name }.merge(page.resource_params(object))) options[:updated_at] = object.updated_at if object.respond_to?(:updated_at) entries << {:path => path, :options => options} end else path = Rails.application.routes.url_helpers.url_for( :only_path => true, :controller => controller, :action => page.name) entries << {:path => path, :options => {}} end entries end module_function :page_to_sitemap_entries def controller_sitemap_entries(controller) entries = [] Pageable.controller_pages(controller).map do |name, page| entries += page_to_sitemap_entries(controller, page) end entries end module_function :controller_sitemap_entries # # Pageable.controller_pages("site/site") # def controller_pages(controller) controller_class = "#{controller}_controller".camelize.constantize controller_class.pages if controller_class.respond_to?(:pages) end module_function :controller_pages included do before_filter :load_current_page end module ClassMethods def page(name, path, options = {}, &block) # ================= # = Parse options = # ================= localize = options.delete(:localize) == false ? false : Fullstack::Cms.config.localize this_controller_name = "#{self.name.underscore}".gsub("_controller", "") uid = "#{this_controller_name}##{name}" parent_uid = if parent_opt = options.delete(:parent) parent_opt = parent_opt.to_s if parent_opt.include?("#") parent_opt else "#{this_controller_name}##{parent_opt}" end end resource_type = options.delete(:resource).try(:to_s) i18n_scope = "pages.#{self.name.underscore.split('/').last}##{name}" title = options.delete(:title) || I18n.t("#{i18n_scope}.title", :default => "#{name}".humanize) # ====================== # = Create page record = # ====================== if Page.table_exists? if localize I18n.available_locales.each do |locale| _page!(uid, _localize_path(path, locale), name, title, parent_uid, resource_type, locale.to_s) end else _page!(uid, path, name, title, parent_uid, resource_type) end end # =================== # = Map page routes = # =================== if localize I18n.available_locales.each do |locale| map(name, _localize_path(path, locale), options.reverse_merge({:locale => locale.to_s, :as => "#{name}_#{locale}"}), &block) end else map(name, path, options, &block) end end def page_names @page_names ||= @pages.map {|name, page| page.name} end def pages @pages ||= ActiveSupport::HashWithIndifferentAccess.new end private def _localize_path(path, locale) path_segments = path.split("/") path_segments.reject!(&:blank?) path_segments.map! {|s| if s =~ /^:/ s else I18n.t(s, :scope => "routing", :default => s, :locale => locale) end } path_segments.unshift(locale.to_s) "/" + path_segments.join("/") end def _page!(uid, path, name, title, parent_uid, resource_type, locale = nil) # puts "_page!(#{[uid, path, name, title, parent_uid, resource_type, locale].map(&:inspect).join(",")})" _page = if locale.nil? Page.find_or_create_by_uid(uid, :title => title, :name => name) else Page.find_or_create_by_uid_and_locale(uid, locale.to_s, :title => title, :name => name) end if parent_uid parent = if locale.nil? Page.find_by_uid(parent_uid) else Page.find_by_uid_and_locale(parent_uid, locale.to_s) end _page.move_to_child_of(parent) unless _page.parent == parent end if resource_type _page.update_attribute(:resource_type, resource_type) unless _page.resource_type == resource_type end if _page.path != path _page.update_attribute(:path, path) end @pages ||= ActiveSupport::HashWithIndifferentAccess.new @pages[name] = _page end end def load_current_page @current_page.reload if @current_page = self.class.pages[action_name] end end