trusty-multi-site-extension 1.0.0

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.
Files changed (62) hide show
  1. data/README.markdown +116 -0
  2. data/Rakefile +120 -0
  3. data/app/assets/images/admin/move_higher.png +0 -0
  4. data/app/assets/images/admin/move_lower.png +0 -0
  5. data/app/assets/images/admin/move_to_bottom.png +0 -0
  6. data/app/assets/images/admin/move_to_top.png +0 -0
  7. data/app/assets/images/admin/remove.png +0 -0
  8. data/app/assets/stylesheets/admin/multi_site.scss +121 -0
  9. data/app/assets/stylesheets/admin/site_chooser.scss +0 -0
  10. data/app/controllers/admin/sites_controller.rb +14 -0
  11. data/app/helpers/scoped_helper.rb +19 -0
  12. data/app/helpers/sites_helper.rb +10 -0
  13. data/app/models/site.rb +86 -0
  14. data/app/views/admin/layouts/_choose_site.html.haml +8 -0
  15. data/app/views/admin/layouts/_site_chooser.html.haml +2 -0
  16. data/app/views/admin/sites/_form.haml +43 -0
  17. data/app/views/admin/sites/edit.haml +7 -0
  18. data/app/views/admin/sites/index.haml +43 -0
  19. data/app/views/admin/sites/new.haml +7 -0
  20. data/app/views/admin/snippets/_choose_site.html.haml +6 -0
  21. data/app/views/admin/users/_choose_site.html.haml +8 -0
  22. data/app/views/site/not_configured.html.haml +7 -0
  23. data/config/initializers/radiant_config.rb +5 -0
  24. data/config/routes.rb +13 -0
  25. data/db/migrate/001_create_sites.rb +13 -0
  26. data/db/migrate/002_add_order_to_sites.rb +9 -0
  27. data/db/migrate/003_add_base_domain_to_sites.rb +9 -0
  28. data/db/migrate/004_add_admin_fields_to_sites.rb +17 -0
  29. data/db/migrate/005_add_sites.rb +13 -0
  30. data/db/migrate/006_remove_user_login_index.rb +8 -0
  31. data/db/migrate/20090810145840_site_abbreviation.rb +9 -0
  32. data/db/migrate/201411031415046078_recreate_non_unique_index_on_snippets_name.rb +11 -0
  33. data/lib/multi_site/admin_ui.rb +46 -0
  34. data/lib/multi_site/application_controller_extensions.rb +40 -0
  35. data/lib/multi_site/application_controller_filter_extensions.rb +21 -0
  36. data/lib/multi_site/engine.rb +5 -0
  37. data/lib/multi_site/page_extensions.rb +43 -0
  38. data/lib/multi_site/pages_controller_extensions.rb +48 -0
  39. data/lib/multi_site/resource_controller_extensions.rb +41 -0
  40. data/lib/multi_site/route_extensions.rb +21 -0
  41. data/lib/multi_site/route_set_extensions.rb +16 -0
  42. data/lib/multi_site/scoped_model.rb +145 -0
  43. data/lib/multi_site/scoped_validation.rb +32 -0
  44. data/lib/multi_site/site_chooser_helper.rb +14 -0
  45. data/lib/multi_site/site_controller_extensions.rb +12 -0
  46. data/lib/tasks/multi_site_extension_tasks.rake +28 -0
  47. data/lib/tasks/scoped_admin_extension_tasks.rake +28 -0
  48. data/lib/trusty-multi-site-extension.rb +1 -0
  49. data/multi_site_extension.rb +66 -0
  50. data/spec/controllers/extended_site_controller_spec.rb +61 -0
  51. data/spec/datasets/site_pages_dataset.rb +13 -0
  52. data/spec/datasets/sites_dataset.rb +10 -0
  53. data/spec/functional/multi_site_routing_spec.rb +37 -0
  54. data/spec/lib/multi_site/admin_ui_spec.rb +35 -0
  55. data/spec/lib/multi_site/scoped_model_spec.rb +182 -0
  56. data/spec/matchers/route_matcher.rb +38 -0
  57. data/spec/models/extended_page_spec.rb +48 -0
  58. data/spec/models/site_spec.rb +83 -0
  59. data/spec/spec.opts +6 -0
  60. data/spec/spec_helper.rb +36 -0
  61. data/trusty-multi-site-extension.gemspec +28 -0
  62. metadata +164 -0
