module Lolita
module Configuration
# Tab is used as a container for different type of resource content.
# It can contain fields, images, audio, video files, maps and other stuff.
# Tab contain following parts, that also are configurable through block or
# arguments passed to tab.
# * nested_fields_for Create fields for different DB table/collection than given.
# * field_set Create fields set for ease use in builders.
# * field Create field in tab, fields also can be included in #nested_fields_for and
# #field_set
# * default_fields
# To create new tab you should pass Lolita::DBI object and tab type, default is :content
# ====Example
# Lolita::Configuration::Tab.new(Lolita::DBI.new(Post),:images)
# To define tab in ORM model, through lolita configuration do the following
# ====Example
# lolita do
# tab(:files)
# end
module Tab
class Base
include Lolita::Builder
# For different types there are different builders(cells)
@@default_tab_type=:default
@@available_types=[:content]
lolita_accessor :title,:name,:type
attr_accessor :dbi,:current_fieldset, :current_nested_form,:current_dbi
attr_reader :field_sets,:nested_forms
# To create new tab the following parametrs need to be provided.
# * dbi Lolita::DBI::Base object, that represents database.
# * *args See #set_attributes, for how these args are processed.
# * &block Block can be passed, anything in block will be evaled for current instance.
def initialize dbi,*args,&block
@fields=Lolita::Configuration::Fields.new
@field_sets = []
@nested_forms = []
self.dbi=dbi
self.current_dbi=dbi
self.set_attributes(*args)
self.instance_eval(&block) if block_given?
validate
end
# Field setter method, accpet *args and &block to be passed.
# For details how to pass args and block see Lolita::Configuration::Field.
# Return field itself.
def field *args, &block
field=Lolita::Configuration::Field.add(self.current_dbi,*args,&block)
field.field_set = current_fieldset
if self.current_dbi!=self.dbi
field.nested_in=self.dbi
field.nested_form = current_nested_form
end
@fields << field
field
end
# Return all fields in tab.
def fields
@fields
end
# Set all fields in tab. Accept fields
as Array.
# Each array element can be Lolita::Configuration::Field object or
# Hash, that will be passed to #field method.
def fields=(fields)
@fields=Lolita::Configuration::Fields.new
if fields.is_a?(Array)
fields.each{|field_attr|
if field_attr.is_a?(Lolita::Configuration::Field)
@fields<class_or_name and &block
# that will be evaluted in current tab instance.
def nested_fields_for class_or_name, options ={},&block
current_class = get_class(class_or_name)
nested_form = Lolita::Configuration::NestedForm.new(self,class_or_name, options)
self.current_nested_form = nested_form
@nested_forms << nested_form
self.current_dbi = Lolita::DBI::Base.new(current_class)
self.instance_eval(&block)
self.current_dbi = self.dbi
self.current_nested_form = nil
end
# Return nested field for given class_or_name
def nested_fields_of class_or_name
current_class=get_class(class_or_name)
self.fields.select{|field|
field.nested_in?(@dbi) && field.dbi.klass==current_class
}
end
# Create new field_set for current tab with given _name_ and &block
# that will be evaluted in current tab instance.
def field_set name,&block
field_set=Lolita::Configuration::FieldSet.new(self,name)
self.current_fieldset = field_set
@field_sets << field_set
self.instance_eval(&block)
self.current_fieldset=nil
end
def fields_with_field_set
used_fieldsets=[]
self.fields.each{|field|
if !field.field_set || (!used_fieldsets.include?(field.field_set))
if field.field_set
yield field.field_set.fields,field.field_set
used_fieldsets<*args.
# First element of args is used as type other interpreted as options.
# Every Hash key is used as setter method, and value as method value.
# ====Example
# set_attributes(:content,:field=>{:name=>"My Field"})
# set_attributes(:field=>{:name=>"My Field"})
def set_attributes *args
if args
options=args.extract_options!
self.type=args.first if args.first.is_a?(Symbol)
options.each{|method,options|
self.send(:"#{method}=",options)
}
end
end
private
def set_default_attributes
@type=@@default_tab_type unless @type
@name="tab_#{self.__id__}" unless @name
@title=set_default_title unless @title
end
def set_default_title
if defined?(::I18n)
::I18n.translate("lolita.tabs.titles.#{@type}")
else
@type.to_s.humanize
end
end
def get_class(association_name)
if association_name.is_a?(Symbol) && assoc = self.current_dbi.reflect_on_association(association_name)
assoc.klass
else
raise ArgumentError, "Association named `#{association_name}` not found for #{self.current_dbi.klass}."
end
end
def validate
set_default_attributes
end
def builder_local_variable_name
:tab
end
class << self
def default_types
@@available_types
end
end
end
end
end
end