module TrustyCms autoload :Cache, 'rack/cache' class << self # Returns the TrustyCms::Config eigenclass object, so it can be used wherever you would use TrustyCms::Config. # # TrustyCms.config['site.title'] # TrustyCms.config['site.url'] = 'example.com' # # but it will also yield itself to a block: # # TrustyCms.config do |config| # config.define 'something', default => 'something' # config['other.thing'] = 'nothing' # end # def config # method must be defined before any initializers run yield TrustyCms::Config if block_given? TrustyCms::Config end # Returns the configuration object with which this application was initialized. # For now it's exactly the same as calling Rails.configuration except that it will also yield itself to a block. # def configuration yield Rails.configuration if block_given? Rails.configuration end # Returns the root directory of this installation (which is usually the gem directory). # This is not the same as Rails.root, which is the instance directory and tends to contain only site-delivery material. # def root Pathname.new(TRUSTY_CMS_ROOT) if defined?(TRUSTY_CMS_ROOT) end def boot! unless booted? preinitialize pick_boot.run end end def booted? defined? TrustyCms::Initializer end def pick_boot case when app? AppBoot.new when vendor? VendorBoot.new else GemBoot.new end end def vendor? File.exist?("#{Rails.root}/vendor/trusty") end def app? File.exist?("#{Rails.root}/lib/trusty_cms.rb") end def preinitialize load(preinitializer_path) if File.exist?(preinitializer_path) end def loaded_via_gem? pick_boot.is_a? GemBoot end def preinitializer_path "#{Rails.root}/config/preinitializer.rb" end end end class Rails::Application::Configuration # The TrustyCms::Configuration class extends Rails::Configuration with three purposes: # * to reset some rails defaults so that files are found in TRUSTY_CMS_ROOT instead of Rails.root # * to notice that some gems and plugins are in fact trusty extensions # * to notice that some trusty extensions add load paths (for plugins, controllers, metal, etc) attr_accessor :extension_paths, :ignored_extensions def initialize_extension_paths self.extension_paths = default_extension_paths self.ignored_extensions = [] end # Sets the locations in which we look for vendored extensions. Normally: # Rails.root/vendor/extensions # TrustyCms.root/vendor/extensions # There are no vendor/* directories in +TRUSTY_CMS_ROOT+ any more but the possibility remains for compatibility reasons. # In test mode we also add a fixtures path for testing the extension loader. # def default_extension_paths env = ENV["RAILS_ENV"] || Rails.env paths = [Rails.root + 'vendor/extensions'] paths.unshift(TRUSTY_CMS_ROOT + "/vendor/extensions") unless Rails.root == TRUSTY_CMS_ROOT paths.unshift(TRUSTY_CMS_ROOT + "test/fixtures/extensions") if env =~ /test/ paths end # The list of extensions, expanded and in load order, that results from combining all the extension # configuration directives. These are the extensions that will actually be loaded or migrated, # and for most purposes this is the list you want to refer to. # # TrustyCms.configuration.enabled_extensions # => [:name, :name, :name, :name] # # Note that an extension enabled is not the same as an extension activated or even loaded: it just means # that the application is configured to load that extension. # def enabled_extensions @enabled_extensions ||= expanded_extension_list - ignored_extensions end # The expanded and ordered list of extensions, including any that may later be ignored. This can be configured # (it is here that the :all entry is expanded to mean 'everything else'), or will default to an alphabetical list # of every extension found among gems and vendor/extensions directories. # # TrustyCms.configuration.expanded_extension_list # => [:name, :name, :name, :name] # # If an extension in the configurted list is not found, a LoadError will be thrown from here. # def expanded_extension_list # NB. it should remain possible to say config.extensions = [] @extension_list ||= extensions ? expand_and_check(extensions) : available_extensions end def expand_and_check(extension_list) #:nodoc missing_extensions = extension_list - [:all] - available_extensions raise LoadError, "These configured extensions have not been found: #{missing_extensions.to_sentence}" if missing_extensions.any? if m = extension_list.index(:all) extension_list[m] = available_extensions - extension_list end extension_list.flatten end # Returns the checked and expanded list of extensions-to-enable. This may be derived from a list passed to # +config.extensions=+ or it may have defaulted to all available extensions. # Without such a call, we default to the alphabetical list of all well-formed vendor and gem extensions # returned by +available_extensions+. # # TrustyCms.configuration.extensions # => [:name, :all, :name] # def extensions @requested_extensions ||= available_extensions end # Sets the list of extensions that will be loaded and the order in which to load them. # It can include an :all marker to mean 'everything else' and is typically set in environment.rb: # config.extensions = [:layouts, :taggable, :all] # config.extensions = [:dashboard, :blog, :all] # config.extensions = [:dashboard, :blog, :all, :comments] # # A LoadError is raised if any of the specified extensions can't be found. # def extensions=(extensions) @requested_extensions = extensions end # This is a configurable list of extension that should not be loaded. # config.ignore_extensions = [:experimental, :broken] # You can also retrieve the list with +ignored_extensions+: # TrustyCms.configuration.ignored_extensions # => [:experimental, :broken] # These exclusions are applied regardless of dependencies and extension locations. A configuration that bundles # required extensions then ignores them will not boot and is likely to fail with errors about unitialized constants. # def ignore_extensions(array) self.ignored_extensions |= array end # Returns an alphabetical list of every extension found among all the load paths and bundled gems. Any plugin or # gem whose path ends in the form +trusty-something-extension+ is considered to be an extension. # # TrustyCms.configuration.available_extensions # => [:name, :name, :name, :name] # # This method is always called during initialization, either as a default or to check that specified extensions are # available. One of its side effects is to populate the ExtensionLoader's list of extension root locations, later # used when activating those extensions that have been enabled. # def available_extensions @available_extensions ||= (vendored_extensions + gem_extensions).uniq.sort.map(&:to_sym) end # Searches the defined extension_paths for subdirectories and returns a list of names as symbols. # # TrustyCms.configuration.vendored_extensions # => [:name, :name] # def vendored_extensions extension_paths.each_with_object([]) do |load_path, found| Dir["#{load_path}/*"].each do |path| if File.directory?(path) ep = TrustyCms::ExtensionLoader.record_path(path) found << ep.name end end end end # Scans the bundled gems for any whose name match the +trusty-something-extension+ format # and returns a list of their names as symbols. # # TrustyCms.configuration.gem_extensions # => [:name, :name] # def gem_extensions Gem.loaded_specs.each_with_object([]) do |(gemname, gemspec), found| if gemname =~ /trusty-.*-extension$/ ep = TrustyCms::ExtensionLoader.record_path(gemspec.full_gem_path, gemname) found << ep.name end end end # Old extension-dependency mechanism now deprecated # def extension(ext) ::ActiveSupport::Deprecation.warn("Extension dependencies have been deprecated and are no longer supported in trusty 1.0. Extensions with dependencies should be packaged as gems and use the .gemspec to declare them.", caller) end # Old gem-invogation method now deprecated # def gem(name, options = {}) ::ActiveSupport::Deprecation.warn("Please declare gem dependencies in your Gemfile (or for an extension, in the .gemspec file).", caller) super end # Returns the AdminUI singleton, giving get-and-set access to the tabs and partial-sets it defines. # More commonly accessed in the initializer via its call to +configuration.admin+. # def admin TrustyCms::AdminUI.instance end private # Overrides the Rails::Initializer default to add plugin paths in TRUSTY_CMS_ROOT as well as Rails.root. # def default_plugin_paths super + ["#{TRUSTY_CMS_ROOT}/lib/plugins", "#{TRUSTY_CMS_ROOT}/vendor/plugins"] end # Overrides the Rails::Initializer default to look for views in TRUSTY_CMS_ROOT rather than Rails.root. # def default_view_path File.join(TRUSTY_CMS_ROOT, 'app', 'views') end # Overrides the Rails::Initializer default to look for controllers in TRUSTY_CMS_ROOT rather than Rails.root. # def default_controller_paths [File.join(TRUSTY_CMS_ROOT, 'app', 'controllers')] end end class Boot def run load_mutex load_initializer end # RubyGems from version 1.6 does not require thread but Rails depend on it # This should newer rails do automaticly def load_mutex begin require "thread" unless defined?(Mutex) rescue LoadError => _ $stderr.puts %(Mutex could not be initialized. #{load_error_message}) exit 1 end end def load_initializer begin require 'trusty_cms' require 'trusty_cms/initializer' rescue LoadError => _ $stderr.puts %(TrustyCms could not be initialized. #{load_error_message}) exit 1 end TrustyCms::Initializer.run(:set_load_path) TrustyCms::Initializer.run(:install_gem_spec_stubs) Rails::GemDependency.add_frozen_gem_path end end class VendorBoot < Boot def load_initializer $LOAD_PATH.unshift "#{Rails.root}/vendor/trusty_cms/lib" super end def load_error_message "Please verify that vendor/trusty contains a complete copy of the TrustyCms sources." end end class AppBoot < Boot def load_initializer $LOAD_PATH.unshift "#{Rails.root}/lib" super end def load_error_message "Please verify that you have a complete copy of the TrustyCms sources." end end class GemBoot < Boot # The location and version of the trusty gem should be set in your Gemfile def load_error_message "Have you run `bundle install`?'." end end