radiant-copy_move-extension 2.1.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.
data/HELP.rdoc ADDED
@@ -0,0 +1,43 @@
1
+ As the name implies, "Copy/move" allows you to copy or move a single page up to an entire tree of pages from one part of the website to another
2
+
3
+ == Usage
4
+
5
+ To copy or move a page or tree click the "Copy/Move" button from the tree list on the "pages" page for the page you want to copy or move.
6
+
7
+ If you have multiple view types for pages then the "Copy/Move" button will only appear on the "Tree view".
8
+ If you have access permissions on page they will be copied when the new page is created and will be maintained if the page is moved
9
+
10
+ == Options
11
+
12
+ Once you have clicked the "Copy/Move" button you will be taken to a page that allows you to decide how the copy/move should take place.
13
+
14
+ === What do you want to do?
15
+
16
+ These 4 radio buttons that allow you to determine exactly what happens.
17
+
18
+ ==== Copy only 'X' page.
19
+
20
+ This will copy only the selected page, no children will be copied.
21
+
22
+ ==== Copy 'X' and its first-level children.
23
+
24
+ This will copy the selected page and all pages one level below it in the tree.
25
+
26
+ ==== Copy 'X' and all of its children.
27
+
28
+ This will copy the selected page and all pages below it in the tree.
29
+
30
+ ==== Only move page.
31
+
32
+ Only move the page, do not create a copy, note that all pages below it in the tree wil be moved as well.
33
+
34
+ === Copy or move under
35
+
36
+ Select the page which you would like to make the parent of the newly copied or moved page.
37
+
38
+ === Page status
39
+
40
+ This allows you to set the status of the new page and all its children.
41
+ * If you choose the "Use the same status" option then all the pages will retain their existing statuses
42
+ * If you set to a status other than "Use the same status" then ALL the pages in the copied/moved tree will have their status changed.
43
+
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ == MIT License
2
+
3
+ Copyright (c) 2007, Andrea Franz - (http://bigchieflabs.com/blog/, http://bigchief.it)
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 all
13
+ 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 THE
21
+ SOFTWARE.
data/README ADDED
@@ -0,0 +1,47 @@
1
+ = CopyMove
2
+
3
+ Created by: Andrea Franz - http://gravityblast.com
4
+ Version: 2.1.0
5
+ Contact: andrea AT gravityblast DOT com
6
+
7
+ This extension adds a new action ('CopyMove') in the Radiant's administration interface near the 'Add child' button. With this extension you can copy or move a page (and all of its children).
8
+
9
+ == Requirements
10
+
11
+ You need the shards extension for this to work for Radiant versions 0.6.6 and under. Versions 0.6.7 and greater have Shards built in.
12
+
13
+ See http://groups.google.com/group/radiantcms-dev/browse_frm/thread/d07f7fffd84b3ce0/5efa6fd6c2e1668e?lnk=gst&q=shards#5efa6fd6c2e1668e
14
+
15
+ == Installation
16
+
17
+ 1. Get the latest version of CopyMove extension code:
18
+
19
+ cd vendor/extensions
20
+
21
+ git clone git://github.com/pilu/radiant-copy-move.git copy_move
22
+
23
+ 1.a FOR RADIANT VERSION < 0.6.7
24
+
25
+ Open the environment.rb and set shards as first extension to be loaded:
26
+ config.extensions = [ :shards, :textile_filter, :markdown_filter, :all ]
27
+
28
+ 1.b FOR RADIANT VERSION >= 0.6.7
29
+
30
+ Shards is already installed and loaded.
31
+
32
+ 2. From your Rails app root type this command:
33
+
34
+ rake RAILS_ENV=production radiant:extensions:copy_move:install
35
+
36
+ Which will copy some needed files to the public directory of your app.
37
+
38
+ == Contributors
39
+
40
+ Benny Degezelle
41
+ Mario T. Lanza
42
+ Daniel Collis-Puro
43
+ Sean Cribbs
44
+
45
+ == Credits
46
+
47
+ This extension contains icons from the FamFamFam Silk icon set. See http://famfamfam.com/
data/Rakefile ADDED
@@ -0,0 +1,137 @@
1
+ begin
2
+ require 'jeweler'
3
+ Jeweler::Tasks.new do |gem|
4
+ gem.name = "radiant-copy_move-extension"
5
+ gem.summary = %Q{Copy/Move extension for Radiant CMS}
6
+ gem.description = %Q{Allows you to to copy pages or move them under a new parent. }
7
+ gem.email = "benny@gorilla-webdesign.be"
8
+ gem.homepage = "http://github.com/jomz/radiant-comments-extension"
9
+ gem.authors = ["Benny Degezelle"]
10
+ gem.add_dependency 'radiant', "=0.9.0"
11
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
12
+ end
13
+ rescue LoadError
14
+ puts "Jeweler (or a dependency) not available. This is only required if you plan to package copy_move as a gem."
15
+ end
16
+
17
+ # In rails 1.2, plugins aren't available in the path until they're loaded.
18
+ # Check to see if the rspec plugin is installed first and require
19
+ # it if it is. If not, use the gem version.
20
+
21
+ # Determine where the RSpec plugin is by loading the boot
22
+ unless defined? RADIANT_ROOT
23
+ ENV["RAILS_ENV"] = "test"
24
+ case
25
+ when ENV["RADIANT_ENV_FILE"]
26
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
27
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
28
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
29
+ else
30
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
31
+ end
32
+ end
33
+
34
+ require 'rake'
35
+ require 'rake/rdoctask'
36
+ require 'rake/testtask'
37
+
38
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
39
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
40
+ require 'spec/rake/spectask'
41
+ require 'cucumber'
42
+ require 'cucumber/rake/task'
43
+
44
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
45
+ Object.send(:remove_const, :RADIANT_ROOT)
46
+
47
+ extension_root = File.expand_path(File.dirname(__FILE__))
48
+
49
+ task :default => :spec
50
+ task :stats => "spec:statsetup"
51
+
52
+ desc "Run all specs in spec directory"
53
+ Spec::Rake::SpecTask.new(:spec) do |t|
54
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
55
+ t.spec_files = FileList['spec/**/*_spec.rb']
56
+ end
57
+
58
+ task :features => 'spec:integration'
59
+
60
+ namespace :spec do
61
+ desc "Run all specs in spec directory with RCov"
62
+ Spec::Rake::SpecTask.new(:rcov) do |t|
63
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
64
+ t.spec_files = FileList['spec/**/*_spec.rb']
65
+ t.rcov = true
66
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
67
+ end
68
+
69
+ desc "Print Specdoc for all specs"
70
+ Spec::Rake::SpecTask.new(:doc) do |t|
71
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
72
+ t.spec_files = FileList['spec/**/*_spec.rb']
73
+ end
74
+
75
+ [:models, :controllers, :views, :helpers].each do |sub|
76
+ desc "Run the specs under spec/#{sub}"
77
+ Spec::Rake::SpecTask.new(sub) do |t|
78
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
79
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
80
+ end
81
+ end
82
+
83
+ desc "Run the Cucumber features"
84
+ Cucumber::Rake::Task.new(:integration) do |t|
85
+ t.fork = true
86
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
87
+ # t.feature_pattern = "#{extension_root}/features/**/*.feature"
88
+ t.profile = "default"
89
+ end
90
+
91
+ # Setup specs for stats
92
+ task :statsetup do
93
+ require 'code_statistics'
94
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
95
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
96
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
97
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
98
+ ::CodeStatistics::TEST_TYPES << "Model specs"
99
+ ::CodeStatistics::TEST_TYPES << "View specs"
100
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
101
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
102
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
103
+ end
104
+
105
+ namespace :db do
106
+ namespace :fixtures do
107
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
108
+ task :load => :environment do
109
+ require 'active_record/fixtures'
110
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
111
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
112
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ desc 'Generate documentation for the copy_move extension.'
120
+ Rake::RDocTask.new(:rdoc) do |rdoc|
121
+ rdoc.rdoc_dir = 'rdoc'
122
+ rdoc.title = 'CopyMoveExtension'
123
+ rdoc.options << '--line-numbers' << '--inline-source'
124
+ rdoc.rdoc_files.include('README')
125
+ rdoc.rdoc_files.include('lib/**/*.rb')
126
+ end
127
+
128
+ # For extensions that are in transition
129
+ desc 'Test the copy_move extension.'
130
+ Rake::TestTask.new(:test) do |t|
131
+ t.libs << 'lib'
132
+ t.pattern = 'test/**/*_test.rb'
133
+ t.verbose = true
134
+ end
135
+
136
+ # Load any custom rakefiles for extension
137
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
data/TODO ADDED
File without changes
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.1.0
@@ -0,0 +1,19 @@
1
+ module CopyMoveHelper
2
+ def page_parent_select_tag
3
+ homes = Object.const_defined?(:MultiSiteExtension) ? [ Page.current_site.homepage ] : Page.find_all_by_parent_id(nil)
4
+ list = homes.inject([]) do |l, home|
5
+ l.concat build_tree(home, [])
6
+ end
7
+ select_tag 'parent_id', options_for_select(list)
8
+ end
9
+
10
+ def build_tree(page, list, level = 0)
11
+ label = "#{'-'*level}#{page.title}"
12
+ id = page.id
13
+ list << [label, id]
14
+ page.children.each do |p|
15
+ build_tree p, list, level + 1
16
+ end
17
+ list
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ - unless simple
2
+ %td.copy-move
3
+ - if page.respond_to?('children')
4
+ = link_to_function image('copy-move', :alt => 'CopyMove', :style => "margin: 6px 0 -6px 0"), "$(this).next('ul').toggle();Event.stop(event);", :class => "action"
5
+ %ul.popup-menu{:style => "display:none"}
6
+ - if page.children.any?
7
+ %li= link_to "Copy page only", copy_page_admin_page_url(page), :style =>"background-image: url(/images/admin/page_white.png)"
8
+ %li= link_to "Copy with first-level children", copy_children_admin_page_url(page), :style =>"background-image: url(/images/admin/page_white_copy.png)"
9
+ %li= link_to "Copy whole subtree", copy_tree_admin_page_url(page), :style =>"background-image: url(/images/admin/page_white_stack.png)"
10
+ %li= link_to "Move entire subtree", move_admin_page_url(page), :style =>"background-image: url(/images/admin/page_white_go.png)"
11
+ - else
12
+ %li= link_to "Copy page", copy_page_admin_page_url(page), :style =>"background-image: url(/images/admin/page_white.png)"
13
+ %li= link_to "Move page", move_admin_page_url(page), :style =>"background-image: url(/images/admin/page_white_go.png)"
@@ -0,0 +1 @@
1
+ %th &nbsp;
@@ -0,0 +1,27 @@
1
+ - content_for :popups do
2
+ #copy-move.popup{:style => "display:none"}
3
+ - form_tag '#', :method => :post do
4
+ %h3 Copy or move page
5
+ %p
6
+ %label{:for => 'parent_id'} New parent:
7
+ = page_parent_select_tag
8
+ %p
9
+ %label{:for => 'status_id'} New status:
10
+ = select_tag "status_id", options_for_select(Status.find_all.map{ |s| [s.name, s.id] }.unshift(['Use the same status', nil]))
11
+ %p.buttons
12
+ = submit_tag "OK"
13
+ or
14
+ = link_to_function "Cancel", "$(this).up('.popup').hide();"
15
+ - content_for :page_scripts do
16
+ :plain
17
+ document.observe('dom:loaded', function(){
18
+ $(document.body).observe('click', function(){$$('ul.popup-menu').invoke('hide');});
19
+ $$('td.copy-move ul.popup-menu a').each(function(element){
20
+ element.observe('click', function(evt){
21
+ evt.stop();
22
+ element.up('ul').hide();
23
+ $('copy-move').centerInViewport();
24
+ $('copy-move').show().down('form').setAttribute('action', element.href);
25
+ });
26
+ });
27
+ });
@@ -0,0 +1,46 @@
1
+ - form_tag :action => "copy_move" do
2
+ .form-area
3
+
4
+ %h2 What do you want to do?
5
+
6
+ %input{:type => "radio", :name => "copy_move_action", :id => "copy_move_action_page", :value => "page", :checked => "true"}
7
+ %label{:for => "copy_move_action_page"}== Copy only '#{@page.title}' page.
8
+
9
+ %br
10
+
11
+ %input{:type => "radio", :name => "copy_move_action", :id => "copy_move_action_children", :value => "children"}
12
+ %label{:for => "copy_move_action_children"}== Copy '#{@page.title}' and its first-level children.
13
+
14
+ %br
15
+
16
+ %input{:type => "radio", :name => "copy_move_action", :id => "copy_move_action_tree", :value => "tree"}
17
+ %label{:for => "copy_move_action_tree"}== Copy '#{@page.title}' and all of its children.
18
+
19
+ %br
20
+
21
+ - if @page.parent
22
+ %input{:type => "radio", :name => "copy_move_action", :id => "copy_move_action_move", :value => "move"}
23
+ %label{:for => "copy_move_action_move"} Only move page.
24
+ %br
25
+
26
+ %br
27
+
28
+ %p
29
+ - if @page.parent
30
+ %strong Copy or move under
31
+ - else
32
+ %strong Copy under
33
+ %br
34
+ = page_parent_select_tag
35
+
36
+
37
+ %p
38
+ %strong Page status
39
+ %br
40
+ = select_tag "status_id", options_for_select(Status.find_all.map{ |s| [s.name, s.id] }.unshift(['Use the same status', nil]))
41
+
42
+ %p.buttons
43
+ = submit_tag "Ok", :class => 'button'
44
+ or
45
+ = link_to "Cancel", admin_pages_url
46
+
@@ -0,0 +1,10 @@
1
+ de:
2
+ copy_move:
3
+ copied:
4
+ 'Eine Kopie von <strong>{{page}}</strong> wurde unterhalb von <strong>{{parent}}</strong> erstellt.'
5
+ immediate_children_copied:
6
+ 'Eine Kopie der Seite <strong>{{page}}</strong> sowie der unmittelbaren Unterseiten wurde unter <strong>{{parent}}</strong> erstellt.'
7
+ descendants_copied:
8
+ 'Eine Kopie der Seite <strong>{{page}}</strong> sowie aller Unterseiten wurde unter <strong>{{parent}}</strong> erstellt.'
9
+ descendants_moved:
10
+ 'Die Seite <strong>{{page}}</strong> und alle Unterseiten wurden verschoben in <strong>{{parent}}</strong>.'
@@ -0,0 +1,10 @@
1
+ en:
2
+ copy_move:
3
+ copied:
4
+ 'A copy of <strong>{{page}}</strong> was created under <strong>{{parent}}</strong>.'
5
+ immediate_children_copied:
6
+ 'Copies of <strong>{{page}}</strong> and its immediate children were created under <strong>{{parent}}</strong>'
7
+ descendants_copied:
8
+ 'Copies of <strong>{{page}}</strong> and all its descendants were created under <strong>{{parent}}</strong>.'
9
+ descendants_moved:
10
+ 'Page <strong>{{page}}</strong> and all its descendants were moved under <strong>{{parent}}</strong>.'
@@ -0,0 +1,10 @@
1
+ nl-BE:
2
+ copy_move:
3
+ copied:
4
+ 'Er werd een kopie van <strong>{{page}}</strong> gemaakt onder <strong>{{parent}}</strong>.'
5
+ immediate_children_copied:
6
+ "Kopieën van <strong>{{page}}</strong> en de eerst onderliggende pagina's zijn gemaakt onder <strong>{{parent}}</strong>"
7
+ descendants_copied:
8
+ "Kopieën van <strong>{{page}}</strong> en alle onderliggende pagina's zijn gemaakt onder <strong>{{parent}}</strong>."
9
+ descendants_moved:
10
+ "De pagina <strong>{{page}}</strong> en alle onderliggende pagina's zijn verplaatst onder <strong>{{parent}}</strong>."
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.with_options(:controller => "admin/pages") do |cm|
3
+ cm.copy_page_admin_page '/admin/pages/:id/copy_page', :action => 'copy_page'
4
+ cm.copy_children_admin_page '/admin/pages/:id/copy_children', :action => 'copy_children'
5
+ cm.copy_tree_admin_page '/admin/pages/:id/copy_tree', :action => 'copy_tree'
6
+ cm.move_admin_page '/admin/pages/:id/move', :action => 'move'
7
+ end
8
+ end
@@ -0,0 +1,28 @@
1
+ require_dependency 'application_controller'
2
+
3
+ class CopyMoveExtension < Radiant::Extension
4
+ version "2.0.1"
5
+ description "Adds the ability to copy and move a page and all of its children"
6
+ url "http://gravityblast.com/projects/radiant-copymove-extension/"
7
+
8
+ # good by for define_routes
9
+ #define_routes do |map|
10
+ # map.with_options(:controller => "admin/pages") do |cm|
11
+ # cm.copy_page_admin_page '/admin/pages/:id/copy_page', :action => 'copy_page'
12
+ # cm.copy_children_admin_page '/admin/pages/:id/copy_children', :action => 'copy_children'
13
+ # cm.copy_tree_admin_page '/admin/pages/:id/copy_tree', :action => 'copy_tree'
14
+ # cm.move_admin_page '/admin/pages/:id/move', :action => 'move'
15
+ # end
16
+ #end
17
+
18
+ def activate
19
+ Admin::PagesController.class_eval do
20
+ include CopyMove::Controller
21
+ helper :copy_move
22
+ end
23
+ Page.class_eval { include CopyMove::Model }
24
+ admin.page.index.add :sitemap_head, 'copy_move_extra_th'
25
+ admin.page.index.add :node, 'copy_move_extra_td', :after => "add_child_column"
26
+ admin.page.index.add :bottom, 'copy_move_popup'
27
+ end
28
+ end
data/lib/copy_move.rb ADDED
@@ -0,0 +1,8 @@
1
+ module CopyMove
2
+ class CircularHierarchy < ActiveRecord::ActiveRecordError
3
+ def initialize(record)
4
+ @record = record
5
+ super("Page #{record.title} cannot be made a descendant of itself.")
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,49 @@
1
+ module CopyMove
2
+ module Controller
3
+ def self.included(base)
4
+ base.class_eval do
5
+ before_filter do |c|
6
+ c.include_stylesheet 'admin/copy_move'
7
+ end
8
+ before_filter :load_page, :only => [:copy_page, :copy_children, :copy_tree, :move]
9
+ before_filter :load_parent, :only => [:copy_page, :copy_children, :copy_tree, :move]
10
+ end
11
+ end
12
+
13
+ def copy_page
14
+ @new_page = @page.copy_to(@parent, params[:status_id])
15
+ flash[:notice] = I18n.t('copied', :scope => :copy_move, :page => @page.title, :parent => @parent.title)
16
+ redirect_to admin_pages_url
17
+ end
18
+
19
+ def copy_children
20
+ @new_page = @page.copy_with_children_to(@parent, params[:status_id])
21
+ flash[:notice] = I18n.t('immediate_children_copied', :scope => :copy_move, :page => @page.title, :parent => @parent.title)
22
+ redirect_to admin_pages_url
23
+ end
24
+
25
+ def copy_tree
26
+ @new_page = @page.copy_tree_to(@parent, params[:status_id])
27
+ flash[:notice] = I18n.t('descendants_copied', :scope => :copy_move, :page => @page.title, :parent => @parent.title)
28
+ redirect_to admin_pages_url
29
+ end
30
+
31
+ def move
32
+ @page.move_under(@parent)
33
+ flash[:notice] = I18n.t('descendants_moved', :scope => :copy_move, :page => @page.title, :parent => @parent.title)
34
+ redirect_to admin_pages_url
35
+ rescue CopyMove::CircularHierarchy => e
36
+ flash[:error] = e.message
37
+ redirect_to admin_pages_url
38
+ end
39
+
40
+ private
41
+ def load_parent
42
+ @parent = Page.find(params[:parent_id])
43
+ end
44
+
45
+ def load_page
46
+ self.model = @page = Page.find(params[:id])
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,48 @@
1
+ module CopyMove
2
+ module Model
3
+ def new_slug_and_title_under(parent)
4
+ test_page = self.clone
5
+ test_page.parent = parent
6
+ until test_page.valid?
7
+ index = (index || 0) + 1
8
+ test_page.title = "#{title} Copy #{index}"
9
+ test_page.slug = "#{slug}-copy-#{index}"
10
+ test_page.breadcrumb = test_page.title
11
+ test_page.errors.clear # Reset error status before revalidating
12
+ end
13
+ {:slug => test_page.slug, :title => test_page.title, :breadcrumb => test_page.breadcrumb}
14
+ end
15
+
16
+ def move_under(parent)
17
+ raise CircularHierarchy.new(self) if parent == self || parent.ancestors.include?(self)
18
+ update_attributes!(:parent_id => parent.id)
19
+ end
20
+
21
+ def copy_to(parent, status = nil)
22
+ parent.children.build(copiable_attributes.symbolize_keys.merge(new_slug_and_title_under(parent))).tap do |new_page|
23
+ self.parts.each do |part|
24
+ new_page.parts << part.clone
25
+ end
26
+ new_page.status_id = status.blank? ? new_page.status_id : status
27
+ new_page.save!
28
+ end
29
+ end
30
+
31
+ def copy_with_children_to(parent, status = nil)
32
+ copy_to(parent, status).tap do |new_page|
33
+ children.each {|child| child.copy_to(new_page, status) }
34
+ end
35
+ end
36
+
37
+ def copy_tree_to(parent, status = nil)
38
+ copy_to(parent, status).tap do |new_page|
39
+ children.each {|child| child.copy_tree_to(new_page, status) }
40
+ end
41
+ end
42
+
43
+ private
44
+ def copiable_attributes
45
+ self.attributes.dup.delete_if {|k,v| [:id, :parent_id].include?(k.to_sym) }
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,28 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :copy_move do
4
+
5
+ desc "Runs the migration of the Copy Move extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ CopyMoveExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ else
11
+ CopyMoveExtension.migrator.migrate
12
+ end
13
+ end
14
+
15
+ desc "Copies public assets of the Copy Move 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 CopyMoveExtension"
19
+ Dir[CopyMoveExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
20
+ path = file.sub(CopyMoveExtension.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
Binary file
Binary file
@@ -0,0 +1,30 @@
1
+ #content table.index .copy-move {
2
+ padding-left:0pt;
3
+ width:100px;
4
+ }
5
+
6
+ td.copy-move {
7
+ position: relative; }
8
+ td.copy-move ul.popup-menu {
9
+ position: absolute;
10
+ z-index: 1000;
11
+ margin-top: 0.5em;
12
+ margin-left: -1.5em;
13
+ background: white;
14
+ border-width: 1px;
15
+ border-color: #bbb;
16
+ border-style: solid;
17
+ border-bottom: none;
18
+ padding: 0; }
19
+ td.copy-move ul.popup-menu li {
20
+ list-style: none; }
21
+ td.copy-move ul.popup-menu li a {
22
+ display: block;
23
+ padding: 0.5em;
24
+ padding-left: 24px;
25
+ background-position: 4px center;
26
+ background-repeat: no-repeat;
27
+ border-bottom: 1px solid #bbb;
28
+ color: black; }
29
+ td.copy-move ul.popup-menu li a:hover {
30
+ background-color: rgb(255, 255, 179); }
@@ -0,0 +1,77 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{radiant-copy_move-extension}
8
+ s.version = "2.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Benny Degezelle"]
12
+ s.date = %q{2010-08-28}
13
+ s.description = %q{Allows you to to copy pages or move them under a new parent. }
14
+ s.email = %q{benny@gorilla-webdesign.be}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README",
18
+ "TODO"
19
+ ]
20
+ s.files = [
21
+ "HELP.rdoc",
22
+ "LICENSE",
23
+ "README",
24
+ "Rakefile",
25
+ "TODO",
26
+ "VERSION",
27
+ "app/helpers/copy_move_helper.rb",
28
+ "app/views/admin/pages/_copy_move_extra_td.haml",
29
+ "app/views/admin/pages/_copy_move_extra_th.haml",
30
+ "app/views/admin/pages/_copy_move_popup.haml",
31
+ "app/views/copy_move/index.html.haml",
32
+ "config/locales/de.yml",
33
+ "config/locales/en.yml",
34
+ "config/locales/nl-BE.yml",
35
+ "config/routes.rb",
36
+ "copy_move_extension.rb",
37
+ "lib/copy_move.rb",
38
+ "lib/copy_move/controller.rb",
39
+ "lib/copy_move/model.rb",
40
+ "lib/tasks/copy_move_extension_tasks.rake",
41
+ "public/images/admin/copy-move.png",
42
+ "public/images/admin/page_white.png",
43
+ "public/images/admin/page_white_copy.png",
44
+ "public/images/admin/page_white_go.png",
45
+ "public/images/admin/page_white_stack.png",
46
+ "public/stylesheets/admin/copy_move.css",
47
+ "radiant-copy_move-extension.gemspec",
48
+ "spec/controllers/copy_move_controller_spec.rb",
49
+ "spec/models/copy_move_spec.rb",
50
+ "spec/spec.opts",
51
+ "spec/spec_helper.rb"
52
+ ]
53
+ s.homepage = %q{http://github.com/jomz/radiant-comments-extension}
54
+ s.rdoc_options = ["--charset=UTF-8"]
55
+ s.require_paths = ["lib"]
56
+ s.rubygems_version = %q{1.3.7}
57
+ s.summary = %q{Copy/Move extension for Radiant CMS}
58
+ s.test_files = [
59
+ "spec/controllers/copy_move_controller_spec.rb",
60
+ "spec/models/copy_move_spec.rb",
61
+ "spec/spec_helper.rb"
62
+ ]
63
+
64
+ if s.respond_to? :specification_version then
65
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
66
+ s.specification_version = 3
67
+
68
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
69
+ s.add_runtime_dependency(%q<radiant>, ["= 0.9.0"])
70
+ else
71
+ s.add_dependency(%q<radiant>, ["= 0.9.0"])
72
+ end
73
+ else
74
+ s.add_dependency(%q<radiant>, ["= 0.9.0"])
75
+ end
76
+ end
77
+
@@ -0,0 +1,167 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Admin::PagesController do
4
+ dataset :users_and_pages
5
+ before :each do
6
+ login_as :existing
7
+ end
8
+
9
+ describe "routes" do
10
+ it "should route URLs to the copy_page action" do
11
+ route_for(:controller => "admin/pages", :action => "copy_page", :id => "1").should == "/admin/pages/1/copy_page"
12
+ params_from(:post, "/admin/pages/1/copy_page").should == {:controller => "admin/pages", :action => "copy_page", :id => "1"}
13
+ end
14
+
15
+ it "should route URLs to the copy_children action" do
16
+ route_for(:controller => "admin/pages", :action => "copy_children", :id => "1").should == "/admin/pages/1/copy_children"
17
+ params_from(:post, "/admin/pages/1/copy_children").should == {:controller => "admin/pages", :action => "copy_children", :id => "1"}
18
+ end
19
+
20
+ it "should route URLs to the copy_tree action" do
21
+ route_for(:controller => "admin/pages", :action => "copy_tree", :id => "1").should == "/admin/pages/1/copy_tree"
22
+ params_from(:post, "/admin/pages/1/copy_tree").should == {:controller => "admin/pages", :action => "copy_tree", :id => "1"}
23
+ end
24
+
25
+ it "should route URLs to the move action" do
26
+ route_for(:controller => "admin/pages", :action => "move", :id => "1").should == "/admin/pages/1/move"
27
+ params_from(:post, "/admin/pages/1/move").should == {:controller => "admin/pages", :action => "move", :id => "1"}
28
+ end
29
+ end
30
+
31
+ describe "POST to /admin/pages/:id/copy_page" do
32
+ before :each do
33
+ post :copy_page, :id => page_id(:first), :parent_id => page_id(:another)
34
+ end
35
+
36
+ it "should load the page" do
37
+ assigns[:page].should == pages(:first)
38
+ end
39
+
40
+ it "should load the parent page" do
41
+ assigns[:parent].should == pages(:another)
42
+ end
43
+
44
+ it "should create a new page" do
45
+ assigns[:new_page].should be
46
+ end
47
+
48
+ it "should write a flash notice" do
49
+ flash[:notice].should be
50
+ end
51
+
52
+ it "should redirect to the sitemap" do
53
+ response.should redirect_to(admin_pages_url)
54
+ end
55
+ end
56
+
57
+ describe "POST to /admin/pages/:id/copy_children" do
58
+ before :each do
59
+ post :copy_children, :id => page_id(:assorted), :parent_id => page_id(:another)
60
+ end
61
+
62
+ it "should load the page" do
63
+ assigns[:page].should == pages(:assorted)
64
+ end
65
+
66
+ it "should load the parent page" do
67
+ assigns[:parent].should == pages(:another)
68
+ end
69
+
70
+ it "should create a new page" do
71
+ assigns[:new_page].should be
72
+ end
73
+
74
+ it "should have copied the children" do
75
+ assigns[:new_page].should have(12).children
76
+ end
77
+
78
+ it "should write a flash notice" do
79
+ flash[:notice].should be
80
+ end
81
+
82
+ it "should redirect to the sitemap" do
83
+ response.should redirect_to(admin_pages_url)
84
+ end
85
+ end
86
+
87
+ describe "POST to /admin/pages/:id/copy_tree" do
88
+ before :each do
89
+ post :copy_tree, :id => page_id(:parent), :parent_id => page_id(:another)
90
+ end
91
+
92
+ it "should load the page" do
93
+ assigns[:page].should == pages(:parent)
94
+ end
95
+
96
+ it "should load the parent page" do
97
+ assigns[:parent].should == pages(:another)
98
+ end
99
+
100
+ it "should create a new page" do
101
+ assigns[:new_page].should be
102
+ end
103
+
104
+ it "should have copied the descendants" do
105
+ assigns[:new_page].should have(3).children
106
+ assigns[:new_page].children.first.should have(1).child
107
+ end
108
+
109
+ it "should write a flash notice" do
110
+ flash[:notice].should be
111
+ end
112
+
113
+ it "should redirect to the sitemap" do
114
+ response.should redirect_to(admin_pages_url)
115
+ end
116
+ end
117
+
118
+ describe "POST to /admin/pages/:id/move" do
119
+ describe "when moving to a valid parent" do
120
+ before :each do
121
+ post :move, :id => page_id(:first), :parent_id => page_id(:another)
122
+ end
123
+
124
+ it "should load the page" do
125
+ assigns[:page].should == pages(:first)
126
+ end
127
+
128
+ it "should load the parent page" do
129
+ assigns[:parent].should == pages(:another)
130
+ end
131
+
132
+ it "should have moved the page to its new parent" do
133
+ assigns[:page].parent.should == assigns[:parent]
134
+ end
135
+
136
+ it "should write a flash notice" do
137
+ flash[:notice].should be
138
+ end
139
+
140
+ it "should redirect to the sitemap" do
141
+ response.should redirect_to(admin_pages_url)
142
+ end
143
+ end
144
+
145
+ describe "when moving to an invalid parent" do
146
+ before :each do
147
+ post :move, :id => page_id(:parent), :parent_id => page_id(:child)
148
+ end
149
+
150
+ it "should load the page" do
151
+ assigns[:page].should == pages(:parent)
152
+ end
153
+
154
+ it "should load the parent page" do
155
+ assigns[:parent].should == pages(:child)
156
+ end
157
+
158
+ it "should write a flash error" do
159
+ flash[:error].should be
160
+ end
161
+
162
+ it "should redirect to the sitemap" do
163
+ response.should redirect_to(admin_pages_url)
164
+ end
165
+ end
166
+ end
167
+ end
@@ -0,0 +1,112 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe CopyMove do
4
+ dataset :pages
5
+
6
+ describe "suggesting a new slug and title" do
7
+ it "should use the same slug and title when there is not a child page of the new parent that has the same slug or title" do
8
+ pages(:first).new_slug_and_title_under(pages(:parent)).should == {:slug => "first", :title => "First"}
9
+ end
10
+
11
+ it "should use a different slug and title when there is a conflicting child page of the new parent" do
12
+ pages(:first).new_slug_and_title_under(pages(:home)).should_not == {:slug => "first", :title => "First"}
13
+ pages(:first).new_slug_and_title_under(pages(:home)).should == {:slug => "first-1", :title => "First (Copy)"}
14
+ end
15
+ end
16
+
17
+ describe "moving under a new parent" do
18
+ it "should refuse to move under itself" do
19
+ lambda { pages(:first).move_under(pages(:first)) }.should raise_error(CopyMove::CircularHierarchy)
20
+ end
21
+
22
+ it "should refuse to move under a descendant of itself" do
23
+ lambda { pages(:parent).move_under(pages(:child)) }.should raise_error(CopyMove::CircularHierarchy)
24
+ end
25
+
26
+ it "should move to a new parent" do
27
+ @page = pages(:first)
28
+ lambda { @page.move_under(pages(:another)) }.should_not raise_error
29
+ end
30
+ end
31
+
32
+ describe "copying the page" do
33
+ before :each do
34
+ @page = pages(:first)
35
+ end
36
+
37
+ it "should duplicate the page" do
38
+ @new_page = @page.copy_to(pages(:another))
39
+ @page.attributes.delete_if {|k,v| [:id, :parent_id].include?(k.to_sym) }.each do |key,value|
40
+ @new_page[key].should == value
41
+ end
42
+ @page.parts.each do |part|
43
+ @new_page.part(part.name).should_not be_nil
44
+ end
45
+ end
46
+
47
+ it "should use a new slug and title if a similar page exists under the new parent" do
48
+ @new_page = @page.copy_to(pages(:home))
49
+ @new_page.slug.should_not == @page.slug
50
+ @new_page.title.should_not == @page.title
51
+ end
52
+
53
+ it "should override the status when given" do
54
+ @new_page = @page.copy_to(pages(:another), Status[:draft].id)
55
+ @new_page.status.should == Status[:draft]
56
+ end
57
+
58
+ it "should ignore a blank status" do
59
+ @new_page = @page.copy_to(pages(:another), ' ')
60
+ @new_page.status.should == Status[:published]
61
+ end
62
+ end
63
+
64
+ describe "copying the page with first-level children" do
65
+ it "should copy the page and its children" do
66
+ @page = pages(:assorted)
67
+ @new_page = @page.copy_with_children_to(pages(:first))
68
+ @new_page.parent.should == pages(:first)
69
+ @new_page.should have(12).children
70
+ end
71
+
72
+ it "should not copy grandchild pages" do
73
+ @page = pages(:parent)
74
+ @new_page = @page.copy_with_children_to(pages(:childless))
75
+ @new_page.children.count.should == 3
76
+ @new_page.children.first.children.count.should == 0
77
+ end
78
+
79
+ it "should override the status when given" do
80
+ @page = pages(:assorted)
81
+ @new_page = @page.copy_with_children_to(pages(:first), Status[:hidden].id)
82
+ @new_page.status.should == Status[:hidden]
83
+ @new_page.children.each do |child|
84
+ child.status.should == Status[:hidden]
85
+ end
86
+ end
87
+ end
88
+
89
+ describe "copying the page with all descendants" do
90
+ before :each do
91
+ @page = pages(:parent)
92
+ end
93
+
94
+ it "should copy the page and all descendants" do
95
+ @new_page = @page.copy_tree_to(pages(:first))
96
+ @new_page.parent.should == pages(:first)
97
+ @new_page.should have(3).children
98
+ @new_page.children.first.should have(1).child
99
+ @new_page.children.first.children.first.should have(1).child
100
+ end
101
+
102
+ it "should override the status when given" do
103
+ @new_page = @page.copy_tree_to(pages(:first), Status[:hidden].id)
104
+ @new_page.status.should == Status[:hidden]
105
+ @new_page.children.each do |child|
106
+ child.status.should == Status[:hidden]
107
+ end
108
+ @new_page.children.first.children.first.status.should == Status[:hidden]
109
+ @new_page.children.first.children.first.children.first.status.should == Status[:hidden]
110
+ end
111
+ end
112
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,6 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
@@ -0,0 +1,36 @@
1
+ unless defined? RADIANT_ROOT
2
+ ENV["RAILS_ENV"] = "test"
3
+ case
4
+ when ENV["RADIANT_ENV_FILE"]
5
+ require ENV["RADIANT_ENV_FILE"]
6
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
7
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment"
8
+ else
9
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment"
10
+ end
11
+ end
12
+ require "#{RADIANT_ROOT}/spec/spec_helper"
13
+
14
+ Dataset::Resolver.default << (File.dirname(__FILE__) + "/datasets")
15
+
16
+ if File.directory?(File.dirname(__FILE__) + "/matchers")
17
+ Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
18
+ end
19
+
20
+ Spec::Runner.configure do |config|
21
+ # config.use_transactional_fixtures = true
22
+ # config.use_instantiated_fixtures = false
23
+ # config.fixture_path = RAILS_ROOT + '/spec/fixtures'
24
+
25
+ # You can declare fixtures for each behaviour like this:
26
+ # describe "...." do
27
+ # fixtures :table_a, :table_b
28
+ #
29
+ # Alternatively, if you prefer to declare them only once, you can
30
+ # do so here, like so ...
31
+ #
32
+ # config.global_fixtures = :table_a, :table_b
33
+ #
34
+ # If you declare global fixtures, be aware that they will be declared
35
+ # for all of your examples, even those that don't use them.
36
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-copy_move-extension
3
+ version: !ruby/object:Gem::Version
4
+ hash: 11
5
+ prerelease: false
6
+ segments:
7
+ - 2
8
+ - 1
9
+ - 0
10
+ version: 2.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Benny Degezelle
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-08-28 00:00:00 +02:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: radiant
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - "="
28
+ - !ruby/object:Gem::Version
29
+ hash: 59
30
+ segments:
31
+ - 0
32
+ - 9
33
+ - 0
34
+ version: 0.9.0
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: "Allows you to to copy pages or move them under a new parent. "
38
+ email: benny@gorilla-webdesign.be
39
+ executables: []
40
+
41
+ extensions: []
42
+
43
+ extra_rdoc_files:
44
+ - LICENSE
45
+ - README
46
+ - TODO
47
+ files:
48
+ - HELP.rdoc
49
+ - LICENSE
50
+ - README
51
+ - Rakefile
52
+ - TODO
53
+ - VERSION
54
+ - app/helpers/copy_move_helper.rb
55
+ - app/views/admin/pages/_copy_move_extra_td.haml
56
+ - app/views/admin/pages/_copy_move_extra_th.haml
57
+ - app/views/admin/pages/_copy_move_popup.haml
58
+ - app/views/copy_move/index.html.haml
59
+ - config/locales/de.yml
60
+ - config/locales/en.yml
61
+ - config/locales/nl-BE.yml
62
+ - config/routes.rb
63
+ - copy_move_extension.rb
64
+ - lib/copy_move.rb
65
+ - lib/copy_move/controller.rb
66
+ - lib/copy_move/model.rb
67
+ - lib/tasks/copy_move_extension_tasks.rake
68
+ - public/images/admin/copy-move.png
69
+ - public/images/admin/page_white.png
70
+ - public/images/admin/page_white_copy.png
71
+ - public/images/admin/page_white_go.png
72
+ - public/images/admin/page_white_stack.png
73
+ - public/stylesheets/admin/copy_move.css
74
+ - radiant-copy_move-extension.gemspec
75
+ - spec/controllers/copy_move_controller_spec.rb
76
+ - spec/models/copy_move_spec.rb
77
+ - spec/spec.opts
78
+ - spec/spec_helper.rb
79
+ has_rdoc: true
80
+ homepage: http://github.com/jomz/radiant-comments-extension
81
+ licenses: []
82
+
83
+ post_install_message:
84
+ rdoc_options:
85
+ - --charset=UTF-8
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ hash: 3
94
+ segments:
95
+ - 0
96
+ version: "0"
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ none: false
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ hash: 3
103
+ segments:
104
+ - 0
105
+ version: "0"
106
+ requirements: []
107
+
108
+ rubyforge_project:
109
+ rubygems_version: 1.3.7
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Copy/Move extension for Radiant CMS
113
+ test_files:
114
+ - spec/controllers/copy_move_controller_spec.rb
115
+ - spec/models/copy_move_spec.rb
116
+ - spec/spec_helper.rb