merbiful-release 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,11 +1,13 @@
1
1
  module Merbiful
2
2
 
3
- class Eruby
3
+ class Erubis
4
4
 
5
5
  def render(text, scope)
6
- ERB.new(text).result(scope)
6
+ ::Erubis::Eruby.new(text).result(scope.instance_eval do binding end)
7
7
  end
8
8
 
9
9
  end
10
10
 
11
+ FILTERS << Erubis
12
+
11
13
  end
@@ -0,0 +1,22 @@
1
+
2
+ module Merbiful
3
+
4
+ module Filter
5
+
6
+ @filters = []
7
+
8
+ def self.register_filter(filter)
9
+ @filters << filter
10
+ end
11
+
12
+ def self.filters
13
+ @filters.inject([[nil, "Verbatim"]]) do |sum, filter|
14
+ filter_name = filter.name.gsub(/^Merbiful::/, "")
15
+ sum + [[filter_name, filter_name]]
16
+ end
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+
@@ -3,9 +3,21 @@ module Merbiful
3
3
 
4
4
  class Haml
5
5
 
6
- def render(text)
6
+ def render(text, scope)
7
+ ::Haml::Engine.new(text).render(scope)
7
8
  end
8
9
 
9
10
  end
10
11
 
12
+ class Sass
13
+
14
+ def render(text, scope)
15
+ ::Sass::Engine.new(text).render
16
+ end
17
+
18
+ end
19
+
20
+ FILTERS << Haml
21
+ FILTERS << Sass
22
+
11
23
  end
@@ -0,0 +1,14 @@
1
+
2
+ module Merbiful
3
+
4
+ class ImageHandler
5
+
6
+ IMAGE_REGEXP = /\.(gif|jpg|jpeg|png|bmp)$/
7
+
8
+ def images
9
+
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Merbiful
3
3
 
4
- class Css
4
+ class Js
5
5
 
6
6
  include DataMapper::Resource
7
7
  include DataMapper::Validate
@@ -10,30 +10,40 @@ module Merbiful
10
10
  property :id, Serial
11
11
 
12
12
  property :name, DataMapper::Types::Text, :nullable => false
13
- property :media, DataMapper::Types::Text
14
13
  property :cached, Boolean, :default => true, :nullable => false
15
14
 
16
15
  property :created_at, DateTime
17
16
  property :updated_at, DateTime
18
17
 
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"
18
+ has n, :js_nesses, :class_name => "Merbiful::Js::Ness"
19
+ has n, :page_versions, :through => :js_nesses, :class_name => "Merbiful::Page::Version", :child_key => [:js_id]
20
+ has n, :js_versions, :class_name => "Merbiful::Js::Version"
21
+
22
+ before :destroy do
23
+ js_nesses.destroy!
24
+ js_versions.destroy!
25
+ end
22
26
 
23
27
  def latest
24
- css_versions.first(:order => [:id.desc])
28
+ js_versions.first(:js_id => self.id, :order => [:id.desc])
25
29
  end
26
30
 
27
- def_delegators :latest, :render
31
+ def_delegators :latest, :render, :body, :filter
32
+
33
+ def path
34
+ "/javascripts/#{latest.id}"
35
+ end
28
36
 
29
37
  class Ness
30
38
  include DataMapper::Resource
31
39
  include DataMapper::Validate
32
40
 
33
41
  property :id, Serial
42
+ property :page_version_id, Integer
43
+ property :js_id, Integer
34
44
 
35
- belongs_to :css, :class_name => "Merbiful::Css"
36
- belongs_to :page_version, :class_name => "Merbiful::Page::Version"
45
+ belongs_to :js, :class_name => "Merbiful::Js", :child_key => [:js_id]
46
+ belongs_to :page_version, :class_name => "Merbiful::Page::Version", :child_key => [:page_version_id]
37
47
  end
38
48
 
39
49
  class Version
@@ -44,7 +54,7 @@ module Merbiful
44
54
 
45
55
  property :id, Serial
46
56
 
47
- property :css_id, Integer, :index => true, :nullable => false
57
+ property :js_id, Integer, :index => true, :nullable => false
48
58
 
49
59
  property :body, DataMapper::Types::Text
50
60
  property :filter, DataMapper::Types::Text
@@ -52,8 +62,12 @@ module Merbiful
52
62
  property :created_at, DateTime
53
63
  property :updated_at, DateTime
54
64
 
55
- belongs_to :css, :class_name => "Merbiful::Css"
65
+ belongs_to :js, :class_name => "Merbiful::Js"
56
66
 
67
+ before :save do
68
+ clear_cache(js.path) if js.latest
69
+ end
70
+
57
71
  end
