module Rssify #:nodoc: module Controller #:nodoc: def self.included(mod) mod.extend(ClassMethods) end module ClassMethods def rssify(options = {}) raise Rssify::Errors::InvalidOptions if options.has_key? :only and options.has_key? :except options.symbolize_keys!.reverse_merge! :enabled => true [:only, :except].each do |type| options[type] = [options[type]].flatten.collect {|k| k.to_sym } if options[type] end write_inheritable_hash(:rss_options, options) include Rssify::Controller::InstanceMethods end end module InstanceMethods #:nodoc: protected def render(options = nil, deprecated_status = nil, &block) return super if options.nil? and !performed? and !rss_can_parse_action return super if options and (options[:format] != :rss and options[:rss].nil?) old_options = options options ||= {} options.reverse_merge! :file => File.dirname(__FILE__) + '/rss.rxml', :use_full_path => false, :layout => false options[:model] = options[:rss] unless options[:rss].is_a? TrueClass rss_set_instance_vars(options) super end def rss_can_parse_action return false unless params[:format] == "rss" options = self.class.read_inheritable_attribute(:rss_options) if options.nil? or !options[:enabled] false elsif options[:only] and !options[:only].include? action_name.to_sym false elsif options[:except] and options[:except].include? action_name.to_sym false else true end end def rss_set_instance_vars(options = {}) rss_options = self.class.read_inheritable_attribute(:rss_options).dup.symbolize_keys rss_options.reverse_merge! :model => controller_name.pluralize.underscore, :title => action_name.gsub('_', ' ').titlecase, :link => url_for rss_options.merge! options.dup.delete_if {|k,v| !rss_options.has_key? k or v.nil? or v.empty? } if [String, Symbol].include? rss_options[:model].class rss_options[:model] = instance_variable_get("@#{rss_options[:model]}") end @rss_items, @rss_options = [rss_options[:model]].flatten.compact, {} raise Rssify::Errors::MissingModelData if @rss_items.empty? rss_options.delete_if {|k,v| [:except, :only, :model, :enabled].include? k } rss_options.each do |key, value| @rss_options[key] = instance_variable_set("@rss_#{key}", instance_variable_get("@rss_#{key}") || value) end end end end module Model #:nodoc: def self.included(mod) mod.extend(ClassMethods) end module ClassMethods def rssify(options = {}) options.symbolize_keys!.each do |key, value| if value.is_a? Proc define_method("#{key}_for_rss", value) else class_eval "def #{key}_for_rss(*args) send(:#{value}, *args) end" end end include Rssify::Model::InstanceMethods end end module InstanceMethods #:nodoc: def title_for_rss pick_responder(:title, :name) end def pubDate_for_rss pick_responder(:pubDate, :created_at, :created_on, :time, :date, :updated_at, :updated_on) end def description_for_rss pick_responder(:description, :desc, :body) end def link_for_rss pick_responder(:link, :url, :permalink) end protected def pick_responder(*methods) send(methods.find {|m| respond_to? m }) end end end module Errors #:nodoc: class InvalidOptions < Exception end class MissingModelData < Exception end end end