radiant-drag_order-extension 0.3.7
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/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
|