58
72
 
59
73
  end
@@ -1,21 +1,49 @@
1
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
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
+
20
48
 
21
49
  end
@@ -8,48 +8,100 @@ module Merbiful
8
8
 
9
9
  include DataMapper::Resource
10
10
  include DataMapper::Validate
11
- include Merbiful::Body
12
-
13
- validates_is_unique :version, :scope => [:path]
11
+ extend Forwardable
14
12
 
15
13
  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
14
+ property :parent_id, Integer, :index => true
15
+
16
+ property :path, DataMapper::Types::Text, :unique_index => true, :nullable => false
20
17
  property :position, Integer
18
+ property :cached, Boolean, :default => true, :nullable => false
19
+
21
20
  property :created_at, DateTime
22
21
  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
22
 
28
- belongs_to :layout, :class_name => "Merbiful::Layout"
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"
29
26
 
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
27
+ validates_is_unique :path
28
+
29
+ before :destroy do
30
+ versions.each do |version|
31
+ version.destroy
36
32
  end
33
+ end
34
+
35
+ before :save do
37
36
  if self.position.nil?
38
- last_position = self.class.first(:parent_path => self.parent_path, :path.not => self.path)
37
+ last_position = self.class.first(:parent_id => self.parent_id, :id.not => self.id)
39
38
  if last_position.nil?
40
39
  self.position = 0
41
40
  else
42
41
  self.position = last_position.position + 1
43
42
  end
44
43
  end
45
- if self.path.nil?
46
- self.path = "/"
47
- end
44
+ end
48
45
 
46
+ def latest
47
+ versions.first(:page_id => self.id, :order => [:id.desc])
49
48
  end
50
49
 
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])
50
+ def_delegators :latest, :render, :layout, :csses, :add_css, :remove_css, :jses, :add_js, :remove_js, :body, :filter, :title, :keywords
51
+
52
+ class Version
53
+
54
+ include DataMapper::Resource
55
+ include DataMapper::Validate
56
+ include Merbiful::Body
57
+
58
+ property :id, Serial
59
+
60
+ property :page_id, Integer, :nullable => false, :index => true
61
+ property :layout_id, Integer, :index => true
62
+
63
+ property :body, DataMapper::Types::Text
64
+ property :filter, DataMapper::Types::Text
65
+ property :title, DataMapper::Types::Text
66
+ property :keywords, DataMapper::Types::Text
67
+
68
+ property :created_at, DateTime
69
+ property :updated_at, DateTime
70
+
71
+ belongs_to :page, :class_name => "Merbiful::Page"
72
+ belongs_to :layout, :class_name => "Merbiful::Layout"
73
+
74
+ has n, :css_nesses, :class_name => "Merbiful::Css::Ness"
75
+ has n, :csses, :through => :css_nesses, :class_name => "Merbiful::Css", :remote_name => :css, :child_key => [:page_version_id]
76
+
77
+ has n, :js_nesses, :class_name => "Merbiful::Js::Ness"
78
+ has n, :jses, :through => :js_nesses, :class_name => "Merbiful::Js", :remote_name => :js, :child_key => [:page_version_id]
79
+
80
+ before :destroy do
81
+ css_nesses.destroy!
82
+ js_nesses.destroy!
83
+ end
84
+
85
+ before :save do
86
+ clear_cache(page.path) if page.latest
87
+ end
88
+
89
+ def add_css(css)
90
+ Merbiful::Css::Ness.create(:css => css, :page_version => self)
91
+ end
92
+
93
+ def remove_css(css)
94
+ css_nesses.first(:css_id => css.id).destroy
95
+ end
96
+
97
+ def add_js(js)
98
+ Merbiful::Js::Ness.create(:js => js, :page_version => self)
99
+ end
100
+
101
+ def remove_js(js)
102
+ js_nesses.first(:js_id => js.id).destroy
103
+ end
104
+
53
105
  end
54
106
 
55
107
  end
@@ -0,0 +1,16 @@
1
+
2
+ String.class_eval do
3
+
4
+ def cached_path
5
+ path = Pathname.new(File.join(Merb.root, "public", self))
6
+ raise "H4xx0r" unless path.to_s.index(Pathname.new(Merb.root).join("public").expand_path.to_s) == 0
7
+ if path.parent.file?
8
+ path.parent.unlink
9
+ elsif path.directory?
10
+ path = path.join("index.html")
11
+ end
12
+ path
13
+ end
14
+
15
+
16
+ end
data/templates/admin.css~ CHANGED
@@ -1,3 +1,14 @@
1
- ul {
2
- background-color: red;
1
+ ul.info {
3
2
  }
3
+
4
+ ul.info li {
5
+ list-style: none none inside;
6
+ display: inline;
7
+ margin: 1px;
8
+ padding: 1px;
9
+ }
10
+
11
+ li.page_title {
12
+ font-weight: bold;
13
+ }
14
+
@@ -2,6 +2,10 @@
2
2
  %link{:href => url(:merbiful_admin_css), :rel => 'Stylesheet', :type => 'text/css'}
3
3
  %body
4
4
  %h1= link_to("Merbiful Release Administration Interface", url(:merbiful_admin_index))
5
+ - if logged_in_user
6
+ %ul.access
7
+ %li= "You are logged in as #{logged_in_user}."
8
+ %li= link_to("Logout", logout_url)
5
9
  %ul.menu
6
10
  %li= link_to("Pages", url(:merbiful_admin, :action => "pages"))
7
11
  %li= link_to("Layouts", url(:merbiful_admin, :action => "layouts"))
@@ -1,9 +1,11 @@
1
1
  %html
2
+ %link{:href => url(:merbiful_admin_css), :rel => 'Stylesheet', :type => 'text/css'}
2
3
  %body
3
- %h1 Merbiful Release Administration Interface
4
+ %h1= link_to("Merbiful Release Administration Interface", url(:merbiful_admin_index))
4
5
  %ul.menu
5
- %li Pages
6
- %li Layouts
7
- %li Css
8
- %li Js
6
+ %li= link_to("Pages", url(:merbiful_admin, :action => "pages"))
7
+ %li= link_to("Layouts", url(:merbiful_admin, :action => "layouts"))
8
+ %li= link_to("Css", url(:merbiful_admin, :action => "css"))
9
+ %li= link_to("Js", url(:merbiful_admin, :action => "js"))
10
+ %li= link_to("Images", url(:merbiful_admin, :action => "images"))
9
11
  = catch_content :for_layout
@@ -6,24 +6,27 @@
6
6
  %a{:href => url(:merbiful_admin, :action => "css", :css_id => css.id)}
7
7
  %li{:class => "css_name"}= css.name
8
8
  %li{:class => "css_version"}= "ver##{css.latest.id} (#{time_ago_in_words(css.latest.created_at)} ago)"
9
- %li= link_to("-", url(:merbiful_admin, :action => "destroy_css", :css_id => css.id))
9
+ %li= link_to("-", url(:merbiful_admin, :action => "destroy_css", :css_id => css.id), :onclick => confirm("Are you absolutely certain that you want to destroy the css named #{css.name}? All versions will be irreversibly destroyed."))
10
10
  - if params[:css_id].to_s == css.id.to_s
11
11
  %table.css
12
12
  %form{:action => url(:merbiful_admin, :action => "css", :css_id => css.id), :method => "post"}
13
+ %tr{:class => "version"}
14
+ %td Viewing version
15
+ %td= @form_css.css_versions(:order => [:id.desc]).collect do |v| "<a class='#{v.id == @form_version.id ? 'active' : 'inactive'}' href='#{url(:merbiful_admin, :action => "css", :css_id => @form_css.id, :version_id => v.id)}'>#{v.id}</a>" end.join(", ")
13
16
  %tr
14
- %td Name
17
+ %td Name (not versioned)
15
18
  %td= text_field(:name => "css[name]", :value => @form_css.name) + errors(@form_css, :name)
16
19
  %tr
17
20
  %td Body
18
- %td~ text_area(@form_css.body, :name => "version[body]", :cols => 80, :rows => (2 * @form_css.body.to_s.split(/\n/).size)) + errors(@form_version, :body)
21
+ %td~ text_area(@form_version.body, :name => "version[body]", :cols => 80, :rows => text_area_rows) + errors(@form_version, :body)
19
22
  %tr{:class => "filter"}
20
23
  %td Filter
21
- %td= select(:name => "version[filter]", :collection => Merbiful::filters, :selected => @form_css.latest.filter) + errors(@form_version, :filter)
24
+ %td= select(:name => "version[filter]", :collection => Merbiful::Filter.filters, :selected => @form_version.filter) + errors(@form_version, :filter)
22
25
  %tr
23
- %td Media
26
+ %td Media (not versioned)
24
27
  %td= text_field(:name => "css[media]", :value => @form_css.media) + errors(@form_css, :media)
25
28
  %tr{:class => "cached"}
26
- %td Cached
29
+ %td Cached (not versioned)
27
30
  %td= check_box(:name => "css[cached]", :checked => @form_css.cached) + errors(@form_css, :cached)
28
31
  %tr{:class => "submit"}
29
- %td{:colspan => "2"}= submit("Save")
32
+ %td{:colspan => "2"}= submit("Save as new version")