milksteak 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/liquid_helpers.rb +7 -0
- data/lib/milksteak/cms.rb +76 -9
- data/lib/milksteak/version.rb +1 -1
- data/lib/milksteak.rb +1 -2
- data/lib/models/layout.rb +5 -0
- data/lib/models/yml_content.rb +16 -2
- data/spec/fixtures/layouts/primary.yml +9 -0
- data/spec/models/layout_spec.rb +4 -0
- data/spec/models/page_spec.rb +20 -0
- data/spec/models/yml_content_spec.rb +10 -2
- metadata +22 -16
data/lib/milksteak/cms.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Milksteak
|
2
2
|
class Cms
|
3
3
|
@@pages = []
|
4
|
-
|
4
|
+
@@routes = nil
|
5
5
|
|
6
6
|
def initialize(app)
|
7
7
|
@app = app
|
@@ -12,6 +12,7 @@ module Milksteak
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def load_pages
|
15
|
+
puts "LOADING PAGES"
|
15
16
|
@@pages = []
|
16
17
|
Milksteak::Page.list.each do |name|
|
17
18
|
name = name.match(/^.+\/(.+)\.yml/)[1]
|
@@ -22,24 +23,90 @@ module Milksteak
|
|
22
23
|
|
23
24
|
# todo: test
|
24
25
|
def routes
|
25
|
-
return
|
26
|
-
|
26
|
+
return @@routes if @@routes
|
27
|
+
puts "LOADING ROUTES"
|
28
|
+
load_pages if @@pages.empty?
|
29
|
+
@@routes = { :primary => [], :dynamic => [] }
|
27
30
|
@@pages.each do |page|
|
28
|
-
|
31
|
+
r = Route.new(page)
|
32
|
+
r.primary ? (@@routes[:primary] << r) : (@@routes[:dynamic] << r)
|
29
33
|
end
|
30
|
-
return
|
34
|
+
return @@routes
|
31
35
|
end
|
32
36
|
|
33
37
|
def route(url)
|
34
|
-
#
|
38
|
+
# search primary first, then dynamic
|
39
|
+
routes[:dynamic].sort { |a,b| b.length <=> a.length }.each do |route|
|
40
|
+
if tmp = url.match(route.pattern)
|
41
|
+
keys = route.page.data["route"].split("/").reject{|x| x[0] != ":"}
|
42
|
+
params = {}
|
43
|
+
# our match data includes the original string, so compare against
|
44
|
+
# its length minus that position
|
45
|
+
if keys.length == tmp.length-1
|
46
|
+
keys.each_with_index do |k,i|
|
47
|
+
k = k.gsub(/^\:/, "")
|
48
|
+
# our arrays are off-by-one because of the case above
|
49
|
+
params[k] = tmp[i+1]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
return { :page => route.page, :params => params }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
routes[:primary].sort { |a,b| b.length <=> a.length }.each do |route|
|
56
|
+
if url.match(route.pattern)
|
57
|
+
if route.page.data["route"] == "/"
|
58
|
+
# do extra checking to see if they asked for /index, /, or /home
|
59
|
+
if %w(index home /).include? url
|
60
|
+
return { :page => route.page }
|
61
|
+
else
|
62
|
+
return {:page => nil}
|
63
|
+
end
|
64
|
+
else
|
65
|
+
return { :page => route.page }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
return nil
|
35
70
|
end
|
36
71
|
|
37
72
|
def _call(env)
|
38
|
-
|
39
|
-
|
40
|
-
|
73
|
+
if match = route(env["PATH_INFO"]) and match[:page]
|
74
|
+
puts match.inspect
|
75
|
+
@response = [match[:page].render]
|
76
|
+
[200, {"Content-Type" => "text/html", "Content-Length" => @response[0].bytesize.to_s}, @response]
|
77
|
+
else
|
78
|
+
@status, @headers, @response = @app.call(env)
|
79
|
+
[@status, @headers, @response]
|
80
|
+
end
|
41
81
|
end
|
42
82
|
end
|
43
83
|
|
44
84
|
# todo: test
|
85
|
+
class Route
|
86
|
+
attr_accessor :pattern
|
87
|
+
attr_accessor :page
|
88
|
+
attr_accessor :primary
|
89
|
+
attr_accessor :length
|
90
|
+
|
91
|
+
def initialize(page)
|
92
|
+
@primary = true
|
93
|
+
@length = page.data["route"].length
|
94
|
+
@page = page
|
95
|
+
@pattern = build_expression(page.data["route"])
|
96
|
+
super
|
97
|
+
end
|
98
|
+
|
99
|
+
private
|
100
|
+
|
101
|
+
def build_expression(url_string)
|
102
|
+
parts = url_string.split("/")
|
103
|
+
parts.each_with_index do |part,x|
|
104
|
+
if part =~ /\:(.+)/
|
105
|
+
parts[x] = "(.+)"
|
106
|
+
@primary = false
|
107
|
+
end
|
108
|
+
end
|
109
|
+
Regexp.new(parts.join("\/"))
|
110
|
+
end
|
111
|
+
end
|
45
112
|
end
|
data/lib/milksteak/version.rb
CHANGED
data/lib/milksteak.rb
CHANGED
@@ -5,6 +5,7 @@ require "milksteak/liquid_helpers"
|
|
5
5
|
require "sinatra/base"
|
6
6
|
require "models/user"
|
7
7
|
require "models/yml_content"
|
8
|
+
require "models/layout"
|
8
9
|
require "models/page"
|
9
10
|
require "models/fragment"
|
10
11
|
require "bluecloth"
|
@@ -54,7 +55,6 @@ module Milksteak
|
|
54
55
|
end
|
55
56
|
|
56
57
|
before '/ms-admin/?*' do
|
57
|
-
|
58
58
|
# note: it is your responsibility to manage users and login processes. Any
|
59
59
|
# reference milksteak uses to a user will be done through the value stored
|
60
60
|
# in session[:ms_user]. It is best to store a string or integer that you can
|
@@ -67,7 +67,6 @@ module Milksteak
|
|
67
67
|
flash[:error] = "You must be logged in to see this area."
|
68
68
|
redirect "/"
|
69
69
|
end
|
70
|
-
|
71
70
|
end
|
72
71
|
|
73
72
|
get "/ms-admin" do
|
data/lib/models/yml_content.rb
CHANGED
@@ -40,8 +40,7 @@ module Milksteak
|
|
40
40
|
def self.render(name)
|
41
41
|
begin
|
42
42
|
p = self.load(name, "r")
|
43
|
-
|
44
|
-
BlueCloth.new(rendered).to_html
|
43
|
+
p.render
|
45
44
|
rescue Errno::ENOENT => e
|
46
45
|
""
|
47
46
|
end
|
@@ -69,5 +68,20 @@ module Milksteak
|
|
69
68
|
end
|
70
69
|
self.data ||= {}
|
71
70
|
end
|
71
|
+
|
72
|
+
# todo: test
|
73
|
+
def render
|
74
|
+
rendered = Liquid::Template.parse(self.content).render(self.data)
|
75
|
+
if self.data["layout"]
|
76
|
+
layout = Milksteak::Layout.load(self.data["layout"])
|
77
|
+
data = layout.data.merge("yield" => rendered)
|
78
|
+
rendered = Liquid::Template.parse(layout.content).render(data)
|
79
|
+
end
|
80
|
+
if self.data["format"]
|
81
|
+
BlueCloth.new(rendered).to_html if self.data["format"] == "markdown"
|
82
|
+
else
|
83
|
+
rendered
|
84
|
+
end
|
85
|
+
end
|
72
86
|
end
|
73
87
|
end
|
data/spec/models/page_spec.rb
CHANGED
@@ -19,5 +19,25 @@ describe Milksteak::Page do
|
|
19
19
|
page.content.should == "TEST CONTENT"
|
20
20
|
File.unlink(File.join(File.dirname(__FILE__), "../fixtures/pages/scratch_page.yml"))
|
21
21
|
end
|
22
|
+
|
23
|
+
it "should render without a layout" do
|
24
|
+
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/pages/sample_page.yml"), "r")
|
25
|
+
File.should_receive(:new).with("/tmp/milk_site/pages/home.yml", "r").and_return f
|
26
|
+
content = Milksteak::Page.render("home")
|
27
|
+
content.should == "This is some test content. This is just a test.\n"
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should render with a layout" do
|
31
|
+
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/pages/sample_page.yml"), "r")
|
32
|
+
File.should_receive(:new).with("/tmp/milk_site/pages/home.yml", "r").and_return f
|
33
|
+
page = Milksteak::Page.load("home")
|
34
|
+
page.data["layout"] = "primary"
|
22
35
|
|
36
|
+
layout = File.open(File.join(File.dirname(__FILE__), "../fixtures/layouts/primary.yml"), "r")
|
37
|
+
File.should_receive(:new).with("/tmp/milk_site/layouts/primary.yml", "r").and_return layout
|
38
|
+
|
39
|
+
content = page.render
|
40
|
+
content.should == "HEADER\n\nThis is some test content. This is just a test.\n\n\nFOOTER\n\n"
|
41
|
+
end
|
42
|
+
|
23
43
|
end
|
@@ -37,11 +37,19 @@ describe TestYmlObject do
|
|
37
37
|
File.unlink(File.join(File.dirname(__FILE__), "../fixtures/objs/scratch_obj.yml"))
|
38
38
|
end
|
39
39
|
|
40
|
-
it "should render obj content" do
|
40
|
+
it "should render obj content plain by default" do
|
41
41
|
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/objs/sample_obj.yml"), "r")
|
42
42
|
File.should_receive(:new).with("/tmp/milk_site/objs/home.yml", "r").and_return f
|
43
43
|
content = TestYmlObject.render("home")
|
44
|
-
content.should == "
|
44
|
+
content.should == "This is a Test Object\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should render obj as markdown when specified as format" do
|
48
|
+
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/objs/sample_obj.yml"), "r")
|
49
|
+
File.should_receive(:new).with("/tmp/milk_site/objs/home.yml", "r").and_return f
|
50
|
+
obj = TestYmlObject.load("home")
|
51
|
+
obj.data["format"] = "markdown"
|
52
|
+
obj.render.should == "<p>This is a Test Object</p>"
|
45
53
|
end
|
46
54
|
|
47
55
|
it "should return empty string if trying to render a obj that doesn't exist" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: milksteak
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.7
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-05-
|
12
|
+
date: 2012-05-24 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &21507120 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *21507120
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: guard-rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &21506660 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *21506660
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: webmock
|
38
|
-
requirement: &
|
38
|
+
requirement: &21506200 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :development
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *21506200
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rack-test
|
49
|
-
requirement: &
|
49
|
+
requirement: &21505780 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ! '>='
|
@@ -54,10 +54,10 @@ dependencies:
|
|
54
54
|
version: '0'
|
55
55
|
type: :development
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *21505780
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: liquid
|
60
|
-
requirement: &
|
60
|
+
requirement: &21505340 !ruby/object:Gem::Requirement
|
61
61
|
none: false
|
62
62
|
requirements:
|
63
63
|
- - ! '>='
|
@@ -65,10 +65,10 @@ dependencies:
|
|
65
65
|
version: '0'
|
66
66
|
type: :runtime
|
67
67
|
prerelease: false
|
68
|
-
version_requirements: *
|
68
|
+
version_requirements: *21505340
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: BlueCloth
|
71
|
-
requirement: &
|
71
|
+
requirement: &21504880 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ! '>='
|
@@ -76,10 +76,10 @@ dependencies:
|
|
76
76
|
version: '0'
|
77
77
|
type: :runtime
|
78
78
|
prerelease: false
|
79
|
-
version_requirements: *
|
79
|
+
version_requirements: *21504880
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: sinatra
|
82
|
-
requirement: &
|
82
|
+
requirement: &21504400 !ruby/object:Gem::Requirement
|
83
83
|
none: false
|
84
84
|
requirements:
|
85
85
|
- - ! '>='
|
@@ -87,7 +87,7 @@ dependencies:
|
|
87
87
|
version: '0'
|
88
88
|
type: :runtime
|
89
89
|
prerelease: false
|
90
|
-
version_requirements: *
|
90
|
+
version_requirements: *21504400
|
91
91
|
description: ! 'Super tiny and simple ruby-based cms that uses yml for content '
|
92
92
|
email:
|
93
93
|
- bryan.thompson@firespring.com
|
@@ -102,11 +102,13 @@ files:
|
|
102
102
|
- Rakefile
|
103
103
|
- Readme.md
|
104
104
|
- lib/helpers.rb
|
105
|
+
- lib/liquid_helpers.rb
|
105
106
|
- lib/milksteak.rb
|
106
107
|
- lib/milksteak/cms.rb
|
107
108
|
- lib/milksteak/liquid_helpers.rb
|
108
109
|
- lib/milksteak/version.rb
|
109
110
|
- lib/models/fragment.rb
|
111
|
+
- lib/models/layout.rb
|
110
112
|
- lib/models/page.rb
|
111
113
|
- lib/models/user.rb
|
112
114
|
- lib/models/yml_content.rb
|
@@ -443,10 +445,12 @@ files:
|
|
443
445
|
- lib/views/login.erb
|
444
446
|
- milksteak.gemspec
|
445
447
|
- spec/fixtures/fragments/sample_fragment.yml
|
448
|
+
- spec/fixtures/layouts/primary.yml
|
446
449
|
- spec/fixtures/objs/sample_obj.yml
|
447
450
|
- spec/fixtures/pages/sample_page.yml
|
448
451
|
- spec/lib/milksteak/cms_spec.rb
|
449
452
|
- spec/models/fragment_spec.rb
|
453
|
+
- spec/models/layout_spec.rb
|
450
454
|
- spec/models/page_spec.rb
|
451
455
|
- spec/models/yml_content_spec.rb
|
452
456
|
- spec/spec_helper.rb
|
@@ -476,10 +480,12 @@ specification_version: 3
|
|
476
480
|
summary: Super tiny and simple ruby-based cms
|
477
481
|
test_files:
|
478
482
|
- spec/fixtures/fragments/sample_fragment.yml
|
483
|
+
- spec/fixtures/layouts/primary.yml
|
479
484
|
- spec/fixtures/objs/sample_obj.yml
|
480
485
|
- spec/fixtures/pages/sample_page.yml
|
481
486
|
- spec/lib/milksteak/cms_spec.rb
|
482
487
|
- spec/models/fragment_spec.rb
|
488
|
+
- spec/models/layout_spec.rb
|
483
489
|
- spec/models/page_spec.rb
|
484
490
|
- spec/models/yml_content_spec.rb
|
485
491
|
- spec/spec_helper.rb
|