radiant-drag_order-extension 0.3.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +76 -0
- data/Rakefile +137 -0
- data/VERSION +1 -0
- data/app/views/admin/pages/_drag_order.html.haml +4 -0
- data/app/views/admin/pages/_drag_order_header.html.haml +2 -0
- data/app/views/admin/pages/_top.html.haml +3 -0
- data/config/routes.rb +7 -0
- data/db/migrate/01_add_position_to_pages.rb +27 -0
- data/db/migrate/02_add_default_position.rb +14 -0
- data/drag_order_extension.rb +16 -0
- data/lib/drag_order/controllers/admin/pages_controller.rb +154 -0
- data/lib/drag_order/models/page.rb +56 -0
- data/lib/drag_order/tags/core.rb +18 -0
- data/lib/tasks/drag_order_extension_tasks.rake +27 -0
- data/public/images/admin/extensions/drag_order/circle.png +0 -0
- data/public/images/admin/extensions/drag_order/copy.png +0 -0
- data/public/images/admin/extensions/drag_order/handle.png +0 -0
- data/public/javascripts/admin/extensions/drag_order/drag_order.js +192 -0
- data/public/stylesheets/sass/admin/extensions/drag_order/drag_order.sass +40 -0
- data/radiant-drag_order-extension.gemspec +63 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +37 -0
- metadata +103 -0
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# DragOrder for Radiant 0.9.0+
|
2
|
+
|
3
|
+
Created by Bright 4, February 2009. Inspired by and based on Sean Cribbs' Reorder extension.
|
4
|
+
|
5
|
+
## Notes
|
6
|
+
|
7
|
+
Only designers and admins have the ability to re-order pages
|
8
|
+
|
9
|
+
Master should work with Radiant Edge. Use git tag radiant-0.9.1 with the Radiant 0.9.1 gem.
|
10
|
+
|
11
|
+
## Installation
|
12
|
+
|
13
|
+
git clone git://github.com/gerrit/radiant-drag-order.git vendor/extensions/drag_order
|
14
|
+
|
15
|
+
rake radiant:extensions:drag_order:migrate
|
16
|
+
rake radiant:extensions:drag_order:update
|
17
|
+
|
18
|
+
## Version History
|
19
|
+
|
20
|
+
### v0.3.7 - 2010-11-22
|
21
|
+
|
22
|
+
* Turned into a gem
|
23
|
+
* Went back to radiant-drag_order-extension instead of radiant-drag-extension
|
24
|
+
|
25
|
+
### v0.3.6 - 2010-08-31
|
26
|
+
|
27
|
+
* updated for Radiant 0.9 edge. Use tag radiant-0.9.1 with released gem version
|
28
|
+
|
29
|
+
### v0.3.5 - 2010-07-09
|
30
|
+
|
31
|
+
* renamed back to DragOrder
|
32
|
+
* SQL Injection fixes
|
33
|
+
* code cleanup
|
34
|
+
|
35
|
+
### v0.3.4 - 29-03-2010
|
36
|
+
|
37
|
+
* Moved assets to extension/drag directory
|
38
|
+
* Updated instructions
|
39
|
+
|
40
|
+
### v0.3.3 - 09-02-2010
|
41
|
+
|
42
|
+
* Made compatible with Radiant 0.9.0
|
43
|
+
|
44
|
+
### v0.3.2 - 18-11-2009
|
45
|
+
|
46
|
+
* Made compatible with Radiant 0.8.1. This extension should now be compatible with at least version >= 0.6.9
|
47
|
+
|
48
|
+
### v0.3.1 - 25-05-2009
|
49
|
+
|
50
|
+
* FIX: if the move request takes some time to finish, the dragline now stays put when dropped instead of still being
|
51
|
+
dragged along with the mouse.
|
52
|
+
* Changed color of the row that is being dragged to fit better with default Radiant colors.
|
53
|
+
* Small robustness-fix for cases when the rake migrate is forgotten.
|
54
|
+
* Modified install instructions in README.
|
55
|
+
|
56
|
+
### v0.3 - 16-03-2009
|
57
|
+
|
58
|
+
* Incorporated copy functionality. When pressing Ctrl or Command, you can copy the item.
|
59
|
+
* Fixed errors which occurred when trying to place two pages with the same slugs. Now, the second one is seen as a copy.
|
60
|
+
* Fixed some JS errors.
|
61
|
+
|
62
|
+
### v0.2.3 - 16-03-2009
|
63
|
+
|
64
|
+
* v0.2.2. was not really compatible with Radiant > 0.6.9... This one should be compatible with versions both before and after 0.7.
|
65
|
+
|
66
|
+
### v0.2.2 - 12-03-2009
|
67
|
+
|
68
|
+
* Made compatible with Radiant > 0.6.9
|
69
|
+
|
70
|
+
### v0.2.1 - 23-02-2009
|
71
|
+
|
72
|
+
* Fixed JS bug that did not allow dragging of child pages which were loaded using AJAX after expanding a page.
|
73
|
+
|
74
|
+
### v0.2 - 21-02-2009
|
75
|
+
|
76
|
+
* Initial commit
|
data/Rakefile
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
begin
|
2
|
+
require 'jeweler'
|
3
|
+
Jeweler::Tasks.new do |gem|
|
4
|
+
gem.name = "radiant-drag_order-extension"
|
5
|
+
gem.summary = %Q{Drag Order Extension for Radiant CMS}
|
6
|
+
gem.description = %Q{Radiant DragOrder allows you to reorder pages funly}
|
7
|
+
gem.email = "dk@dirkkelly.com"
|
8
|
+
gem.homepage = "http://github.com/dirkkelly/radiant-drag_order-extension"
|
9
|
+
gem.authors = ["Dirk Kelly"]
|
10
|
+
gem.add_dependency 'radiant', '>= 0.9.1'
|
11
|
+
end
|
12
|
+
Jeweler::GemcutterTasks.new
|
13
|
+
rescue LoadError
|
14
|
+
puts "Jeweler (or a dependency) not available. This is only required if you plan to package drag_order 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["#{extension_root}/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 drag_order extension.'
|
120
|
+
Rake::RDocTask.new(:rdoc) do |rdoc|
|
121
|
+
rdoc.rdoc_dir = 'rdoc'
|
122
|
+
rdoc.title = 'DragOrderExtension'
|
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 drag_order 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/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.3.7
|
data/config/routes.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
class AddPositionToPages < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
unless Page.column_names.include?('position') # ie. unless the reorder extension has been installed
|
4
|
+
add_column :pages, :position, :integer
|
5
|
+
Page.reset_column_information
|
6
|
+
say_with_time("Putting all pages in a default order...") do
|
7
|
+
ActiveRecord::Base.record_timestamps = false
|
8
|
+
Page.find_all_by_parent_id(nil).each do |p|
|
9
|
+
put_children_into_list(p)
|
10
|
+
end
|
11
|
+
ActiveRecord::Base.record_timestamps = true
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.down
|
17
|
+
remove_column :pages, :position
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.put_children_into_list(page)
|
21
|
+
page.children.find(:all, :order => "title asc").each_with_index do |pg, idx|
|
22
|
+
pg.update_attribute('position', idx + 1)
|
23
|
+
put_children_into_list(pg)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class AddDefaultPosition < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_column :pages, :position, :integer, :default => 0
|
4
|
+
|
5
|
+
Page.all.each do |page|
|
6
|
+
page.position = 0 if page.position.nil?
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.down
|
11
|
+
change_column :pages, :position, :integer, :default => nil
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
class DragOrderExtension < Radiant::Extension
|
2
|
+
version YAML::load_file(File.join(File.dirname(__FILE__), 'VERSION'))
|
3
|
+
description "Radiant DragOrder allows you to reorder pages funly"
|
4
|
+
url "https://github.com/dirkkelly/radiant-drag-order"
|
5
|
+
|
6
|
+
def activate
|
7
|
+
Page.send :include, DragOrder::Models::Page
|
8
|
+
StandardTags.send :include, DragOrder::Tags::Core
|
9
|
+
Admin::PagesController.send :include, DragOrder::Controllers::Admin::PagesController
|
10
|
+
|
11
|
+
admin.pages.index.add :sitemap_head, "drag_order_header", :before => "title_column_header"
|
12
|
+
admin.pages.index.add :node, "drag_order", :before => "title_column"
|
13
|
+
admin.pages.index.add :top, "top"
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
@@ -0,0 +1,154 @@
|
|
1
|
+
module DragOrder
|
2
|
+
module Controllers
|
3
|
+
module Admin
|
4
|
+
module PagesController
|
5
|
+
|
6
|
+
def self.included(base)
|
7
|
+
base.class_eval do
|
8
|
+
|
9
|
+
helper_method :order_dragger
|
10
|
+
|
11
|
+
def move_to
|
12
|
+
@page = Page.find(params[:id])
|
13
|
+
@old_parent = @page.parent
|
14
|
+
@current_position = params[:pos].to_i
|
15
|
+
|
16
|
+
ensure_no_nil_position_values
|
17
|
+
|
18
|
+
remove_page_from_old_position unless copying?
|
19
|
+
|
20
|
+
@target = Page.find(params[:rel])
|
21
|
+
|
22
|
+
make_room_for_page if @current_position != 2
|
23
|
+
|
24
|
+
if copying?
|
25
|
+
@orig_parts = @page.parts
|
26
|
+
@page = @page.clone
|
27
|
+
end
|
28
|
+
|
29
|
+
@target.reload
|
30
|
+
|
31
|
+
put_page
|
32
|
+
|
33
|
+
solve_slug_conflicts if copying? || new_parent_different?
|
34
|
+
|
35
|
+
@page.save!
|
36
|
+
|
37
|
+
create_copy_of_parts if copying?
|
38
|
+
|
39
|
+
clear_cache
|
40
|
+
redirect_back_or_to_admin_pages_page
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def order_dragger
|
45
|
+
%{<img src="/images/admin/extensions/drag_order/handle.png" alt ="Drag this icon to move the page" />}
|
46
|
+
end
|
47
|
+
|
48
|
+
def copying?
|
49
|
+
params[:copy].to_i > 0
|
50
|
+
end
|
51
|
+
|
52
|
+
def ensure_no_nil_position_values
|
53
|
+
if @page.newly_created_siblings?
|
54
|
+
i = 1
|
55
|
+
@page.siblings_and_self.each do |p|
|
56
|
+
p.position = i
|
57
|
+
p.save
|
58
|
+
i += 1
|
59
|
+
end
|
60
|
+
@page.reload
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def remove_page_from_old_position
|
65
|
+
@page.following_siblings.each do |sibling|
|
66
|
+
sibling.position -= 1
|
67
|
+
sibling.save!
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def put_page
|
72
|
+
if @current_position != 2
|
73
|
+
@page.parent = @target.parent
|
74
|
+
@page.position = @target.position.to_i + (@current_position == 1 ? 1 : -1)
|
75
|
+
else
|
76
|
+
@page.parent = @target
|
77
|
+
@page.position = 1
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def make_room_for_page
|
82
|
+
new_siblings = Page.children_of_after_position(@target.parent_id, @target.position + @current_position)
|
83
|
+
new_siblings.each do |sibling|
|
84
|
+
if sibling != @page || copying?
|
85
|
+
sibling.position += 1
|
86
|
+
sibling.save!
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def new_parent_different?
|
92
|
+
# @page.parent.changed? always gives false...
|
93
|
+
@page.parent != @old_parent
|
94
|
+
end
|
95
|
+
|
96
|
+
def solve_slug_conflicts
|
97
|
+
check_slug = @page.slug.sub(/-copy-?[0-9]*$/, "")
|
98
|
+
count = 0
|
99
|
+
parent_id = @current_position == 2 ? @target.id : @target.parent.id
|
100
|
+
duplicates = Page.children_of_with_slug_like(parent_id, check_slug )
|
101
|
+
duplicates.each do |d|
|
102
|
+
m = d.slug.match("^#{check_slug}(-copy-?([0-9]*))?$")
|
103
|
+
if !m.nil?
|
104
|
+
if !(m[2].nil? || m[2] == "")
|
105
|
+
nc = m[2].to_i + 1
|
106
|
+
elsif m[1]
|
107
|
+
nc = 2
|
108
|
+
else
|
109
|
+
nc = 1
|
110
|
+
end
|
111
|
+
count = nc if nc > count
|
112
|
+
end
|
113
|
+
end
|
114
|
+
if count > 0
|
115
|
+
# Remove old copy counters
|
116
|
+
re = / - COPY ?[0-9]*$/
|
117
|
+
@page.title.sub! re, ""
|
118
|
+
@page.breadcrumb.sub! re, ""
|
119
|
+
# Add new copy counters
|
120
|
+
@page.slug = check_slug + "-copy" + (count > 1 ? "-" + count.to_s : "")
|
121
|
+
@page.title += " - COPY" + (count > 1 ? " " + count.to_s : "")
|
122
|
+
@page.breadcrumb += " - COPY" + (count > 1 ? " " + count.to_s : "")
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
def create_copy_of_parts
|
127
|
+
@orig_parts.each do |op|
|
128
|
+
@page.parts.create({
|
129
|
+
:name => op.name,
|
130
|
+
:filter_id => op.filter_id,
|
131
|
+
:content => op.content
|
132
|
+
})
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
def redirect_back_or_to_admin_pages_page
|
137
|
+
redirect_to(:back) rescue redirect_to(admin_page_url)
|
138
|
+
end
|
139
|
+
|
140
|
+
def clear_cache
|
141
|
+
if defined? ResponseCache == 'constant'
|
142
|
+
ResponseCache.instance.clear
|
143
|
+
else
|
144
|
+
Radiant::Cache.clear
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module DragOrder
|
2
|
+
module Models
|
3
|
+
module Page
|
4
|
+
|
5
|
+
if defined?(Page::NONDRAFT_FIELDS)
|
6
|
+
Page::NONDRAFT_FIELDS << 'position'
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.included(base)
|
10
|
+
base.class_eval do
|
11
|
+
|
12
|
+
before_validation_on_create :set_initial_position
|
13
|
+
|
14
|
+
self.reflections[:children].options[:order] = "position ASC"
|
15
|
+
|
16
|
+
class << self
|
17
|
+
|
18
|
+
def children_of_after_position(parent, position)
|
19
|
+
find_all_by_parent_id(parent, :conditions => [ 'position >= ?', position ])
|
20
|
+
end
|
21
|
+
|
22
|
+
def children_of_with_slug_like(parent, slug)
|
23
|
+
find_all_by_parent_id(parent, :conditions => [ 'slug LIKE ?', slug ])
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
def newly_created_siblings?
|
29
|
+
self.class.find_all_by_parent_id(parent_id, :conditions => ["position is null"] ).size > 0
|
30
|
+
end
|
31
|
+
|
32
|
+
def siblings_and_self
|
33
|
+
self.class.find_all_by_parent_id(parent_id, :order => ["position ASC"] )
|
34
|
+
end
|
35
|
+
|
36
|
+
def following_siblings
|
37
|
+
self.class.find_all_by_parent_id(parent_id, :conditions => [ 'position > ?', position ] )
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
def set_initial_position
|
42
|
+
self.position ||= begin
|
43
|
+
if last_sibling = Page.find_by_parent_id(parent_id, :order => [ "position DESC" ])
|
44
|
+
last_sibling.position + 1
|
45
|
+
else
|
46
|
+
0
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DragOrder
|
2
|
+
module Tags
|
3
|
+
module Core
|
4
|
+
|
5
|
+
def self.included(base)
|
6
|
+
base.class_eval do
|
7
|
+
def children_find_options_with_drag_order(tag)
|
8
|
+
options = children_find_options_without_drag_order(tag)
|
9
|
+
options[:order].sub!(/published_at/i, 'position') unless tag.attr['by']
|
10
|
+
options
|
11
|
+
end
|
12
|
+
alias_method_chain :children_find_options, :drag_order
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
namespace :radiant do
|
2
|
+
namespace :extensions do
|
3
|
+
namespace :drag_order do
|
4
|
+
|
5
|
+
desc "Runs the migration of the DragOrder extension"
|
6
|
+
task :migrate => :environment do
|
7
|
+
require 'radiant/extension_migrator'
|
8
|
+
if ENV["VERSION"]
|
9
|
+
DragOrderExtension.migrator.migrate(ENV["VERSION"].to_i)
|
10
|
+
else
|
11
|
+
DragOrderExtension.migrator.migrate
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Copies public assets of the DragOrder extensions to the instance public/ directory."
|
16
|
+
task :update => :environment do
|
17
|
+
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
18
|
+
Dir[DragOrderExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
19
|
+
path = file.sub(DragOrderExtension.root, '')
|
20
|
+
directory = File.dirname(path)
|
21
|
+
mkdir_p RAILS_ROOT + directory, :verbose => false
|
22
|
+
cp file, RAILS_ROOT + path, :verbose => false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,192 @@
|
|
1
|
+
var DragOrder = Class.create({
|
2
|
+
|
3
|
+
// Constants
|
4
|
+
BEFORE : 0,
|
5
|
+
AFTER : 1,
|
6
|
+
CHILD : 2,
|
7
|
+
CHILD_PAD : 21,
|
8
|
+
NO_COPY : 0,
|
9
|
+
COPY : 1,
|
10
|
+
|
11
|
+
// Defaults
|
12
|
+
origRow : null,
|
13
|
+
expandObj : null,
|
14
|
+
rowHeight : 0,
|
15
|
+
dragLine : null,
|
16
|
+
moveTo : null,
|
17
|
+
|
18
|
+
initialize: function(table) {
|
19
|
+
// Needed in order to use SiteMap function. Already created in sitemap.js,
|
20
|
+
// but cannot be referred to...
|
21
|
+
this.sMap = SiteMapBehavior.attach(new Element('table'));
|
22
|
+
|
23
|
+
// Attach listeners to drag images in table
|
24
|
+
var _this = this;
|
25
|
+
Event.observe( $(table), 'mousedown', function(evt){
|
26
|
+
if ($(evt.target.parentNode).hasClassName('drag_order') && evt.target.tagName.toLowerCase() == 'img')
|
27
|
+
_this.rowDragStart(evt);
|
28
|
+
}.bindAsEventListener(this) );
|
29
|
+
document.dragOrderObj = this;
|
30
|
+
},
|
31
|
+
|
32
|
+
rowDragStart: function(evt) {
|
33
|
+
// Store original row, give it a color, store the height of the row and initialise some objects
|
34
|
+
this.origRow = evt.findElement('tr');
|
35
|
+
this.origRow.addClassName('dragging');
|
36
|
+
this.rowHeight = this.origRow.getHeight();
|
37
|
+
this.moveTo = new Object();
|
38
|
+
this.expandObj = new Object();
|
39
|
+
this.childEdge = $(evt.target).cumulativeOffset().left + $(evt.target).getWidth();
|
40
|
+
|
41
|
+
// Attach event listeners for the movement
|
42
|
+
this.moveBind = this.rowDragMove.bindAsEventListener(this);
|
43
|
+
Event.observe($(document.body), 'mousemove', this.moveBind);
|
44
|
+
this.stopBind = this.rowDragStop.bindAsEventListener(this);
|
45
|
+
Event.observe($(document.body), 'mouseup', this.stopBind);
|
46
|
+
|
47
|
+
return this.cancelEvent(evt);
|
48
|
+
},
|
49
|
+
|
50
|
+
rowDragMove: function(evt) {
|
51
|
+
// If no origRow is available, we've come here by mistake
|
52
|
+
if (!this.origRow) return false;
|
53
|
+
|
54
|
+
// Create dragline
|
55
|
+
if (!this.dragLine) {
|
56
|
+
this.dragLine = new Element('div');
|
57
|
+
this.dragLine.id = 'drag_line';
|
58
|
+
this.dragLine.setStyle({
|
59
|
+
position: 'absolute'
|
60
|
+
});
|
61
|
+
this.dragLine.innerHTML = "line";
|
62
|
+
dragLineCircle = new Element('div');
|
63
|
+
this.dragLine.appendChild(dragLineCircle);
|
64
|
+
document.body.appendChild(this.dragLine);
|
65
|
+
}
|
66
|
+
else
|
67
|
+
this.dragLine.show();
|
68
|
+
|
69
|
+
// If children are visible, hide them first
|
70
|
+
if (this.sMap.isExpanded(this.origRow))
|
71
|
+
this.sMap.hideBranch(this.origRow, this.origRow.getElementsByClassName('expander')[0] );
|
72
|
+
|
73
|
+
// Loop through all rows
|
74
|
+
var _this = document.dragOrderObj;
|
75
|
+
var top;
|
76
|
+
this.origRow.parentNode.getElementsBySelector('tr').find(function(obj){
|
77
|
+
top = obj.cumulativeOffset().top;
|
78
|
+
|
79
|
+
// Check if cursor is over row
|
80
|
+
if (evt.pageY >= top && evt.pageY <= top + _this.rowHeight) {
|
81
|
+
|
82
|
+
// If row has children and is collapsed, create timer for expansion
|
83
|
+
if (obj.hasClassName('children_hidden') && _this.expandObj != obj) {
|
84
|
+
_this.expandObj.row = obj;
|
85
|
+
if (_this.expandObj.timer)
|
86
|
+
clearTimeout(_this.expandObj.timer);
|
87
|
+
_this.expandObj.timer = setTimeout("document.dragOrderObj.rowDragExpand();", 750);
|
88
|
+
}
|
89
|
+
else if (_this.expandObj != obj) {
|
90
|
+
_this.expandObj.row = null;
|
91
|
+
clearTimeout(_this.expandObj.timer);
|
92
|
+
}
|
93
|
+
|
94
|
+
var targetRow = null;
|
95
|
+
var targetLoc;
|
96
|
+
// If on the upper half of the row, put the dragline at the top of the row (= bottom of previous)
|
97
|
+
if (evt.pageY >= top && evt.pageY <= top + _this.rowHeight / 2 && obj.previous()) {
|
98
|
+
if (obj.previous().hasClassName('children_visible')) {
|
99
|
+
targetRow = obj;
|
100
|
+
targetLoc = _this.BEFORE;
|
101
|
+
}
|
102
|
+
else {
|
103
|
+
targetRow = _this.sMap.extractLevel(obj.previous()) > _this.sMap.extractLevel(obj) ? obj : obj.previous();
|
104
|
+
targetLoc = _this.sMap.extractLevel(obj.previous()) > _this.sMap.extractLevel(obj) ? _this.BEFORE : _this.AFTER;
|
105
|
+
}
|
106
|
+
}
|
107
|
+
// If on the lower half of the row, put the line at the bottom of the row
|
108
|
+
else if (evt.pageY > top + _this.rowHeight / 2 && evt.pageY <= top + _this.rowHeight) {
|
109
|
+
// Check for moving as new child
|
110
|
+
if (obj != _this.origRow && !_this.sMap.hasChildren(obj) && evt.pageX > _this.childEdge) {
|
111
|
+
targetRow = obj;
|
112
|
+
targetLoc = _this.CHILD;
|
113
|
+
}
|
114
|
+
else {
|
115
|
+
targetRow = obj.hasClassName('children_visible') ? obj.next() : obj;
|
116
|
+
targetLoc = obj.hasClassName('children_visible') ? _this.BEFORE : _this.AFTER;
|
117
|
+
}
|
118
|
+
}
|
119
|
+
|
120
|
+
// Check for copy action
|
121
|
+
var copy = evt.ctrlKey || evt.metaKey ? true : false;
|
122
|
+
if (copy)
|
123
|
+
_this.dragLine.getElementsByTagName('div')[0].addClassName('copy');
|
124
|
+
else
|
125
|
+
_this.dragLine.getElementsByTagName('div')[0].removeClassName('copy');
|
126
|
+
}
|
127
|
+
|
128
|
+
// If a row has been found
|
129
|
+
if (targetRow) {
|
130
|
+
// Set the dragline
|
131
|
+
var padding = parseInt(targetRow.firstDescendant().getStyle('padding-left')) + 30;
|
132
|
+
_this.dragLine.style.width = targetRow.getWidth() - padding - (targetLoc == _this.CHILD ? _this.CHILD_PAD : 0) + 'px';
|
133
|
+
_this.dragLine.setStyle({
|
134
|
+
left: targetRow.cumulativeOffset().left + padding + (targetLoc == _this.CHILD ? _this.CHILD_PAD : 0) + 'px',
|
135
|
+
top: targetRow.cumulativeOffset().top + (targetLoc == _this.AFTER || targetLoc == _this.CHILD ? _this.rowHeight : 0) - 1 + 'px'
|
136
|
+
});
|
137
|
+
|
138
|
+
// Store the found row and options
|
139
|
+
_this.moveTo.hovering = obj;
|
140
|
+
_this.moveTo.relativeTo = targetRow;
|
141
|
+
_this.moveTo.side = targetLoc;
|
142
|
+
_this.moveTo.copy = copy;
|
143
|
+
|
144
|
+
return true;
|
145
|
+
}
|
146
|
+
|
147
|
+
});
|
148
|
+
|
149
|
+
return this.cancelEvent(evt);
|
150
|
+
},
|
151
|
+
|
152
|
+
rowDragExpand: function(row) {
|
153
|
+
row = this.expandObj.row;
|
154
|
+
this.sMap.showBranch(row, row.getElementsByClassName('expander')[0] );
|
155
|
+
},
|
156
|
+
|
157
|
+
rowDragStop: function() {
|
158
|
+
|
159
|
+
if (this.moveTo.relativeTo && (this.moveTo.hovering != this.origRow || this.moveTo.copy))
|
160
|
+
window.location.href = "/admin/pages/" + this.sMap.extractPageId(this.origRow) + "/move_to/" + this.sMap.extractPageId(this.moveTo.relativeTo) + "/" + this.moveTo.side + "/" + (this.moveTo.copy ? this.COPY : this.NO_COPY);
|
161
|
+
else {
|
162
|
+
// Cleanup not necessary when redirected
|
163
|
+
this.origRow.removeClassName('dragging');
|
164
|
+
|
165
|
+
this.origRow = null;
|
166
|
+
if (this.expandObj.timer) clearTimeout(this.expandObj.timer);
|
167
|
+
this.expandObj = null;
|
168
|
+
if (this.dragLine) this.dragLine.hide();
|
169
|
+
}
|
170
|
+
|
171
|
+
Event.stopObserving(document.body, 'mousemove', this.moveBind);
|
172
|
+
Event.stopObserving(document.body, 'mouseup', this.stopBind);
|
173
|
+
},
|
174
|
+
|
175
|
+
cancelEvent: function(evt) {
|
176
|
+
// Cancel default event actions
|
177
|
+
evt.returnValue = false;
|
178
|
+
evt.cancel = true;
|
179
|
+
if (evt.preventDefault) evt.preventDefault();
|
180
|
+
return false;
|
181
|
+
}
|
182
|
+
|
183
|
+
});
|
184
|
+
|
185
|
+
// If the DOM is loaded, create the DragOrder object
|
186
|
+
document.observe('dom:loaded', function() {
|
187
|
+
$$('table.index').each(function(table){
|
188
|
+
if(table.identify() == 'pages' || table.identify() == 'site_map') {
|
189
|
+
new DragOrder(table);
|
190
|
+
}
|
191
|
+
});
|
192
|
+
});
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#content
|
2
|
+
|
3
|
+
table.index
|
4
|
+
|
5
|
+
tr.dragging
|
6
|
+
:background
|
7
|
+
:color #D3ECF4
|
8
|
+
|
9
|
+
td
|
10
|
+
:color white
|
11
|
+
|
12
|
+
.drag_order
|
13
|
+
:width 24px
|
14
|
+
|
15
|
+
img
|
16
|
+
:cursor move
|
17
|
+
|
18
|
+
|
19
|
+
#drag_line
|
20
|
+
:position relative
|
21
|
+
:height 3px
|
22
|
+
:font
|
23
|
+
:size 0px
|
24
|
+
:background
|
25
|
+
:color #800080
|
26
|
+
|
27
|
+
div
|
28
|
+
:position absolute
|
29
|
+
:height 9px
|
30
|
+
:width 9px
|
31
|
+
:margin -3px 0 0 -9px
|
32
|
+
:background
|
33
|
+
:image url(/images/admin/extensions/drag_order/circle.png)
|
34
|
+
|
35
|
+
&.copy
|
36
|
+
:height 20px
|
37
|
+
:width 20px
|
38
|
+
:margin -9px 0 0 -20px
|
39
|
+
:background
|
40
|
+
:image url(/images/admin/extensions/drag_order/copy.png)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{radiant-drag_order-extension}
|
8
|
+
s.version = "0.3.7"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Dirk Kelly"]
|
12
|
+
s.date = %q{2010-11-22}
|
13
|
+
s.description = %q{Radiant DragOrder allows you to reorder pages funly}
|
14
|
+
s.email = %q{dk@dirkkelly.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.md"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
"README.md",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"app/views/admin/pages/_drag_order.html.haml",
|
23
|
+
"app/views/admin/pages/_drag_order_header.html.haml",
|
24
|
+
"app/views/admin/pages/_top.html.haml",
|
25
|
+
"config/routes.rb",
|
26
|
+
"db/migrate/01_add_position_to_pages.rb",
|
27
|
+
"db/migrate/02_add_default_position.rb",
|
28
|
+
"drag_order_extension.rb",
|
29
|
+
"lib/drag_order/controllers/admin/pages_controller.rb",
|
30
|
+
"lib/drag_order/models/page.rb",
|
31
|
+
"lib/drag_order/tags/core.rb",
|
32
|
+
"lib/tasks/drag_order_extension_tasks.rake",
|
33
|
+
"public/images/admin/extensions/drag_order/circle.png",
|
34
|
+
"public/images/admin/extensions/drag_order/copy.png",
|
35
|
+
"public/images/admin/extensions/drag_order/handle.png",
|
36
|
+
"public/javascripts/admin/extensions/drag_order/drag_order.js",
|
37
|
+
"public/stylesheets/sass/admin/extensions/drag_order/drag_order.sass",
|
38
|
+
"radiant-drag_order-extension.gemspec",
|
39
|
+
"spec/spec.opts",
|
40
|
+
"spec/spec_helper.rb"
|
41
|
+
]
|
42
|
+
s.homepage = %q{http://github.com/dirkkelly/radiant-drag_order-extension}
|
43
|
+
s.require_paths = ["lib"]
|
44
|
+
s.rubygems_version = %q{1.3.7}
|
45
|
+
s.summary = %q{Drag Order Extension for Radiant CMS}
|
46
|
+
s.test_files = [
|
47
|
+
"spec/spec_helper.rb"
|
48
|
+
]
|
49
|
+
|
50
|
+
if s.respond_to? :specification_version then
|
51
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
52
|
+
s.specification_version = 3
|
53
|
+
|
54
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
55
|
+
s.add_runtime_dependency(%q<radiant>, [">= 0.9.1"])
|
56
|
+
else
|
57
|
+
s.add_dependency(%q<radiant>, [">= 0.9.1"])
|
58
|
+
end
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<radiant>, [">= 0.9.1"])
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,37 @@
|
|
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
|
+
if File.directory?(File.dirname(__FILE__) + "/scenarios")
|
15
|
+
Scenario.load_paths.unshift File.dirname(__FILE__) + "/scenarios"
|
16
|
+
end
|
17
|
+
if File.directory?(File.dirname(__FILE__) + "/matchers")
|
18
|
+
Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file }
|
19
|
+
end
|
20
|
+
|
21
|
+
Spec::Runner.configure do |config|
|
22
|
+
# config.use_transactional_fixtures = true
|
23
|
+
# config.use_instantiated_fixtures = false
|
24
|
+
# config.fixture_path = RAILS_ROOT + '/spec/fixtures'
|
25
|
+
|
26
|
+
# You can declare fixtures for each behaviour like this:
|
27
|
+
# describe "...." do
|
28
|
+
# fixtures :table_a, :table_b
|
29
|
+
#
|
30
|
+
# Alternatively, if you prefer to declare them only once, you can
|
31
|
+
# do so here, like so ...
|
32
|
+
#
|
33
|
+
# config.global_fixtures = :table_a, :table_b
|
34
|
+
#
|
35
|
+
# If you declare global fixtures, be aware that they will be declared
|
36
|
+
# for all of your examples, even those that don't use them.
|
37
|
+
end
|
metadata
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: radiant-drag_order-extension
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 3
|
9
|
+
- 7
|
10
|
+
version: 0.3.7
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Dirk Kelly
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2010-11-22 00:00:00 +08:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 57
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 9
|
33
|
+
- 1
|
34
|
+
version: 0.9.1
|
35
|
+
name: radiant
|
36
|
+
requirement: *id001
|
37
|
+
description: Radiant DragOrder allows you to reorder pages funly
|
38
|
+
email: dk@dirkkelly.com
|
39
|
+
executables: []
|
40
|
+
|
41
|
+
extensions: []
|
42
|
+
|
43
|
+
extra_rdoc_files:
|
44
|
+
- README.md
|
45
|
+
files:
|
46
|
+
- README.md
|
47
|
+
- Rakefile
|
48
|
+
- VERSION
|
49
|
+
- app/views/admin/pages/_drag_order.html.haml
|
50
|
+
- app/views/admin/pages/_drag_order_header.html.haml
|
51
|
+
- app/views/admin/pages/_top.html.haml
|
52
|
+
- config/routes.rb
|
53
|
+
- db/migrate/01_add_position_to_pages.rb
|
54
|
+
- db/migrate/02_add_default_position.rb
|
55
|
+
- drag_order_extension.rb
|
56
|
+
- lib/drag_order/controllers/admin/pages_controller.rb
|
57
|
+
- lib/drag_order/models/page.rb
|
58
|
+
- lib/drag_order/tags/core.rb
|
59
|
+
- lib/tasks/drag_order_extension_tasks.rake
|
60
|
+
- public/images/admin/extensions/drag_order/circle.png
|
61
|
+
- public/images/admin/extensions/drag_order/copy.png
|
62
|
+
- public/images/admin/extensions/drag_order/handle.png
|
63
|
+
- public/javascripts/admin/extensions/drag_order/drag_order.js
|
64
|
+
- public/stylesheets/sass/admin/extensions/drag_order/drag_order.sass
|
65
|
+
- radiant-drag_order-extension.gemspec
|
66
|
+
- spec/spec.opts
|
67
|
+
- spec/spec_helper.rb
|
68
|
+
has_rdoc: true
|
69
|
+
homepage: http://github.com/dirkkelly/radiant-drag_order-extension
|
70
|
+
licenses: []
|
71
|
+
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
hash: 3
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
none: false
|
88
|
+
requirements:
|
89
|
+
- - ">="
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 3
|
92
|
+
segments:
|
93
|
+
- 0
|
94
|
+
version: "0"
|
95
|
+
requirements: []
|
96
|
+
|
97
|
+
rubyforge_project:
|
98
|
+
rubygems_version: 1.3.7
|
99
|
+
signing_key:
|
100
|
+
specification_version: 3
|
101
|
+
summary: Drag Order Extension for Radiant CMS
|
102
|
+
test_files:
|
103
|
+
- spec/spec_helper.rb
|