module Lolita module SystemConfiguration class Base attr_reader :scope, :modules, :routes, :controllers,:resources attr_accessor :mappings,:default_route,:user_classes,:authentication attr_writer :default_locale def initialize(scope) @scope=scope @mappings={} @resources={} @default_module=nil @user_classes=[] @modules=[] @routes={} @controllers={} end def application &block @application ||= Lolita::SystemConfiguration::Application.new if block_given? yield @application end @application end def navigation @navigation||=Lolita::Navigation::Base.new() @navigation end def locales=(value) unless value.is_a?(Array) @locales=[value] else @locales=value end end def locales @locales || [] end def locale() @locale || default_locale end def locale=given_locale @locale=if locales.include?(given_locale.to_s.to_sym) given_locale.to_s.to_sym else Lolita.default_locale end end # Return default locale. First looks for defined default locale for Lolita, when not found than # take first of defined #locales for Lolita, if there no defined locales for Lolita, than # look for I18n and take default locale from there or if there is no I18n than take :en def default_locale @default_locale || self.locales.first || (defined?(::I18n) ? ::I18n.default_locale : :en) end # Call (with #call) to route klass # And return all names of routes that are needed for resource. # When with #add_module routes are defined like # Lolita.add_module MyModule, :route=>:my_module # then this will be passed to the method that creates routes, but # when Proc is passed to :route then this Proc should return # name of route or nil. # These names then are used for methods like lolita_[route_name]_route # that should be required somewhere in you module. def conditional_routes(klass=nil) @routes.map{|name,route| if route.first if route.last.respond_to?(:call) route.last.call(klass) else route.last end end }.compact end # Find all routes that is needed for defined classes # And return only one for each different route. def common_routes(klasses) @routes.map{|name,route| unless route.first klasses.map{|klass| route.last.respond_to?(:call) ? route.last.call(klass) : route.last} end }.flatten.compact.uniq end # Include module in Lolita, don't know why i need this def use(module_name) Lolita.send(:include,module_name) end def add_mapping(resource,options={}) mapping = Lolita::Mapping.new(resource, options) self.mappings[mapping.name] = mapping mapping end # Add new module to Lolita # Accpted options # * controller - not in use # * nested - is route stands itsefl or is used in combination with resource # * route - Symbol of route name or lambad, that return route name based on resource. # Route name is used to call method lolita_[route_name] in Mapper class, and that should draw route. # * :name - name of module, underscored symbol. Used to draw default route, by default always # lolita_rest is called, but if route with resource name is found, than by default this route will be drawn. # Like lolita_for :posts, can go to different controller than rest and do other things. # * :path - some file that will be included. Deprecated will be removed # ====Example # Lolita.add_module Lolita::Posts, :route=>:post, :name=>:post # lolita_for :posts #=> create url whatever is defined in lolita_post method, and goes to :controller=>"lolita/posts" # Lolita.add_module Lolita::FileUpload, :route=>lambda{|resource| resource.lolita.tabs.by_type(:file) ? :file_upload : nil} # lolita_for :users #=> creat default rest urls and also call method lolita_file_upload if user lolita define :file tab. # To add route for public interface that goes to added module, than use # Lolita.add_module Post, :name=>:posts # And then when in routes.rb will be defined lolita_for(:posts) it will call method lolita_posts_route # and that method should define resource. # ====Example # # require this in your gem or lib # module ActionDispatch::Routing # class Mapper # protected # def lolita_posts_route mapping, controllers # resources mapping.plural,:only=>[:index,:new,:create], # :controller=>controllers[:posts],:module=>mapping.module # end # end # end # You open Mapper class and add your method that call #resources or #match or other method that define route # For common route for all lolita resources your method should look like this # ====Example # def lolita_files_route # mapping=Lolita.add_mapping(:files,:class_name=>"Lolita::Multimedia::File",:module=>"file_upload") # scope :module=>mapping.module do # resources mapping.name # end # end def add_module module_container, options={} raise ArgumentError, "Can't add module without module container!" unless module_container options.assert_valid_keys(:controller,:route,:model,:path,:name,:nested) name=options[:name]||module_container.to_s.to_sym self.modules<