Chris@909: # An instance of Plugin is created for each plugin loaded by Rails, and
Chris@909: # stored in the Engines.plugins PluginList
Chris@909: # (see Engines::RailsExtensions::RailsInitializer for more details).
Chris@909: #
Chris@909: # Engines.plugins[:plugin_name]
Chris@909: #
Chris@909: # Other properties of the Plugin instance can also be set.
Chris@909: module Engines
Chris@909: class Plugin < Rails::Plugin
Chris@909: # Plugins can add paths to this attribute in init.rb if they need
Chris@909: # controllers loaded from additional locations.
Chris@909: attr_accessor :controller_paths
Chris@909:
Chris@909: # The directory in this plugin to mirror into the shared directory
Chris@909: # under +public+.
Chris@909: #
Chris@909: # Defaults to "assets" (see default_public_directory).
Chris@909: attr_accessor :public_directory
Chris@909:
Chris@909: protected
Chris@909: # The default set of code paths which will be added to the routing system
Chris@909: def default_controller_paths
Chris@909: %w(app/controllers components)
Chris@909: end
Chris@909:
Chris@909: # Attempts to detect the directory to use for public files.
Chris@909: # If +assets+ exists in the plugin, this will be used. If +assets+ is missing
Chris@909: # but +public+ is found, +public+ will be used.
Chris@909: def default_public_directory
Chris@909: Engines.select_existing_paths(%w(assets public).map { |p| File.join(directory, p) }).first
Chris@909: end
Chris@909:
Chris@909: public
Chris@909:
Chris@909: def initialize(directory)
Chris@909: super directory
Chris@909: @controller_paths = default_controller_paths
Chris@909: @public_directory = default_public_directory
Chris@909: end
Chris@909:
Chris@909: # Extends the superclass' load method to additionally mirror public assets
Chris@909: def load(initializer)
Chris@909: return if loaded?
Chris@909: super initializer
Chris@909: add_plugin_locale_paths
Chris@909: Assets.mirror_files_for(self)
Chris@909: end
Chris@909:
Chris@909: # select those paths that actually exist in the plugin's directory
Chris@909: def select_existing_paths(name)
Chris@909: Engines.select_existing_paths(self.send(name).map { |p| File.join(directory, p) })
Chris@909: end
Chris@909:
Chris@909: def add_plugin_locale_paths
Chris@909: locale_path = File.join(directory, 'locales')
Chris@909: return unless File.exists?(locale_path)
Chris@909:
Chris@909: locale_files = Dir[File.join(locale_path, '*.{rb,yml}')]
Chris@909: return if locale_files.blank?
Chris@909:
Chris@909: first_app_element =
Chris@909: I18n.load_path.select{ |e| e =~ /^#{ RAILS_ROOT }/ }.reject{ |e| e =~ /^#{ RAILS_ROOT }\/vendor\/plugins/ }.first
Chris@909: app_index = I18n.load_path.index(first_app_element) || - 1
Chris@909:
Chris@909: I18n.load_path.insert(app_index, *locale_files)
Chris@909: end
Chris@909:
Chris@909: # The path to this plugin's public files
Chris@909: def public_asset_directory
Chris@909: "#{File.basename(Engines.public_directory)}/#{name}"
Chris@909: end
Chris@909:
Chris@909: # The directory containing this plugin's migrations (plugin/db/migrate)
Chris@909: def migration_directory
Chris@909: File.join(self.directory, 'db', 'migrate')
Chris@909: end
Chris@909:
Chris@909: # Returns the version number of the latest migration for this plugin. Returns
Chris@909: # nil if this plugin has no migrations.
Chris@909: def latest_migration
Chris@909: migrations.last
Chris@909: end
Chris@909:
Chris@909: # Returns the version numbers of all migrations for this plugin.
Chris@909: def migrations
Chris@909: migrations = Dir[migration_directory+"/*.rb"]
Chris@909: migrations.map { |p| File.basename(p).match(/0*(\d+)\_/)[1].to_i }.sort
Chris@909: end
Chris@909:
Chris@909: # Migrate this plugin to the given version. See Engines::Plugin::Migrator for more
Chris@909: # information.
Chris@909: def migrate(version = nil)
Chris@909: Engines::Plugin::Migrator.migrate_plugin(self, version)
Chris@909: end
Chris@909: end
Chris@909: end
Chris@909: