parlement 0.10 → 0.11
Sign up to get free protection for your applications and to get access to all the features.
- 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
|