merbiful-release 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. data/Rakefile +44 -0
  2. data/lib/merbiful-release/admin.rb +281 -0
  3. data/lib/merbiful-release/admin.rb~ +12 -0
  4. data/lib/merbiful-release/body.rb +36 -0
  5. data/lib/merbiful-release/body.rb~ +15 -0
  6. data/lib/merbiful-release/controller.rb +55 -0
  7. data/lib/merbiful-release/controller.rb~ +12 -0
  8. data/lib/merbiful-release/css.rb +70 -0
  9. data/lib/merbiful-release/css.rb~ +62 -0
  10. data/lib/merbiful-release/erubis.rb +13 -0
  11. data/lib/merbiful-release/erubis.rb~ +11 -0
  12. data/lib/merbiful-release/eruby.rb~ +11 -0
  13. data/lib/merbiful-release/filters.rb +22 -0
  14. data/lib/merbiful-release/haml.rb +23 -0
  15. data/lib/merbiful-release/haml.rb~ +11 -0
  16. data/lib/merbiful-release/images.rb +28 -0
  17. data/lib/merbiful-release/js.rb +69 -0
  18. data/lib/merbiful-release/js.rb~ +62 -0
  19. data/lib/merbiful-release/layout.rb +49 -0
  20. data/lib/merbiful-release/layout.rb~ +21 -0
  21. data/lib/merbiful-release/merbiful.rb~ +8 -0
  22. data/lib/merbiful-release/page.rb +98 -0
  23. data/lib/merbiful-release/page.rb~ +57 -0
  24. data/lib/merbiful-release/relative_time.rb +116 -0
  25. data/lib/merbiful-release/relative_time.rb~ +78 -0
  26. data/lib/merbiful-release/routes.rb +42 -0
  27. data/lib/merbiful-release/routes.rb~ +4 -0
  28. data/lib/merbiful-release/version.rb~ +45 -0
  29. data/lib/merbiful-release.rb +29 -0
  30. data/lib/merbiful-release.rb~ +2 -0
  31. data/templates/admin.css +17 -0
  32. data/templates/admin.css~ +3 -0
  33. data/templates/admin_layout.html.haml +11 -0
  34. data/templates/admin_layout.html.haml~ +9 -0
  35. data/templates/admin_layout.html.rhtml~ +10 -0
  36. data/templates/css.html.haml +29 -0
  37. data/templates/css.html.haml.orig +28 -0
  38. data/templates/css.html.haml~ +29 -0
  39. data/templates/images.html.haml +17 -0
  40. data/templates/index.html.haml +2 -0
  41. data/templates/index.html.haml~ +2 -0
  42. data/templates/js.html.haml +26 -0
  43. data/templates/js.html.haml~ +29 -0
  44. data/templates/layouts.html.haml +23 -0
  45. data/templates/layouts.html.haml~ +0 -0
  46. data/templates/page_form.html.haml +41 -0
  47. data/templates/page_form.html.haml~ +1 -0
  48. data/templates/pages.html.haml~ +3 -0
  49. metadata +120 -0
