| CODENOTIFIER | HelpYou are not signed inSign in |
Project: Redmine
Revision: 1775
Author: jplang
Date: 30 Aug 2008 10:42:56
Changes:Added missing plugins.
Files:| ... | ...@@ -0,0 +1,18 @@ | |
| 1 | module Engines | |
| 2 | class Plugin | |
| 3 | class Loader < Rails::Plugin::Loader | |
| 4 | protected | |
| 5 | def register_plugin_as_loaded(plugin) | |
| 6 | super plugin | |
| 7 | Engines.plugins << plugin | |
| 8 | register_to_routing(plugin) | |
| 9 | end | |
| 10 | ||
| 11 | # Registers the plugin's controller_paths for the routing system. | |
| 12 | def register_to_routing(plugin) | |
| 13 | initializer.configuration.controller_paths += plugin.select_existing_paths(:controller_paths) | |
| 14 | initializer.configuration.controller_paths.uniq! | |
| 15 | end | |
| 16 | end | |
| 17 | end | |
| 18 | end | |
| 0 | 19 | \ No newline at end of file |
| ... | ...@@ -0,0 +1,5 @@ | |
| 1 | # Only call Engines.init once, in the after_initialize block so that Rails | |
| 2 | # plugin reloading works when turned on | |
| 3 | config.after_initialize do | |
| 4 | Engines.init if defined? :Engines | |
| 5 | end |
| ... | ...@@ -0,0 +1,161 @@ | |
| 1 | # Contains the enhancements to Rails' migrations system to support the | |
| 2 | # Engines::Plugin::Migrator. See Engines::RailsExtensions::Migrations for more | |
| 3 | # information. | |
| 4 | ||
| 5 | require "engines/plugin/migrator" | |
| 6 | ||
| 7 | # = Plugins and Migrations: Background | |
| 8 | # | |
| 9 | # Rails uses migrations to describe changes to the databases as your application | |
| 10 | # evolves. Each change to your application - adding and removing models, most | |
| 11 | # commonly - might require tweaks to your schema in the form of new tables, or new | |
| 12 | # columns on existing tables, or possibly the removal of tables or columns. Migrations | |
| 13 | # can even include arbitrary code to *transform* data as the underlying schema | |
| 14 | # changes. | |
| 15 | # | |
| 16 | # The point is that at any particular stage in your application's development, | |
| 17 | # migrations serve to transform the database into a state where it is compatible | |
| 18 | # and appropriate at that time. | |
| 19 | # | |
| 20 | # == What about plugins? | |
| 21 | # | |
| 22 | # If you want to share models using plugins, chances are that you might also | |
| 23 | # want to include the corresponding migrations to create tables for those models. | |
| 24 | # With the engines plugin installed, plugins can carry migration data easily: | |
| 25 | # | |
| 26 | # vendor/ | |
| 27 | # | | |
| 28 | # plugins/ | |
| 29 | # | | |
| 30 | # my_plugin/ | |
| 31 | # |- init.rb | |
| 32 | # |- lib/ | |
| 33 | # |- db/ | |
| 34 | # |-migrate/ | |
| 35 | # |- 001_do_something.rb | |
| 36 | # |- 002_and_something_else.rb | |
| 37 | # |- ... | |
| 38 | # | |
| 39 | # When you install a plugin which contains migrations, you are undertaking a | |
| 40 | # further step in the development of your application, the same as the addition | |
| 41 | # of any other code. With this in mind, you may want to 'roll back' the | |
| 42 | # installation of this plugin at some point, and the database should be able | |
| 43 | # to migrate back to the point without this plugin in it too. | |
| 44 | # | |
| 45 | # == An example | |
| 46 | # | |
| 47 | # For example, our current application is at version 14 (according to the | |
| 48 | # +schema_info+ table), when we decide that we want to add a tagging plugin. The | |
| 49 | # tagging plugin chosen includes migrations to create the tables it requires | |
| 50 | # (say, _tags_ and _taggings_, for instance), along with the models and helpers | |
| 51 | # one might expect. | |
| 52 | # | |
| 53 | # After installing this plugin, these tables should be created in our database. | |
| 54 | # Rather than running the migrations directly from the plugin, they should be | |
| 55 | # integrated into our main migration stream in order to accurately reflect the | |
| 56 | # state of our application's database *at this moment in time*. | |
| 57 | # | |
| 58 | # $ script/generate plugin_migration | |
| 59 | # exists db/migrate | |
| 60 | # create db/migrate/015_migrate_tagging_plugin_to_version_3.rb | |
| 61 | # | |
| 62 | # This migration will take our application to version 15, and contains the following, | |
| 63 | # typical migration code: | |
| 64 | # | |
| 65 | # class MigrateTaggingPluginToVersion3 < ActiveRecord::Migration | |
| 66 | # def self.up | |
| 67 | # Engines.plugins[:tagging].migrate(3) | |
| 68 | # end | |
| 69 | # def self.down | |
| 70 | # Engines.plugins[:tagging].migrate(0) | |
| 71 | # end | |
| 72 | # end | |
| 73 | # | |
| 74 | # When we migrate our application up, using <tt>rake db:migrate</tt> as normal, | |
| 75 | # the plugin will be migrated up to its latest version (3 in this example). If we | |
| 76 | # ever decide to migrate the application back to the state it was in at version 14, | |
| 77 | # the plugin migrations will be taken back down to version 0 (which, typically, | |
| 78 | # would remove all tables the plugin migrations define). | |
| 79 | # | |
| 80 | # == Upgrading plugins | |
| 81 | # | |
| 82 | # It might happen that later in an application's life, we update to a new version of | |
| 83 | # the tagging plugin which requires some changes to our database. The tagging plugin | |
| 84 | # provides these changes in the form of its own migrations. | |
| 85 | # | |
| 86 | # In this case, we just need to re-run the plugin_migration generator to create a | |
| 87 | # new migration from the current revision to the newest one: | |
| 88 | # | |
| 89 | # $ script/generate plugin_migration | |
| 90 | # exists db/migrate | |
| 91 | # create db/migrate/023_migrate_tagging_plugin_to_version_5.rb | |
| 92 | # | |
| 93 | # The contents of this migration are: | |
| 94 | # | |
| 95 | # class MigrateTaggingPluginToVersion3 < ActiveRecord::Migration | |
| 96 | # def self.up | |
| 97 | # Engines.plugins[:tagging].migrate(5) | |
| 98 | # end | |
| 99 | # def self.down | |
| 100 | # Engines.plugins[:tagging].migrate(3) | |
| 101 | # end | |
| 102 | # end | |
| 103 | # | |
| 104 | # Notice that if we were to migrate down to revision 22 or lower, the tagging plugin | |
| 105 | # will be migrated back down to version 3 - the version we were previously at. | |
| 106 | # | |
| 107 | # | |
| 108 | # = Creating migrations in plugins | |
| 109 | # | |
| 110 | # In order to use the plugin migration functionality that engines provides, a plugin | |
| 111 | # only needs to provide regular migrations in a <tt>db/migrate</tt> folder within it. | |
| 112 | # | |
| 113 | # = Explicitly migrating plugins | |
| 114 | # | |
| 115 | # It's possible to migrate plugins within your own migrations, or any other code. | |
| 116 | # Simply get the Plugin instance, and its Plugin#migrate method with the version | |
| 117 | # you wish to end up at: | |
| 118 | # | |
| 119 | # Engines.plugins[:whatever].migrate(version) | |
| 120 | # | |
| 121 | # --- | |
| 122 | # | |
| 123 | # The Engines::RailsExtensions::Migrations module defines extensions for Rails' | |
| 124 | # migration systems. Specifically: | |
| 125 | # | |
| 126 | # * Adding a hook to initialize_schema_migrations_table to create the plugin schema | |
| 127 | # info table. | |
| 128 | # | |
| 129 | module Engines::RailsExtensions::Migrations | |
| 130 | def self.included(base) # :nodoc: | |
| 131 | base.class_eval { alias_method_chain :initialize_schema_migrations_table, :engine_additions } | |
| 132 | end | |
| 133 | ||
| 134 | # Create the schema tables, and ensure that the plugin schema table | |
| 135 | # is also initialized. The plugin schema info table is defined by | |
| 136 | # Engines::Plugin::Migrator.schema_info_table_name. | |
| 137 | def initialize_schema_migrations_table_with_engine_additions | |
| 138 | initialize_schema_migrations_table_without_engine_additions | |
| 139 | ||
| 140 | # create the plugin schema stuff. | |
| 141 | begin | |
| 142 | execute <<-ESQL | |
| 143 | CREATE TABLE #{Engines::Plugin::Migrator.schema_info_table_name} | |
| 144 | (plugin_name #{type_to_sql(:string)}, version #{type_to_sql(:integer)}) | |
| 145 | ESQL | |
| 146 | rescue ActiveRecord::StatementInvalid | |
| 147 | # Schema has been initialized | |
| 148 | end | |
| 149 | end | |
| 150 | end | |
| 151 | ||
| 152 | module ::ActiveRecord #:nodoc: | |
| 153 | module ConnectionAdapters #:nodoc: | |
| 154 | module SchemaStatements #:nodoc: | |
| 155 | include Engines::RailsExtensions::Migrations | |
| 156 | end | |
| 157 | end | |
| 158 | end | |
| 159 | ||
| 160 | # Set ActiveRecord to ignore the plugin schema table by default | |
| 161 | ::ActiveRecord::SchemaDumper.ignore_tables << Engines.schema_info_table | |
| 0 | 162 | \ No newline at end of file |
| ... | ...@@ -0,0 +1,30 @@ | |
| 1 | # The PluginList class is an array, enhanced to allow access to loaded plugins | |
| 2 | # by name, and iteration over loaded plugins in order of priority. This array is used | |
| 3 | # by Engines::RailsExtensions::RailsInitializer to create the Engines.plugins array. | |
| 4 | # | |
| 5 | # Each loaded plugin has a corresponding Plugin instance within this array, and | |
| 6 | # the order the plugins were loaded is reflected in the entries in this array. | |
| 7 | # | |
| 8 | # For more information, see the Rails module. | |
| 9 | module Engines | |
| 10 | class Plugin | |
| 11 | class List < Array | |
| 12 | # Finds plugins with the set with the given name (accepts Strings or Symbols), or | |
| 13 | # index. So, Engines.plugins[0] returns the first-loaded Plugin, and Engines.plugins[:engines] | |
| 14 | # returns the Plugin instance for the engines plugin itself. | |
| 15 | def [](name_or_index) | |
| 16 | if name_or_index.is_a?(Fixnum) | |
| 17 | super | |
| 18 | else | |
| 19 | self.find { |plugin| plugin.name.to_s == name_or_index.to_s } | |
| 20 | end | |
| 21 | end | |
| 22 | ||
| 23 | # Go through each plugin, highest priority first (last loaded first). Effectively, | |
| 24 | # this is like <tt>Engines.plugins.reverse</tt> | |
| 25 | def by_precedence | |
| 26 | reverse | |
| 27 | end | |
| 28 | end | |
| 29 | end | |
| 30 | end | |
| 0 | 31 | \ No newline at end of file |
| ... | ...@@ -0,0 +1,21 @@ | |
| 1 | Copyright (c) 2008 James Adam | |
| 2 | ||
| 3 | The MIT License | |
| 4 | ||
| 5 | Permission is hereby granted, free of charge, to any person obtaining a copy | |
| 6 | of this software and associated documentation files (the "Software"), to deal | |
| 7 | in the Software without restriction, including without limitation the rights | |
| 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
| 9 | copies of the Software, and to permit persons to whom the Software is | |
| 10 | furnished to do so, subject to the following conditions: | |
| 11 | ||
| 12 | The above copyright notice and this permission notice shall be included in | |
| 13 | all copies or substantial portions of the Software. | |
| 14 | ||
| 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
| 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
| 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
| 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
| 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
| 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
| 21 | THE SOFTWARE. | |
| 0 | 22 | \ No newline at end of file |
| ... | ...@@ -0,0 +1,2 @@ | |
| 1 | require File.dirname(__FILE__) + '/lib/acts_as_customizable' | |
| 2 | ActiveRecord::Base.send(:include, Redmine::Acts::Customizable) |
| ... | ...@@ -0,0 +1,145 @@ | |
| 1 | # One of the magic features that that engines plugin provides is the ability to | |
| 2 | # override selected methods in controllers and helpers from your application. | |
| 3 | # This is achieved by trapping requests to load those files, and then mixing in | |
| 4 | # code from plugins (in the order the plugins were loaded) before finally loading | |
| 5 | # any versions from the main +app+ directory. | |
| 6 | # | |
| 7 | # The behaviour of this extension is output to the log file for help when | |
| 8 | # debugging. | |
| 9 | # | |
| 10 | # == Example | |
| 11 | # | |
| 12 | # A plugin contains the following controller in <tt>plugin/app/controllers/my_controller.rb</tt>: | |
| 13 | # | |
| 14 | # class MyController < ApplicationController | |
| 15 | # def index | |
| 16 | # @name = "HAL 9000" | |
| 17 | # end | |
| 18 | # def list | |
| 19 | # @robots = Robot.find(:all) | |
| 20 | # end | |
| 21 | # end | |
| 22 | # | |
| 23 | # In one application that uses this plugin, we decide that the name used in the | |
| 24 | # index action should be "Robbie", not "HAL 9000". To override this single method, | |
| 25 | # we create the corresponding controller in our application | |
| 26 | # (<tt>RAILS_ROOT/app/controllers/my_controller.rb</tt>), and redefine the method: | |
| 27 | # | |
| 28 | # class MyController < ApplicationController | |
| 29 | # def index | |
| 30 | # @name = "Robbie" | |
| 31 | # end | |
| 32 | # end | |
| 33 | # | |
| 34 | # The list method remains as it was defined in the plugin controller. | |
| 35 | # | |
| 36 | # The same basic principle applies to helpers, and also views and partials (although | |
| 37 | # view overriding is performed in Engines::RailsExtensions::Templates; see that | |
| 38 | # module for more information). | |
| 39 | # | |
| 40 | # === What about models? | |
| 41 | # | |
| 42 | # Unfortunately, it's not possible to provide this kind of magic for models. | |
| 43 | # The only reason why it's possible for controllers and helpers is because | |
| 44 | # they can be recognised by their filenames ("whatever_controller", "jazz_helper"), | |
| 45 | # whereas models appear the same as any other typical Ruby library ("node", | |
| 46 | # "user", "image", etc.). | |
| 47 | # | |
| 48 | # If mixing were allowed in models, it would mean code mixing for *every* | |
| 49 | # file that was loaded via +require_or_load+, and this could result in | |
| 50 | # problems where, for example, a Node model might start to include | |
| 51 | # functionality from another file called "node" somewhere else in the | |
| 52 | # <tt>$LOAD_PATH</tt>. | |
| 53 | # | |
| 54 | # One way to overcome this is to provide model functionality as a module in | |
| 55 | # a plugin, which developers can then include into their own model | |
| 56 | # implementations. | |
| 57 | # | |
| 58 | # Another option is to provide an abstract model (see the ActiveRecord::Base | |
| 59 | # documentation) and have developers subclass this model in their own | |
| 60 | # application if they must. | |
| 61 | # | |
| 62 | # --- | |
| 63 | # | |
| 64 | # The Engines::RailsExtensions::Dependencies module includes a method to | |
| 65 | # override Dependencies.require_or_load, which is called to load code needed | |
| 66 | # by Rails as it encounters constants that aren't defined. | |
| 67 | # | |
| 68 | # This method is enhanced with the code-mixing features described above. | |
| 69 | # | |
| 70 | module Engines::RailsExtensions::Dependencies | |
| 71 | def self.included(base) #:nodoc: | |
| 72 | base.class_eval { alias_method_chain :require_or_load, :engine_additions } | |
| 73 | end | |
| 74 | ||
| 75 | # Attempt to load the given file from any plugins, as well as the application. | |
| 76 | # This performs the 'code mixing' magic, allowing application controllers and | |
| 77 | # helpers to override single methods from those in plugins. | |
| 78 | # If the file can be found in any plugins, it will be loaded first from those | |
| 79 | # locations. Finally, the application version is loaded, using Ruby's behaviour | |
| 80 | # to replace existing methods with their new definitions. | |
| 81 | # | |
| 82 | # If <tt>Engines.disable_code_mixing == true</tt>, the first controller/helper on the | |
| 83 | # <tt>$LOAD_PATH</tt> will be used (plugins' +app+ directories are always lower on the | |
| 84 | # <tt>$LOAD_PATH</tt> than the main +app+ directory). | |
| 85 | # | |
| 86 | # If <tt>Engines.disable_application_code_loading == true</tt>, controllers will | |
| 87 | # not be loaded from the main +app+ directory *if* they are present in any | |
| 88 | # plugins. | |
| 89 | # | |
| 90 | # Returns true if the file could be loaded (from anywhere); false otherwise - | |
| 91 | # mirroring the behaviour of +require_or_load+ from Rails (which mirrors | |
| 92 | # that of Ruby's own +require+, I believe). | |
| 93 | def require_or_load_with_engine_additions(file_name, const_path=nil) | |
| 94 | return require_or_load_without_engine_additions(file_name, const_path) if Engines.disable_code_mixing | |
| 95 | ||
| 96 | file_loaded = false | |
| 97 | ||
| 98 | # try and load the plugin code first | |
| 99 | # can't use model, as there's nothing in the name to indicate that the file is a 'model' file | |
| 100 | # rather than a library or anything else. | |
| 101 | Engines.code_mixing_file_types.each do |file_type| | |
| 102 | # if we recognise this type | |
| 103 | # (this regexp splits out the module/filename from any instances of app/#{type}, so that | |
| 104 | # modules are still respected.) | |
| 105 | if file_name =~ /^(.*app\/#{file_type}s\/)?(.*_#{file_type})(\.rb)?$/ | |
| 106 | base_name = $2 | |
| 107 | # ... go through the plugins from first started to last, so that | |
| 108 | # code with a high precedence (started later) will override lower precedence | |
| 109 | # implementations | |
| 110 | Engines.plugins.each do |plugin| | |
| 111 | plugin_file_name = File.expand_path(File.join(plugin.directory, 'app', "#{file_type}s", base_name)) | |
| 112 | Engines.logger.debug("checking plugin '#{plugin.name}' for '#{base_name}'") | |
| 113 | if File.file?("#{plugin_file_name}.rb") | |
| 114 | Engines.logger.debug("==> loading from plugin '#{plugin.name}'") | |
| 115 | file_loaded = true if require_or_load_without_engine_additions(plugin_file_name, const_path) | |
| 116 | end | |
| 117 | end | |
| 118 | ||
| 119 | # finally, load any application-specific controller classes using the 'proper' | |
| 120 | # rails load mechanism, EXCEPT when we're testing engines and could load this file | |
| 121 | # from an engine | |
| 122 | if Engines.disable_application_code_loading | |
| 123 | Engines.logger.debug("loading from application disabled.") | |
| 124 | else | |
| 125 | # Ensure we are only loading from the /app directory at this point | |
| 126 | app_file_name = File.join(RAILS_ROOT, 'app', "#{file_type}s", "#{base_name}") | |
| 127 | if File.file?("#{app_file_name}.rb") | |
| 128 | Engines.logger.debug("loading from application: #{base_name}") | |
| 129 | file_loaded = true if require_or_load_without_engine_additions(app_file_name, const_path) | |
| 130 | else | |
| 131 | Engines.logger.debug("(file not found in application)") | |
| 132 | end | |
| 133 | end | |
| 134 | end | |
| 135 | end | |
| 136 | ||
| 137 | # if we managed to load a file, return true. If not, default to the original method. | |
| 138 | # Note that this relies on the RHS of a boolean || not to be evaluated if the LHS is true. | |
| 139 | file_loaded || require_or_load_without_engine_additions(file_name, const_path) | |
| 140 | end | |
| 141 | end | |
| 142 | ||
| 143 | module ::Dependencies #:nodoc: | |
| 144 | include Engines::RailsExtensions::Dependencies | |
| 145 | end | |
| 0 | 146 | \ No newline at end of file |
| ... | ...@@ -0,0 +1,84 @@ | |
| 1 | # Effective use of Rails' routes can help create a tidy and elegant set of URLs, | |
| 2 | # and is a significant part of creating an external API for your web application. | |
| 3 | # | |
| 4 | # When developing plugins which contain controllers, it seems obvious that including | |
| 5 | # the corresponding routes would be extremely useful. This is particularly true | |
| 6 | # when exposing RESTful resources using the new REST-ian features of Rails. | |
| 7 | # | |
| 8 | # == Including routes in your plugin | |
| 9 | # | |
| 10 | # The engines plugin makes it possible to include a set of routes within your plugin | |
| 11 | # very simply, as it turns out. In your plugin, you simply include a <tt>routes.rb</tt> | |
| 12 | # file like the one below at the root of your plugin: | |
| 13 | # | |
| 14 | # connect "/login", :controller => "my_plugin/account", :action => "login" | |
| 15 | # | |
| 16 | # # add a named route | |
| 17 | # logout "/logout", :controller => "my_plugin/account", :action => "logout" | |
| 18 | # | |
| 19 | # # some restful stuff | |
| 20 | # resources :things do |t| | |
| 21 | # t.resources :other_things | |
| 22 | # end | |
| 23 | # | |
| 24 | # Everywhere in a normal <tt>RAILS_ROOT/config/routes.rb</tt> file | |
| 25 | # where you might have <tt>map.connect</tt>, you just use <tt>connect</tt> in your | |
| 26 | # plugin's <tt>routes.rb</tt>. | |
| 27 | # | |
| 28 | # === Hooking it up in your application | |
| 29 | # | |
| 30 | # While it would be possible to have each plugin's routes automagically included into | |
| 31 | # the application's route set, to do so would actually be a stunningly bad idea. Route | |
| 32 | # priority is the key issue here. You, the application developer, needs to be in complete | |
| 33 | # control when it comes to specifying the priority of routes in your application, since | |
| 34 | # the ordering of your routes directly affects how Rails will interpret incoming requests. | |
| 35 | # | |
| 36 | # To add plugin routes into your application's <tt>routes.rb</tt> file, you need to explicitly | |
| 37 | # map them in using the Engines::RailsExtensions::Routing#from_plugin method: | |
| 38 | # | |
| 39 | # ApplicationController::Routing::Routes.draw do |map| | |
| 40 | # | |
| 41 | # map.connect "/app_stuff", :controller => "application_thing" # etc... | |
| 42 | # | |
| 43 | # # This line includes the routes from the given plugin at this point, giving you | |
| 44 | # # control over the priority of your application routes | |
| 45 | # map.from_plugin :your_plugin | |
| 46 | # | |
| 47 | # map.connect ":controller/:action/:id" | |
| 48 | # end | |
| 49 | # | |
| 50 | # By including routes in plugins which have controllers, you can now share in a simple way | |
| 51 | # a compact and elegant URL scheme which corresponds to those controllers. | |
| 52 | # | |
| 53 | # --- | |
| 54 | # | |
| 55 | # The Engines::RailsExtensions::Routing module defines extensions to Rails' | |
| 56 | # routing (ActionController::Routing) mechanism such that routes can be loaded | |
| 57 | # from a given plugin. | |
| 58 | # | |
| 59 | # The key method is Engines::RailsExtensions::Routing#from_plugin, which can be called | |
| 60 | # within your application's <tt>config/routes.rb</tt> file to load plugin routes at that point. | |
| 61 | # | |
| 62 | module Engines::RailsExtensions::Routing | |
| 63 | # Loads the set of routes from within a plugin and evaluates them at this | |
| 64 | # point within an application's main <tt>routes.rb</tt> file. | |
| 65 | # | |
| 66 | # Plugin routes are loaded from <tt><plugin_root>/routes.rb</tt>. | |
| 67 | def from_plugin(name) | |
| 68 | map = self # to make 'map' available within the plugin route file | |
| 69 | routes_path = Engines.plugins[name].routes_path | |
| 70 | Engines.logger.debug "loading routes from #{routes_path}" | |
| 71 | eval(IO.read(routes_path), binding, routes_path) if File.file?(routes_path) | |
| 72 | end | |
| 73 | end | |
| 74 | ||
| 75 | ||
| 76 | module ::ActionController #:nodoc: | |
| 77 | module Routing #:nodoc: | |
| 78 | class RouteSet #:nodoc: | |
| 79 | class Mapper #:nodoc: | |
| 80 | include Engines::RailsExtensions::Routing | |
| 81 | end | |
| 82 | end | |
| 83 | end | |
| 84 | end |
| ... | ...@@ -0,0 +1,267 @@ | |
| 1 | = EDGE | |
| 2 | ||
| 3 | * Refactored the view loading to work with changes in Edge Rails | |
| 4 | ||
| 5 | * Fixed integration of plugin migrations with the new, default timestamped migrations in Edge Rails | |
| 6 | ||
| 7 | * Refactored tests into the plugin itself - the plugin can now generate its own test_app harness and run tests within it. | |
| 8 | ||
| 9 | ||
| 10 | = 2.0.0 - (ANOTHER) MASSIVE INTERNAL REFACTORING | |
| 11 | ||
| 12 | * Engines now conforms to the new plugin loading mechanism, delegating plugin load order and lots of other things to Rails itself. | |
| 13 | ||
| 14 | ||
| 15 | ||
| 16 | = 1.2.2 | |
| 17 | ||
| 18 | * Added the ability to code mix different types of files, cleaning up the existing code-mixing implementation slightly (Ticket #271) | |
| 19 | ||
| 20 | ||
| 21 | = 1.2.1 | |
| 22 | ||
| 23 | * Added documentation to clarify some of the issues with Rails unloading classes that aren't required using "require_dependency" (Ticket #266) | |
| 24 | ||
| 25 | * Fixed a bug where test_help was being loaded when it wasn't needed, and was actually causing problems (Ticket #265) | |
| 26 | ||
| 27 | ||
| 28 | = 1.2.0 - MASSIVE INTERNAL REFACTORING | |
| 29 | ||
| 30 | * !!!Support for Rails < 1.2 has been dropped!!!; if you are using Rails =< 1.1.6, please use Engines 1.1.6, available from http://svn.rails-engines.org/engines/tags/rel_1.1.6 | |
| 31 | ||
| 32 | * Engines are dead! Long live plugins! There is now no meaningful notion of an engine - all plugins can take advantage of the more powerful features that the engines plugin provides by including app directories, etc. | |
| 33 | ||
| 34 | * Init_engine.rb is no longer used; please use the plugin-standard init.rb instead. | |
| 35 | ||
| 36 | * Engines.start is no longer required; please use the config.plugins array provided by Rails instead | |
| 37 | ||
| 38 | * To get the most benefit from Engines, set config.plugins to ["engines", "*"] to load the engines plugin first, and then all other plugins in their normal order after. | |
| 39 | ||
| 40 | * Access all loaded plugins via the new Rails.plugins array, and by name using Rails.plugins[:plugin_name]. | |
| 41 | ||
| 42 | * Access plugin metadata loaded automatically from about.yml: Rails.plugins[:name].about. Plugin#version is provided directly, for easy access. | |
| 43 | ||
| 44 | * Module.config is has been removed - use mattr_accessor instead, and initialize your default values via the init.rb mechanism. | |
| 45 | ||
| 46 | * Public asset helpers have been rewritten; instead of engine_stylesheet, now use stylesheet_link_tag :name, :plugin => "plugin_name" | |
| 47 | ||
| 48 | * Plugin migrations have been reworked to integrate into the main migration stream. Please run script/generate plugin_migration to create plugin migrations in your main application. | |
| 49 | ||
| 50 | * The fixture method for loading fixtures against any class has been removed; instead, engines will now provide a mechanism for loading fixtures from all plugins, by mirroring fixtures into a common location. | |
| 51 | ||
| 52 | * All references to engines have been removed; For example, any rake tasks which applied to engines now apply to all plugins. The default Rails rake tasks for plugins are overridden where necessary. | |
| 53 | ||
| 54 | * Layouts can now be shared via plugins - inspiration gratefully taken from PluginAWeek's plugin_routing :) | |
| 55 | ||
| 56 | * Actual routing from plugins is now possible, by including routes.rb in your plugin directory and using the from_plugin method in config/routes.rb (Ticket #182) | |
| 57 | ||
| 58 | * Controllers are no longer loaded twice if they're not present in the normal app/ directory (Ticket #177) | |
| 59 | ||
| 60 | * The preferred location for javascripts/stylesheets/etc is now 'assets' rather than 'public' | |
| 61 | ||
| 62 | * Ensure that plugins started before routing have their controllers appropriately added to config.controller_paths (Ticket #258) | |
| 63 | ||
| 64 | * Removed Engines.version - it's not longer relevant, now we're loading version information from about.yml files. | |
| 65 | ||
| 66 | * Added a huge amount of documentation to all new modules. | |
| 67 | ||
| 68 | * Added new warning message if installation of engines 1.2.x is attempted in a Rails 1.1.x application | |
| 69 | ||
| 70 | * Added details of the removal of the config method to UPGRADING | |
| 71 | ||
| 72 | * Removed the plugins:info rake task in favour of adding information to script/about via the Rails::Info module (Ticket #261) | |
| 73 | ||
| 74 | * Improved handling of testing and documentation tasks for plugins | |
| 75 | ||
| 76 | ||
| 77 | ||
| 78 | = 1.1.4 | |
| 79 | ||
| 80 | * Fixed creation of multipart emails (Ticket #190) | |
| 81 | ||
| 82 | * Added a temporary fix to the code-mixing issue. In your engine's test/test_helper.rb, please add the following lines: | |
| 83 | ||
| 84 | # Ensure that the code mixing and view loading from the application is disabled | |
| 85 | Engines.disable_app_views_loading = true | |
| 86 | Engines.disable_app_code_mixing = true | |
| 87 | ||
| 88 | which will prevent code mixing for controllers and helpers, and loading views from the application. One thing to remember is to load any controllers/helpers using 'require_or_load' in your tests, to ensure that the engine behaviour is respected (Ticket #135) | |
| 89 | ||
| 90 | * Added tasks to easily test engines individually (Ticket #120) | |
| 91 | ||
| 92 | * Fixture extensions will now fail with an exception if the corresponding class cannot be loaded (Ticket #138) | |
| 93 | ||
| 94 | * Patch for new routing/controller loading in Rails 1.1.6. The routing code is now replaced with the contents of config.controller_paths, along with controller paths from any started engines (Ticket #196) | |
| 95 | ||
| 96 | * Rails' Configuration instance is now stored, and available from all engines and plugins. | |
| 97 | ||
| 98 | ||
| 99 | ||
| 100 | = 1.1.3 | |
| 101 | ||
| 102 | * Fixed README to show 'models' rather than 'model' class (Ticket #167) | |
| 103 | * Fixed dependency loading to work with Rails 1.1.4 (Ticket #180) | |
| 104 | ||
| 105 | ||
| 106 | ||
| 107 | = 1.1.2 | |
| 108 | ||
| 109 | * Added better fix to version checking (Ticket #130, jdell@gbdev.com). | |
| 110 | ||
| 111 | * Fixed generated init_engine.rb so that VERSION module doesn't cause probems (Ticket #131, japgolly@gmail.com) | |
| 112 | ||
| 113 | * Fixed error with Rails 1.0 when trying to ignore the engine_schema_info table (Ticket #132, snowblink@gmail.com) | |
| 114 | ||
| 115 | * Re-added old style rake tasks (Ticket #133) | |
| 116 | ||
| 117 | * No longer adding all subdirectories of <engine>/app or <engine>/lib, as this can cause issues when files are grouped in modules (Ticket #149, kasatani@gmail.com) | |
| 118 | ||
| 119 | * Fixed engine precidence ordering for Rails 1.1 (Ticket #146) | |
| 120 | ||
| 121 | * Added new Engines.each method to assist in processing the engines in the desired order (Ticket #146) | |
| 122 | ||
| 123 | * Fixed annoying error message at appears when starting the console in development mode (Ticket #134) | |
| 124 | ||
| 125 | * Engines is now super-careful about loading the correct version of Rails from vendor (Ticket #154) | |
| 126 | ||
| 127 | ||
| 128 | ||
| 129 | = 1.1.1 | |
| 130 | ||
| 131 | * Fixed migration rake task failing when given a specific version (Ticket #115) | |
| 132 | ||
| 133 | * Added new rake task "test:engines" which will test engines (and other plugins) but ensure that the test database is cloned from development beforehand (Ticket #125) | |
| 134 | ||
| 135 | * Fixed issue where 'engine_schema_info' table was included in schema dumps (Ticket #87) | |
| 136 | ||
| 137 | * Fixed multi-part emails (Ticket #121) | |
| 138 | ||
| 139 | * Added an 'install.rb' file to new engines created by the bundled generator, which installs the engines plugin automatically if it doesn't already exist (Ticket #122) | |
| 140 | ||
| 141 | * Added a default VERSION module to generated engines (Ticket #123) | |
| 142 | ||
| 143 | * Refactored copying of engine's public files to a method of an Engine instance. You can now call Engines.get(:engine_name).copy_public_files (Ticket #108) | |
| 144 | ||
| 145 | * Changed engine generator templates from .rb files to .erb files (Ticket #106) | |
| 146 | ||
| 147 | * Fixed the test_helper.erb file to use the correct testing extensions and not load any schema - the schema will be cloned automatically via rake test:engines | |
| 148 | ||
| 149 | * Fixed problem when running with Rails 1.1.1 where version wasn't determined correctly (Ticket #129) | |
| 150 | ||
| 151 | * Fixed bug preventing engines from loading when both Rails 1.1.0 and 1.1.1 gems are installed and in use. | |
| 152 | ||
| 153 | * Updated version (d'oh!) | |
| 154 | ||
| 155 | ||
| 156 | ||
| 157 | = 1.1.0 | |
| 158 | ||
| 159 | * Improved regexp matching for Rails 1.0 engines with peculiar paths | |
| 160 | ||
| 161 | * Engine instance objects can be accessed via Engines[:name], an alias for Engines.get(:name) (Ticket #99) | |
| 162 | ||
| 163 | * init_engine.rb is now processed as the final step in the Engine.start process, so it can access files within the lib directory, which is now in the $LOAD_PATH at that point. (Ticket #99) | |
| 164 | ||
| 165 | * Clarified MIT license (Ticket #98) | |
| 166 | ||
| 167 | * Updated Rake tasks to integrate smoothly with Rails 1.1 namespaces | |
| 168 | ||
| 169 | * Changed the version to "1.1.0 (svn)" | |
| 170 | ||
| 171 | * Added more information about using the plugin with Edge Rails to the README | |
| 172 | ||
| 173 | * moved extensions into lib/engines/ directory to enable use of Engines module in extension code. | |
| 174 | ||
| 175 | * Added conditional require_or_load method which attempts to detect the current Rails version. To use the Edge Rails version of the loading mechanism, add the line: | |
| 176 | ||
| 177 | * Engines.config :edge, true | |
| 178 | ||
| 179 | * to your environment.rb file. | |
| 180 | ||
| 181 | * Merged changes from /branches/edge and /branches/rb_1.0 into /trunk | |
| 182 | ||
| 183 | * engine_schema_info now respects the prefix/suffixes set for ActiveRecord::Base (Ticket #67) | |
| 184 | ||
| 185 | * added ActiveRecord::Base.wrapped_table_name(name) method to assist in determining the correct table name | |
| 186 | ||
| 187 | ||
| 188 | ||
| 189 | = 1.0.6 | |
| 190 | ||
| 191 | * Added ability to determine version information for engines: rake engine_info | |
| 192 | ||
| 193 | * Added a custom logger for the Engines module, to stop pollution of the Rails logs. | |
| 194 | ||
| 195 | * Added some more tests (in particular, see rails_engines/applications/engines_test). | |
| 196 | ||
| 197 | * Another attempt at solving Ticket #53 - controllers and helpers should now be loadable from modules, and if a full path (including RAILS_ROOT/ENGINES_ROOT) is given, it should be safely stripped from the require filename such that corresponding files can be located in any active engines. In other words, controller/helper overloading should now completely work, even if the controllers/helpers are in modules. | |
| 198 | ||
| 199 | * Added (finally) patch from Ticket #22 - ActionMailer helpers should now load | |
| 200 | ||
| 201 | * Removed support for Engines.start :engine, :engine_name => 'whatever'. It was pointless. | |
| 202 | ||
| 203 | * Fixed engine name referencing; engine_stylesheet/engine_javascript can now happily use shorthand engine names (i.e. :test == :test_engine) (Ticket #45) | |
| 204 | ||
| 205 | * Fixed minor documentation error ('Engine.start' ==> 'Engines.start') (Ticket #57) | |
| 206 | ||
| 207 | * Fixed double inclusion of RAILS_ROOT in engine_migrate rake task (Ticket #61) | |
| 208 | ||
| 209 | * Added ability to force config values even if given as a hash (Ticket #62) | |
| 210 | ||
| 211 | ||
| 212 | ||
| 213 | = 1.0.5 | |
| 214 | ||
| 215 | * Fixed bug stopping fixtures from loading with PostgreSQL | |
| 216 | ||
| 217 | ||
| 218 | ||
| 219 | = 1.0.4 | |
| 220 | ||
| 221 | * Another attempt at loading controllers within modules (Ticket #56) | |
| 222 | ||
| 223 | ||
| 224 | ||
| 225 | = 1.0.3 | |
| 226 | ||
| 227 | * Fixed serious dependency bug stopping controllers being loaded (Ticket #56) | |
| 228 | ||
| 229 | ||
| 230 | ||
| 231 | = 1.0.2 | |
| 232 | ||
| 233 | * Fixed bug with overloading controllers in modules from /app directory | |
| 234 | ||
| 235 | * Fixed exception thrown when public files couldn't be created; exception is now logged (Ticket #52) | |
| 236 | ||
| 237 | * Fixed problem with generated test_helper.rb file via File.expand_path (Ticket #50) | |
| 238 | ||
| 239 | ||
| 240 | ||
| 241 | = 1.0.1 | |
| 242 | ||
| 243 | * Added engine generator for creation of new engines | |
| 244 | ||
| 245 | * Fixed 'Engine' typo in README | |
| 246 | ||
| 247 | * Fixed bug in fixtures extensions | |
| 248 | ||
| 249 | * Fixed /lib path management bug | |
| 250 | ||
| 251 | * Added method to determine public directory location from Engine object | |
| 252 | ||
| 253 | * Fixed bug in the error message in get_engine_dir() | |
| 254 | ||
| 255 | * Added proper component loading | |
| 256 | ||
| 257 | * Added preliminary tests for the config() methods module | |
| 258 | ||
| 259 | ||
| 260 | ||
| 261 | = pre-v170 | |
| 262 | ||
| 263 | * Fixed copyright notices to point to DHH, rather than me. | |
| 264 | ||
| 265 | * Moved extension require statements into lib/engines.rb, so the will be loaded if another module/file calls require 'engines | |
| 266 | ||
| 267 | * Added a CHANGELOG file (this file) |
| ... | ...@@ -0,0 +1,119 @@ | |
| 1 | # The engines plugin makes it trivial to share public assets using plugins. | |
| 2 | # To do this, include an <tt>assets</tt> directory within your plugin, and put | |
| 3 | # your javascripts, stylesheets and images in subdirectories of that folder: | |
| 4 | # | |
| 5 | # my_plugin | |
| 6 | # |- init.rb | |
| 7 | # |- lib/ | |
| 8 | # |- assets/ | |
| 9 | # |- javascripts/ | |
| 10 | # | |- my_functions.js | |
| 11 | # | | |
| 12 | # |- stylesheets/ | |
| 13 | # | |- my_styles.css | |
| 14 | # | | |
| 15 | # |- images/ | |
| 16 | # |- my_face.jpg | |
| 17 | # | |
| 18 | # Files within the <tt>asset</tt> structure are automatically mirrored into | |
| 19 | # a publicly-accessible folder each time your application starts (see | |
| 20 | # Engines::Assets#mirror_assets). | |
| 21 | # | |
| 22 | # | |
| 23 | # == Using plugin assets in views | |
| 24 | # | |
| 25 | # It's also simple to use Rails' helpers in your views to use plugin assets. | |
| 26 | # The default helper methods have been enhanced by the engines plugin to accept | |
| 27 | # a <tt>:plugin</tt> option, indicating the plugin containing the desired asset. | |
| 28 | # | |
| 29 | # For example, it's easy to use plugin assets in your layouts: | |
| 30 | # | |
| 31 | # <%= stylesheet_link_tag "my_styles", :plugin => "my_plugin", :media => "screen" %> | |
| 32 | # <%= javascript_include_tag "my_functions", :plugin => "my_plugin" %> |