Skip to content

Instantly share code, notes, and snippets.

@mikehale
Created June 12, 2009 03:02
Show Gist options
  • Select an option

  • Save mikehale/128404 to your computer and use it in GitHub Desktop.

Select an option

Save mikehale/128404 to your computer and use it in GitHub Desktop.
require 'radiant/extension'
require 'method_observer'
module Radiant
class ExtensionLoader
class DependenciesObserver < MethodObserver
attr_accessor :config
def initialize(rails_config)
@config = rails_config
end
def before_clear(*args)
ExtensionLoader.deactivate_extensions
end
def after_clear(*args)
ExtensionLoader.load_extensions
ExtensionLoader.activate_extensions
end
end
include Simpleton
attr_accessor :initializer, :extensions
def initialize
self.extensions = []
end
def configuration
initializer.configuration
end
def extension_load_paths
load_extension_roots.map { |extension| load_paths_for(extension) }.flatten.select { |d| File.directory?(d) }
end
def plugin_paths
load_extension_roots.map {|extension| "#{extension}/vendor/plugins" }.select {|d| File.directory?(d) }
end
def add_extension_paths
extension_load_paths.reverse_each do |path|
configuration.load_paths.unshift path
$LOAD_PATH.unshift path
end
end
def add_plugin_paths
configuration.plugin_paths.concat plugin_paths
end
def controller_paths
extensions.map { |extension| "#{extension.root}/app/controllers" }.select { |d| File.directory?(d) }
end
def add_controller_paths
configuration.controller_paths.concat(controller_paths)
end
def view_paths
extensions.map { |extension| "#{extension.root}/app/views" }.select { |d| File.directory?(d) }
end
# Load the extensions
def load_extensions
@observer ||= DependenciesObserver.new(configuration).observe(::ActiveSupport::Dependencies)
self.extensions = load_extension_roots.map do |root|
begin
File.basename(root) =~ /^radiant-(.+)-extension-.+$/
if root_name = $1
extension_file = "#{root_name.sub(/^\d+_/,'')}_extension"
else
extension_file = "#{File.basename(root).sub(/^\d+_/,'')}_extension"
end
extension = extension_file.camelize.constantize
extension.unloadable
extension.root = root
extension
rescue LoadError, NameError => e
$stderr.puts "Could not load extension from file: #{extension_file}.\n#{e.inspect}"
nil
end
end.compact
end
def deactivate_extensions
extensions.each &:deactivate
end
def activate_extensions
initializer.initialize_default_admin_tabs
# Reset the view paths after
initializer.initialize_framework_views
# Reset the admin UI regions
initializer.admin.load_default_regions
extensions.each &:activate
# Make sure we have our subclasses loaded!
Page.load_subclasses
end
alias :reactivate :activate_extensions
private
def load_paths_for(dir)
if File.directory?(dir)
%w(lib app/models app/controllers app/helpers test/helpers).collect do |p|
path = "#{dir}/#{p}"
path if File.directory?(path)
end.compact << dir
else
[]
end
end
def load_extension_roots
@load_extension_roots ||= unless configuration.extensions.empty?
select_extension_roots + gem_extension_roots
else
[]
end
end
def gem_extension_roots
require 'rubygems'
Gem.all_load_paths.map {|path| path.gsub(/lib$/, '') }.select do |path|
File.basename(path) =~ /^radiant-(.+)-extension-.+$/
true if $1
end
end
def select_extension_roots
all_roots = all_extension_roots.dup
roots = configuration.extensions.map do |ext_name|
if :all === ext_name
:all
else
ext_path = all_roots.detect do |maybe_path|
File.basename(maybe_path).sub(/^\d+_/, '') == ext_name.to_s
end
raise LoadError, "Cannot find the extension '#{ext_name}'!" if ext_path.nil?
all_roots.delete(ext_path)
end
end
if placeholder = roots.index(:all)
# replace the :all symbol with any remaining paths
roots[placeholder, 1] = all_roots
end
roots
end
def all_extension_roots
@all_extension_roots ||= configuration.extension_paths.map do |path|
Dir["#{path}/*"].map {|f| File.expand_path(f) if File.directory?(f) }.compact.sort
end.flatten
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment