module ManageableContent class Manager # Retrieves a list of Controllers eligible for having manageable content. # A Controller is eligible if it has set contents with :manageable_content_for. # This method is cached if Rails.configuration.cache_classes is true. def self.eligible_controllers if Rails.configuration.cache_classes @@eligible_controllers ||= find_eligible_controllers else find_eligible_controllers end end # Retrieves a list of custom pages eligible for having manageable content. # A page is eligible if it is configured on ManageableContent::Engine.config.custom_pages. # This method is cached if Rails.configuration.cache_classes is true. def self.eligible_custom if Rails.configuration.cache_classes @@eligible_custom ||= ManageableContent::Engine.config.custom_pages.keys.sort else ManageableContent::Engine.config.custom_pages.keys.sort end end # Generates a Page and PageContent for each Controller or custom page with manageable content keys, # and the layout Page for manageable layout content keys. # Custom pages can be defined within an initializer with the following code: # # ManageableContent::Engine.config.custom_pages = { # "static/page1" => [:body], # "static/page2" => [:body, :footer] # } def self.generate! controllers = eligible_controllers Engine.config.locales.each do |locale| # layout page Controllers::Dsl.manageable_layout_content_keys.each_key do |layout| generate_page! layout, locale, Controllers::Dsl.manageable_layout_content_keys[layout] end # controllers pages controllers.each do |controller_class| generate_page! controller_class.controller_path, locale, controller_class.manageable_content_keys end # custom pages ManageableContent::Engine.config.custom_pages.each do |custom_page, content_keys| generate_page! custom_page, locale, content_keys end end controllers end # Retrieves a Page relation with a filter for eligible Pages. # A Page is eligible if the corresponding controller is still eligible # (from the eligible_controllers method). # # This method should be used to access a list of valid Pages instead of directly accessing the # Page model. def self.pages eligible_keys = eligible_controllers.map {|controller_class| controller_class.controller_path } + eligible_custom Page.where(:key => eligible_keys) end # Retrieves a Page relation for the given key and locale. # By default I18n.locale is used as the locale option. def self.page(key, locale = I18n.locale) Page.with_contents.where(:key => key, :locale => locale) end # Retrieves a list of eligible keys for a given Page key. # This can be useful to check if a PageContent is still relevant # based on the current configurations. # # This will return a list of page keys with it's corresponding content type (:string or :text). def self.eligible_contents(key) layout_content_keys = Controllers::Dsl.manageable_layout_content_keys[key] || {} content_keys = begin "#{key.camelize}Controller".constantize.manageable_content_keys rescue NameError ManageableContent::Engine.config.custom_pages[key] || {} end layout_content_keys.merge(content_keys) end protected # Retrieves a list of Controllers eligible for having manageable content. # A Controller is eligible if it has set contents with :manageable_content_for. def self.find_eligible_controllers controllers.uniq.select do |controller_class| controller_class.respond_to?(:manageable_content_keys) && controller_class.manageable_content_keys.present? && controller_class.manageable_content_custom_key_evaluator.nil? end.sort do |controller_a, controller_b| controller_a.name <=> controller_b.name end end # Generates a Page and PageContent for the given key, locale and content keys. def self.generate_page!(key, locale, content_keys) Rails.logger.info "Generating ManageableContent::Page for key '#{key}', locale '#{locale}' and keys [#{content_keys.keys.join(',')}]" Page.transaction do page = Manager.page(key, locale).first || Page.new if page.new_record? page.key = key page.locale = locale page.save! end content_keys.each do |content_key, content_type| page_content = page.page_content(content_key) || page.page_contents.build page_content.key = content_key page_content.short = content_type == :string end page.save! end end def self.controllers Rails.configuration.paths["app/controllers"].expanded.inject([]) do |controllers, dir| controllers += Dir["#{dir}/**/*_controller.rb"].map do |file| file.gsub("#{dir}/", "").gsub(".rb", "").camelize.constantize end end end end end