require 'kaminari'
require 'orm_adapter'
require 'puffer/orm_adapter/base'
require 'puffer/orm_adapter/active_record' if defined?(ActiveRecord::Base::OrmAdapter)
require 'puffer/orm_adapter/mongoid' if defined?(Mongoid::Document::OrmAdapter)
#require 'puffer/orm_adapter/data_mapper' if defined?(DataMapper::Resource::OrmAdapter)
#require 'puffer/orm_adapter/mongo_mapper' if defined?(MongoMapper::Document::OrmAdapter)
require 'puffer/extensions/controller'
require 'puffer/extensions/core'
require 'puffer/extensions/mapper'
require 'puffer/extensions/form'
require 'puffer/extensions/directive_processor'
require 'puffer/extensions/engine'
require 'puffer/engine'
module Puffer
class PufferError < StandardError
end
class ComponentMissing < PufferError
end
module Controller
autoload :Action, 'puffer/controller/actions'
autoload :MemberAction, 'puffer/controller/actions'
autoload :CollectionAction, 'puffer/controller/actions'
end
module Component
autoload :Base, 'puffer/component'
end
# Puffer has two types of mappings. If maps field.type to component
# class and also maps field attributes to field.type
mattr_accessor :_component_mappings
self._component_mappings = {}
# Maps field.type to component class
#
# ex:
#
# Puffer.map_component :ckeditor, :rich, :text, :to => CkeditorComponent
#
# this declaration maps even text fields to use CkeditorComponent for
# rendering
def self.map_component *args
to = args.extract_options![:to]
args.each { |type| _component_mappings[type.to_sym] = to }
end
def self.component_for field
type = field
type = field.type if field.respond_to? :type
(_component_mappings[type.to_sym] || "#{type}_component").to_s.camelize.constantize
rescue NameError
raise ComponentMissing, "Missing `#{type}` component for `#{field}` field. Please use Puffer.map_component binding or specify field type manually"
end
map_component :belongs_to, :has_one, :to => :ReferencesOneComponent
map_component :has_many, :has_and_belongs_to_many, :to => :ReferencesManyComponent
map_component :date, :time, :datetime, :date_time, :timestamp, :to => :DateTimeComponent
map_component :integer, :float, :decimal, :big_decimal, :to => :StringComponent
map_component :"mongoid/fields/serializable/object", :"bson/object_id", :symbol, :array, :hash, :set, :range, :to => :StringComponent
mattr_accessor :_field_type_customs
self._field_type_customs = []
# Appends or prepends custom type.
#
# ex:
#
# Puffer.append_custom_field_type :paperclip do |field|
# field.model.respond_to?(:attachment_definitions)
# && field.model.attachment_definitions.key?(:field.field_name.to_sym)
# end
def self.prepend_custom_field_type custom_type, &block
_field_type_customs.shift [custom_type, block]
end
def self.append_custom_field_type custom_type, &block
_field_type_customs.push [custom_type, block]
end
def self.field_type_for field
custom_type = swallow_nil{_field_type_customs.detect {|(type, block)| block.call(field) }.first}
case custom_type
when Proc then
custom_type.call(field)
else
custom_type
end
end
append_custom_field_type :select do |field|
field.options.key? :select
end
append_custom_field_type :password do |field|
field.name =~ /password/
end
append_custom_field_type(proc {|type| type.reflection.macro}) do |field|
field.reflection
end
end