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.reverse_merge!(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