parlement 0.10 → 0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGES +11 -0
- data/MEMORY +9 -1
- data/README +5 -4
- data/app/controllers/account_controller.rb +10 -13
- data/app/controllers/application.rb +4 -5
- data/app/controllers/elt_controller.rb +9 -7
- data/app/controllers/person_controller.rb +1 -3
- data/app/controllers/subscriber_controller.rb +10 -10
- data/app/helpers/elt_helper.rb +2 -0
- data/app/models/elt.rb +28 -19
- data/app/models/mail.rb +26 -14
- data/app/models/mail_notify.rb +5 -4
- data/app/models/person.rb +11 -2
- data/app/views/account/_login.rhtml +3 -3
- data/app/views/account/_show.rhtml +12 -14
- data/app/views/elt/_choice.rhtml +3 -3
- data/app/views/elt/_elt.rhtml +4 -4
- data/app/views/elt/_list.rhtml +2 -2
- data/app/views/elt/_listByDate.rhtml +1 -1
- data/app/views/elt/_listByVote.rhtml +1 -1
- data/app/views/elt/new.rhtml +3 -3
- data/app/views/elt/show.rhtml +2 -2
- data/app/views/layouts/top.rhtml +6 -0
- data/app/views/mail_notify/publish.text.html.rhtml +1 -1
- data/app/views/person/_listElts.rhtml +5 -3
- data/app/views/person/show.rhtml +1 -2
- data/config/boot.rb +5 -4
- data/config/environment.rb +6 -4
- data/config/routes.rb +3 -2
- data/db/development_structure.sql +15 -4
- data/db/migrate/006_last_activity.rb +10 -0
- data/db/schema.rb +67 -49
- data/public/dispatch.fcgi +1 -0
- data/public/javascripts/controls.js +41 -23
- data/public/javascripts/dragdrop.js +317 -99
- data/public/javascripts/effects.js +301 -166
- data/public/javascripts/prototype.js +932 -402
- data/public/stylesheets/default.css +3 -2
- data/test/unit/elt_test.rb +13 -0
- data/test/unit/mail_test.rb +3 -1
- data/vendor/plugins/engines/CHANGELOG +203 -99
- data/vendor/plugins/engines/MIT-LICENSE +1 -1
- data/vendor/plugins/engines/README +32 -384
- data/vendor/plugins/engines/Rakefile +14 -0
- data/vendor/plugins/engines/UPGRADING +93 -0
- data/vendor/plugins/engines/about.yml +7 -0
- data/vendor/plugins/engines/generators/plugin_migration/USAGE +45 -0
- data/vendor/plugins/engines/generators/plugin_migration/plugin_migration_generator.rb +79 -0
- data/vendor/plugins/engines/generators/plugin_migration/templates/plugin_migration.erb +13 -0
- data/vendor/plugins/engines/init.rb +34 -47
- data/vendor/plugins/engines/install.rb +32 -0
- data/vendor/plugins/engines/lib/engines/{ruby_extensions.rb → deprecated_config_support.rb} +135 -113
- data/vendor/plugins/engines/lib/engines/plugin.rb +214 -0
- data/vendor/plugins/engines/lib/engines/plugin_list.rb +31 -0
- data/vendor/plugins/engines/lib/engines/plugin_migrator.rb +60 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/active_record.rb +19 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/dependencies.rb +143 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/migrations.rb +155 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/public_asset_helpers.rb +116 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/rails.rb +20 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/rails_initializer.rb +86 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/routing.rb +77 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions/templates.rb +140 -0
- data/vendor/plugins/engines/lib/engines/rails_extensions.rb +6 -0
- data/vendor/plugins/engines/lib/engines/testing.rb +88 -0
- data/vendor/plugins/engines/lib/engines.rb +281 -425
- data/vendor/plugins/engines/tasks/engines.rake +108 -137
- metadata +218 -250
- data/db/ROOT/perso.txt +0 -214
- data/public/images/indicator.gif +0 -0
- data/public/images/orange_by_darren_Hester_350o.jpg +0 -0
- data/public/images/smile.png +0 -0
- data/vendor/plugins/engines/generators/engine/USAGE +0 -26
- data/vendor/plugins/engines/generators/engine/engine_generator.rb +0 -199
- data/vendor/plugins/engines/generators/engine/templates/README +0 -85
- data/vendor/plugins/engines/generators/engine/templates/init_engine.erb +0 -15
- data/vendor/plugins/engines/generators/engine/templates/install.erb +0 -4
- data/vendor/plugins/engines/generators/engine/templates/lib/engine.erb +0 -6
- data/vendor/plugins/engines/generators/engine/templates/licenses/GPL +0 -18
- data/vendor/plugins/engines/generators/engine/templates/licenses/LGPL +0 -19
- data/vendor/plugins/engines/generators/engine/templates/licenses/MIT +0 -22
- data/vendor/plugins/engines/generators/engine/templates/licenses/None +0 -1
- data/vendor/plugins/engines/generators/engine/templates/public/javascripts/engine.js +0 -0
- data/vendor/plugins/engines/generators/engine/templates/public/stylesheets/engine.css +0 -0
- data/vendor/plugins/engines/generators/engine/templates/tasks/engine.rake +0 -0
- data/vendor/plugins/engines/generators/engine/templates/test/test_helper.erb +0 -17
- data/vendor/plugins/engines/lib/bundles/require_resource.rb +0 -124
- data/vendor/plugins/engines/lib/bundles.rb +0 -77
- data/vendor/plugins/engines/lib/engines/action_mailer_extensions.rb +0 -140
- data/vendor/plugins/engines/lib/engines/action_view_extensions.rb +0 -141
- data/vendor/plugins/engines/lib/engines/active_record_extensions.rb +0 -21
- data/vendor/plugins/engines/lib/engines/dependencies_extensions.rb +0 -129
- data/vendor/plugins/engines/lib/engines/migration_extensions.rb +0 -53
- data/vendor/plugins/engines/lib/engines/routing_extensions.rb +0 -28
- data/vendor/plugins/engines/lib/engines/testing_extensions.rb +0 -327
- data/vendor/plugins/engines/tasks/deprecated_engines.rake +0 -7
- data/vendor/plugins/engines/test/action_view_extensions_test.rb +0 -9
- data/vendor/plugins/engines/test/ruby_extensions_test.rb +0 -115
- data/vendor/plugins/guid/README.TXT +0 -29
- data/vendor/plugins/guid/init.rb +0 -30
- data/vendor/plugins/guid/lib/usesguid.rb +0 -37
- data/vendor/plugins/guid/lib/uuid22.rb +0 -43
- data/vendor/plugins/guid/lib/uuidtools.rb +0 -572
- data/vendor/plugins/responds_to_parent/MIT-LICENSE +0 -20
- data/vendor/plugins/responds_to_parent/README +0 -42
- data/vendor/plugins/responds_to_parent/Rakefile +0 -22
- data/vendor/plugins/responds_to_parent/init.rb +0 -1
- data/vendor/plugins/responds_to_parent/lib/responds_to_parent.rb +0 -46
- data/vendor/plugins/responds_to_parent/test/responds_to_parent_test.rb +0 -115
|
@@ -0,0 +1,116 @@
|
|
|
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
|
+
# Plugin#mirror_public_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" %>
|
|
33
|
+
#
|
|
34
|
+
# ... and similarly in views and partials, it's easy to use plugin images:
|
|
35
|
+
#
|
|
36
|
+
# <%= image_tag "my_face", :plugin => "my_plugin" %>
|
|
37
|
+
# <!-- or -->
|
|
38
|
+
# <%= image_path "my_face", :plugin => "my_plugin" %>
|
|
39
|
+
#
|
|
40
|
+
# Where the default helpers allow the specification of more than one file (i.e. the
|
|
41
|
+
# javascript and stylesheet helpers), you can do similarly for multiple assets from
|
|
42
|
+
# within a single plugin.
|
|
43
|
+
#
|
|
44
|
+
# ---
|
|
45
|
+
#
|
|
46
|
+
# This module enhances four of the methods from ActionView::Helpers::AssetTagHelper:
|
|
47
|
+
#
|
|
48
|
+
# * stylesheet_link_tag
|
|
49
|
+
# * javascript_include_tag
|
|
50
|
+
# * image_path
|
|
51
|
+
# * image_tag
|
|
52
|
+
#
|
|
53
|
+
# Each one of these methods now accepts the key/value pair <tt>:plugin => "plugin_name"</tt>,
|
|
54
|
+
# which can be used to specify the originating plugin for any assets.
|
|
55
|
+
#
|
|
56
|
+
module Engines::RailsExtensions::PublicAssetHelpers
|
|
57
|
+
def self.included(base) #:nodoc:
|
|
58
|
+
base.class_eval do
|
|
59
|
+
[:stylesheet_link_tag, :javascript_include_tag, :image_path, :image_tag].each do |m|
|
|
60
|
+
alias_method_chain m, :engine_additions
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Adds plugin functionality to Rails' default stylesheet_link_tag method.
|
|
66
|
+
def stylesheet_link_tag_with_engine_additions(*sources)
|
|
67
|
+
stylesheet_link_tag_without_engine_additions(*Engines::RailsExtensions::PublicAssetHelpers.pluginify_sources("stylesheets", *sources))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Adds plugin functionality to Rails' default javascript_include_tag method.
|
|
71
|
+
def javascript_include_tag_with_engine_additions(*sources)
|
|
72
|
+
javascript_include_tag_without_engine_additions(*Engines::RailsExtensions::PublicAssetHelpers.pluginify_sources("javascripts", *sources))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
#--
|
|
76
|
+
# Our modified image_path now takes a 'plugin' option, though it doesn't require it
|
|
77
|
+
#++
|
|
78
|
+
|
|
79
|
+
# Adds plugin functionality to Rails' default image_path method.
|
|
80
|
+
def image_path_with_engine_additions(source, options={})
|
|
81
|
+
options.stringify_keys!
|
|
82
|
+
source = Engines::RailsExtensions::PublicAssetHelpers.plugin_asset_path(options["plugin"], "images", source) if options["plugin"]
|
|
83
|
+
image_path_without_engine_additions(source)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# Adds plugin functionality to Rails' default image_tag method.
|
|
87
|
+
def image_tag_with_engine_additions(source, options={})
|
|
88
|
+
options.stringify_keys!
|
|
89
|
+
if options["plugin"]
|
|
90
|
+
source = Engines::RailsExtensions::PublicAssetHelpers.plugin_asset_path(options["plugin"], "images", source)
|
|
91
|
+
options.delete("plugin")
|
|
92
|
+
end
|
|
93
|
+
image_tag_without_engine_additions(source, options)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
#--
|
|
97
|
+
# The following are methods on this module directly because of the weird-freaky way
|
|
98
|
+
# Rails creates the helper instance that views actually get
|
|
99
|
+
#++
|
|
100
|
+
|
|
101
|
+
# Convert sources to the paths for the given plugin, if any plugin option is given
|
|
102
|
+
def self.pluginify_sources(type, *sources)
|
|
103
|
+
options = sources.last.is_a?(Hash) ? sources.pop.stringify_keys : { }
|
|
104
|
+
sources.map! { |s| plugin_asset_path(options["plugin"], type, s) } if options["plugin"]
|
|
105
|
+
options.delete("plugin") # we don't want it appearing in the HTML
|
|
106
|
+
sources << options # re-add options
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Returns the publicly-addressable relative URI for the given asset, type and plugin
|
|
110
|
+
def self.plugin_asset_path(plugin_name, type, asset)
|
|
111
|
+
raise "No plugin called '#{plugin_name}' - please use the full name of a loaded plugin." if Rails.plugins[plugin_name].nil?
|
|
112
|
+
"/#{Rails.plugins[plugin_name].public_asset_directory}/#{type}/#{asset}"
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
::ActionView::Helpers::AssetTagHelper.send(:include, Engines::RailsExtensions::PublicAssetHelpers)
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# In order to give a richer infrastructure for dealing with plugins, the engines
|
|
2
|
+
# plugin adds two new attributes to the Rails module:
|
|
3
|
+
#
|
|
4
|
+
# [+plugins+] A PluginList instance which holds the currently loaded plugins
|
|
5
|
+
# [+configuration+] The current Rails::Configuration instance, so that we can
|
|
6
|
+
# query any parameters that might be set *after* Rails has
|
|
7
|
+
# loaded, as well as during plugin initialization
|
|
8
|
+
#
|
|
9
|
+
#--
|
|
10
|
+
# Here we just re-open the Rails module and add our custom accessors; it
|
|
11
|
+
# may be cleaner to seperate them into a module, but in this case that seems
|
|
12
|
+
# like overkill.
|
|
13
|
+
#++
|
|
14
|
+
module Rails
|
|
15
|
+
# The set of all loaded plugins
|
|
16
|
+
mattr_accessor :plugins
|
|
17
|
+
|
|
18
|
+
# The Rails::Initializer::Configuration object
|
|
19
|
+
mattr_accessor :configuration
|
|
20
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Enhances the Rails::Initializer class to be a bit smarter about
|
|
2
|
+
# plugins. See Engines::RailsExtensions::RailsInitializer for more
|
|
3
|
+
# details.
|
|
4
|
+
|
|
5
|
+
require "engines/rails_extensions/rails"
|
|
6
|
+
require 'engines/plugin_list'
|
|
7
|
+
|
|
8
|
+
# The engines plugin changes the way that Rails actually loads other plugins.
|
|
9
|
+
# It creates instances of the Plugin class to represent each plugin, stored
|
|
10
|
+
# in the <tt>Rails.plugins</tt> PluginList.
|
|
11
|
+
#
|
|
12
|
+
# ---
|
|
13
|
+
#
|
|
14
|
+
# Three methods from the original Rails::Initializer module are overridden
|
|
15
|
+
# by Engines::RailsExtensions::RailsInitializer:
|
|
16
|
+
#
|
|
17
|
+
# [+load_plugin+] which now creates Plugin instances and calls Plugin#load
|
|
18
|
+
# [+after_initialize+] which now performs Engines.after_initialize in addition
|
|
19
|
+
# to the given config block
|
|
20
|
+
# [<tt>plugin_enabled?</tt>] which now respects the result of
|
|
21
|
+
# Engines.load_all_plugins?
|
|
22
|
+
#
|
|
23
|
+
module Engines::RailsExtensions::RailsInitializer
|
|
24
|
+
def self.included(base) #:nodoc:
|
|
25
|
+
base.class_eval do
|
|
26
|
+
alias_method_chain :load_plugin, :engine_additions
|
|
27
|
+
alias_method_chain :after_initialize, :engine_additions
|
|
28
|
+
alias_method_chain :plugin_enabled?, :engine_additions
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# Loads all plugins in configuration.plugin_paths, regardless of the contents
|
|
33
|
+
# of configuration.plugins
|
|
34
|
+
def load_all_plugins
|
|
35
|
+
# a nil value implies we don't care about plugins; load 'em all in a reliable order
|
|
36
|
+
find_plugins(configuration.plugin_paths).sort.each { |path| load_plugin path }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Loads a plugin, performing the extra load path/public file magic of
|
|
40
|
+
# engines by calling Plugin#load.
|
|
41
|
+
def load_plugin_with_engine_additions(directory)
|
|
42
|
+
name = plugin_name(directory)
|
|
43
|
+
return false if loaded_plugins.include?(name)
|
|
44
|
+
|
|
45
|
+
logger.debug "loading plugin from #{directory} with engine additions"
|
|
46
|
+
|
|
47
|
+
# add the Plugin object
|
|
48
|
+
plugin = Plugin.new(plugin_name(directory), directory)
|
|
49
|
+
Rails.plugins << plugin
|
|
50
|
+
|
|
51
|
+
# do the other stuff that load_plugin used to do. This includes
|
|
52
|
+
# allowing the plugin's init.rb to set configuration options on
|
|
53
|
+
# it's instance, which can then be used in it's initialization
|
|
54
|
+
load_plugin_without_engine_additions(directory)
|
|
55
|
+
|
|
56
|
+
# perform additional loading tasks like mirroring public assets
|
|
57
|
+
# and adding app directories to the appropriate load paths
|
|
58
|
+
plugin.load
|
|
59
|
+
|
|
60
|
+
true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Allow the engines plugin to do whatever it needs to do after Rails has
|
|
64
|
+
# loaded, and then call the actual after_initialize block. Currently, this
|
|
65
|
+
# is call Engines.after_initialize.
|
|
66
|
+
def after_initialize_with_engine_additions
|
|
67
|
+
Engines.after_initialize
|
|
68
|
+
after_initialize_without_engine_additions
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
protected
|
|
72
|
+
|
|
73
|
+
# Returns true if the plugin at the given path should be loaded; false
|
|
74
|
+
# otherwise. If Engines.load_all_plugins? is true, this method will return
|
|
75
|
+
# true regardless of the path given.
|
|
76
|
+
def plugin_enabled_with_engine_additions?(path)
|
|
77
|
+
Engines.load_all_plugins? || plugin_enabled_without_engine_additions?(path)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Returns the name of the plugin at the given path.
|
|
81
|
+
def plugin_name(path)
|
|
82
|
+
File.basename(path)
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
::Rails::Initializer.send(:include, Engines::RailsExtensions::RailsInitializer)
|
|
@@ -0,0 +1,77 @@
|
|
|
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 1.2.
|
|
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
|
+
# At the point in which routing is loaded, we cannot guarantee that all
|
|
69
|
+
# plugins are in Rails.plugins, so instead we need to use find_plugin_path
|
|
70
|
+
path = Engines.find_plugin_path(name)
|
|
71
|
+
routes_path = File.join(path, name.to_s, "routes.rb")
|
|
72
|
+
logger.debug "loading routes from #{routes_path}"
|
|
73
|
+
eval(IO.read(routes_path), binding, routes_path) if File.file?(routes_path)
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
::ActionController::Routing::RouteSet::Mapper.send(:include, Engines::RailsExtensions::Routing)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# As well as providing code overloading for controllers and helpers
|
|
2
|
+
# (see Engines::RailsExtensions::Dependencies), the engines plugin also allows
|
|
3
|
+
# developers to selectively override views and partials within their application.
|
|
4
|
+
#
|
|
5
|
+
# == An example
|
|
6
|
+
#
|
|
7
|
+
# This is achieved in much the same way as controller overriding. Our plugin contains
|
|
8
|
+
# a view to be rendered at the URL <tt>/test/hello</tt>, in
|
|
9
|
+
# <tt>our_plugin/app/views/test/hello.rhtml</tt>:
|
|
10
|
+
#
|
|
11
|
+
# <div class="greeting">Hi, <%= @dude.name %>, what's up?</div>
|
|
12
|
+
#
|
|
13
|
+
# If in a particular application we're not happy with this message, we can override
|
|
14
|
+
# it by replacing the partial in our own application -
|
|
15
|
+
# <tt>RAILS_ROOT/app/views/test/hello.rhtml</tt>:
|
|
16
|
+
#
|
|
17
|
+
# <div class="greeting custom_class">Wassup <%= @dude.name %>.
|
|
18
|
+
# Waaaaassaaaaaaaaup</div>
|
|
19
|
+
#
|
|
20
|
+
# This view will then be rendered in favour of that in the plugin.
|
|
21
|
+
#
|
|
22
|
+
module Engines::RailsExtensions::Templates
|
|
23
|
+
|
|
24
|
+
# Override the finding of partials and views. This is achieved by wrapping
|
|
25
|
+
# the (private) method #full_template_path_with_engine_additions, that checks
|
|
26
|
+
# for the given template within plugins as well as the application.
|
|
27
|
+
module ActionView
|
|
28
|
+
def self.included(base) #:nodoc:
|
|
29
|
+
base.class_eval { alias_method_chain :full_template_path, :engine_additions }
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
def full_template_path_with_engine_additions(template_path, extension)
|
|
34
|
+
path_in_app_directory = full_template_path_from_application(template_path, extension)
|
|
35
|
+
|
|
36
|
+
# First check for this template in the application. If it exists, the user has
|
|
37
|
+
# overridden anything from the plugin, so use it (unless we're testing plugins;
|
|
38
|
+
# see full_template_path_from_application())
|
|
39
|
+
return path_in_app_directory if path_in_app_directory && File.exist?(path_in_app_directory)
|
|
40
|
+
|
|
41
|
+
# Otherwise, check in the plugins to see if the template can be found there.
|
|
42
|
+
# Load this in order so that more recently started plugins will take priority.
|
|
43
|
+
Rails.plugins.by_precedence do |plugin|
|
|
44
|
+
plugin_specific_path = File.join(plugin.root, 'app', 'views',
|
|
45
|
+
template_path.to_s + '.' + extension.to_s)
|
|
46
|
+
return plugin_specific_path if File.exist?(plugin_specific_path)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# If it cannot be found anywhere, return the default path.
|
|
50
|
+
return full_template_path_without_engine_additions(template_path, extension)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Return a path to this template within our default app/views directory.
|
|
54
|
+
# In some circumstances, we may wish to prevent users from overloading views,
|
|
55
|
+
# such as when we are testing plugins with views. In this case, return "".
|
|
56
|
+
def full_template_path_from_application(template_path, extension)
|
|
57
|
+
if Engines.disable_application_view_loading
|
|
58
|
+
nil
|
|
59
|
+
else
|
|
60
|
+
full_template_path_without_engine_additions(template_path, extension)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
# The Layout module overrides a single (private) method in ActionController::Layout::ClassMethods,
|
|
67
|
+
# called #layout_list. This method now returns an array of layouts, including those in plugins.
|
|
68
|
+
module Layout
|
|
69
|
+
def self.included(base) #:nodoc:
|
|
70
|
+
base.class_eval { alias_method_chain :layout_list, :engine_additions }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
# Return the list of layouts, including any in the <tt>app/views/layouts</tt>
|
|
75
|
+
# directories of loaded plugins.
|
|
76
|
+
def layout_list_with_engine_additions
|
|
77
|
+
plugin_layouts = Rails.plugins.by_precedence.map do |p|
|
|
78
|
+
File.join(p.root, "app", "views", "layouts")
|
|
79
|
+
end
|
|
80
|
+
layout_list_without_engine_additions + Dir["{#{plugin_layouts.join(",")}}/**/*"]
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# The way ActionMailer is coded in terms of finding templates is very restrictive, to the point
|
|
86
|
+
# where all templates for rendering must exist under the single base path. This is difficult to
|
|
87
|
+
# work around without re-coding significant parts of the action mailer code.
|
|
88
|
+
#
|
|
89
|
+
# ---
|
|
90
|
+
#
|
|
91
|
+
# The MailTemplates module overrides two (private) methods from ActionMailer to enable mail
|
|
92
|
+
# templates within plugins:
|
|
93
|
+
#
|
|
94
|
+
# [+template_path+] which now produces the contents of #template_paths
|
|
95
|
+
# [+render+] which now find the first matching template and creates an ActionVew::Base
|
|
96
|
+
# instance with the correct @base_path for that template
|
|
97
|
+
module MailTemplates
|
|
98
|
+
def self.included(base) #:nodoc:
|
|
99
|
+
base.class_eval do
|
|
100
|
+
alias_method_chain :template_path, :engine_additions
|
|
101
|
+
alias_method_chain :render, :engine_additions
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
private
|
|
106
|
+
# Returns all possible template paths for the current mailer, including those
|
|
107
|
+
# within the loaded plugins.
|
|
108
|
+
def template_paths
|
|
109
|
+
paths = Rails.plugins.by_precedence.map { |p| "#{p.root}/app/views/#{mailer_name}" }
|
|
110
|
+
paths.unshift(template_path_without_engine_additions) unless Engines.disable_application_view_loading
|
|
111
|
+
paths
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Return something that Dir[] can glob against. This method is called in
|
|
115
|
+
# ActionMailer::Base#create! and used as part of an argument to Dir. We can
|
|
116
|
+
# take advantage of this by using some of the features of Dir.glob to search
|
|
117
|
+
# multiple paths for matching files.
|
|
118
|
+
def template_path_with_engine_additions
|
|
119
|
+
"{#{template_paths.join(",")}}"
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# We've broken this up so that we can dynamically alter the base_path that ActionView
|
|
123
|
+
# is rendering from so that templates can be located from plugins.
|
|
124
|
+
def render_with_engine_additions(opts)
|
|
125
|
+
template_path_for_method = Dir["#{template_path}/#{opts[:file]}*"].first
|
|
126
|
+
body = opts.delete(:body)
|
|
127
|
+
i = initialize_template_class(body)
|
|
128
|
+
i.base_path = File.dirname(template_path_for_method)
|
|
129
|
+
i.render(opts)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
::ActionView::Base.send(:include, Engines::RailsExtensions::Templates::ActionView)
|
|
136
|
+
::ActionController::Layout::ClassMethods.send(:include, Engines::RailsExtensions::Templates::Layout)
|
|
137
|
+
|
|
138
|
+
if Object.const_defined?(:ActionMailer) # We don't need to do this if ActionMailer hasn't been loaded.
|
|
139
|
+
::ActionMailer::Base.send(:include, Engines::RailsExtensions::Templates::MailTemplates)
|
|
140
|
+
end
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
# This module contains all the extensions that the engines plugin makes to
|
|
2
|
+
# Rails core. Explanations of how each extension works are included as RDoc
|
|
3
|
+
# documentation for each of the modules listed.
|
|
4
|
+
module Engines::RailsExtensions
|
|
5
|
+
# let's not rely *entirely* on Rails' magic modules. Not just yet.
|
|
6
|
+
end
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Contains the enhancements to assist in testing plugins. See Engines::Testing
|
|
2
|
+
# for more details.
|
|
3
|
+
|
|
4
|
+
require 'test/unit'
|
|
5
|
+
require 'test_help'
|
|
6
|
+
|
|
7
|
+
require 'tmpdir'
|
|
8
|
+
require 'fileutils'
|
|
9
|
+
|
|
10
|
+
# In most cases, Rails' own plugin testing mechanisms are sufficient. However, there
|
|
11
|
+
# are cases where plugins can be given a helping hand in the testing arena. This module
|
|
12
|
+
# contains some methods to assist when testing plugins that contain fixtures.
|
|
13
|
+
#
|
|
14
|
+
# == Fixtures and plugins
|
|
15
|
+
#
|
|
16
|
+
# Since Rails' own fixtures method is fairly strict about where files can be loaded from,
|
|
17
|
+
# the simplest approach when running plugin tests with fixtures is to simply copy all
|
|
18
|
+
# fixtures into a single temporary location and inform the standard Rails mechanism to
|
|
19
|
+
# use this directory, rather than RAILS_ROOT/test/fixtures.
|
|
20
|
+
#
|
|
21
|
+
# The Engines::Testing#setup_plugin_fixtures method does this, copying all plugin fixtures
|
|
22
|
+
# into the temporary location before and tests are performed. This behaviour is invoked
|
|
23
|
+
# the the rake tasks provided by the Engines plugin, in the "test:plugins" namespace. If
|
|
24
|
+
# necessary, you can invoke the task manually.
|
|
25
|
+
#
|
|
26
|
+
# If you wish to take advantage of this, add a call to the Engines::Testing.set_fixture_path
|
|
27
|
+
# method somewhere before your tests (in a test_helper file, or above the TestCase itself).
|
|
28
|
+
#
|
|
29
|
+
# = Testing plugins
|
|
30
|
+
#
|
|
31
|
+
# Normally testing a plugin will require that Rails is loaded, unless you are including
|
|
32
|
+
# a skeleton Rails environment or set of mocks within your plugin tests. If you require
|
|
33
|
+
# the Rails environment to be started, you must ensure that this actually happens; while
|
|
34
|
+
# it's not obvious, your tests do not automatically run with Rails loaded.
|
|
35
|
+
#
|
|
36
|
+
# The simplest way to setup plugin tests is to include a test helper with the following
|
|
37
|
+
# contents:
|
|
38
|
+
#
|
|
39
|
+
# # Load the normal Rails helper. This ensures the environment is loaded
|
|
40
|
+
# require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
|
|
41
|
+
# # Ensure that we are using the temporary fixture path
|
|
42
|
+
# Engines::Testing.set_fixture_path
|
|
43
|
+
#
|
|
44
|
+
# Then run tests using the provided tasks (<tt>test:plugins</tt>, or the tasks that the engines
|
|
45
|
+
# plugin provides - <tt>test:plugins:units</tt>, etc.).
|
|
46
|
+
#
|
|
47
|
+
# Alternatively, you can explicitly load the environment by adpating the contents of the
|
|
48
|
+
# default <tt>test_helper</tt>:
|
|
49
|
+
#
|
|
50
|
+
# ENV["RAILS_ENV"] = "test"
|
|
51
|
+
# # Note that we are requiring config/environment from the root of the enclosing application.
|
|
52
|
+
# require File.expand_path(File.dirname(__FILE__) + "/../../../../config/environment")
|
|
53
|
+
# require 'test_help'
|
|
54
|
+
#
|
|
55
|
+
module Engines::Testing
|
|
56
|
+
mattr_accessor :temporary_fixtures_directory
|
|
57
|
+
self.temporary_fixtures_directory = FileUtils.mkdir_p(File.join(Dir.tmpdir, "rails_fixtures"))
|
|
58
|
+
|
|
59
|
+
# Copies fixtures from plugins and the application into a temporary directory
|
|
60
|
+
# (Engines::Testing.temporary_fixtures_directory).
|
|
61
|
+
#
|
|
62
|
+
# If a set of plugins is not given, fixtures are copied from all plugins in order
|
|
63
|
+
# of precedence, meaning that plugins can 'overwrite' the fixtures of others if they are
|
|
64
|
+
# loaded later; the application's fixtures are copied last, allowing any custom fixtures
|
|
65
|
+
# to override those in the plugins. If no argument is given, plugins are loaded via
|
|
66
|
+
# PluginList#by_precedence.
|
|
67
|
+
#
|
|
68
|
+
# This method is called by the engines-supplied plugin testing rake tasks
|
|
69
|
+
def self.setup_plugin_fixtures(plugins=Rails.plugins.by_precedence)
|
|
70
|
+
|
|
71
|
+
# Copy all plugin fixtures, and then the application fixtures, into this directory
|
|
72
|
+
plugins.each do |plugin|
|
|
73
|
+
plugin_fixtures_directory = File.join(plugin.root, "test", "fixtures")
|
|
74
|
+
if File.directory?(plugin_fixtures_directory)
|
|
75
|
+
Engines.mirror_files_from(plugin_fixtures_directory, self.temporary_fixtures_directory)
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
Engines.mirror_files_from(File.join(RAILS_ROOT, "test", "fixtures"),
|
|
79
|
+
self.temporary_fixtures_directory)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# Sets the fixture path used by Test::Unit::TestCase to the temporary
|
|
83
|
+
# directory which contains all plugin fixtures.
|
|
84
|
+
def self.set_fixture_path
|
|
85
|
+
Test::Unit::TestCase.fixture_path = self.temporary_fixtures_directory
|
|
86
|
+
$LOAD_PATH.unshift self.temporary_fixtures_directory
|
|
87
|
+
end
|
|
88
|
+
end
|