@@ -0,0 +1,13 @@
1
+ class CreateSites < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :sites do |t|
4
+ t.column :name, :string
5
+ t.column :domain, :string
6
+ t.column :homepage_id, :integer
7
+ end
8
+ end
9
+
10
+ def self.down
11
+ drop_table :sites
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ class AddOrderToSites < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :position, :integer, :default => 0
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sites, :position
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class AddBaseDomainToSites < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :base_domain, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sites, :base_domain
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ class AddAdminFieldsToSites < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :created_by_id, :integer
4
+ add_column :sites, :created_at, :datetime
5
+ add_column :sites, :updated_by_id, :integer
6
+ add_column :sites, :updated_at, :datetime
7
+ add_column :sites, :subtitle, :string
8
+ end
9
+
10
+ def self.down
11
+ remove_column :sites, :created_by_id
12
+ remove_column :sites, :created_at
13
+ remove_column :sites, :udpated_by_id
14
+ remove_column :sites, :updated_at
15
+ remove_column :sites, :subtitle
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ class AddSites < ActiveRecord::Migration
2
+ def self.up
3
+ [:layouts, :snippets, :users].each do |table|
4
+ add_column table, :site_id, :integer
5
+ end
6
+ end
7
+
8
+ def self.down
9
+ [:layouts, :snippets, :users].each do |table|
10
+ add_column table, :site_id, :integer
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ class RemoveUserLoginIndex < ActiveRecord::Migration
2
+ def self.up
3
+ remove_index "users", :name => "login"
4
+ end
5
+
6
+ def self.down
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ class SiteAbbreviation < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :sites, :abbreviation, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :sites, :abbreviation
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ class RecreateNonUniqueIndexOnSnippetsName < ActiveRecord::Migration
2
+ def self.up
3
+ remove_index :snippets, :name => "name"
4
+ add_index :snippets, [:name, :site_id ], :name => "name_site_id", :unique => true
5
+ end
6
+
7
+ def self.down
8
+ remove_index :snippets, :name => "name_site_id"
9
+ add_index :snippets, :name, :name => "name", :unique => true
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ # This is included into AdminUI and defines editing regions for the site administration pages.
2
+ # Note that the AdminUI object is a singleton and it is not sufficient to add to its initialization routines: you also have to call load_default_site_regions on the admin singleton that has already been defined.
3
+
4
+ module MultiSite::AdminUI
5
+
6
+ def self.included(base)
7
+ base.class_eval do
8
+
9
+ attr_accessor :site
10
+ alias_method :sites, :site
11
+
12
+ protected
13
+
14
+ # The site-admin pages have these regions:
15
+
16
+ # Edit view:
17
+ # * main: edit_header, edit_form
18
+ # * form: edit_name edit_domain edit_homepage
19
+ # * form_bottom: edit_timestamp edit_buttons
20
+
21
+ # Index view
22
+ # * thead: title_header domain_header basedomain_header modify_header order_header
23
+ # * tbody: title_cell domain_cell basedomain_cell modify_cell order_cell (repeating row)
24
+ # * bottom: new_button
25
+
26
+ def load_default_site_regions
27
+ OpenStruct.new.tap do |site|
28
+ site.edit = TrustyCms::AdminUI::RegionSet.new do |edit|
29
+ edit.main.concat %w{edit_header edit_form}
30
+ edit.form.concat %w{edit_name edit_domain edit_homepage}
31
+ edit.form_bottom.concat %w{edit_timestamp edit_buttons}
32
+ end
33
+ site.index = TrustyCms::AdminUI::RegionSet.new do |index|
34
+ index.thead.concat %w{title_header domain_header basedomain_header modify_header order_header}
35
+ index.tbody.concat %w{title_cell domain_cell basedomain_cell modify_cell order_cell}
36
+ index.bottom.concat %w{new_button}
37
+ end
38
+ site.remove = site.index
39
+ site.new = site.edit
40
+ end
41
+ end
42
+
43
+ end
44
+ end
45
+ end
46
+
@@ -0,0 +1,40 @@
1
+ module MultiSite::ApplicationControllerExtensions
2
+
3
+ def current_site
4
+ Page.current_site
5
+ end
6
+
7
+ def current_site=(site=nil)
8
+ Page.current_site = site
9
+ end
10
+
11
+ # this is overridden in Admin::ResourceController to respond correctly
12
+
13
+ def sited_model?
14
+ false
15
+ end
16
+
17
+
18
+ def set_site
19
+ true if self.current_site = discover_current_site
20
+ end
21
+
22
+ # chains will attach here
23
+
24
+ def discover_current_site
25
+ site_from_host
26
+ end
27
+
28
+ # and add more ways to determine the current site
29
+
30
+ def site_from_host
31
+ Site.find_for_host(request.host)
32
+ end
33
+
34
+ def self.included(base)
35
+ base.class_eval {
36
+ helper_method :current_site, :current_site=
37
+ }
38
+ end
39
+
40
+ end
@@ -0,0 +1,21 @@
1
+ module MultiSite::ApplicationControllerFilterExtensions
2
+
3
+ def self.included(base)
4
+ base.class_eval {
5
+ prepend_before_filter :set_site
6
+ alias_method_chain :authenticate, :site
7
+ }
8
+ end
9
+
10
+ protected
11
+
12
+ def authenticate_with_site
13
+ self.current_site = discover_current_site
14
+ authenticate_without_site
15
+ end
16
+
17
+ def set_site
18
+ true if self.current_site = discover_current_site
19
+ end
20
+
21
+ end
@@ -0,0 +1,5 @@
1
+ module MultiSite
2
+ class Engine < Rails::Engine
3
+ paths["app/helpers"] = []
4
+ end
5
+ end
@@ -0,0 +1,43 @@
1
+ # Unlike other scoped classes, there is no site association in the Page class. Instead, Site has a homepage association and Page has some retrieval methods that turn a page request into site information.
2
+
3
+ module MultiSite::PageExtensions
4
+ def self.included(base)
5
+ base.class_eval {
6
+ alias_method_chain :url, :sites
7
+ mattr_accessor :current_site
8
+ has_one :site, :foreign_key => "homepage_id", :dependent => :nullify
9
+ }
10
+ base.extend ClassMethods
11
+ class << base
12
+ def find_by_path(path, live=true)
13
+ root = homepage
14
+ raise Page::MissingRootPageError unless root
15
+ root.find_by_path(path, live)
16
+ end
17
+ def current_site
18
+ @current_site ||= Site.default
19
+ end
20
+ def current_site=(site)
21
+ @current_site = site
22
+ end
23
+ end
24
+ end
25
+
26
+ module ClassMethods
27
+ def homepage
28
+ if current_site.is_a?(Site)
29
+ homepage = self.current_site.homepage
30
+ end
31
+ homepage ||= find_by_parent_id(nil)
32
+ end
33
+ end
34
+
35
+ def url_with_sites
36
+ if parent
37
+ parent.child_url(self)
38
+ else
39
+ "/"
40
+ end
41
+ end
42
+
43
+ end
@@ -0,0 +1,48 @@
1
+ module MultiSite::PagesControllerExtensions
2
+ def self.included(base)
3
+ base.class_eval {
4
+ alias_method_chain :discover_current_site, :root
5
+ alias_method_chain :index, :site
6
+ alias_method_chain :continue_url, :site
7
+ alias_method_chain :remove, :back
8
+ responses.destroy.default do
9
+ return_url = session[:came_from]
10
+ session[:came_from] = nil
11
+ if model.class == Page
12
+ redirect_to return_url || admin_pages_url(:root => model.root.id)
13
+ else
14
+ redirect_to continue_url(params)
15
+ end
16
+ end
17
+ }
18
+ end
19
+
20
+ # for compatibility with the standard issue of multi_site,
21
+ # a root parameter overrides other ways of setting site
22
+
23
+ def discover_current_site_with_root
24
+ site_from_root || discover_current_site_without_root
25
+ end
26
+
27
+ def site_from_root
28
+ if params[:root] && @homepage = Page.find(params[:root])
29
+ @site = @homepage.root.site
30
+ end
31
+ end
32
+
33
+ def index_with_site
34
+ @site ||= Page.current_site
35
+ @homepage ||= @site.homepage if @site
36
+ @homepage ||= Page.homepage
37
+ response_for :plural
38
+ end
39
+
40
+ def remove_with_back
41
+ session[:came_from] = request.env["HTTP_REFERER"]
42
+ remove_without_back
43
+ end
44
+
45
+ def continue_url_with_site(options={})
46
+ options[:redirect_to] || (params[:continue] ? edit_admin_page_url(model) : admin_pages_url(:root => model.root.id))
47
+ end
48
+ end
@@ -0,0 +1,41 @@
1
+ module MultiSite::ResourceControllerExtensions
2
+
3
+ def self.included(base)
4
+ base.class_eval {
5
+ alias_method_chain :discover_current_site, :input
6
+ }
7
+ end
8
+
9
+ def current_site=(site=nil)
10
+ Page.current_site = site
11
+ set_session_site
12
+ end
13
+
14
+ # among other things this determines whether the site chooser is shown in the submenu
15
+
16
+ def sited_model?
17
+ model_class == Page || model_class.is_site_scoped?
18
+ end
19
+
20
+ protected
21
+
22
+ def discover_current_site_with_input
23
+ site_from_param || site_from_session || discover_current_site_without_input
24
+ end
25
+
26
+ # for interface consistency we want to be able to remember site choices between requests
27
+
28
+ def set_session_site(site_id=nil)
29
+ site_id ||= current_site.id.to_s if current_site.is_a? Site
30
+ session[:site_id] = site_id
31
+ end
32
+
33
+ def site_from_session
34
+ session[:site_id] && Site.find(session[:site_id]) rescue nil
35
+ end
36
+
37
+ def site_from_param
38
+ params[:site_id] && Site.find(params[:site_id]) rescue nil
39
+ end
40
+
41
+ end
@@ -0,0 +1,21 @@
1
+ module MultiSite
2
+ module RouteExtensions
3
+
4
+ def self.included(base)
5
+ base.alias_method_chain(:recognition_conditions, :site)
6
+ end
7
+
8
+ def recognition_conditions_with_site
9
+ result = recognition_conditions_without_site
10
+ if site_names = conditions.delete(:site)
11
+ domains = [*site_names].map{ |site| Regexp.compile(::Site.find_by_name(site).domain) }
12
+ conditions[:site] = Regexp.union(*domains)
13
+ result << "conditions[:site] === env[:site]"
14
+ end
15
+ result
16
+ end
17
+
18
+ end
19
+ end
20
+
21
+ ActionController::Routing::Route.send :include, MultiSite::RouteExtensions
@@ -0,0 +1,16 @@
1
+ module MultiSite
2
+ module RouteSetExtensions
3
+
4
+ def self.included(base)
5
+ base.alias_method_chain :extract_request_environment, :site
6
+ end
7
+
8
+ def extract_request_environment_with_site(request)
9
+ env = extract_request_environment_without_site(request)
10
+ env.merge! :site => request.host
11
+ end
12
+
13
+ end
14
+ end
15
+
16
+ ActionController::Routing::RouteSet.send :include, MultiSite::RouteSetExtensions
@@ -0,0 +1,145 @@
1
+ module MultiSite
2
+
3
+ module ScopedModel
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+ def is_site_scoped?
10
+ false
11
+ end
12
+
13
+ # only option at the moment is :shareable, which we take to mean that sites are optional:
14
+ # if true it causes us not to set the site automatically or to validate its presence,
15
+ # and to extend the scoping conditions so that objects with no site are returned as
16
+ # well as objects with the specified site
17
+ # that is, anything without a site is considered to be shared among all sites
18
+ # the default is false
19
+
20
+ def is_site_scoped(options={})
21
+ return if is_site_scoped?
22
+
23
+ options = {
24
+ :shareable => false
25
+ }.merge(options)
26
+
27
+ class_eval <<-EO
28
+ extend MultiSite::ScopedModel::ScopedClassMethods
29
+ include MultiSite::ScopedModel::ScopedInstanceMethods
30
+ EO
31
+
32
+ belongs_to :site
33
+ Site.send(:has_many, plural_symbol_for_class)
34
+
35
+ before_validation :set_site
36
+ validates_presence_of :site unless options[:shareable]
37
+
38
+ class << self
39
+ attr_accessor :shareable
40
+ alias_method_chain :all, :site
41
+ alias_method_chain :where, :site
42
+ alias_method_chain :paginate, :site
43
+ %w{count average minimum maximum sum}.each do |getter|
44
+ alias_method_chain getter.intern, :site
45
+ end
46
+ end
47
+
48
+ self.shareable = options[:shareable]
49
+ end
50
+ end
51
+
52
+ module ScopedClassMethods
53
+ def all_with_site(options = {})
54
+ return all_without_site(options) unless sites?
55
+ with_scope(:find => {:conditions => site_scope_condition}) do
56
+ all_without_site(options)
57
+ end
58
+ end
59
+
60
+ def where_with_site(options = {})
61
+ return where_without_site(options) unless sites?
62
+ with_scope(:find => {:conditions => site_scope_condition}) do
63
+ where_without_site(options)
64
+ end
65
+ end
66
+
67
+ def paginate_with_site(options={})
68
+ return paginate_without_site(options) unless sites?
69
+ with_scope(:find => {:conditions => site_scope_condition}) do
70
+ paginate_without_site(options)
71
+ end
72
+ end
73
+
74
+ %w{count average minimum maximum sum}.each do |getter|
75
+ define_method("#{getter}_with_site") do |*args|
76
+ return send("#{getter}_without_site".intern, *args) unless sites?
77
+ with_scope(:find => {:conditions => site_scope_condition}) do
78
+ send "#{getter}_without_site".intern, *args
79
+ end
80
+ end
81
+ end
82
+
83
+ # this only works with :all and :first
84
+ # and should only be used in odd cases like migration.
85
+ def find_without_site(*args)
86
+ options = args.extract_options!
87
+ #set_readonly_option!(options)
88
+
89
+ case args.first
90
+ when :first then find_initial_without_site(options) # defined here
91
+ when :all then all_without_site(options) # already defined by the alias chain
92
+ end
93
+ end
94
+
95
+ def find_initial_without_site(options)
96
+ options.update(:limit => 1)
97
+ all_without_site(options).first
98
+ end
99
+
100
+ def sites?
101
+ Site.table_exists? && Site.several?
102
+ end
103
+
104
+ def current_site!
105
+ raise(ActiveRecord::SiteNotFound, "#{self} is site-scoped but current_site is #{self.current_site.inspect}", caller) if sites? && !self.current_site && !self.is_shareable?
106
+ self.current_site
107
+ end
108
+
109
+ def current_site
110
+ Page.current_site
111
+ end
112
+
113
+ def site_scope_condition
114
+ if self.shareable
115
+ condition = ""
116
+ condition << "#{self.table_name}.site_id = #{self.current_site.id} OR " if self.current_site
117
+ condition << "#{self.table_name}.site_id IS NULL"
118
+ else
119
+ condition = "#{self.table_name}.site_id = #{self.current_site!.id}"
120
+ end
121
+ condition
122
+ end
123
+
124
+ def plural_symbol_for_class
125
+ self.to_s.pluralize.underscore.intern
126
+ end
127
+
128
+ def is_site_scoped?
129
+ true
130
+ end
131
+
132
+ def is_shareable?
133
+ !!self.shareable
134
+ end
135
+ end
136
+
137
+ module ScopedInstanceMethods
138
+ protected
139
+ def set_site
140
+ self.site ||= self.class.current_site! unless self.class.is_shareable?
141
+ end
142
+ end
143
+ end
144
+ end
145
+
@@ -0,0 +1,32 @@
1
+ module MultiSite::ScopedValidation
2
+
3
+ def self.included(base)
4
+
5
+ base.class_eval do
6
+ # scoping validations to the site should be very simple
7
+ # all you would normally need is something like this:
8
+ #
9
+ # validates_uniqueness_of :email, :scope => :site_id
10
+ #
11
+ # but if you want to scope core trusty classes, you have a problem:
12
+ # their uniqueness validations have already been declared
13
+ # The only answer is to reach right back and change the validates_uniqueness_of method
14
+ # and to make it more awkward, that has to happen so early that we can't reflect on the site association.
15
+ # Hence the check for a site_id column. It's a hack, but a fairly harmless one.
16
+
17
+ def validates_uniqueness_of_with_site(*attr)
18
+ if table_exists? && column_names.include?('site_id')
19
+ configuration = attr.extract_options!
20
+ configuration[:scope] ||= :site_id
21
+ attr.push(configuration)
22
+ end
23
+ validates_uniqueness_of_without_site(*attr)
24
+ end
25
+
26
+ alias_method_chain :validates_uniqueness_of, :site
27
+ end
28
+
29
+ end
30
+ end
31
+
32
+ ActiveRecord::Validations::ClassMethods.send :include, MultiSite::ScopedValidation
@@ -0,0 +1,14 @@
1
+ module MultiSite::SiteChooserHelper
2
+
3
+ def sites_chooser_thing
4
+ return "" unless admin? && defined?(Site) && defined?(controller) && controller.sited_model? && controller.template_name == 'index' && Site.several?
5
+ options = Site.find(:all).map{ |site| "<li>" + link_to( site.name, "#{request.path}?site_id=#{site.id}", :class => site == current_site ? 'fg' : '') + "</li>" }.join("")
6
+ chooser = %{<div id="site_chooser">}
7
+ #chooser << link_to("sites", admin_sites_url, {:id => 'show_site_list', :class => 'expandable'})
8
+ chooser << %{<ul id="nav"><li>Current Site: #{current_site.name}}
9
+ chooser << %{<ul class="expansion">#{options}</ul></li></ul>}
10
+ chooser << %{</div>}
11
+ chooser
12
+ end
13
+
14
+ end
@@ -0,0 +1,12 @@
1
+ module MultiSite::SiteControllerExtensions
2
+ def self.included(base)
3
+ base.class_eval do
4
+ before_filter :set_site
5
+ end
6
+ end
7
+
8
+ def set_site
9
+ Page.current_site = Site.find_for_host(request.host)
10
+ true
11
+ end
12
+ end
@@ -0,0 +1,28 @@
1
+ namespace :trusty do
2
+ namespace :extensions do
3
+ namespace :multi_site do
4
+
5
+ desc "Runs the migration of the Multi Site extension"
6
+ task :migrate => :environment do
7
+ require 'trusty_cms/extension_migrator'
8
+ if ENV["VERSION"]
9
+ MultiSiteExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ else
11
+ MultiSiteExtension.migrator.migrate
12
+ end
13
+ end
14
+
15
+ desc "Copies public assets of the Multi Site to the instance public/ directory."
16
+ task :update => :environment do
17
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
18
+ puts "Copying assets from MultiSiteExtension"
19
+ Dir[MultiSiteExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
20
+ path = file.sub(MultiSiteExtension.root, '')
21
+ directory = File.dirname(path)
22
+ mkdir_p RAILS_ROOT + directory, :verbose => false
23
+ cp file, RAILS_ROOT + path, :verbose => false
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,28 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :scoped_admin do
4
+
5
+ desc "Runs the migration of the Scoped Admin extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ ScopedAdminExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ else
11
+ ScopedAdminExtension.migrator.migrate
12
+ end
13
+ end
14
+
15
+ desc "Copies public assets of the Scoped Admin to the instance public/ directory."
16
+ task :update => :environment do
17
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
18
+ puts "Copying assets from ScopedAdminExtension"
19
+ Dir[ScopedAdminExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
20
+ path = file.sub(ScopedAdminExtension.root, '')
21
+ directory = File.dirname(path)
22
+ mkdir_p RAILS_ROOT + directory
23
+ cp file, RAILS_ROOT + path
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1 @@
1
+ # Nothing to see here