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.
data/Rakefile CHANGED
@@ -5,7 +5,7 @@ require 'pathname'
5
5
 
6
6
  PLUGIN = "merbiful-release"
7
7
  NAME = "merbiful-release"
8
- GEM_VERSION = "0.2.1"
8
+ GEM_VERSION = "0.2.2"
9
9
  AUTHOR = "Martin Kihlgren"
10
10
  EMAIL = "martin@wemind.se"
11
11
  HOMEPAGE = ""
@@ -21,6 +21,9 @@ spec = Gem::Specification.new do |s|
21
21
  s.author = AUTHOR
22
22
  s.email = EMAIL
23
23
  s.homepage = HOMEPAGE
24
+ %w(merb-core merb_helpers merb_datamapper merb-action-args merb-assets merb-haml dm-core dm-aggregates dm-migrations dm-timestamps dm-validations).each do |dep|
25
+ s.add_dependency(dep)
26
+ end
24
27
  s.require_path = 'lib'
25
28
  s.autorequire = PLUGIN
26
29
  s.files = %w(Rakefile LICENSE) + Dir.glob("{lib,specs,templates}/**/*")
@@ -1,2 +1,29 @@
1
1
 
2
- require File.join(File.dirname(__FILE__), 'merbiful-release', 'merbiful.rb')
2
+ require 'merb-core'
3
+ require 'merb-action-args'
4
+ require 'merb_helpers'
5
+ require 'merb-assets'
6
+ require 'dm-core'
7
+ require 'dm-validations'
8
+ require 'dm-timestamps'
9
+ require 'dm-aggregates'
10
+ require 'haml'
11
+ require 'forwardable'
12
+ require 'pathname'
13
+ require 'erubis'
14
+ require 'pp'
15
+ require 'digest/sha1'
16
+
17
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'filters.rb')
18
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'relative_time.rb')
19
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'images.rb')
20
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'controller.rb')
21
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'body.rb')
22
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'admin.rb')
23
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'routes.rb')
24
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'css.rb')
25
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'js.rb')
26
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'page.rb')
27
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'layout.rb')
28
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'haml.rb')
29
+ require File.join(File.dirname(__FILE__), 'merbiful-release', 'erubis.rb')
@@ -5,6 +5,31 @@ module Merbiful
5
5
 
6
6
  include RelativeTimeHelpers
7
7
 
8
+ before :authorize!
9
+
10
+ def authorize!
11
+ unless authorized?
12
+ redirect login_url
13
+ throw :halt, "Access denied"
14
+ end
15
+ end
16
+
17
+ def logged_in_user
18
+ nil
19
+ end
20
+
21
+ def login_url
22
+ ""
23
+ end
24
+
25
+ def logout_url
26
+ ""
27
+ end
28
+
29
+ def authorized?
30
+ true
31
+ end
32
+
8
33
  def index
9
34
  render_template_with_layout("index.html.haml")
10
35
  end
@@ -1,10 +1,282 @@
1
1
 
2
2
  module Merbiful
3
3
 
4
- class Controller < Merb::Controller
4
+ class Admin < Merb::Controller
5
+
6
+ include RelativeTimeHelpers
7
+
8
+ def index
9
+ render_template_with_layout("index.html.haml")
10
+ end
11
+
12
+ def layouts
13
+ @form_layout = Layout.get(params[:layout_id])
14
+ if request.post?
15
+ @form_layout.update_attributes(params[:layout])
16
+ if @form_layout.valid?
17
+ @form_layout.save
18
+ @form_version = Layout::Version.new(params[:version].merge(:layout => @form_layout))
19
+ if @form_version.valid?
20
+ @form_version.save
21
+ redirect url(:merbiful_admin, :action => "layouts", :layout_id => @form_layout.id)
22
+ end
23
+ end
24
+ else
25
+ if @form_layout
26
+ @form_version = Layout::Version.get(params[:version_id])
27
+ @form_version = @form_layout.latest unless @form_version
28
+ end
29
+ end
30
+ render_template_with_layout("layouts.html.haml")
31
+ end
32
+
33
+ def js
34
+ @form_js = Js.get(params[:js_id])
35
+ if request.post?
36
+ params[:js][:cached] = !!params[:js][:cached]
37
+ @form_js.update_attributes(params[:js])
38
+ if @form_js.valid?
39
+ @form_js.save
40
+ @form_version = Js::Version.new(params[:version].merge(:js => @form_js))
41
+ if @form_version.valid?
42
+ @form_version.save
43
+ redirect url(:merbiful_admin, :action => "js", :js_id => @form_js.id)
44
+ end
45
+ end
46
+ else
47
+ if @form_js
48
+ @form_version = Js::Version.get(params[:version_id])
49
+ @form_version = @form_js.latest unless @form_version
50
+ end
51
+ end
52
+ render_template_with_layout("js.html.haml")
53
+ end
54
+
55
+ def images
56
+ if request.post?
57
+ end
58
+ render_template_with_layout("images.html.haml")
59
+ end
60
+
61
+ def css
62
+ @form_css = Css.get(params[:css_id])
63
+ if request.post?
64
+ params[:css][:cached] = !!params[:css][:cached]
65
+ @form_css.update_attributes(params[:css])
66
+ if @form_css.valid?
67
+ @form_css.save
68
+ @form_version = Css::Version.new(params[:version].merge(:css => @form_css))
69
+ if @form_version.valid?
70
+ @form_version.save
71
+ redirect url(:merbiful_admin, :action => "css", :css_id => @form_css.id)
72
+ end
73
+ end
74
+ else
75
+ if @form_css
76
+ @form_version = Css::Version.get(params[:version_id])
77
+ @form_version = @form_css.latest unless @form_version
78
+ end
79
+ end
80
+ render_template_with_layout("css.html.haml")
81
+ end
82
+
83
+ def pages
84
+ if Page.count == 0
85
+ new_root = Page.create(:path => "/")
86
+ new_root_version = Page::Version.create(:page => new_root, :body => "Here be Dagon")
87
+ end
88
+ @form_page = Page.get(params[:page_id])
89
+ if request.post?
90
+ params[:page][:cached] = !!params[:page][:cached]
91
+ @form_page.update_attributes(params[:page])
92
+ if @form_page.valid?
93
+ @form_page.save
94
+ version_csses = params[:version].delete(:css)
95
+ version_jses = params[:version].delete(:js)
96
+ @form_version = Page::Version.new(params[:version].merge(:page => @form_page))
97
+ version_csses.each do |css|
98
+ @form_version.add_css(Css.get(css))
99
+ end if version_csses
100
+ version_jses.each do |js|
101
+ @form_version.add_js(Js.get(js))
102
+ end if version_jses
103
+ if @form_version.valid?
104
+ @form_version.save
105
+ redirect url(:merbiful_admin, :action => "pages", :page_id => @form_page.id)
106
+ end
107
+ end
108
+ else
109
+ if @form_page
110
+ @form_version = Page::Version.get(params[:version_id])
111
+ @form_version = @form_page.latest unless @form_version
112
+ end
113
+ end
114
+ render_with_layout(Page.all(:parent_id => nil).collect do |page|
115
+ "<ul class='root'>\n#{render_page(page)}\n</ul>"
116
+ end.join("\n"))
117
+ end
118
+
119
+ def render_css
120
+ read_template("admin.css")
121
+ end
122
+
123
+ def destroy_page
124
+ page = Page.get(params[:page_id])
125
+ page.destroy
126
+ redirect url(:merbiful_admin, :action => "pages")
127
+ end
128
+
129
+ def upload_image
130
+ path = Pathname.new(File.join(Merb.root, "public", "images", File.basename(params[:image][:filename])))
131
+ raise "H4xx0r" unless path.to_s.index(Pathname.new(Merb.root).expand_path.to_s) == 0
132
+ Pathname.new(params[:image][:tempfile].path).rename(path)
133
+ redirect url(:merbiful_admin, :action => "images")
134
+ end
135
+
136
+ def delete_image
137
+ path = Pathname.new(File.join(Merb.root, "public", params[:path])).expand_path
138
+ raise "H4xx0r" unless path.to_s.index(Pathname.new(Merb.root).expand_path.to_s) == 0
139
+ path.unlink
140
+ redirect url(:merbiful_admin, :action => "images")
141
+ end
142
+
143
+ def destroy_layout
144
+ layout = Layout.get(params[:layout_id])
145
+ layout.destroy
146
+ redirect url(:merbiful_admin, :action => "layouts")
147
+ end
148
+
149
+ def destroy_css
150
+ css = Css.get(params[:css_id])
151
+ css.destroy
152
+ redirect url(:merbiful_admin, :action => "css")
153
+ end
154
+
155
+ def destroy_js
156
+ js = Js.get(params[:js_id])
157
+ js.destroy
158
+ redirect url(:merbiful_admin, :action => "js")
159
+ end
160
+
161
+ def create_page
162
+ parent = Page.get(params[:parent_id])
163
+ new_page = Page.create(:parent => parent, :path => next_path(parent.path))
164
+ new_page_version = Page::Version.create(:page => new_page)
165
+ redirect url(:merbiful_admin, :action => "pages", :page_id => new_page.id)
166
+ end
167
+
168
+ def create_css
169
+ new_css = Css.create(:name => next_name(Css))
170
+ new_css_version = Css::Version.create(:css => new_css)
171
+ redirect url(:merbiful_admin, :action => 'css', :css_id => new_css.id)
172
+ end
173
+
174
+ def create_js
175
+ new_js = Js.create(:name => next_name(Js))
176
+ new_js_version = Js::Version.create(:js => new_js)
177
+ redirect url(:merbiful_admin, :action => 'js', :js_id => new_js.id)
178
+ end
179
+
180
+ def create_layout
181
+ new_layout = Layout.create(:name => next_name(Layout))
182
+ new_layout_version = Layout::Version.create(:layout => new_layout)
183
+ redirect url(:merbiful_admin, :action => 'layouts', :layout_id => new_layout.id)
184
+ end
185
+
186
+ def move_page_up
187
+ page = Page.get(params[:page_id])
188
+ page.position -= 1
189
+ page.save
190
+ redirect url(:merbiful_admin, :action => "pages")
191
+ end
192
+
193
+ def move_page_down
194
+ page = Page.get(params[:page_id])
195
+ page.position += 1
196
+ page.save
197
+ redirect url(:merbiful_admin, :action => "pages")
198
+ end
199
+
200
+ private
201
+
202
+ def confirm(message)
203
+ "return confirm('#{message}');"
204
+ end
205
+
206
+ def text_area_rows
207
+ 20
208
+ end
209
+
210
+ def next_path(parent_path)
211
+ index = 0
212
+ while Page.first(:path => File.join(parent_path, index.to_s))
213
+ index += 1
214
+ end
215
+ return File.join(parent_path, index.to_s)
216
+ end
217
+
218
+ def next_name(klass)
219
+ index = 0
220
+ while klass.first(:name => index.to_s)
221
+ index += 1
222
+ end
223
+ return index.to_s
224
+ end
225
+
226
+ def errors(obj, meth)
227
+ return ""
228
+ if obj.errors.on(meth)
229
+ obj.errors.on(meth).join(", ")
230
+ else
231
+ ""
232
+ end
233
+ end
234
+
235
+ def render_children(page, ind = "")
236
+ rval = []
237
+ rval << "<ul class='children'>"
238
+ page.children(:order => [:position, :id]).each do |child|
239
+ rval << render_page(child, ind + " ")
240
+ end
241
+ rval << "</ul>"
242
+ return rval.collect do |line| ind + line end.join("\n")
243
+ end
5
244
 
6
- def display(what)
7
- render what.inspect
245
+ def render_page(page, ind = "")
246
+ rval = []
247
+ rval << "<li class='page'>"
248
+ rval << "<ul class='page_info info'>"
249
+ rval << "<a href='#{url(:merbiful_admin, :action => 'pages', :page_id => page.id)}'>"
250
+ rval << "<li class='page_path'>#{page.path}</li>"
251
+ rval << "<li class='page_title'>#{page.title || "untitled"}</li>"
252
+ rval << "<li class='page_version'>ver##{page.latest.id} (#{time_ago_in_words(page.latest.created_at)} ago)</li>"
253
+ rval << "</a>"
254
+ rval << "<li class='up'><a href='#{url(:merbiful_admin, :action => 'move_page_up', :page_id => page.id)}'>&uarr;</a></li>"
255
+ rval << "<li class='down'><a href='#{url(:merbiful_admin, :action => 'move_page_down', :page_id => page.id)}'>&darr;</a></li>"
256
+ rval << "<li class='remove'><a href='#{url(:merbiful_admin, :action => 'destroy_page', :page_id => page.id)}' onclick=\"#{confirm("Are you absolutely certain that you want to destroy the page at #{page.path}? All versions will be irreversibly destroyed.")}\">-</a></li>" unless page.parent_id.nil?
257
+ rval << "<li class='append'><a href='#{url(:merbiful_admin, :action => 'create_page', :parent_id => page.id)}'>+</a></li>"
258
+ rval << "</ul>"
259
+ rval << render_template_without_layout("page_form.html.haml") if params[:page_id].to_s == page.id.to_s
260
+ rval << render_children(page, ind) unless page.children.empty?
261
+ rval << "</li>"
262
+ return rval.collect do |line| ind + line end.join("\n")
263
+ end
264
+
265
+ def read_template(template)
266
+ Pathname.new(__FILE__).parent.parent.parent.join("templates").join(template).read
267
+ end
268
+
269
+ def render_with_layout(text)
270
+ throw_content :for_layout, text
271
+ ::Haml::Engine.new(read_template("admin_layout.html.haml")).render(self)
272
+ end
273
+
274
+ def render_template_with_layout(template)
275
+ render_with_layout(::Haml::Engine.new(read_template(template)).render(self))
276
+ end
277
+
278
+ def render_template_without_layout(template)
279
+ ::Haml::Engine.new(read_template(template)).render(self)
8
280
  end
