Permalink
Browse files

Initial commit 2

  • Loading branch information...
0 parents commit dc216adc32fdf53db84d7f9752a89748e486d707 Bright 4 committed Feb 20, 2009
38 README
@@ -0,0 +1,38 @@
+= Drag Order v0.2
+
+Created by Bright 4, February 2009. Inspired by and based on Sean Cribbs' Reorder extension.
+
+This extension allows pages to be moved to any arbitrary (valid) place in the document tree structure by dragging the page to its new position and dropping it there.
+The admin UI is extended with a small drag-button for each page.
+
+The drag-and-drop style was inspired by the way OS-X implements this in various screens.
+
+
+== Installation
+
+1) Unpack/checkout/export the extension into vendor/extensions of your project.
+
+2) Run the extension migrations (replace {environment} by the target environment, e.g. production).
+ $ rake {environment} radiant:extensions:drag_order:migrate
+
+3) Run the extension update task.
+ $ rake {environment} radiant:extensions:drag_order:update
+
+4) Restart the server and you're ready to drag-and-drop pages.
+ To bypass the ordering system simply supply a "by" option to the finder tags.
+
+
+== Usage
+
+- Click and hold the drag-button of the page you wish to move. If the page has children and is expanded, this page will collapse (because a page cannot be placed in between its descendants).
+- Drag the page to its new position. The purple bar shows the new location and indentation of the page.
+- If, while dragging, you hold the cursor above a page with collapsed children, this page will expand after one second.
+- If you want to place the page you are dragging as the child of a page which does not have any children yet, you can either press-and-hold Ctrl or Command or make sure the mouse cursor is located to the right of the drag-button.
+- If the page has been dragged to the correct location, release the mouse cursor. The admin page will reload with the page at its new position.
+
+
+== Notes
+
+- Requires Javascript
+- *** DOES NOT WORK IN (all versions of) SAFARI 2 ***
+ This is due to the fact that Radiants' own JS files do not work correctly under Safari 2
120 Rakefile
@@ -0,0 +1,120 @@
+# I think this is the one that should be moved to the extension Rakefile template
+
+# In rails 1.2, plugins aren't available in the path until they're loaded.
+# Check to see if the rspec plugin is installed first and require
+# it if it is. If not, use the gem version.
+
+# Determine where the RSpec plugin is by loading the boot
+unless defined? RADIANT_ROOT
+ ENV["RAILS_ENV"] = "test"
+ case
+ when ENV["RADIANT_ENV_FILE"]
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
+ else
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
+ end
+end
+
+require 'rake'
+require 'rake/rdoctask'
+require 'rake/testtask'
+
+rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
+$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
+require 'spec/rake/spectask'
+# require 'spec/translator'
+
+# Cleanup the RADIANT_ROOT constant so specs will load the environment
+Object.send(:remove_const, :RADIANT_ROOT)
+
+extension_root = File.expand_path(File.dirname(__FILE__))
+
+task :default => :spec
+task :stats => "spec:statsetup"
+
+desc "Run all specs in spec directory"
+Spec::Rake::SpecTask.new(:spec) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+end
+
+namespace :spec do
+ desc "Run all specs in spec directory with RCov"
+ Spec::Rake::SpecTask.new(:rcov) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ t.rcov = true
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
+ end
+
+ desc "Print Specdoc for all specs"
+ Spec::Rake::SpecTask.new(:doc) do |t|
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
+ t.spec_files = FileList['spec/**/*_spec.rb']
+ end
+
+ [:models, :controllers, :views, :helpers].each do |sub|
+ desc "Run the specs under spec/#{sub}"
+ Spec::Rake::SpecTask.new(sub) do |t|
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
+ end
+ end
+
+ # Hopefully no one has written their extensions in pre-0.9 style
+ # desc "Translate specs from pre-0.9 to 0.9 style"
+ # task :translate do
+ # translator = ::Spec::Translator.new
+ # dir = RAILS_ROOT + '/spec'
+ # translator.translate(dir, dir)
+ # end
+
+ # Setup specs for stats
+ task :statsetup do
+ require 'code_statistics'
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
+ ::CodeStatistics::TEST_TYPES << "Model specs"
+ ::CodeStatistics::TEST_TYPES << "View specs"
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
+ end
+
+ namespace :db do
+ namespace :fixtures do
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
+ task :load => :environment do
+ require 'active_record/fixtures'
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
+ end
+ end
+ end
+ end
+end
+
+desc 'Generate documentation for the drag_order extension.'
+Rake::RDocTask.new(:rdoc) do |rdoc|
+ rdoc.rdoc_dir = 'rdoc'
+ rdoc.title = 'DragOrderExtension'
+ rdoc.options << '--line-numbers' << '--inline-source'
+ rdoc.rdoc_files.include('README')
+ rdoc.rdoc_files.include('lib/**/*.rb')
+end
+
+# For extensions that are in transition
+desc 'Test the drag_order extension.'
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.verbose = true
+end
+
+# Load any custom rakefiles for extension
+Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,2 @@
+- unless simple
+ %td.drag_order= level > 0 ? order_dragger : ""
@@ -0,0 +1 @@
+%th.drag_order
@@ -0,0 +1,2 @@
+- include_stylesheet 'admin/drag_order'
+- include_javascript 'admin/drag_order'
@@ -0,0 +1,24 @@
+class AddPositionToPages < ActiveRecord::Migration
+ def self.up
+ add_column :pages, :position, :integer
+ Page.reset_column_information
+ say_with_time("Putting all pages in a default order...") do
+ ActiveRecord::Base.record_timestamps = false
+ Page.find_all_by_parent_id(nil).each do |p|
+ put_children_into_list(p)
+ end
+ ActiveRecord::Base.record_timestamps = true
+ end
+ end
+
+ def self.down
+ remove_column :pages, :position
+ end
+
+ def self.put_children_into_list(page)
+ page.children.find(:all, :order => "title asc").each_with_index do |pg, idx|
+ pg.update_attribute('position', idx + 1)
+ put_children_into_list(pg)
+ end
+ end
+end
@@ -0,0 +1,28 @@
+# Uncomment this if you reference any of your controllers in activate
+require_dependency 'application'
+
+class DragOrderExtension < Radiant::Extension
+ version "0.1"
+ description "Order and move pages, with drag-and-drop. Based on Sean Cribbs' Reorder extension."
+ url "http://www.bright4.nl/"
+
+ define_routes do |map|
+ map.with_options :controller => "admin/page" do |page|
+ page.page_move_to "admin/pages/:id/move_to/:rel/:pos", :action => "move_to"
+ end
+ end
+
+ def activate
+ admin.page.index.add :sitemap_head, "drag_order_header"
+ admin.page.index.add :node, "drag_order"
+ admin.page.index.add :top, "header"
+ Page.send :include, DragOrder::PageExtensions
+ (Admin::PageController rescue Admin::PagesController).send :helper, DragOrder::PageHelper
+ (Admin::PageController rescue Admin::PagesController).send :include, DragOrder::PageControllerExtensions
+ StandardTags.send :include, DragOrder::TagExtensions
+ end
+
+ def deactivate
+ end
+
+end
@@ -0,0 +1,50 @@
+module DragOrder::PageControllerExtensions
+
+ def move_to
+ @page = Page.find(params[:id])
+ @rel = Page.find(params[:rel])
+ @loc = params[:pos].to_i
+
+ # Set initial position if the page has none yet
+ if @page.position == nil
+ @last_page = Page.find_all_by_parent_id( @page.parent.id, :order => [ "position DESC" ], :limit => 1 )
+ @last_page.each do |p|
+ @page.position = p.position.to_i + 1
+ end
+ end
+
+ # Remove the page from its old position
+ @old_siblings = Page.find_all_by_parent_id( @page.parent.id, :conditions => [ "position > " + @page.position.to_s ] )
+ @old_siblings.each do |s|
+ s.position -= 1
+ s.save
+ end
+
+ @rel.reload
+ if @loc != 2
+ # Make room for the page
+ @new_siblings = Page.find_all_by_parent_id( @rel.parent.id, :conditions => [ "position >= " + (@rel.position + @loc).to_s ] )
+ @new_siblings.each do |s|
+ if s.id != @page.id
+ s.position += 1
+ s.save
+ end
+ end
+ end
+
+ # Put the page
+ @rel.reload
+ if @loc != 2
+ @page.parent = @rel.parent
+ @page.position = @rel.position + (@loc == 1 ? 1 : -1)
+ else
+ @page.parent = @rel
+ @page.position = 1
+ end
+ @page.save
+
+ # Redirect back to the admin pages page
+ request.env["HTTP_REFERER"] ? redirect_to(:back) : redirect_to(admin_page_url)
+ end
+
+end
@@ -0,0 +1,11 @@
+module DragOrder::PageExtensions
+ def self.included(base)
+ base.class_eval {
+ self.reflections[:children].options[:order] = "position ASC"
+ }
+
+ if defined?(Page::NONDRAFT_FIELDS)
+ Page::NONDRAFT_FIELDS << 'position'
+ end
+ end
+end
@@ -0,0 +1,7 @@
+module DragOrder::PageHelper
+ def order_dragger
+ image("drag_order.png",
+ :alt => "Drag this icon to move the page"
+ )
+ end
+end
@@ -0,0 +1,11 @@
+module DragOrder::TagExtensions
+ def self.included(base)
+ base.class_eval { alias_method_chain :children_find_options, :drag_order }
+ end
+
+ def children_find_options_with_drag_order(tag)
+ options = children_find_options_without_drag_order(tag)
+ options[:order].sub!(/published_at/i, 'position') unless tag.attr['by']
+ options
+ end
+end
@@ -0,0 +1,28 @@
+namespace :radiant do
+ namespace :extensions do
+ namespace :drag_order do
+
+ desc "Runs the migration of the Drag Order extension"
+ task :migrate => :environment do
+ require 'radiant/extension_migrator'
+ if ENV["VERSION"]
+ DragOrderExtension.migrator.migrate(ENV["VERSION"].to_i)
+ else
+ DragOrderExtension.migrator.migrate
+ end
+ end
+
+ desc "Copies public assets of the Drag Order to the instance public/ directory."
+ task :update => :environment do
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
+ Dir[DragOrderExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
+ path = file.sub(DragOrderExtension.root, '')
+ directory = File.dirname(path)
+ puts "Copying #{path}..."
+ mkdir_p RAILS_ROOT + directory
+ cp file, RAILS_ROOT + path
+ end
+ end
+ end
+ end
+end
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.

0 comments on commit dc216ad

Please sign in to comment.