milksteak 0.0.6 → 0.0.7
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/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
|