9
281
 
10
282
  end
@@ -2,14 +2,35 @@
2
2
  module Merbiful
3
3
 
4
4
  module Body
5
- def to_html(controller)
6
- if self.filter.nil?
7
- self.body
8
- else
9
- filter_class = Merbiful.const_get(self.filter.to_sym)
10
- filter_class.new.render(self.body, controller)
5
+
6
+ def render(controller, caches = {})
7
+ rval = if self.filter.blank?
8
+ self.body
9
+ else
10
+ filter_class = Merbiful.const_get(self.filter.to_sym)
11
+ filter_class.new.render(self.body, controller)
12
+ end
13
+ unless Merb.environment == "development"
14
+ caches.each do |destination, to_cache|
15
+ if to_cache
16
+ path = Pathname.new(File.join(Merb.root, "public", destination))
17
+ Merb.logger.info("Flushing to #{path.inspect}")
18
+ path.parent.mkpath
19
+ path.open("w") do |out|
20
+ out.write(rval)
21
+ end
22
+ end
23
+ end
11
24
  end
25
+ return rval
26
+ end
27
+
28
+ def clear_cache(target)
29
+ return if target == "/"
30
+ path = Pathname.new(File.join(Merb.root, "public", target))
31
+ path.unlink if path.exist?
12
32
  end
33
+
13
34
  end
14
35
 
15
36
  end
@@ -17,23 +17,34 @@ module Merbiful
17
17
  property :updated_at, DateTime
18
18
 
19
19
  has n, :css_nesses, :class_name => "Merbiful::Css::Ness"
20
- has n, :page_versions, :through => :css_nesses, :class_name => "Merbiful::Page::Version"
20
+ has n, :page_versions, :through => :css_nesses, :class_name => "Merbiful::Page::Version", :child_key => [:css_id]
21
21
  has n, :css_versions, :class_name => "Merbiful::Css::Version"
22
22
 
23
+ before :destroy do
24
+ css_nesses.destroy!
25
+ css_versions.destroy!
26
+ end
27
+
23
28
  def latest
24
- css_versions.first(:order => [:id.desc])
29
+ css_versions.first(:css_id => self.id, :order => [:id.desc])
25
30
  end
26
31
 
27
- def_delegators :latest, :render
32
+ def_delegators :latest, :render, :body, :filter
33
+
34
+ def path
35
+ "/stylesheets/#{latest.id}"
36
+ end
28
37
 
29
38
  class Ness
30
39
  include DataMapper::Resource
31
40
  include DataMapper::Validate
32
41
 
33
42
  property :id, Serial
43
+ property :page_version_id, Integer
44
+ property :css_id, Integer
34
45
 
35
- belongs_to :css, :class_name => "Merbiful::Css"
36
- belongs_to :page_version, :class_name => "Merbiful::Page::Version"
46
+ belongs_to :css, :class_name => "Merbiful::Css", :child_key => [:css_id]
47
+ belongs_to :page_version, :class_name => "Merbiful::Page::Version", :child_key => [:page_version_id]
37
48
  end
38
49
 
39
50
  class Version
@@ -54,6 +65,10 @@ module Merbiful
54
65
 
55
66
  belongs_to :css, :class_name => "Merbiful::Css"
56
67
 
68
+ before :save do
69
+ clear_cache(css.path) if css.latest
70
+ end
71
+
57
72
  end
58
73
 
59
74
  end