staugaard-comatose 2.0.2
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/CHANGELOG +176 -0
- data/INSTALL +19 -0
- data/LICENSE +20 -0
- data/MANIFEST +91 -0
- data/README.rdoc +148 -0
- data/Rakefile +122 -0
- data/SPECS +61 -0
- data/about.yml +7 -0
- data/bin/comatose +109 -0
- data/comatose.gemspec +113 -0
- data/generators/comatose_migration/USAGE +15 -0
- data/generators/comatose_migration/comatose_migration_generator.rb +59 -0
- data/generators/comatose_migration/templates/migration.rb +35 -0
- data/generators/comatose_migration/templates/v4_upgrade.rb +15 -0
- data/generators/comatose_migration/templates/v6_upgrade.rb +23 -0
- data/generators/comatose_migration/templates/v7_upgrade.rb +22 -0
- data/init.rb +2 -0
- data/install.rb +16 -0
- data/lib/acts_as_versioned.rb +543 -0
- data/lib/comatose.rb +33 -0
- data/lib/comatose/comatose_drop.rb +79 -0
- data/lib/comatose/configuration.rb +68 -0
- data/lib/comatose/page_wrapper.rb +119 -0
- data/lib/comatose/processing_context.rb +69 -0
- data/lib/comatose/tasks/admin.rb +60 -0
- data/lib/comatose/tasks/data.rb +82 -0
- data/lib/comatose/tasks/setup.rb +52 -0
- data/lib/comatose/version.rb +4 -0
- data/lib/comatose_admin_controller.rb +349 -0
- data/lib/comatose_admin_helper.rb +37 -0
- data/lib/comatose_controller.rb +142 -0
- data/lib/comatose_helper.rb +3 -0
- data/lib/comatose_page.rb +141 -0
- data/lib/liquid.rb +52 -0
- data/lib/liquid/block.rb +96 -0
- data/lib/liquid/context.rb +190 -0
- data/lib/liquid/document.rb +17 -0
- data/lib/liquid/drop.rb +48 -0
- data/lib/liquid/errors.rb +7 -0
- data/lib/liquid/extensions.rb +53 -0
- data/lib/liquid/file_system.rb +62 -0
- data/lib/liquid/htmltags.rb +64 -0
- data/lib/liquid/standardfilters.rb +111 -0
- data/lib/liquid/standardtags.rb +399 -0
- data/lib/liquid/strainer.rb +42 -0
- data/lib/liquid/tag.rb +25 -0
- data/lib/liquid/template.rb +88 -0
- data/lib/liquid/variable.rb +39 -0
- data/lib/redcloth.rb +1129 -0
- data/lib/support/class_options.rb +36 -0
- data/lib/support/inline_rendering.rb +48 -0
- data/lib/support/route_mapper.rb +50 -0
- data/lib/text_filters.rb +138 -0
- data/lib/text_filters/markdown.rb +14 -0
- data/lib/text_filters/markdown_smartypants.rb +15 -0
- data/lib/text_filters/none.rb +8 -0
- data/lib/text_filters/rdoc.rb +13 -0
- data/lib/text_filters/simple.rb +8 -0
- data/lib/text_filters/textile.rb +15 -0
- data/rails/init.rb +3 -0
- data/resources/layouts/comatose_admin_template.html.erb +28 -0
- data/resources/public/images/collapsed.gif +0 -0
- data/resources/public/images/expanded.gif +0 -0
- data/resources/public/images/no-children.gif +0 -0
- data/resources/public/images/page.gif +0 -0
- data/resources/public/images/spinner.gif +0 -0
- data/resources/public/images/title-hover-bg.gif +0 -0
- data/resources/public/javascripts/comatose_admin.js +401 -0
- data/resources/public/stylesheets/comatose_admin.css +381 -0
- data/tasks/comatose.rake +9 -0
- data/test/behaviors.rb +106 -0
- data/test/fixtures/comatose_pages.yml +96 -0
- data/test/functional/comatose_admin_controller_test.rb +112 -0
- data/test/functional/comatose_controller_test.rb +44 -0
- data/test/javascripts/test.html +26 -0
- data/test/javascripts/test_runner.js +307 -0
- data/test/test_helper.rb +43 -0
- data/test/unit/class_options_test.rb +52 -0
- data/test/unit/comatose_page_test.rb +128 -0
- data/test/unit/processing_context_test.rb +108 -0
- data/test/unit/text_filters_test.rb +52 -0
- data/views/comatose_admin/_form.html.erb +96 -0
- data/views/comatose_admin/_page_list_item.html.erb +60 -0
- data/views/comatose_admin/delete.html.erb +18 -0
- data/views/comatose_admin/edit.html.erb +5 -0
- data/views/comatose_admin/index.html.erb +18 -0
- data/views/comatose_admin/new.html.erb +5 -0
- data/views/comatose_admin/reorder.html.erb +30 -0
- data/views/comatose_admin/versions.html.erb +40 -0
- data/views/layouts/comatose_admin.html.erb +814 -0
- data/views/layouts/comatose_admin_customize.html.erb +28 -0
- data/views/layouts/comatose_content.html.erb +17 -0
- metadata +147 -0
data/lib/comatose.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
|
2
|
+
module Comatose
|
3
|
+
|
4
|
+
# DEPRECATED
|
5
|
+
# Loads extensions from RAILS_ROOT/lib/comatose/*.rb
|
6
|
+
def self.load_extensions
|
7
|
+
Dir[File.join(RAILS_ROOT, 'lib', 'comatose', '*.rb')].each do |path|
|
8
|
+
require "comatose/#{File.basename(path)}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
|
14
|
+
require 'acts_as_versioned'
|
15
|
+
require 'redcloth' unless defined?(RedCloth)
|
16
|
+
require 'liquid' unless defined?(Liquid)
|
17
|
+
|
18
|
+
require 'support/class_options'
|
19
|
+
require 'text_filters'
|
20
|
+
|
21
|
+
require 'comatose/configuration'
|
22
|
+
require 'comatose/comatose_drop'
|
23
|
+
require 'comatose/processing_context'
|
24
|
+
require 'comatose/page_wrapper'
|
25
|
+
require 'comatose/version'
|
26
|
+
|
27
|
+
require 'support/inline_rendering'
|
28
|
+
require 'support/route_mapper'
|
29
|
+
|
30
|
+
require 'dispatcher' unless defined?(::Dispatcher)
|
31
|
+
::Dispatcher.to_prepare :comatose do
|
32
|
+
Comatose.config.after_setup.call
|
33
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module Comatose
|
2
|
+
|
3
|
+
class ComatoseDrop < ::Liquid::Drop
|
4
|
+
|
5
|
+
private :initialize
|
6
|
+
|
7
|
+
def before_method(method)
|
8
|
+
self.send(method.to_sym)
|
9
|
+
rescue
|
10
|
+
ComatoseController.logger.debug "Error calling #{method}: #{$!}"
|
11
|
+
raise $!
|
12
|
+
end
|
13
|
+
|
14
|
+
class << self
|
15
|
+
# Define a new ComatoseDrop by name
|
16
|
+
def define( name, &block )
|
17
|
+
d = ComatoseDrop.new
|
18
|
+
d.instance_eval(&block)
|
19
|
+
Comatose.registered_drops[name] = d
|
20
|
+
rescue
|
21
|
+
ComatoseController.logger.debug "Drop '#{name}' was not included: #{$!}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
|
28
|
+
# Returns/initializes a hash for storing ComatoseDrops
|
29
|
+
def registered_drops
|
30
|
+
@registered_drops ||= {}
|
31
|
+
end
|
32
|
+
|
33
|
+
# Simple wrapper around the ProcessingContext.define method
|
34
|
+
# I think Comatose.define_drop is probably simpler to remember too
|
35
|
+
def define_drop(name, &block)
|
36
|
+
ComatoseDrop.define(name, &block)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Registers a 'filter' for Liquid use
|
40
|
+
def register_filter(module_name)
|
41
|
+
Liquid::Template.register_filter(module_name)
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
#
|
49
|
+
# Some Default Filters/Drops
|
50
|
+
#
|
51
|
+
|
52
|
+
module IncludeFilter
|
53
|
+
def include(input)
|
54
|
+
page = ComatosePage.find_by_path(input)
|
55
|
+
params = @context['params']
|
56
|
+
# TODO: Add more of the context into the included page's context...
|
57
|
+
page.to_html( { 'params' => params } )
|
58
|
+
rescue
|
59
|
+
"Page at <tt>#{input}</tt> could not be found. <pre>#{$!}</pre>"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
Comatose.register_filter IncludeFilter
|
64
|
+
|
65
|
+
|
66
|
+
module TimeagoFilter
|
67
|
+
class Helpers
|
68
|
+
extend ActionView::Helpers::DateHelper
|
69
|
+
end
|
70
|
+
|
71
|
+
def time_ago(input)
|
72
|
+
TimeagoFilter::Helpers.distance_of_time_in_words_to_now( input, true )
|
73
|
+
rescue
|
74
|
+
#puts "Oops! -- #{$!}"
|
75
|
+
input
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
Comatose.register_filter TimeagoFilter
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module Comatose
|
2
|
+
|
3
|
+
def self.config
|
4
|
+
@@config ||= Configuration.new
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.configure(&block)
|
8
|
+
raise "#configure must be sent a block" unless block_given?
|
9
|
+
yield config
|
10
|
+
config.validate!
|
11
|
+
end
|
12
|
+
|
13
|
+
# All of the 'mount' points for Comatose
|
14
|
+
def self.mount_points
|
15
|
+
@@mount_points ||= []
|
16
|
+
end
|
17
|
+
|
18
|
+
# Adds a 'mount' point to the list of known roots...
|
19
|
+
def self.add_mount_point(path, info={:index=>''})
|
20
|
+
path = "/#{path}" unless path.starts_with? '/'
|
21
|
+
info[:root]=path
|
22
|
+
mount_points << info
|
23
|
+
end
|
24
|
+
|
25
|
+
class Configuration
|
26
|
+
|
27
|
+
attr_accessor_with_default :admin_title, 'Comatose'
|
28
|
+
attr_accessor_with_default :admin_includes, []
|
29
|
+
attr_accessor_with_default :admin_helpers, []
|
30
|
+
attr_accessor_with_default :admin_sub_title, 'The Micro CMS'
|
31
|
+
attr_accessor_with_default :content_type, 'utf-8'
|
32
|
+
attr_accessor_with_default :default_filter, 'Textile'
|
33
|
+
attr_accessor_with_default :default_processor, :liquid
|
34
|
+
attr_accessor_with_default :default_tree_level, 2
|
35
|
+
attr_accessor_with_default :disable_caching, false
|
36
|
+
attr_accessor_with_default :hidden_meta_fields, []
|
37
|
+
attr_accessor_with_default :helpers, []
|
38
|
+
attr_accessor_with_default :includes, []
|
39
|
+
|
40
|
+
# 'Blockable' setters
|
41
|
+
blockable_attr_accessor :authorization
|
42
|
+
blockable_attr_accessor :admin_authorization
|
43
|
+
blockable_attr_accessor :admin_get_author
|
44
|
+
blockable_attr_accessor :admin_get_root_page
|
45
|
+
blockable_attr_accessor :after_setup
|
46
|
+
|
47
|
+
def initialize
|
48
|
+
# Default procs for blockable attrs....
|
49
|
+
@authorization = Proc.new { true }
|
50
|
+
@admin_authorization = Proc.new { true }
|
51
|
+
@admin_get_author = Proc.new { request.env['REMOTE_ADDR'] }
|
52
|
+
@admin_get_root_page = Proc.new { ComatosePage.root }
|
53
|
+
@after_setup = Proc.new { true }
|
54
|
+
end
|
55
|
+
|
56
|
+
def validate!
|
57
|
+
# Rips through the config and validates it's, er, valid
|
58
|
+
raise ConfigurationError.new( "admin_get_author must be a Proc or Symbol" ) unless @admin_get_author.is_a? Proc or @admin_get_author.is_a? Symbol
|
59
|
+
raise ConfigurationError.new( "admin_authorization must be a Proc or Symbol" ) unless @admin_authorization.is_a? Proc or @admin_authorization.is_a? Symbol
|
60
|
+
raise ConfigurationError.new( "authorization must be a Proc or Symbol" ) unless @authorization.is_a? Proc or @authorization.is_a? Symbol
|
61
|
+
true
|
62
|
+
end
|
63
|
+
|
64
|
+
class ConfigurationError < StandardError; end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# Giving direct access to the AR model is disconcerting, so this wraps the AR
|
2
|
+
# Model to prevent access to certain, destructive behavior
|
3
|
+
class Comatose::PageWrapper
|
4
|
+
|
5
|
+
@@allowed_methods = %w(id full_path uri slug keywords title to_html filter_type author updated_on created_on)
|
6
|
+
@@custom_methods = %w(link content parent next previous children rchildren first_child last_child has_keyword)
|
7
|
+
|
8
|
+
attr_accessor :page
|
9
|
+
private :page
|
10
|
+
|
11
|
+
def initialize( page, locals={} )
|
12
|
+
@page = page
|
13
|
+
@keyword_lst = []
|
14
|
+
@keyword_hsh = {}
|
15
|
+
unless page.nil?
|
16
|
+
@keyword_lst = (page.keywords || '').downcase.split(',').map {|k| k.strip }
|
17
|
+
@keyword_lst.each {|kw| @keyword_hsh[kw] = true}
|
18
|
+
end
|
19
|
+
@locals = locals
|
20
|
+
end
|
21
|
+
|
22
|
+
def has_keyword?(keyword)
|
23
|
+
@page.has_keyword?(keyword)
|
24
|
+
end
|
25
|
+
|
26
|
+
def has_keyword
|
27
|
+
@keyword_hsh
|
28
|
+
end
|
29
|
+
|
30
|
+
def next
|
31
|
+
@next_page ||= begin
|
32
|
+
if @page.lower_item.nil?
|
33
|
+
nil
|
34
|
+
else
|
35
|
+
Comatose::PageWrapper.new( @page.lower_item )
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def previous
|
41
|
+
@prev_page ||= begin
|
42
|
+
if @page.higher_item.nil?
|
43
|
+
nil
|
44
|
+
else
|
45
|
+
Comatose::PageWrapper.new( @page.higher_item )
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def first_child
|
51
|
+
children.first
|
52
|
+
end
|
53
|
+
|
54
|
+
def def last_child
|
55
|
+
children.last
|
56
|
+
end
|
57
|
+
|
58
|
+
# Generates a link to this page... You can pass in the link text,
|
59
|
+
# otherwise it will default to the page title.
|
60
|
+
def link( title=nil )
|
61
|
+
title = @page.title if title.nil?
|
62
|
+
TextFilters[@page.filter_type].create_link(title, @page.uri)
|
63
|
+
end
|
64
|
+
|
65
|
+
def content
|
66
|
+
@page.to_html( @locals )
|
67
|
+
end
|
68
|
+
|
69
|
+
def parent
|
70
|
+
@parent ||= begin
|
71
|
+
if @page.parent.nil?
|
72
|
+
nil
|
73
|
+
else
|
74
|
+
Comatose::PageWrapper.new( @page.parent )
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def children
|
80
|
+
# Cache the results so that you can have multiple calls to #children without a penalty
|
81
|
+
@children ||= @page.children.to_a.collect {|child| Comatose::PageWrapper.new( child, @locals )}
|
82
|
+
end
|
83
|
+
|
84
|
+
# Children, in reverse order
|
85
|
+
def rchildren
|
86
|
+
children.reverse
|
87
|
+
end
|
88
|
+
|
89
|
+
def [](key)
|
90
|
+
if @@allowed_methods.include? key.to_s #or page.attributes.has_key? key.to_s
|
91
|
+
page.send( key )
|
92
|
+
elsif @@custom_methods.include? key
|
93
|
+
self.send(key.to_sym)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def has_key?(key)
|
98
|
+
@@allowed_methods.include? key or @@custom_methods.include? key
|
99
|
+
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
@page.title
|
103
|
+
end
|
104
|
+
|
105
|
+
def to_liquid
|
106
|
+
self
|
107
|
+
end
|
108
|
+
|
109
|
+
def method_missing(method_id, *args)
|
110
|
+
#STDERR.puts "Looking for method: #{method_id} (#{method_id.class.to_s}) in [#{@@allowed_methods.join(', ')}] or [#{page.attributes.keys.join(', ')}]"
|
111
|
+
if @@allowed_methods.include? method_id.to_s or page.attributes.has_key? method_id.to_s
|
112
|
+
page.send( method_id, *args)
|
113
|
+
else
|
114
|
+
# Access nazi says: NO ACCESS FOR YOU!!
|
115
|
+
# but he says it silently...
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# This is the rendering context object you have access to in text processing...
|
2
|
+
class Comatose::ProcessingContext
|
3
|
+
@@supported_methods = %w(page include)
|
4
|
+
|
5
|
+
def initialize( page, locals={} )
|
6
|
+
@locals = locals.stringify_keys if locals.respond_to? :stringify_keys
|
7
|
+
@page = Comatose::PageWrapper.new(page, @locals)
|
8
|
+
end
|
9
|
+
|
10
|
+
def page
|
11
|
+
@page
|
12
|
+
end
|
13
|
+
|
14
|
+
def include(path, locals={})
|
15
|
+
begin
|
16
|
+
page = ComatosePage.find_by_path(path)
|
17
|
+
page.to_html( @locals.merge(locals) )
|
18
|
+
rescue
|
19
|
+
"<p>Page at <tt>#{path}</tt> could not be found.</p>"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def find_by_path(path)
|
24
|
+
begin
|
25
|
+
page = ComatosePage.find_by_path(path)
|
26
|
+
Comatose::PageWrapper.new(page, @locals)
|
27
|
+
rescue
|
28
|
+
"<p>Page at <tt>#{path}</tt> could not be found.</p>"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def [](key)
|
33
|
+
if key.to_s.downcase == 'page'
|
34
|
+
@page
|
35
|
+
elsif @locals.has_key? key
|
36
|
+
@locals[key]
|
37
|
+
elsif Comatose.registered_drops.has_key? key
|
38
|
+
Comatose.registered_drops[key]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def has_key?(key)
|
43
|
+
@@supported_methods.include?(key) or @locals.has_key?(key) or Comatose.registered_drops.has_key?(key)
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_liquid
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_binding
|
51
|
+
binding
|
52
|
+
end
|
53
|
+
|
54
|
+
def method_missing(method_id, *args)
|
55
|
+
method_name = method_id.to_s
|
56
|
+
if @locals.has_key? method_name
|
57
|
+
@locals[method_name]
|
58
|
+
elsif Comatose.registered_drops.has_key? method_name
|
59
|
+
Comatose.registered_drops[method_name].context = self
|
60
|
+
Comatose.registered_drops[method_name]
|
61
|
+
else
|
62
|
+
"<!-- ProcessingContext: Couldn't find #{method_id} -->"
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
namespace :comatose do
|
5
|
+
#
|
6
|
+
# Customization Tasks
|
7
|
+
#
|
8
|
+
namespace :admin do
|
9
|
+
|
10
|
+
desc "Create Comatose views, layouts, and public files..."
|
11
|
+
task :customize do
|
12
|
+
puts "Copying public files..."
|
13
|
+
plugin_dir = File.join(File.dirname(__FILE__), '../../..')
|
14
|
+
FileUtils.cp(
|
15
|
+
Dir[File.join(plugin_dir, 'resources', 'public', 'stylesheets', '*.css')],
|
16
|
+
File.join(RAILS_ROOT, 'public', 'stylesheets'),
|
17
|
+
:verbose => true
|
18
|
+
)
|
19
|
+
FileUtils.cp(
|
20
|
+
Dir[File.join(plugin_dir, 'resources', 'public', 'javascripts', '*.js')],
|
21
|
+
File.join(RAILS_ROOT, 'public', 'javascripts'),
|
22
|
+
:verbose => true
|
23
|
+
)
|
24
|
+
puts "Copying application views..."
|
25
|
+
FileUtils.mkdir_p(File.join(RAILS_ROOT, 'app', 'views', 'comatose_admin'))
|
26
|
+
FileUtils.cp(
|
27
|
+
Dir[File.join(plugin_dir, 'views', 'comatose_admin', '*.html.erb')],
|
28
|
+
File.join(RAILS_ROOT, 'app', 'views', 'comatose_admin'),
|
29
|
+
:verbose => true
|
30
|
+
)
|
31
|
+
puts "Copying application layout..."
|
32
|
+
FileUtils.cp(
|
33
|
+
File.join(plugin_dir, 'views', 'layouts', 'comatose_admin_customize.html.erb'),
|
34
|
+
File.join(RAILS_ROOT, 'app', 'views', 'layouts', 'comatose_admin.html.erb'),
|
35
|
+
:verbose => true
|
36
|
+
)
|
37
|
+
puts "Finished."
|
38
|
+
end
|
39
|
+
|
40
|
+
|
41
|
+
desc "Removes the customized files... It doesn't ask for any confirmation, nor is it Subversion-safe -- so be warned!"
|
42
|
+
task :teardown do
|
43
|
+
puts "Removing public files..."
|
44
|
+
FileUtils.rm(
|
45
|
+
File.join(RAILS_ROOT, 'public', 'stylesheets', 'comatose_admin.css')
|
46
|
+
)
|
47
|
+
FileUtils.rm(
|
48
|
+
File.join(RAILS_ROOT, 'public', 'javascripts', 'comatose_admin.js')
|
49
|
+
)
|
50
|
+
|
51
|
+
puts "Removing application views..."
|
52
|
+
FileUtils.rm_rf(
|
53
|
+
File.join(RAILS_ROOT, 'app', 'views', 'comatose_admin')
|
54
|
+
)
|
55
|
+
FileUtils.rm(
|
56
|
+
File.join(RAILS_ROOT, 'app', 'views', 'layouts', 'comatose_admin.html.erb')
|
57
|
+
)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/tasklib'
|
3
|
+
|
4
|
+
namespace :comatose do
|
5
|
+
#
|
6
|
+
# Data Migration Tasks
|
7
|
+
#
|
8
|
+
namespace :data do
|
9
|
+
|
10
|
+
def page_to_hash(page)
|
11
|
+
data = page.attributes.clone
|
12
|
+
# Pull out the specific, or unnecessary fields
|
13
|
+
%w(id parent_id updated_on author position version created_on full_path).each {|key| data.delete(key)}
|
14
|
+
if !page.children.empty?
|
15
|
+
data['children'] = []
|
16
|
+
page.children.each do |child|
|
17
|
+
data['children'] << page_to_hash(child)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
data
|
21
|
+
end
|
22
|
+
|
23
|
+
def hash_to_page_tree(hsh, page)
|
24
|
+
child_ary = hsh.delete 'children'
|
25
|
+
page.update_attributes(hsh)
|
26
|
+
page.save
|
27
|
+
child_ary.each do |child_hsh|
|
28
|
+
if child_pg = page.children.find_by_slug( child_hsh['slug'] )
|
29
|
+
hash_to_page_tree( child_hsh, child_pg )
|
30
|
+
else
|
31
|
+
hash_to_page_tree( child_hsh, page.children.create )
|
32
|
+
end
|
33
|
+
end if child_ary
|
34
|
+
end
|
35
|
+
|
36
|
+
desc "Saves a page tree from page FROM or '' to file TO_FILE or db/comatose-pages.yml"
|
37
|
+
task :export do
|
38
|
+
require "#{RAILS_ROOT}/config/environment"
|
39
|
+
|
40
|
+
root = ENV['FROM'] || ''
|
41
|
+
target = ENV['TO_FILE'] || 'db/comatose-pages.yml'
|
42
|
+
# Nested hash of the page tree...
|
43
|
+
from = ComatosePage.find_by_path(root)
|
44
|
+
if from
|
45
|
+
data = page_to_hash( from )
|
46
|
+
File.open(target, 'w') {|f| f.write data.to_yaml }
|
47
|
+
else
|
48
|
+
puts "Could not find the page at '#{root}', export aborted!"
|
49
|
+
end
|
50
|
+
|
51
|
+
puts "Finished."
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "Loads page tree data FROM_FILE or db/comatose-pages.yml in to TO or ComatosePage.root"
|
55
|
+
task :import do
|
56
|
+
require "#{RAILS_ROOT}/config/environment"
|
57
|
+
|
58
|
+
src = ENV['FROM_FILE'] || 'db/comatose-pages.yml'
|
59
|
+
root = ENV['TO'] || ''
|
60
|
+
target = (root == '') ? ComatosePage.root : ComatosePage.find_by_path(root)
|
61
|
+
data = YAML::load( File.open(src) )
|
62
|
+
#hash_to_page(data, target)
|
63
|
+
if target
|
64
|
+
if root == ''
|
65
|
+
hash_to_page_tree(data, target)
|
66
|
+
else
|
67
|
+
if page = target.children.find_by_slug(data['slug'])
|
68
|
+
hash_to_page_tree(data, page)
|
69
|
+
else
|
70
|
+
hash_to_page_tree(data, target.children.create)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
else
|
74
|
+
puts "Could not find the page at '#{root}', import aborted!"
|
75
|
+
# TODO: Ask to create the specified path if it doesn't exist?
|
76
|
+
end
|
77
|
+
puts "Finished."
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|