radiant-backend_archive_view-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md ADDED
@@ -0,0 +1,7 @@
1
+ Radiant Backend Archive View Extension
2
+ --------------------------------------
3
+
4
+ This extension is intended for use with Radiant version 1.0 or higher.
5
+ It was designed specifically for heavy content sites.
6
+ It will divide children of ArchivePages into subpages per year and month.
7
+ Also, months that would expand with many pages are truncated to show only a dozen. A "more pages" link appears with which you can get more pages.
data/Rakefile ADDED
@@ -0,0 +1,117 @@
1
+ # Determine where the RSpec plugin is by loading the boot
2
+ unless defined? RADIANT_ROOT
3
+ ENV["RAILS_ENV"] = "test"
4
+ case
5
+ when ENV["RADIANT_ENV_FILE"]
6
+ require File.dirname(ENV["RADIANT_ENV_FILE"]) + "/boot"
7
+ when File.dirname(__FILE__) =~ %r{vendor/radiant/vendor/extensions}
8
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot"
9
+ else
10
+ require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot"
11
+ end
12
+ end
13
+
14
+ require 'rake'
15
+ require 'rake/rdoctask'
16
+ require 'rake/testtask'
17
+
18
+ rspec_base = File.expand_path(RADIANT_ROOT + '/vendor/plugins/rspec/lib')
19
+ $LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base)
20
+ require 'spec/rake/spectask'
21
+ require 'cucumber'
22
+ require 'cucumber/rake/task'
23
+
24
+ # Cleanup the RADIANT_ROOT constant so specs will load the environment
25
+ Object.send(:remove_const, :RADIANT_ROOT)
26
+
27
+ extension_root = File.expand_path(File.dirname(__FILE__))
28
+
29
+ task :default => :spec
30
+ task :stats => "spec:statsetup"
31
+
32
+ desc "Run all specs in spec directory"
33
+ Spec::Rake::SpecTask.new(:spec) do |t|
34
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
35
+ t.spec_files = FileList['spec/**/*_spec.rb']
36
+ end
37
+
38
+ task :features => 'spec:integration'
39
+
40
+ namespace :spec do
41
+ desc "Run all specs in spec directory with RCov"
42
+ Spec::Rake::SpecTask.new(:rcov) do |t|
43
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
44
+ t.spec_files = FileList['spec/**/*_spec.rb']
45
+ t.rcov = true
46
+ t.rcov_opts = ['--exclude', 'spec', '--rails']
47
+ end
48
+
49
+ desc "Print Specdoc for all specs"
50
+ Spec::Rake::SpecTask.new(:doc) do |t|
51
+ t.spec_opts = ["--format", "specdoc", "--dry-run"]
52
+ t.spec_files = FileList['spec/**/*_spec.rb']
53
+ end
54
+
55
+ [:models, :controllers, :views, :helpers].each do |sub|
56
+ desc "Run the specs under spec/#{sub}"
57
+ Spec::Rake::SpecTask.new(sub) do |t|
58
+ t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""]
59
+ t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"]
60
+ end
61
+ end
62
+
63
+ desc "Run the Cucumber features"
64
+ Cucumber::Rake::Task.new(:integration) do |t|
65
+ t.fork = true
66
+ t.cucumber_opts = ['--format', (ENV['CUCUMBER_FORMAT'] || 'pretty')]
67
+ # t.feature_pattern = "#{extension_root}/features/**/*.feature"
68
+ t.profile = "default"
69
+ end
70
+
71
+ # Setup specs for stats
72
+ task :statsetup do
73
+ require 'code_statistics'
74
+ ::STATS_DIRECTORIES << %w(Model\ specs spec/models)
75
+ ::STATS_DIRECTORIES << %w(View\ specs spec/views)
76
+ ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers)
77
+ ::STATS_DIRECTORIES << %w(Helper\ specs spec/views)
78
+ ::CodeStatistics::TEST_TYPES << "Model specs"
79
+ ::CodeStatistics::TEST_TYPES << "View specs"
80
+ ::CodeStatistics::TEST_TYPES << "Controller specs"
81
+ ::CodeStatistics::TEST_TYPES << "Helper specs"
82
+ ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/}
83
+ end
84
+
85
+ namespace :db do
86
+ namespace :fixtures do
87
+ desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y"
88
+ task :load => :environment do
89
+ require 'active_record/fixtures'
90
+ ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym)
91
+ (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file|
92
+ Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*'))
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ desc 'Generate documentation for the backend_archive_view extension.'
100
+ Rake::RDocTask.new(:rdoc) do |rdoc|
101
+ rdoc.rdoc_dir = 'rdoc'
102
+ rdoc.title = 'BackendArchiveViewExtension'
103
+ rdoc.options << '--line-numbers' << '--inline-source'
104
+ rdoc.rdoc_files.include('README')
105
+ rdoc.rdoc_files.include('lib/**/*.rb')
106
+ end
107
+
108
+ # For extensions that are in transition
109
+ desc 'Test the backend_archive_view extension.'
110
+ Rake::TestTask.new(:test) do |t|
111
+ t.libs << 'lib'
112
+ t.pattern = 'test/**/*_test.rb'
113
+ t.verbose = true
114
+ end
115
+
116
+ # Load any custom rakefiles for extension
117
+ Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f }
@@ -0,0 +1,14 @@
1
+ - unless simple
2
+ %td.actions
3
+ - unless page.class.to_s =~ /TreePage/
4
+ - if page.respond_to?('children')
5
+ = link_to image('copy-move', :alt => 'CopyMove') + ' ' + t('copy_move.button'), "#copy_move_#{page.id}", :class => "action dropdown"
6
+ %ul.menu{:id => "copy_move_#{page.id}"}
7
+ - if page.children.any?
8
+ %li.copy_page_only= link_to image('page_white') + ' ' + t('copy_move.copy_page_only'), copy_page_path(page.id), :class => 'popup'
9
+ %li.copy_with_first_level_children= link_to image('page_white_copy') + ' ' + t('copy_move.copy_with_first_level_children'), copy_children_path(page.id), :class => 'popup'
10
+ %li.copy_whole_subtree= link_to image('page_white_stack') + ' ' + t('copy_move.copy_whole_subtree'), copy_tree_path(page.id), :class => 'popup'
11
+ %li.move_entire_subtree= link_to image('page_white_go') + ' ' + t('copy_move.move_entire_subtree'), move_page_path(page.id), :class => 'popup'
12
+ - else
13
+ %li.copy_page= link_to image('page_white') + ' ' + t('copy_move.copy_page'), copy_page_path(page.id), :class => 'popup'
14
+ %li.move_page= link_to image('page_white_go') + ' ' + t('copy_move.move_page'), move_page_path(page.id), :class => 'popup'
@@ -0,0 +1,42 @@
1
+ %tr.page{:class =>"level_#{level}#{children_class}#{virtual_class}", :id => "page_#{page.id}"}
2
+ - render_region :node, :locals => {:page => page, :level => level, :simple => simple} do |node|
3
+ - node.title_column do
4
+ %td.name{:style => "padding-left: #{padding_left(level)}px"}
5
+ %span.w1
6
+ - if simple
7
+ = icon
8
+ = node_title
9
+ - else
10
+ = expander(level) + link_to("#{icon} #{node_title}", edit_admin_page_url(page), :title => page.url) unless page.class.to_s =~ /TreePage/
11
+ = page_type
12
+ = spinner
13
+ - node.status_column do
14
+ - unless simple
15
+ %td.status
16
+ - unless page.class.to_s =~ /TreePage/
17
+ %span.status{:class => "#{page.status.name.downcase}_status", :title => "#{timestamp(page.published_at) if page.published_at}"}
18
+ = t(page.status.name.downcase)
19
+ - if page.parent.try(:class_name) =~ /ArchivePage/ && page.published_at
20
+ %br
21
+ %small= I18n.l page.published_at, :format => (:short)
22
+ - node.actions_column do
23
+ - unless simple
24
+ %td.actions
25
+ - unless page.class.to_s =~ /TreePage/
26
+ = page.add_child_option
27
+ = page.remove_option
28
+
29
+ - if expanded
30
+ - if page.respond_to?(:tree_children)
31
+ - if page.tree_children.size > 15
32
+ = render_nodes page.tree_children[0...15], :level => level + 1, :simple => simple
33
+ %tr{:class => "level_#{level + 1} node_fetcher"}
34
+ %td.nodes_fetcher{:style => "padding-left: #{padding_left(level)}px; text-align: center", :colspan => 4}
35
+ %a.more_node_fetcher{:href => "#"}= t("more") + " " + t("pages").downcase
36
+ = image('spinner.gif', :class => 'busy', :id => "node_fetcher_#{page.id}_spinner",
37
+ :alt => "", :title => "",
38
+ :style => 'display: none;')
39
+ - else
40
+ = render_nodes page.tree_children, :level => level + 1, :simple => simple
41
+ - else
42
+ = render_nodes page.children, :level => level + 1, :simple => simple
@@ -0,0 +1,51 @@
1
+ - pages.each do |page|
2
+ - next if page.try(:sheet?)
3
+ - prepare_node(page)
4
+
5
+ %tr.page{:class =>"level_#{level}#{children_class}#{virtual_class}", :id => "page_#{page.id}"}
6
+ - render_region :node, :locals => {:page => page, :level => level, :simple => simple} do |node|
7
+ - node.title_column do
8
+ %td.name{:style => "padding-left: #{padding_left(level)}px"}
9
+ %span.w1
10
+ - if simple
11
+ = icon
12
+ = node_title
13
+ - else
14
+ = expander(level)
15
+ - unless page.class.to_s =~ /TreePage/
16
+ = link_to("#{icon} #{node_title}", edit_admin_page_url(page), :title => page.url)
17
+ - else
18
+ = "#{icon} #{node_title}"
19
+ = page_type
20
+ = spinner
21
+ - node.status_column do
22
+ - unless simple
23
+ %td.status
24
+ - unless page.class.to_s =~ /TreePage/
25
+ %span.status{:class => "#{page.status.name.downcase}_status", :title => "#{timestamp(page.published_at) if page.published_at}"}
26
+ = t(page.status.name.downcase)
27
+ - if page.parent.try(:class_name) =~ /ArchivePage/ && page.published_at
28
+ %br
29
+ %small= I18n.l page.published_at, :format => (:short)
30
+ - node.actions_column do
31
+ - unless simple
32
+ %td.actions
33
+ - unless page.class.to_s =~ /TreePage/
34
+ = page.add_child_option
35
+ = page.remove_option
36
+
37
+ - if expanded
38
+ - if page.respond_to?(:tree_children)
39
+ - if page.tree_children.size > 15
40
+ = render_nodes page.tree_children[0...15], :level => level + 1, :simple => simple
41
+ %tr{:class => "level_#{level + 1} node_fetcher"}
42
+ %td.nodes_fetcher{:style => "padding-left: #{padding_left(level)}px; text-align: center", :colspan => 4}
43
+ %a.more_node_fetcher{:href => "#"}= t("more") + " " + t("pages").downcase
44
+ = image('spinner.gif', :class => 'busy', :id => "node_fetcher_#{page.id}_spinner",
45
+ :alt => "", :title => "",
46
+ :style => 'display: none;')
47
+ - else
48
+ = render_nodes page.tree_children, :level => level + 1, :simple => simple
49
+ - else
50
+ = render_nodes page.children, :level => level + 1, :simple => simple
51
+
@@ -0,0 +1,15 @@
1
+ - if @offset.nil? || @offset < 12
2
+ - if @parent.respond_to?(:tree_children)
3
+ = render_nodes @parent.tree_children[0...12], :level => @level + 1
4
+ - if @parent.tree_children.size > 12
5
+ %tr{:class => "level_#{@level + 1} node_fetcher"}
6
+ %td.nodes_fetcher{:style => "padding-left: #{padding_left(@level)}px; text-align: center", :colspan => 5}
7
+ %a.more_node_fetcher{:href => "#"}= t("more") + " " + t("pages").downcase
8
+ = image('spinner.gif',
9
+ :class => 'busy', :id => "node_fetcher_#{@parent.id}_spinner",
10
+ :alt => "", :title => "",
11
+ :style => 'display: none;')
12
+ - else
13
+ - if @parent.respond_to?(:tree_children)
14
+ - @parent.tree_children[@offset...@end].each do |child|
15
+ = render_node child, :expand => 1, :level => @level + 1
@@ -0,0 +1,14 @@
1
+ # Uncomment this if you reference any of your controllers in activate
2
+ # require_dependency 'application_controller'
3
+ require 'radiant-backend_archive_view-extension'
4
+ class BackendArchiveViewExtension < Radiant::Extension
5
+ version RadiantBackendArchiveViewExtension::VERSION
6
+ description RadiantBackendArchiveViewExtension::DESCRIPTION
7
+ url RadiantBackendArchiveViewExtension::URL
8
+
9
+ def activate
10
+ ArchivePage.send :include, ArchivePageTreeStructure
11
+ Admin::PagesController.send(:include, PagesControllerExtensions)
12
+ Admin::NodeHelper.send(:include, NodeHelperChanges)
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ Radiant.config do |config|
2
+ # config.define "setting.name", :default => 'value', :select_from => ['foo', 'bar']
3
+ end
@@ -0,0 +1,3 @@
1
+ ---
2
+ en:
3
+ backend archive view: Backend Archive View
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ ActionController::Routing::Routes.draw do |map|
2
+ map.with_options(:controller => 'admin/pages') do |pages|
3
+ pages.tree_children 'admin/pages/:page_id/tree_children', :action => "tree_children"
4
+ pages.more_nodes 'admin/pages/:page_id/more_nodes/:offset', :action => "more_nodes"
5
+ end
6
+ end
data/cucumber.yml ADDED
@@ -0,0 +1 @@
1
+ default: --format progress features --tags ~@proposed,~@in_progress
@@ -0,0 +1,16 @@
1
+ # Sets up the Rails environment for Cucumber
2
+ ENV["RAILS_ENV"] = "test"
3
+ # Extension root
4
+ extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
5
+ require extension_env+'.rb'
6
+
7
+ Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step}
8
+
9
+ Cucumber::Rails::World.class_eval do
10
+ include Dataset
11
+ datasets_directory "#{RADIANT_ROOT}/spec/datasets"
12
+ Dataset::Resolver.default = Dataset::DirectoryResolver.new("#{RADIANT_ROOT}/spec/datasets", File.dirname(__FILE__) + '/../../spec/datasets', File.dirname(__FILE__) + '/../datasets')
13
+ self.datasets_database_dump_path = "#{Rails.root}/tmp/dataset"
14
+
15
+ # dataset :backend_archive_view
16
+ end
@@ -0,0 +1,14 @@
1
+ def path_to(page_name)
2
+ case page_name
3
+
4
+ when /the homepage/i
5
+ root_path
6
+
7
+ when /login/i
8
+ login_path
9
+ # Add more page name => path mappings here
10
+
11
+ else
12
+ raise "Can't find mapping from \"#{page_name}\" to a path."
13
+ end
14
+ end
@@ -0,0 +1,127 @@
1
+ module ArchivePageTreeStructure
2
+ def tree_children
3
+ tree_children = []
4
+ last = edge_date(false)
5
+ if last
6
+ first = edge_date(true)
7
+ current = first
8
+ while(current <= last)
9
+ tree_children.unshift ArchiveYearTreePage.new(self, current, last)
10
+ current = current.next_year.beginning_of_year
11
+ end
12
+ end
13
+ tree_children #+ children.find(:all, :conditions => ['virtual = ?', true])
14
+ end
15
+
16
+ def edge_date(first)
17
+ if !first && children.find(:first, :conditions => 'updated_at is null')
18
+ return Time.now
19
+ end
20
+ order = first ? 'asc' : 'desc'
21
+ child = children.find(:first, :order => "published_at #{order}", :conditions => 'not(published_at is null)')
22
+ edge = child.published_at if child
23
+ child = children.find(:first, :order => "updated_at #{order}", :conditions => 'published_at is null and not(updated_at is null)')
24
+ if child
25
+ if first
26
+ edge = child.updated_at if !edge || child.updated_at < edge
27
+ else
28
+ edge = child.updated_at if !edge || child.updated_at > edge
29
+ end
30
+ end
31
+ edge
32
+ end
33
+
34
+ def tree_child(slug)
35
+ first = [edge_date(true),Time.utc(slug.to_i)].max
36
+ last = edge_date(false)
37
+ ArchiveYearTreePage.new(self, first, last)
38
+ end
39
+
40
+ class ArchiveTreePage
41
+ def virtual?
42
+ true
43
+ end
44
+ def self.display_name
45
+ 'Page'
46
+ end
47
+ def class_name
48
+ 'Page'
49
+ end
50
+ def allowed_children_cache
51
+ ""
52
+ end
53
+ def children
54
+ tree_children
55
+ end
56
+ def sheet?
57
+ false
58
+ end
59
+ def url
60
+ "#{@parent.url}#{title}"
61
+ end
62
+ def status
63
+ Status.new(:name => ' ')
64
+ end
65
+ end
66
+
67
+ class ArchiveYearTreePage < ArchiveTreePage
68
+ def initialize(parent, start_time, end_time=nil)
69
+ @parent = parent
70
+ @start_time = start_time
71
+ @end_time = end_time
72
+ end
73
+ def id
74
+ @start_time.strftime("#{@parent.id}_%Y")
75
+ end
76
+ def title
77
+ @start_time.strftime("%Y")
78
+ end
79
+ def breadcrumb
80
+ title
81
+ end
82
+ def tree_children
83
+ start_month = @start_time.month
84
+ end_month = 12
85
+ end_month = @end_time.month if @end_time && @end_time.year <= @start_time.year
86
+ (@start_time.month..end_month).map do |m|
87
+ tree_child(m)
88
+ end.reverse
89
+ end
90
+ def tree_child(slug)
91
+ ArchiveMonthTreePage.new(@parent, @start_time.beginning_of_year.months_since(slug.to_i - 1))
92
+ end
93
+ end
94
+
95
+ class ArchiveMonthTreePage < ArchiveTreePage
96
+ def initialize(parent, start_time)
97
+ @parent = parent
98
+ @start_time = start_time
99
+ end
100
+ def id
101
+ @start_time.strftime("#{@parent.id}_%Y_%m")
102
+ end
103
+ def title
104
+ I18n.l @start_time, :format => "%B"
105
+ end
106
+ def breadcrumb
107
+ title
108
+ end
109
+ def tree_children
110
+ end_time = @start_time.next_month.beginning_of_month
111
+ condition_string = 'virtual = ? and (published_at >= ? and published_at < ? or (published_at is null and ('
112
+ condition_string += 'updated_at is null or ' if Time.now.utc.beginning_of_month == @start_time.beginning_of_month
113
+ condition_string += '(updated_at >= ? and updated_at < ?))))'
114
+ @parent.children.find(:all,
115
+ :conditions => [
116
+ condition_string,
117
+ false,
118
+ @start_time,
119
+ end_time,
120
+ @start_time,
121
+ end_time,
122
+ ],
123
+ :order => 'published_at desc, updated_at desc'
124
+ )
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,73 @@
1
+ module NodeHelperChanges
2
+ def self.included(clazz)
3
+ clazz.class_eval do
4
+ def node_title
5
+ %{<span class="title">#{ @current_node.breadcrumb }</span>}
6
+ end
7
+
8
+ def expanded_rows
9
+ unless @expanded_rows
10
+ @expanded_rows = case
11
+ when rows = cookies[:expanded_rows]
12
+ rows.split(',').select { |x| /^\d+(_[\d_a-z]+)?$/i === x rescue nil }.compact
13
+ else
14
+ []
15
+ end
16
+
17
+ if homepage and !@expanded_rows.include?(homepage.id.to_s)
18
+ @expanded_rows << homepage.id.to_s
19
+ end
20
+ end
21
+ @expanded_rows
22
+ end
23
+
24
+ def expanded
25
+ show_all? || expanded_rows.include?(@current_node.id.to_s)
26
+ end
27
+
28
+ def children_class
29
+ if has_children?
30
+ if expanded
31
+ " children_visible"
32
+ else
33
+ " children_hidden"
34
+ end
35
+ else
36
+ " no_children"
37
+ end
38
+ end
39
+
40
+ def expander(level)
41
+ unless !has_children? or level == 0
42
+ image((expanded ? "collapse" : "expand"),
43
+ :class => "expander", :alt => 'toggle children',
44
+ :title => '')
45
+ else
46
+ ""
47
+ end
48
+ end
49
+
50
+ def has_children?
51
+ if @current_node.respond_to? :tree_children
52
+ @current_node.tree_children.any?
53
+ else
54
+ @current_node.children.any?
55
+ end
56
+ end
57
+
58
+ def prepare_node(page)
59
+ @current_node = page
60
+ page.extend MenuRenderer
61
+ page.view = self
62
+ if page.additional_menu_features?
63
+ page.extend(*page.menu_renderer_modules)
64
+ end
65
+ end
66
+
67
+ def render_nodes(pages, locals = {})
68
+ locals.reverse_merge!(:level => 0, :simple => false).merge!(:pages => pages)
69
+ render :partial => 'admin/pages/nodes', :locals => locals
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,136 @@
1
+ module PagesControllerExtensions
2
+ def self.included(clazz)
3
+ clazz.class_eval do
4
+ def index_with_tree_children
5
+ if params[:page_id] && (Page.find(params[:page_id]).respond_to?(:tree_children)) || params[:page_id] =~ /_/
6
+ id, *tree_children = params[:page_id].split('_')
7
+ @parent = tree_children.inject(Page.find(id)) {|current, slug| current.tree_child(slug) }
8
+ @level = params[:level].to_i
9
+ # @template_name = 'index'
10
+ response.headers['Content-Type'] = 'text/html;charset=utf-8'
11
+ render :action => 'children.html.haml', :layout => false, :locals => {:simple => true}
12
+ else
13
+ index_without_tree_children
14
+ end
15
+ end
16
+ alias_method_chain :index, :tree_children
17
+
18
+ def tree_children
19
+ id, *tree_children = params[:page_id].split('_')
20
+ @parent = tree_children.inject(Page.find(id)) {|current, slug| current.tree_child(slug) }
21
+ @level = params[:level].to_i
22
+ @template_name = 'index'
23
+ response.headers['Content-Type'] = 'text/html;charset=utf-8'
24
+ render :action => 'children.html.haml', :layout => false
25
+ end
26
+
27
+ def more_nodes
28
+ id, *tree_children = params[:page_id].split('_')
29
+ if tree_children.nil? # regular page
30
+ @parent = Page.find id
31
+ else
32
+ @parent = tree_children.inject(Page.find(id)) {|current, slug| current.tree_child(slug) }
33
+ end
34
+
35
+ @level = params[:level].to_i
36
+ @offset = params[:offset].to_i
37
+ @end = @offset + 10
38
+ @template_name = 'index'
39
+ response.headers['Content-Type'] = 'text/html;charset=utf-8'
40
+ render :action => 'children.html.haml', :layout => false
41
+ end
42
+
43
+ before_filter :include_admin_tree_javascript, :only => :index
44
+ private
45
+ def include_admin_tree_javascript
46
+ @content_for_page_scripts ||= ''
47
+ @content_for_page_scripts <<(<<-EOF)
48
+ Object.extend(SiteMapBehavior.prototype, {
49
+ onclick: function(event) {
50
+ if (this.isExpander(event.target)) {
51
+ var row = event.findElement('tr');
52
+ if (this.hasChildren(row)) {
53
+ this.toggleBranch(row, event.target);
54
+ }
55
+ }
56
+ if (this.isMoreNodeFetcher(event.target)) {
57
+ var row = event.findElement('tr')
58
+ this.getMoreNodes(row, event.target);
59
+ return false;
60
+ }
61
+ },
62
+ extractPageId: function(row) {
63
+ if (/page_([\\d]+(_[\\d_A-Z]+)?)/i.test(row.id)) {
64
+ return RegExp.$1;
65
+ }
66
+ else {
67
+ return row.id;
68
+ }
69
+ },
70
+ extractOffset: function(row) {
71
+ var level = this.extractLevel(row.previous(1))
72
+ var counter = 10
73
+ var found = 0
74
+ while(found == 0){
75
+ if(this.extractLevel(row.previous(counter)) == level)
76
+ counter += 1
77
+ else
78
+ found = 1
79
+ }
80
+ return counter
81
+ },
82
+ isMoreNodeFetcher: function(element) {
83
+ return element.match('a.more_node_fetcher');
84
+ },
85
+ getBranch: function(row) {
86
+ var id = this.extractPageId(row);
87
+ var level = this.extractLevel(row);
88
+ var spinner = $('busy_' + id);
89
+
90
+ if(id.include("_")){
91
+ new Ajax.Updater(
92
+ row,
93
+ '/admin/pages/' + id + '/tree_children?level=' + level,
94
+ {
95
+ insertion: "after",
96
+ onLoading: function() { spinner.show(); this.updating = true }.bind(this),
97
+ onComplete: function() { spinner.fade(); this.updating = false }.bind(this),
98
+ method: 'get'
99
+ }
100
+ );
101
+ }
102
+ else{
103
+ new Ajax.Updater(
104
+ row,
105
+ '/admin/pages/' + id + '/children?level=' + level,
106
+ {
107
+ insertion: "after",
108
+ onLoading: function() { spinner.show(); this.updating = true }.bind(this),
109
+ onComplete: function() { spinner.fade(); this.updating = false }.bind(this),
110
+ method: 'get'
111
+ }
112
+ );
113
+ }
114
+ },
115
+ getMoreNodes: function(row) {
116
+ var offset = this.extractOffset(row);
117
+ var level = this.extractLevel(row.previous(offset));
118
+ var id = this.extractPageId(row.previous(offset));
119
+ var spinner = $('node_fetcher_' + id + '_spinner');
120
+ new Ajax.Updater(
121
+ row,
122
+ '/admin/pages/' + id + '/more_nodes/' + offset + '?level=' + level,
123
+ {
124
+ insertion: "before",
125
+ onLoading: function() { spinner.show(); this.updating = true }.bind(this),
126
+ onComplete: function() { spinner.fade(); this.updating = false }.bind(this),
127
+ method: 'get'
128
+ }
129
+ );
130
+ }
131
+ });
132
+ EOF
133
+ end
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,8 @@
1
+ module RadiantBackendArchiveViewExtension
2
+ VERSION = '1.0.0'
3
+ SUMMARY = %q{Backend Archive View for Radiant CMS}
4
+ DESCRIPTION = %q{Helps organize ArchivePages with many children.}
5
+ URL = "https://github.com/jomz/radiant-backend_archive_view-extension"
6
+ AUTHORS = ["Benny Degezelle"]
7
+ EMAIL = ["hi@monkeypatch.be"]
8
+ end
@@ -0,0 +1,55 @@
1
+ namespace :radiant do
2
+ namespace :extensions do
3
+ namespace :backend_archive_view do
4
+
5
+ desc "Runs the migration of the Backend Archive View extension"
6
+ task :migrate => :environment do
7
+ require 'radiant/extension_migrator'
8
+ if ENV["VERSION"]
9
+ BackendArchiveViewExtension.migrator.migrate(ENV["VERSION"].to_i)
10
+ Rake::Task['db:schema:dump'].invoke
11
+ else
12
+ BackendArchiveViewExtension.migrator.migrate
13
+ Rake::Task['db:schema:dump'].invoke
14
+ end
15
+ end
16
+
17
+ desc "Copies public assets of the Backend Archive View to the instance public/ directory."
18
+ task :update => :environment do
19
+ is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
20
+ puts "Copying assets from BackendArchiveViewExtension"
21
+ Dir[BackendArchiveViewExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
22
+ path = file.sub(BackendArchiveViewExtension.root, '')
23
+ directory = File.dirname(path)
24
+ mkdir_p RAILS_ROOT + directory, :verbose => false
25
+ cp file, RAILS_ROOT + path, :verbose => false
26
+ end
27
+ unless BackendArchiveViewExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
28
+ puts "Copying rake tasks from BackendArchiveViewExtension"
29
+ local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
30
+ mkdir_p local_tasks_path, :verbose => false
31
+ Dir[File.join BackendArchiveViewExtension.root, %w(lib tasks *.rake)].each do |file|
32
+ cp file, local_tasks_path, :verbose => false
33
+ end
34
+ end
35
+ end
36
+
37
+ desc "Syncs all available translations for this ext to the English ext master"
38
+ task :sync => :environment do
39
+ # The main translation root, basically where English is kept
40
+ language_root = BackendArchiveViewExtension.root + "/config/locales"
41
+ words = TranslationSupport.get_translation_keys(language_root)
42
+
43
+ Dir["#{language_root}/*.yml"].each do |filename|
44
+ next if filename.match('_available_tags')
45
+ basename = File.basename(filename, '.yml')
46
+ puts "Syncing #{basename}"
47
+ (comments, other) = TranslationSupport.read_file(filename, basename)
48
+ words.each { |k,v| other[k] ||= words[k] } # Initializing hash variable as empty if it does not exist
49
+ other.delete_if { |k,v| !words[k] } # Remove if not defined in en.yml
50
+ TranslationSupport.write_file(filename, basename, comments, other)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "radiant-backend_archive_view-extension"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "radiant-backend_archive_view-extension"
7
+ s.version = RadiantBackendArchiveViewExtension::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = RadiantBackendArchiveViewExtension::AUTHORS
10
+ s.email = RadiantBackendArchiveViewExtension::EMAIL
11
+ s.homepage = RadiantBackendArchiveViewExtension::URL
12
+ s.summary = RadiantBackendArchiveViewExtension::SUMMARY
13
+ s.description = RadiantBackendArchiveViewExtension::DESCRIPTION
14
+
15
+ s.add_dependency "radiant", ">= 1.0.0.rc3"
16
+
17
+ ignores = if File.exist?('.gitignore')
18
+ File.read('.gitignore').split("\n").inject([]) {|a,p| a + Dir[p] }
19
+ else
20
+ []
21
+ end
22
+ s.files = Dir['**/*'] - ignores
23
+ s.test_files = Dir['test/**/*','spec/**/*','features/**/*'] - ignores
24
+ # s.executables = Dir['bin/*'] - ignores
25
+ s.require_paths = ["lib"]
26
+ 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,109 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: radiant-backend_archive_view-extension
3
+ version: !ruby/object:Gem::Version
4
+ hash: 23
5
+ prerelease:
6
+ segments:
7
+ - 1
8
+ - 0
9
+ - 0
10
+ version: 1.0.0
11
+ platform: ruby
12
+ authors:
13
+ - Benny Degezelle
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-11-18 00:00:00 +01: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: 15424051
30
+ segments:
31
+ - 1
32
+ - 0
33
+ - 0
34
+ - rc
35
+ - 3
36
+ version: 1.0.0.rc3
37
+ type: :runtime
38
+ version_requirements: *id001
39
+ description: Helps organize ArchivePages with many children.
40
+ email:
41
+ - hi@monkeypatch.be
42
+ executables: []
43
+
44
+ extensions: []
45
+
46
+ extra_rdoc_files: []
47
+
48
+ files:
49
+ - app/views/admin/pages/_copy_move_extra_td.html.haml
50
+ - app/views/admin/pages/_node.html.haml
51
+ - app/views/admin/pages/_nodes.html.haml
52
+ - app/views/admin/pages/children.html.haml
53
+ - backend_archive_view_extension.rb
54
+ - config/initializers/radiant_config.rb
55
+ - config/locales/en.yml
56
+ - config/routes.rb
57
+ - cucumber.yml
58
+ - features/support/env.rb
59
+ - features/support/paths.rb
60
+ - lib/archive_page_tree_structure.rb
61
+ - lib/node_helper_changes.rb
62
+ - lib/pages_controller_extensions.rb
63
+ - lib/radiant-backend_archive_view-extension.rb
64
+ - lib/tasks/backend_archive_view_extension_tasks.rake
65
+ - radiant-backend_archive_view-extension-1.0.0.gem
66
+ - radiant-backend_archive_view-extension.gemspec
67
+ - Rakefile
68
+ - README.md
69
+ - spec/spec.opts
70
+ - spec/spec_helper.rb
71
+ has_rdoc: true
72
+ homepage: https://github.com/jomz/radiant-backend_archive_view-extension
73
+ licenses: []
74
+
75
+ post_install_message:
76
+ rdoc_options: []
77
+
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ">="
84
+ - !ruby/object:Gem::Version
85
+ hash: 3
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ">="
93
+ - !ruby/object:Gem::Version
94
+ hash: 3
95
+ segments:
96
+ - 0
97
+ version: "0"
98
+ requirements: []
99
+
100
+ rubyforge_project:
101
+ rubygems_version: 1.5.3
102
+ signing_key:
103
+ specification_version: 3
104
+ summary: Backend Archive View for Radiant CMS
105
+ test_files:
106
+ - spec/spec.opts
107
+ - spec/spec_helper.rb
108
+ - features/support/env.rb
109
+ - features/support/paths.rb