radiant-backend_archive_view-extension 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/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