module Sidebars class Field attr_accessor :key attr_accessor :options include ApplicationHelper include ActionView::Helpers::TagHelper include ActionView::Helpers::FormTagHelper include ActionView::Helpers::FormOptionsHelper def initialize(key = nil, options = { }) @key, @options = key.to_s, options end def label_html(sidebar) content_tag('label', options[:label] || key.humanize.gsub(/url/i, 'URL')) end def input_html(sidebar) text_field_tag(input_name(sidebar), sidebar.config[key], options) end def line_html(sidebar) label_html(sidebar) + "
" + input_html(sidebar) + "
" end def input_name(sidebar) "configure[#{sidebar.id}][#{key}]" end class SelectField < self def input_html(sidebar) select_tag(input_name(sidebar), options_for_select(options[:choices], sidebar.config[key]), options) end end class TextAreaField < self def input_html(sidebar) html_options = { "rows" => "10", "cols" => "30", "style" => "width:255px"}.update(options.stringify_keys) text_area_tag(input_name(sidebar), h(sidebar.config[key]), html_options) end end class RadioField < self def input_html(sidebar) options[:choices].collect do |choice| value = value_for(choice) radio_button_tag(input_name(sidebar), value, value == sidebar.config[key], options) + content_tag('label', label_for(choice)) end.join("
") end def label_for(choice) choice.is_a?(Array) ? choice.last : choice.to_s.humanize end def value_for(choice) choice.is_a?(Array) ? choice.first : choice end end class CheckBoxField < self def input_html(sidebar) check_box_tag(input_name(sidebar), 1, sidebar.config[key], options)+ hidden_field_tag(input_name(sidebar),0) end def line_html(sidebar) input_html(sidebar) + ' ' + label_html(sidebar) + '
' end end def self.build(key, options) field = class_for(options).new(key, options) end def self.class_for(options) case options[:input_type] when :text_area TextAreaField when :textarea TextAreaField when :radio RadioField when :checkbox CheckBoxField when :select SelectField else if options[:choices] SelectField else self end end end end class Sidebars::Plugin < ApplicationController include ApplicationHelper helper :theme @@subclasses = { } class << self def inherited(child) @@subclasses[self] ||= [] @@subclasses[self] |= [child] super end def subclasses @@subclasses[self] ||= [] @@subclasses[self] + extra = @@subclasses[self].inject([]) {|list, subclass| list | subclass.subclasses } end def available_sidebars Sidebars::Plugin.subclasses.select do |sidebar| sidebar.concrete? end end def concrete? self.to_s !~ /^Sidebars::(Co(mponent|nsolidated))?Plugin/ end # The name that's stored in the DB. This is the final chunk of the # controller name, like 'xml' or 'flickr'. def short_name self.to_s.underscore.split(%r{/}).last end @@display_name_of = { } @@description_of = { } # The name that shows up in the UI def display_name(new_dn = nil) # This is the default, but it's best to override it self.display_name = new_dn if new_dn @@display_name_of[self] || short_name.humanize end def display_name=(name) @@display_name_of[self] = name end def description(new_desc = nil) self.description = new_desc if new_desc @@description_of[self] || short_name.humanize end def description=(desc) @@description_of[self] = desc end @@fields = { } @@default_config = { } def setting(key, default=nil, options={ }) fields << Field.build(key, options) default_config[key.to_s] = default self.send(:define_method, key) do @sb_config[key.to_s] end self.helper_method(key) end def default_config @@default_config[self] ||= HashWithIndifferentAccess.new end def default_config=(newval) @@default_config[self] = newval end def fields @@fields[self] ||= [] end def fields=(newval) @@fields[self] = newval end def default_helper_module! end end def index @sidebar=params['sidebar'] set_config @sb_config = @sidebar.config content render :action=>'content' unless performed? end def configure_wrapper @sidebar=params['sidebar'] set_config configure render :action=>'configure' unless performed? end # This controller is used on to actually display sidebar items. def content end # This controller is used to configure the sidebar from /admin/sidebar def configure render :partial => 'sidebar/row', :collection => self.class.fields end private def set_config @sidebar.config ||= {} @sidebar.config = self.class.default_config.dup.merge(@sidebar.config) @sidebar.config ||= (self.class.default_config) end def sb_config(key) config = @sidebar.class.default_config config.merge!(@sidebar.config || {}) config[key.to_s] end # Horrid hack to make check_cache happy def controller self end def log_processing logger.info "\n\nProcessing #{controller_class_name}\##{action_name} (for #{request_origin})" end end end