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 +7 -0
- data/Rakefile +117 -0
- data/app/views/admin/pages/_copy_move_extra_td.html.haml +14 -0
- data/app/views/admin/pages/_node.html.haml +42 -0
- data/app/views/admin/pages/_nodes.html.haml +51 -0
- data/app/views/admin/pages/children.html.haml +15 -0
- data/backend_archive_view_extension.rb +14 -0
- data/config/initializers/radiant_config.rb +3 -0
- data/config/locales/en.yml +3 -0
- data/config/routes.rb +6 -0
- data/cucumber.yml +1 -0
- data/features/support/env.rb +16 -0
- data/features/support/paths.rb +14 -0
- data/lib/archive_page_tree_structure.rb +127 -0
- data/lib/node_helper_changes.rb +73 -0
- data/lib/pages_controller_extensions.rb +136 -0
- data/lib/radiant-backend_archive_view-extension.rb +8 -0
- data/lib/tasks/backend_archive_view_extension_tasks.rake +55 -0
- data/radiant-backend_archive_view-extension.gemspec +26 -0
- data/spec/spec.opts +6 -0
- data/spec/spec_helper.rb +36 -0
- metadata +109 -0
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
|
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,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
data/spec/spec_helper.rb
ADDED
@@ -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
|