@@ -0,0 +1,28 @@
1
+
2
+ module Merbiful
3
+
4
+ module Images
5
+
6
+ IMAGE_REGEXP = /\.(gif|jpg|jpeg|png|bmp)$/i
7
+
8
+ def self.images
9
+ rval = []
10
+ Dir.glob(File.join(Merb.root, "public", "images", "*")).each do |file|
11
+ if file.match(IMAGE_REGEXP)
12
+ rval << Pathname.new("/").join(Pathname.new(file).relative_path_from(Pathname.new(File.join(Merb.root, "public"))))
13
+ end
14
+ end
15
+ rval
16
+ end
17
+
18
+ def self.delete_possible?(image)
19
+ Pathname.new(File.join(Merb.root, "public", image)).writable?
20
+ end
21
+
22
+ def self.upload_possible?
23
+ Pathname.new(File.join(Merb.root, "public", "images")).writable?
24
+ end
25
+
26
+ end
27
+
28
+ end
@@ -0,0 +1,69 @@
1
+
2
+ module Merbiful
3
+
4
+ class Js
5
+
6
+ include DataMapper::Resource
7
+ include DataMapper::Validate
8
+ extend Forwardable
9
+
10
+ property :id, Serial
11
+
12
+ property :name, DataMapper::Types::Text, :nullable => false
13
+ property :cached, Boolean, :default => true, :nullable => false
14
+
15
+ property :created_at, DateTime
16
+ property :updated_at, DateTime
17
+
18
+ has n, :js_nesses, :class_name => "Merbiful::Js::Ness"
19
+ has n, :page_versions, :through => :js_nesses, :class_name => "Merbiful::Page::Version"
20
+ has n, :js_versions, :class_name => "Merbiful::Js::Version"
21
+
22
+ def latest
23
+ js_versions.first(:js_id => self.id, :order => [:id.desc])
24
+ end
25
+
26
+ def_delegators :latest, :render, :body, :filter
27
+
28
+ def path
29
+ "/javascripts/#{latest.id}"
30
+ end
31
+
32
+ class Ness
33
+ include DataMapper::Resource
34
+ include DataMapper::Validate
35
+
36
+ property :id, Serial
37
+
38
+ belongs_to :js, :class_name => "Merbiful::Js"
39
+ belongs_to :page_version, :class_name => "Merbiful::Page::Version"
40
+ end
41
+
42
+ class Version
43
+
44
+ include DataMapper::Resource
45
+ include DataMapper::Validate
46
+ include Merbiful::Body
47
+
48
+ property :id, Serial
49
+
50
+ property :js_id, Integer, :index => true, :nullable => false
51
+
52
+ property :body, DataMapper::Types::Text
53
+ property :filter, DataMapper::Types::Text
54
+
55
+ property :created_at, DateTime
56
+ property :updated_at, DateTime
57
+
58
+ belongs_to :js, :class_name => "Merbiful::Js"
59
+
60
+ before :save do
61
+ clear_cache(js.path) if js.latest
62
+ end
63
+
64
+ end
65
+
66
+ end
67
+
68
+
69
+ end
@@ -0,0 +1,62 @@
1
+
2
+ module Merbiful
3
+
4
+ class Css
5
+
6
+ include DataMapper::Resource
7
+ include DataMapper::Validate
8
+ extend Forwardable
9
+
10
+ property :id, Serial
11
+
12
+ property :name, DataMapper::Types::Text, :nullable => false
13
+ property :media, DataMapper::Types::Text
14
+ property :cached, Boolean, :default => true, :nullable => false
15
+
16
+ property :created_at, DateTime
17
+ property :updated_at, DateTime
18
+
19
+ has n, :css_nesses, :class_name => "Merbiful::Css::Ness"
20
+ has n, :page_versions, :through => :css_nesses, :class_name => "Merbiful::Page::Version"
21
+ has n, :css_versions, :class_name => "Merbiful::Css::Version"
22
+
23
+ def latest
24
+ css_versions.first(:order => [:id.desc])
25
+ end
26
+
27
+ def_delegators :latest, :render
28
+
29
+ class Ness
30
+ include DataMapper::Resource
31
+ include DataMapper::Validate
32
+
33
+ property :id, Serial
34
+
35
+ belongs_to :css, :class_name => "Merbiful::Css"
36
+ belongs_to :page_version, :class_name => "Merbiful::Page::Version"
37
+ end
38
+
39
+ class Version
40
+
41
+ include DataMapper::Resource
42
+ include DataMapper::Validate
43
+ include Merbiful::Body
44
+
45
+ property :id, Serial
46
+
47
+ property :css_id, Integer, :index => true, :nullable => false
48
+
49
+ property :body, DataMapper::Types::Text
50
+ property :filter, DataMapper::Types::Text
51
+
52
+ property :created_at, DateTime
53
+ property :updated_at, DateTime
54
+
55
+ belongs_to :css, :class_name => "Merbiful::Css"
56
+
57
+ end
58
+
59
+ end
60
+
61
+
62
+ end
@@ -0,0 +1,49 @@
1
+
2
+ module Merbiful
3
+
4
+ class Layout
5
+
6
+ include DataMapper::Resource
7
+ include DataMapper::Validate
8
+ extend Forwardable
9
+
10
+ property :id, Serial
11
+
12
+ property :name, DataMapper::Types::Text, :nullable => false
13
+
14
+ property :created_at, DateTime
15
+ property :updated_at, DateTime
16
+
17
+ has n, :layout_versions, :class_name => "Merbiful::Layout::Version"
18
+ has n, :page_versions, :class_name => "Merbiful::Page::Version"
19
+
20
+ def latest
21
+ layout_versions.first(:layout_id => self.id, :order => [:id.desc])
22
+ end
23
+
24
+ def_delegators :latest, :render, :body, :filter
25
+
26
+ class Version
27
+
28
+ include DataMapper::Resource
29
+ include DataMapper::Validate
30
+ include Merbiful::Body
31
+
32
+ property :id, Serial
33
+
34
+ property :layout_id, Integer, :index => true, :nullable => false
35
+
36
+ property :body, DataMapper::Types::Text
37
+ property :filter, DataMapper::Types::Text
38
+
39
+ property :created_at, DateTime
40
+ property :updated_at, DateTime
41
+
42
+ belongs_to :layout, :class_name => "Merbiful::Layout"
43
+
44
+ end
45
+
46
+ end
47
+
48
+
49
+ end
@@ -0,0 +1,21 @@
1
+
2
+ class Page
3
+
4
+ include DataMapper::Resource
5
+ include DataMapper::Validate
6
+
7
+ property :id, Integer, :key => true, :serial => true
8
+ property :version, Integer, :key => true
9
+ property :body, DataMapper::Types::Text
10
+ property :filter, DataMapper::Types::Text
11
+ property :parent_id, Integer
12
+ property :path, DataMapper::Types::Text, :key => true
13
+ property :created_at, DateTime
14
+ property :updated_at, DateTime
15
+ property :position, Integer
16
+ property :author, DataMapper::Types::Text
17
+ property :layout, Integer
18
+ property :title, DataMapper::Types::Text
19
+ property :keywords, DataMapper::Types::Text
20
+
21
+ end
@@ -0,0 +1,8 @@
1
+
2
+ class Merbiful < Application
3
+
4
+ def peek
5
+
6
+ end
7
+
8
+ end
@@ -0,0 +1,98 @@
1
+
2
+ module Merbiful
3
+
4
+ class Page
5
+
6
+ class NoSuchFilterError < RuntimeError
7
+ end
8
+
9
+ include DataMapper::Resource
10
+ include DataMapper::Validate
11
+ extend Forwardable
12
+
13
+ property :id, Serial
14
+ property :parent_id, Integer, :index => true
15
+
16
+ property :path, DataMapper::Types::Text, :unique_index => true, :nullable => false
17
+ property :position, Integer
18
+ property :cached, Boolean, :default => true, :nullable => false
19
+
20
+ property :created_at, DateTime
21
+ property :updated_at, DateTime
22
+
23
+ belongs_to :parent, :class_name => "Merbiful::Page", :child_key => [:parent_id]
24
+ has n, :children, :class_name => "Merbiful::Page", :child_key => [:parent_id]
25
+ has n, :versions, :class_name => "Merbiful::Page::Version"
26
+
27
+ validates_is_unique :path
28
+
29
+ before :save do
30
+ if self.position.nil?
31
+ last_position = self.class.first(:parent_id => self.parent_id, :id.not => self.id)
32
+ if last_position.nil?
33
+ self.position = 0
34
+ else
35
+ self.position = last_position.position + 1
36
+ end
37
+ end
38
+ end
39
+
40
+ def latest
41
+ versions.first(:page_id => self.id, :order => [:id.desc])
42
+ end
43
+
44
+ def_delegators :latest, :render, :layout, :csses, :add_css, :remove_css, :jses, :add_js, :remove_js, :body, :filter, :title, :keywords
45
+
46
+ class Version
47
+
48
+ include DataMapper::Resource
49
+ include DataMapper::Validate
50
+ include Merbiful::Body
51
+
52
+ property :id, Serial
53
+
54
+ property :page_id, Integer, :nullable => false, :index => true
55
+ property :layout_id, Integer, :index => true
56
+
57
+ property :body, DataMapper::Types::Text
58
+ property :filter, DataMapper::Types::Text
59
+ property :title, DataMapper::Types::Text
60
+ property :keywords, DataMapper::Types::Text
61
+
62
+ property :created_at, DateTime
63
+ property :updated_at, DateTime
64
+
65
+ belongs_to :page, :class_name => "Merbiful::Page"
66
+ belongs_to :layout, :class_name => "Merbiful::Layout"
67
+
68
+ has n, :css_nesses, :class_name => "Merbiful::Css::Ness"
69
+ has n, :csses, :through => :css_nesses, :class_name => "Merbiful::Css", :remote_name => :css
70
+
71
+ has n, :js_nesses, :class_name => "Merbiful::Js::Ness"
72
+ has n, :jses, :through => :js_nesses, :class_name => "Merbiful::Js", :remote_name => :js
73
+
74
+ before :save do
75
+ clear_cache(page.path) if page.latest
76
+ end
77
+
78
+ def add_css(css)
79
+ Merbiful::Css::Ness.new(:css => css, :page_version => self).save
80
+ end
81
+
82
+ def remove_css(css)
83
+ css_nesses.first(:css_id => css.id).destroy
84
+ end
85
+
86
+ def add_js(js)
87
+ Merbiful::Js::Ness.new(:js => js, :page_version => self).save
88
+ end
89
+
90
+ def remove_js(js)
91
+ js_nesses.first(:js_id => js.id).destroy
92
+ end
93
+
94
+ end
95
+
96
+ end
97
+
98
+ end
@@ -0,0 +1,57 @@
1
+
2
+ module Merbiful
3
+
4
+ class Page
5
+
6
+ class NoSuchFilterError < RuntimeError
7
+ end
8
+
9
+ include DataMapper::Resource
10
+ include DataMapper::Validate
11
+ include Merbiful::Body
12
+
13
+ validates_is_unique :version, :scope => [:path]
14
+
15
+ property :id, Serial
16
+ property :version, Integer, :index => true
17
+ property :body, DataMapper::Types::Text
18
+ property :filter, DataMapper::Types::Text
19
+ property :path, DataMapper::Types::Text, :index => true
20
+ property :position, Integer
21
+ property :created_at, DateTime
22
+ property :updated_at, DateTime
23
+ property :title, DataMapper::Types::Text
24
+ property :keywords, DataMapper::Types::Text
25
+ property :parent_path, DataMapper::Types::Text
26
+ property :layout_id, Integer
27
+
28
+ belongs_to :layout, :class_name => "Merbiful::Layout"
29
+
30
+ before :save do
31
+ last_version = self.class.first(:path => self.path, :order => [:version.desc])
32
+ if last_version.nil?
33
+ self.version = 0
34
+ else
35
+ self.version = last_version.version + 1
36
+ end
37
+ if self.position.nil?
38
+ last_position = self.class.first(:parent_path => self.parent_path, :path.not => self.path)
39
+ if last_position.nil?
40
+ self.position = 0
41
+ else
42
+ self.position = last_position.position + 1
43
+ end
44
+ end
45
+ if self.path.nil?
46
+ self.path = "/"
47
+ end
48
+
49
+ end
50
+
51
+ def children
52
+ Page.find_by_sql(["SELECT id FROM merbiful_pages WHERE parent_path = ? GROUP BY path ORDER BY version DESC", self.path])
53
+ end
54
+
55
+ end
56
+
57
+ end
@@ -0,0 +1,116 @@
1
+
2
+ module Merbiful
3
+
4
+ module RelativeTimeHelpers
5
+
6
+ class << self
7
+ attr_accessor :time_class
8
+ attr_accessor :time_output
9
+ end
10
+
11
+ self.time_class = Time
12
+ self.time_output = {
13
+ :today => 'today',
14
+ :yesterday => 'yesterday',
15
+ :tomorrow => 'tomorrow',
16
+ :initial_format => '%b %d',
17
+ :year_format => ', %Y'
18
+ }
19
+
20
+ def distance_of_time_in_words(from_time, to_time = 0, include_seconds = false)
21
+ from_time = from_time.to_time if from_time.respond_to?(:to_time)
22
+ to_time = to_time.to_time if to_time.respond_to?(:to_time)
23
+ distance_in_minutes = (((to_time - from_time).abs)/60).round
24
+ distance_in_seconds = ((to_time - from_time).abs).round
25
+
26
+ case distance_in_minutes
27
+ when 0..1
28
+ return (distance_in_minutes == 0) ? 'less than a minute' : '1 minute' unless include_seconds
29
+ case distance_in_seconds
30
+ when 0..4 then 'less than 5 seconds'
31
+ when 5..9 then 'less than 10 seconds'
32
+ when 10..19 then 'less than 20 seconds'
33
+ when 20..39 then 'half a minute'
34
+ when 40..59 then 'less than a minute'
35
+ else '1 minute'
36
+ end
37
+
38
+ when 2..44 then "#{distance_in_minutes} minutes"
39
+ when 45..89 then 'about 1 hour'
40
+ when 90..1439 then "about #{(distance_in_minutes.to_f / 60.0).round} hours"
41
+ when 1440..2879 then '1 day'
42
+ when 2880..43199 then "#{(distance_in_minutes / 1440).round} days"
43
+ when 43200..86399 then 'about 1 month'
44
+ when 86400..525599 then "#{(distance_in_minutes / 43200).round} months"
45
+ when 525600..1051199 then 'about 1 year'
46
+ else "over #{(distance_in_minutes / 525600).round} years"
47
+ end
48
+ end
49
+
50
+ def time_ago_in_words(from_time, include_seconds = false)
51
+ distance_of_time_in_words(from_time, Time.now, include_seconds)
52
+ end
53
+
54
+ def relative_date(time)
55
+ date = time.to_date
56
+ today = time_class.now.to_date
57
+ if date == today
58
+ time_output[:today]
59
+ elsif date == (today - 1)
60
+ time_output[:yesterday]
61
+ elsif date == (today + 1)
62
+ time_output[:tomorrow]
63
+ else
64
+ fmt = time_output[:initial_format].dup
65
+ fmt << time_output[:year_format] unless date.year == today.year
66
+ time.strftime_ordinalized(fmt)
67
+ end
68
+ end
69
+
70
+ def relative_date_span(times)
71
+ times = [times.first, times.last].collect!(&:to_date)
72
+ times.sort!
73
+ if times.first == times.last
74
+ relative_date(times.first)
75
+ else
76
+ first = times.first; last = times.last; now = time_class.now
77
+ [first.strftime_ordinalized('%b %d')].tap do |arr|
78
+ arr << ", #{first.year}" unless first.year == last.year
79
+ arr << ' - '
80
+ arr << last.strftime('%b') << ' ' unless first.year == last.year && first.month == last.month
81
+ arr << last.day.ordinalize
82
+ arr << ", #{last.year}" unless first.year == last.year && last.year == now.year
83
+ end.to_s
84
+ end
85
+ end
86
+
87
+ def relative_time_span(times)
88
+ times = [times.first, times.last].collect!(&:to_time)
89
+ times.sort!
90
+ if times.first == times.last
91
+ "#{prettier_time(times.first)} #{relative_date(times.first)}"
92
+ elsif times.first.to_date == times.last.to_date
93
+ same_half = (times.first.hour/12 == times.last.hour/12)
94
+ "#{prettier_time(times.first, !same_half)} - #{prettier_time(times.last)} #{relative_date(times.first)}"
95
+
96
+ else
97
+ first = times.first; last = times.last; now = time_class.now
98
+ [prettier_time(first)].tap do |arr|
99
+ arr << ' '
100
+ arr << first.strftime_ordinalized('%b %d')
101
+ arr << ", #{first.year}" unless first.year == last.year
102
+ arr << ' - '
103
+ arr << prettier_time(last)
104
+ arr << ' '
105
+ arr << last.strftime('%b') << ' ' unless first.year == last.year && first.month == last.month
106
+ arr << last.day.ordinalize
107
+ arr << ", #{last.year}" unless first.year == last.year && last.year == now.year
108
+ end.to_s
109
+ end
110
+ end
111
+
112
+ def prettier_time(time, ampm=true)
113
+ time.strftime("%I:%M#{" %p" if ampm}").sub(/^0/, '')
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,78 @@
1
+ module Merbiful
2
+
3
+ module RelativeTimeHelpers
4
+ mattr_accessor :time_class
5
+ mattr_accessor :time_output
6
+
7
+ self.time_class = Time
8
+ self.time_output = {
9
+ :today => 'today',
10
+ :yesterday => 'yesterday',
11
+ :tomorrow => 'tomorrow',
12
+ :initial_format => '%b %d',
13
+ :year_format => ', %Y'
14
+ }
15
+
16
+ def relative_date(time)
17
+ date = time.to_date
18
+ today = time_class.now.to_date
19
+ if date == today
20
+ time_output[:today]
21
+ elsif date == (today - 1)
22
+ time_output[:yesterday]
23
+ elsif date == (today + 1)
24
+ time_output[:tomorrow]
25
+ else
26
+ fmt = time_output[:initial_format].dup
27
+ fmt << time_output[:year_format] unless date.year == today.year
28
+ time.strftime_ordinalized(fmt)
29
+ end
30
+ end
31
+
32
+ def relative_date_span(times)
33
+ times = [times.first, times.last].collect!(&:to_date)
34
+ times.sort!
35
+ if times.first == times.last
36
+ relative_date(times.first)
37
+ else
38
+ first = times.first; last = times.last; now = time_class.now
39
+ [first.strftime_ordinalized('%b %d')].tap do |arr|
40
+ arr << ", #{first.year}" unless first.year == last.year
41
+ arr << ' - '
42
+ arr << last.strftime('%b') << ' ' unless first.year == last.year && first.month == last.month
43
+ arr << last.day.ordinalize
44
+ arr << ", #{last.year}" unless first.year == last.year && last.year == now.year
45
+ end.to_s
46
+ end
47
+ end
48
+
49
+ def relative_time_span(times)
50
+ times = [times.first, times.last].collect!(&:to_time)
51
+ times.sort!
52
+ if times.first == times.last
53
+ "#{prettier_time(times.first)} #{relative_date(times.first)}"
54
+ elsif times.first.to_date == times.last.to_date
55
+ same_half = (times.first.hour/12 == times.last.hour/12)
56
+ "#{prettier_time(times.first, !same_half)} - #{prettier_time(times.last)} #{relative_date(times.first)}"
57
+
58
+ else
59
+ first = times.first; last = times.last; now = time_class.now
60
+ [prettier_time(first)].tap do |arr|
61
+ arr << ' '
62
+ arr << first.strftime_ordinalized('%b %d')
63
+ arr << ", #{first.year}" unless first.year == last.year
64
+ arr << ' - '
65
+ arr << prettier_time(last)
66
+ arr << ' '
67
+ arr << last.strftime('%b') << ' ' unless first.year == last.year && first.month == last.month
68
+ arr << last.day.ordinalize
69
+ arr << ", #{last.year}" unless first.year == last.year && last.year == now.year
70
+ end.to_s
71
+ end
72
+ end
73
+
74
+ def prettier_time(time, ampm=true)
75
+ time.strftime("%I:%M#{" %p" if ampm}").sub(/^0/, '')
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,42 @@
1
+
2
+ Merb.logger.info("Compiling merbiful routes...")
3
+ Merb::Router.append do |r|
4
+ r.match("/merbiful_admin").to(:controller => "admin", :namespace => "merbiful", :action => "index").name(:merbiful_admin_index)
5
+ r.match("/merbiful_admin/:action").to(:controller => "admin", :namespace => "merbiful").name(:merbiful_admin)
6
+ r.match("/stylesheets/admin").to(:controller => "admin", :namespace => "merbiful", :action => "render_css").name(:merbiful_admin_css)
7
+ r.match("/stylesheets/:id").to(:controller => "controller", :namespace => "merbiful", :action => "css")
8
+ r.match("/javascripts/:id").to(:controller => "controller", :namespace => "merbiful", :action => "js")
9
+ r.match(/(.*)/).to(:controller => "controller", :namespace => "merbiful", :action => "display", :what => "[1]")
10
+ end
11
+
12
+ module Merbiful
13
+
14
+ PREPEND_ROUTES = Merb::Router.routes[0..4]
15
+ APPEND_ROUTES = Merb::Router.routes[5..-1]
16
+
17
+ end
18
+
19
+ module Merb
20
+
21
+ class Router
22
+
23
+ class << self
24
+
25
+ alias :merbiful_old_prepare :prepare
26
+
27
+ def prepare(first = [], last = [], &block)
28
+ merbiful_old_prepare(first + ::Merbiful::PREPEND_ROUTES, last + ::Merbiful::APPEND_ROUTES, &block)
29
+ end
30
+
31
+ alias :merbiful_old_compile :compile
32
+
33
+ def compile
34
+ merbiful_old_compile unless compiled_statement.blank?
35
+ end
36
+
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
@@ -0,0 +1,4 @@
1
+ Merb.logger.info("Compiling merbiful routes...")
2
+ Merb::Router.prepare do |r|
3
+ r.match(/(.*)/).to(:controller => "merbiful", :action => "peek")
4
+ end
@@ -0,0 +1,45 @@
1
+
2
+ module Merbiful
3
+
4
+ class Page
5
+
6
+ class NoSuchFilterError < RuntimeError
7
+ end
8
+
9
+ include DataMapper::Resource
10
+ include DataMapper::Validate
11
+ include Merbiful::Body
12
+
13
+ validates_is_unique :version, :scope => [:path]
14
+
15
+ property :id, Serial
16
+ property :version, Integer, :index => true
17
+ property :body, DataMapper::Types::Text
18
+ property :filter, DataMapper::Types::Text
19
+ property :path, DataMapper::Types::Text, :index => true
20
+ property :position, Integer
21
+ property :created_at, DateTime
22
+ property :updated_at, DateTime
23
+ property :title, DataMapper::Types::Text
24
+ property :keywords, DataMapper::Types::Text
25
+ property :parent_path, DataMapper::Types::Text
26
+ property :layout_id, Integer
27
+
28
+ before :save do
29
+ if self.position.nil?
30
+ last_position = self.class.first(:parent_path => self.parent_path, :path.not => self.path)
31
+ if last_position.nil?
32
+ self.position = 0
33
+ else
34
+ self.position = last_position.position + 1
35
+ end
36
+ end
37
+ if self.path.nil?
38
+ self.path = "/"
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ end