milksteak 0.0.3 → 0.0.4
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/Readme.md +19 -1
- data/lib/milksteak/cms.rb +18 -3
- data/lib/milksteak/version.rb +1 -1
- data/lib/milksteak.rb +23 -3
- data/lib/models/fragment.rb +5 -0
- data/lib/models/page.rb +10 -65
- data/lib/models/yml_content.rb +73 -0
- data/lib/views/admin.erb +5 -0
- data/lib/views/layouts/admin.erb +103 -4
- data/spec/fixtures/fragments/sample_fragment.yml +5 -0
- data/spec/fixtures/objs/sample_obj.yml +5 -0
- data/spec/fixtures/pages/sample_page.yml +1 -0
- data/spec/lib/milksteak/cms_spec.rb +39 -3
- data/spec/models/fragment_spec.rb +7 -0
- data/spec/models/page_spec.rb +10 -45
- data/spec/models/yml_content_spec.rb +62 -0
- data/spec/spec_helper.rb +4 -1
- metadata +26 -15
data/Readme.md
CHANGED
@@ -1,4 +1,9 @@
|
|
1
|
-
|
1
|
+
Milksteak is a little experiment in tiny-cms-land. My goal with it is to build the minimum structure necessary
|
2
|
+
and keep it as far from anything like rails as possible, with minimum requirements, fast tests, and simple
|
3
|
+
structure. Expect the project to change rather dramatically as I add to it, feel free to fork and do whatever
|
4
|
+
you like, and as always, pull requests are very welcome.
|
5
|
+
|
6
|
+
# Install
|
2
7
|
|
3
8
|
gem install milksteak
|
4
9
|
gem 'milksteak' # if using bundler
|
@@ -35,3 +40,16 @@ text to be editable.
|
|
35
40
|
|
36
41
|
Here's the sidebar content. I can use the {{yml_variables}} and such.
|
37
42
|
|
43
|
+
# Roadmap
|
44
|
+
|
45
|
+
* Blog/News engine
|
46
|
+
* Photo galleries
|
47
|
+
* Flexible collection types for data lists and content types (kinda hard to bullet-point intention here)
|
48
|
+
* Support for storage back-ends rather than YML, if necessary
|
49
|
+
* Tie into Tonic CMS (v3) API
|
50
|
+
* Dynamic page routes (currently pages are treated as content fragments)
|
51
|
+
* ... Contact me with your requests and ideas, or fork and add your own
|
52
|
+
|
53
|
+
# License
|
54
|
+
|
55
|
+
Milksteak is released under the MIT license and is copyright (c) 2012 Bryan Thompson
|
data/lib/milksteak/cms.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Milksteak
|
2
|
-
|
2
|
+
class Cms
|
3
|
+
@@pages = []
|
4
|
+
|
3
5
|
def initialize(app)
|
4
6
|
@app = app
|
5
7
|
end
|
@@ -7,9 +9,22 @@ module Milksteak
|
|
7
9
|
def call(env)
|
8
10
|
dup._call(env)
|
9
11
|
end
|
10
|
-
|
12
|
+
|
13
|
+
def load_pages
|
14
|
+
@@pages = []
|
15
|
+
Milksteak::Page.list.each do |name|
|
16
|
+
name = name.match(/^.+\/(.+)\.yml/)[1]
|
17
|
+
page = Milksteak::Page.load(name, "r")
|
18
|
+
@@pages << page
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def route(url)
|
23
|
+
# TODO
|
24
|
+
end
|
25
|
+
|
11
26
|
def _call(env)
|
12
|
-
puts "OK"
|
27
|
+
#puts "OK"
|
13
28
|
@status, @headers, @response = @app.call(env)
|
14
29
|
[@status, @headers, @response]
|
15
30
|
end
|
data/lib/milksteak/version.rb
CHANGED
data/lib/milksteak.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require "milksteak/version"
|
2
|
+
require "milksteak/cms"
|
2
3
|
require "sinatra/base"
|
3
4
|
require "models/user"
|
5
|
+
require "models/yml_content"
|
4
6
|
require "models/page"
|
7
|
+
require "models/fragment"
|
5
8
|
require "liquid"
|
6
9
|
require "bluecloth"
|
7
10
|
|
@@ -48,9 +51,26 @@ module Milksteak
|
|
48
51
|
msgs.join
|
49
52
|
end
|
50
53
|
end
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
+
|
55
|
+
before '/ms-admin/?*' do
|
56
|
+
|
57
|
+
# note: it is your responsibility to manage users and login processes. Any
|
58
|
+
# reference milksteak uses to a user will be done through the value stored
|
59
|
+
# in session[:ms_user]. It is best to store a string or integer that you can
|
60
|
+
# use on your own to reference the user. This might change at some point to
|
61
|
+
# allowing you to put a Milksteak::User in this variable with predictable
|
62
|
+
# fields that you could populate on login. That way, we can present user actions
|
63
|
+
# in an easy manner.
|
64
|
+
|
65
|
+
unless session[:ms_user]
|
66
|
+
flash[:error] = "You must be logged in to see this area."
|
67
|
+
redirect "/"
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
get "/ms-admin" do
|
73
|
+
erb "admin", :layout => "admin"
|
54
74
|
end
|
55
75
|
end
|
56
76
|
end
|
data/lib/models/page.rb
CHANGED
@@ -1,73 +1,18 @@
|
|
1
1
|
module Milksteak
|
2
|
-
class Page
|
3
|
-
attr_accessor :
|
2
|
+
class Page < YmlContent
|
3
|
+
attr_accessor :route
|
4
4
|
|
5
|
-
def self.
|
6
|
-
milk_root = Milksteak::Admin.milk_root
|
7
|
-
page_dir = File.join(Milksteak::Admin.milk_root, "pages")
|
8
|
-
FileUtils.mkdir(milk_root) unless File.exist? milk_root
|
9
|
-
FileUtils.mkdir(page_dir) unless File.exist? page_dir
|
10
|
-
Dir.glob("#{page_dir}/*.yml")
|
11
|
-
end
|
5
|
+
def self.folder; "pages"; end
|
12
6
|
|
13
|
-
#
|
14
|
-
|
15
|
-
|
16
|
-
page_dir = File.join(Milksteak::Admin.milk_root, "pages")
|
17
|
-
FileUtils.mkdir(milk_root) unless File.exist? milk_root
|
18
|
-
FileUtils.mkdir(page_dir) unless File.exist? page_dir
|
19
|
-
|
20
|
-
page_dir = File.join(page_dir, "#{name}.yml")
|
21
|
-
f = File.exist?(page_dir) ? File.open(page_dir, mode) : File.new(page_dir, mode)
|
22
|
-
|
23
|
-
p = self.new
|
24
|
-
p.name = name
|
25
|
-
p.file = f
|
26
|
-
p.read_yaml
|
27
|
-
p
|
28
|
-
end
|
7
|
+
# override write to include validation for :route. If validation
|
8
|
+
# becomes something that is needed on a bigger scale, we'll need
|
9
|
+
# to put this into another method activerecord-style
|
29
10
|
|
30
|
-
# writes to a page. Replaces params and content, doesn't merge.
|
31
11
|
def self.write(name, params = {}, content)
|
32
|
-
|
33
|
-
|
34
|
-
p.content = content
|
35
|
-
p.write_yaml
|
36
|
-
p.file.close
|
37
|
-
p
|
38
|
-
end
|
39
|
-
|
40
|
-
def self.render(name)
|
41
|
-
begin
|
42
|
-
p = self.load(name, "r")
|
43
|
-
rendered = Liquid::Template.parse(p.content).render(p.data)
|
44
|
-
BlueCloth.new(rendered).to_html
|
45
|
-
rescue Errno::ENOENT => e
|
46
|
-
""
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def write_yaml
|
51
|
-
if self.data.empty?
|
52
|
-
self.file.write("---\n")
|
53
|
-
else
|
54
|
-
self.file.write(YAML.dump(self.data))
|
55
|
-
end
|
56
|
-
self.file.write("---\n\n")
|
57
|
-
self.file.write(self.content)
|
58
|
-
end
|
59
|
-
|
60
|
-
def read_yaml
|
61
|
-
self.content = self.file.read
|
62
|
-
begin
|
63
|
-
if self.content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)(.*)/m
|
64
|
-
self.content = $3
|
65
|
-
self.data = YAML.load($1)
|
66
|
-
end
|
67
|
-
rescue => e
|
68
|
-
puts "YAML Exception reading #{name}: #{e.message}"
|
69
|
-
end
|
70
|
-
self.data ||= {}
|
12
|
+
raise NoRouteException unless params["route"]
|
13
|
+
super
|
71
14
|
end
|
72
15
|
end
|
16
|
+
|
17
|
+
class NoRouteException < Exception; end
|
73
18
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module Milksteak
|
2
|
+
class YmlContent
|
3
|
+
attr_accessor :name, :file, :data, :content, :output
|
4
|
+
|
5
|
+
def self.list
|
6
|
+
milk_root = Milksteak::Admin.milk_root
|
7
|
+
page_dir = File.join(Milksteak::Admin.milk_root, self.folder)
|
8
|
+
FileUtils.mkdir(milk_root) unless File.exist? milk_root
|
9
|
+
FileUtils.mkdir(page_dir) unless File.exist? page_dir
|
10
|
+
Dir.glob("#{page_dir}/*.yml")
|
11
|
+
end
|
12
|
+
|
13
|
+
# loads a page from yaml, sets data and content attributes, returns a Milksteak::Page
|
14
|
+
def self.load(name, mode = "r")
|
15
|
+
milk_root = Milksteak::Admin.milk_root
|
16
|
+
page_dir = File.join(Milksteak::Admin.milk_root, self.folder)
|
17
|
+
FileUtils.mkdir(milk_root) unless File.exist? milk_root
|
18
|
+
FileUtils.mkdir(page_dir) unless File.exist? page_dir
|
19
|
+
|
20
|
+
page_dir = File.join(page_dir, "#{name}.yml")
|
21
|
+
f = File.exist?(page_dir) ? File.open(page_dir, mode) : File.new(page_dir, mode)
|
22
|
+
|
23
|
+
p = self.new
|
24
|
+
p.name = name
|
25
|
+
p.file = f
|
26
|
+
p.read_yaml
|
27
|
+
p
|
28
|
+
end
|
29
|
+
|
30
|
+
# writes to a page. Replaces params and content, doesn't merge.
|
31
|
+
def self.write(name, params = {}, content)
|
32
|
+
p = self.load(name, "w+")
|
33
|
+
p.data = params
|
34
|
+
p.content = content
|
35
|
+
p.write_yaml
|
36
|
+
p.file.close
|
37
|
+
p
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.render(name)
|
41
|
+
begin
|
42
|
+
p = self.load(name, "r")
|
43
|
+
rendered = Liquid::Template.parse(p.content).render(p.data)
|
44
|
+
BlueCloth.new(rendered).to_html
|
45
|
+
rescue Errno::ENOENT => e
|
46
|
+
""
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def write_yaml
|
51
|
+
if self.data.empty?
|
52
|
+
self.file.write("---\n")
|
53
|
+
else
|
54
|
+
self.file.write(YAML.dump(self.data))
|
55
|
+
end
|
56
|
+
self.file.write("---\n\n")
|
57
|
+
self.file.write(self.content)
|
58
|
+
end
|
59
|
+
|
60
|
+
def read_yaml
|
61
|
+
self.content = self.file.read
|
62
|
+
begin
|
63
|
+
if self.content =~ /^(---\s*\n.*?\n?)^(---\s*$\n?)(.*)/m
|
64
|
+
self.content = $3
|
65
|
+
self.data = YAML.load($1)
|
66
|
+
end
|
67
|
+
rescue => e
|
68
|
+
puts "YAML Exception reading #{name}: #{e.message}"
|
69
|
+
end
|
70
|
+
self.data ||= {}
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/views/admin.erb
ADDED
data/lib/views/layouts/admin.erb
CHANGED
@@ -1,8 +1,107 @@
|
|
1
|
-
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
2
3
|
<head>
|
3
|
-
<
|
4
|
+
<meta charset="utf-8">
|
5
|
+
<title>ms-admin</title>
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
|
+
<meta name="description" content="">
|
8
|
+
<meta name="author" content="">
|
9
|
+
|
10
|
+
<script src="/milksteak/js/jquery.js"></script>
|
11
|
+
<script src="/milksteak/js/jquery-ui.min.js"></script>
|
12
|
+
<script src="/milksteak/js/jquery.calendrical.js"></script>
|
13
|
+
<script src="/milksteak/js/moment.min.js"></script>
|
14
|
+
<script src="/milksteak/js/mustache.js"></script>
|
15
|
+
<script src="/milksteak/js/underscore.js"></script>
|
16
|
+
<script src="/milksteak/js/backbone.js"></script>
|
17
|
+
<script src="/milksteak/js/prettify.js"></script>
|
18
|
+
|
19
|
+
<!-- Le styles -->
|
20
|
+
<link href="/milksteak/css/calendrical.css" rel="stylesheet">
|
21
|
+
<link href="/milksteak/css/bootstrap.css" rel="stylesheet">
|
22
|
+
<style type="text/css">
|
23
|
+
body {
|
24
|
+
padding-top: 60px;
|
25
|
+
padding-bottom: 40px;
|
26
|
+
}
|
27
|
+
.sidebar-nav {
|
28
|
+
padding: 9px 0;
|
29
|
+
}
|
30
|
+
th.text_right, td.text_right { text-align: right; }
|
31
|
+
th.text_center, td.text_center { text-align: center; }
|
32
|
+
</style>
|
33
|
+
<link href="/milksteak/css/bootstrap-responsive.css" rel="stylesheet">
|
34
|
+
<link href="/milksteak/css/prettify.css" type="text/css" rel="stylesheet" />
|
35
|
+
<link href="/milksteak/css/style.css" rel="stylesheet">
|
36
|
+
|
37
|
+
|
38
|
+
<!-- Le HTML5 shim, for IE6-8 support of HTML5 elements -->
|
39
|
+
<!--[if lt IE 9]>
|
40
|
+
<script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
41
|
+
<![endif]-->
|
42
|
+
|
43
|
+
<!-- Le fav and touch icons -->
|
44
|
+
<link rel="shortcut icon" href="images/favicon.ico">
|
45
|
+
<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
|
46
|
+
<link rel="apple-touch-icon" sizes="72x72" href="images/apple-touch-icon-72x72.png">
|
47
|
+
<link rel="apple-touch-icon" sizes="114x114" href="images/apple-touch-icon-114x114.png">
|
4
48
|
</head>
|
5
|
-
|
6
|
-
|
49
|
+
|
50
|
+
<body>
|
51
|
+
|
52
|
+
<div class="navbar navbar-fixed-top">
|
53
|
+
<div class="navbar-inner">
|
54
|
+
<div class="container-fluid">
|
55
|
+
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
|
56
|
+
<span class="icon-bar"></span>
|
57
|
+
</a>
|
58
|
+
<a class="brand" href="#">Milksteak</a>
|
59
|
+
<div class="nav-collapse">
|
60
|
+
<ul class="nav">
|
61
|
+
<li><a href="/merchants">Dashboard</a></li>
|
62
|
+
</ul>
|
63
|
+
<p class="navbar-text pull-right">
|
64
|
+
Log In
|
65
|
+
</p>
|
66
|
+
</div><!--/.nav-collapse -->
|
67
|
+
</div>
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
|
71
|
+
<div class="container-fluid">
|
72
|
+
<div class="row-fluid">
|
73
|
+
<div class="span12">
|
74
|
+
<div class="row-fluid">
|
75
|
+
<%= flash_messages %>
|
76
|
+
<%= yield %>
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
</div>
|
80
|
+
|
81
|
+
<hr>
|
82
|
+
<footer>
|
83
|
+
<p>Milksteak CMS © 2012 Bryan Thompson</p>
|
84
|
+
</footer>
|
85
|
+
|
86
|
+
</div><!--/.fluid-container-->
|
87
|
+
|
88
|
+
<!-- Le javascript
|
89
|
+
================================================== -->
|
90
|
+
<!-- Placed at the end of the document so the pages load faster -->
|
91
|
+
<script src="/milksteak/js/bootstrap-transition.js"></script>
|
92
|
+
<script src="/milksteak/js/bootstrap-alert.js"></script>
|
93
|
+
<script src="/milksteak/js/bootstrap-modal.js"></script>
|
94
|
+
<script src="/milksteak/js/bootstrap-dropdown.js"></script>
|
95
|
+
<script src="/milksteak/js/bootstrap-scrollspy.js"></script>
|
96
|
+
<script src="/milksteak/js/bootstrap-tab.js"></script>
|
97
|
+
<script src="/milksteak/js/bootstrap-tooltip.js"></script>
|
98
|
+
<script src="/milksteak/js/bootstrap-popover.js"></script>
|
99
|
+
<script src="/milksteak/js/bootstrap-button.js"></script>
|
100
|
+
<script src="/milksteak/js/bootstrap-collapse.js"></script>
|
101
|
+
<script src="/milksteak/js/bootstrap-carousel.js"></script>
|
102
|
+
<script src="/milksteak/js/bootstrap-typeahead.js"></script>
|
103
|
+
<script src="/ms-admin/app.js"></script>
|
104
|
+
|
7
105
|
</body>
|
8
106
|
</html>
|
107
|
+
|
@@ -5,8 +5,44 @@ describe Milksteak do
|
|
5
5
|
Milksteak::Admin.milk_root.should_not be_nil
|
6
6
|
end
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
context "non-logged-in visitors" do
|
9
|
+
it "should redirect to / from /ms-admin" do
|
10
|
+
get "/ms-admin"
|
11
|
+
last_response.status.should == 302
|
12
|
+
get "/ms-admin/"
|
13
|
+
last_response.status.should == 302
|
14
|
+
end
|
11
15
|
end
|
16
|
+
|
17
|
+
context "logged-in users" do
|
18
|
+
it "should successfuly render /ms-admin" do
|
19
|
+
get "/ms-admin", {}, 'rack.session' => { :ms_user => "bryan-test-user-id" }
|
20
|
+
last_response.status.should == 200
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
describe Milksteak::Cms do
|
27
|
+
before :all do
|
28
|
+
Milksteak::Cms.class_eval("@@pages").should == []
|
29
|
+
Milksteak::Page.should_receive(:list).and_return ["./spec/fixtures/pages/sample_page.yml"]
|
30
|
+
f = File.open(File.join(File.dirname(__FILE__), "../../fixtures/pages/sample_page.yml"), "r")
|
31
|
+
File.should_receive(:new).with("/tmp/milk_site/pages/sample_page.yml", "r").and_return f
|
32
|
+
@a = Milksteak::Cms.new(Sinatra::Application)
|
33
|
+
@a.load_pages
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should pull list of pages and process routes" do
|
37
|
+
pages = Milksteak::Cms.class_eval("@@pages")
|
38
|
+
pages.length.should == 1
|
39
|
+
pages[0].data["route"].should == "/test-page"
|
40
|
+
end
|
41
|
+
|
42
|
+
pending "should find and route an existing page with an appropriate route" do
|
43
|
+
page = @a.route("/test-page")
|
44
|
+
pages.data["route"].should == "/test-page"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not find a page for a non-existant route"
|
12
48
|
end
|
data/spec/models/page_spec.rb
CHANGED
@@ -1,58 +1,23 @@
|
|
1
1
|
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
2
2
|
|
3
3
|
describe Milksteak::Page do
|
4
|
-
it "should make the page dir if it doesn't exist" do
|
5
|
-
File.stub(:exist?).and_return false
|
6
|
-
FileUtils.should_receive(:mkdir).twice.and_return true
|
7
|
-
Milksteak::Page.list.should be_an Array
|
8
|
-
end
|
9
|
-
|
10
|
-
it "should get list of pages from milk_root/pages" do
|
11
|
-
Milksteak::Page.list.should be_an Array
|
12
|
-
end
|
13
|
-
|
14
|
-
# this utility method is used by the read and write methods as a consistent
|
15
|
-
# way to access yml page documents.
|
16
|
-
it "should load a page into params" do
|
17
|
-
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/pages/sample_page.yml"), "r")
|
18
|
-
f.stub(:save).and_return true
|
19
|
-
File.should_receive(:new).with("/tmp/milk_site/pages/home.yml", "r").and_return f
|
20
|
-
page = Milksteak::Page.load("home", "r")
|
21
|
-
page.should be_a Milksteak::Page
|
22
|
-
page.data.should == { "description" => "This is just a test." }
|
23
|
-
page.content.should == "This is some test content. {{description}}\n"
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should write a page with contents in params" do
|
27
|
-
f = File.new(File.join(File.dirname(__FILE__), "../fixtures/pages/scratch_page.yml"), "w+")
|
28
|
-
File.should_receive(:new).with("/tmp/milk_site/pages/home.yml", "w+").and_return f
|
29
|
-
page = Milksteak::Page.write("home", { "description" => "TEST PAGE"}, "TEST CONTENT")
|
30
|
-
page.data.should == { "description" => "TEST PAGE" }
|
31
|
-
page.content.should == "TEST CONTENT"
|
32
|
-
File.unlink(File.join(File.dirname(__FILE__), "../fixtures/pages/scratch_page.yml"))
|
33
|
-
end
|
34
|
-
|
35
|
-
it "should render page content" do
|
36
|
-
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/pages/sample_page.yml"), "r")
|
37
|
-
File.should_receive(:new).with("/tmp/milk_site/pages/home.yml", "r").and_return f
|
38
|
-
content = Milksteak::Page.render("home")
|
39
|
-
content.should == "<p>This is some test content. This is just a test.</p>"
|
40
|
-
end
|
41
4
|
|
42
|
-
it "should
|
43
|
-
|
44
|
-
|
45
|
-
|
5
|
+
it "should raise errors if trying to save without a route variable" do
|
6
|
+
File.should_not_receive(:new)
|
7
|
+
lambda {
|
8
|
+
Milksteak::Page.write("test", {}, "content")
|
9
|
+
}.should raise_error Milksteak::NoRouteException
|
46
10
|
end
|
47
11
|
|
48
|
-
it "should
|
12
|
+
it "should save with a route" do
|
49
13
|
f = File.new(File.join(File.dirname(__FILE__), "../fixtures/pages/scratch_page.yml"), "w+")
|
50
14
|
File.should_receive(:new).with("/tmp/milk_site/pages/home.yml", "w+").and_return f
|
51
|
-
page = Milksteak::Page.write("home",
|
52
|
-
|
15
|
+
page = Milksteak::Page.write("home",
|
16
|
+
{ "description" => "TEST PAGE", "route" => "/test-page"},
|
17
|
+
"TEST CONTENT")
|
18
|
+
page.data.should == { "description" => "TEST PAGE", "route" => "/test-page" }
|
53
19
|
page.content.should == "TEST CONTENT"
|
54
20
|
File.unlink(File.join(File.dirname(__FILE__), "../fixtures/pages/scratch_page.yml"))
|
55
21
|
end
|
56
22
|
|
57
|
-
it "should route pages using middleware"
|
58
23
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), "../spec_helper.rb")
|
2
|
+
|
3
|
+
class TestYmlObject < Milksteak::YmlContent
|
4
|
+
def self.folder; "objs"; end
|
5
|
+
end
|
6
|
+
|
7
|
+
describe TestYmlObject do
|
8
|
+
|
9
|
+
it "should make the obj dir if it doesn't exist" do
|
10
|
+
File.stub(:exist?).and_return false
|
11
|
+
FileUtils.should_receive(:mkdir).twice.and_return true
|
12
|
+
TestYmlObject.list.should be_an Array
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should get list of objs from milk_root/objs" do
|
16
|
+
TestYmlObject.list.should be_an Array
|
17
|
+
end
|
18
|
+
|
19
|
+
# this utility method is used by the read and write methods as a consistent
|
20
|
+
# way to access yml obj documents.
|
21
|
+
it "should load a obj into params" do
|
22
|
+
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/objs/sample_obj.yml"), "r")
|
23
|
+
f.stub(:save).and_return true
|
24
|
+
File.should_receive(:new).with("/tmp/milk_site/objs/home.yml", "r").and_return f
|
25
|
+
obj = TestYmlObject.load("home", "r")
|
26
|
+
obj.should be_a TestYmlObject
|
27
|
+
obj.data.should == { "description" => "Test Object" }
|
28
|
+
obj.content.should == "This is a {{description}}\n"
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should write a obj with contents in params" do
|
32
|
+
f = File.new(File.join(File.dirname(__FILE__), "../fixtures/objs/scratch_obj.yml"), "w+")
|
33
|
+
File.should_receive(:new).with("/tmp/milk_site/objs/home.yml", "w+").and_return f
|
34
|
+
obj = TestYmlObject.write("home", { "description" => "TEST PAGE"}, "TEST CONTENT")
|
35
|
+
obj.data.should == { "description" => "TEST PAGE" }
|
36
|
+
obj.content.should == "TEST CONTENT"
|
37
|
+
File.unlink(File.join(File.dirname(__FILE__), "../fixtures/objs/scratch_obj.yml"))
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should render obj content" do
|
41
|
+
f = File.open(File.join(File.dirname(__FILE__), "../fixtures/objs/sample_obj.yml"), "r")
|
42
|
+
File.should_receive(:new).with("/tmp/milk_site/objs/home.yml", "r").and_return f
|
43
|
+
content = TestYmlObject.render("home")
|
44
|
+
content.should == "<p>This is a Test Object</p>"
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should return empty string if trying to render a obj that doesn't exist" do
|
48
|
+
FileUtils.stub(:mkdir).and_return true
|
49
|
+
empty = TestYmlObject.render("home")
|
50
|
+
empty.should == ""
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should accept an empty hash" do
|
54
|
+
f = File.new(File.join(File.dirname(__FILE__), "../fixtures/objs/scratch_obj.yml"), "w+")
|
55
|
+
File.should_receive(:new).with("/tmp/milk_site/objs/home.yml", "w+").and_return f
|
56
|
+
obj = TestYmlObject.write("home", {}, "TEST CONTENT")
|
57
|
+
obj.data.should == {}
|
58
|
+
obj.content.should == "TEST CONTENT"
|
59
|
+
File.unlink(File.join(File.dirname(__FILE__), "../fixtures/objs/scratch_obj.yml"))
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/spec/spec_helper.rb
CHANGED
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.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-05-23 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rspec
|
16
|
-
requirement: &
|
16
|
+
requirement: &22354600 !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: *22354600
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: guard-rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &22305220 !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: *22305220
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: webmock
|
38
|
-
requirement: &
|
38
|
+
requirement: &22304680 !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: *22304680
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rack-test
|
49
|
-
requirement: &
|
49
|
+
requirement: &22304080 !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: *22304080
|
58
58
|
- !ruby/object:Gem::Dependency
|
59
59
|
name: liquid
|
60
|
-
requirement: &
|
60
|
+
requirement: &22303480 !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: *22303480
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: BlueCloth
|
71
|
-
requirement: &
|
71
|
+
requirement: &22302660 !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: *22302660
|
80
80
|
- !ruby/object:Gem::Dependency
|
81
81
|
name: sinatra
|
82
|
-
requirement: &
|
82
|
+
requirement: &22301800 !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: *22301800
|
91
91
|
description: ! 'Super tiny and simple ruby-based cms that uses yml for content '
|
92
92
|
email:
|
93
93
|
- bryan.thompson@firespring.com
|
@@ -105,8 +105,10 @@ files:
|
|
105
105
|
- lib/milksteak.rb
|
106
106
|
- lib/milksteak/cms.rb
|
107
107
|
- lib/milksteak/version.rb
|
108
|
+
- lib/models/fragment.rb
|
108
109
|
- lib/models/page.rb
|
109
110
|
- lib/models/user.rb
|
111
|
+
- lib/models/yml_content.rb
|
110
112
|
- lib/public/milksteak/codemirror2/keymap/emacs.js
|
111
113
|
- lib/public/milksteak/codemirror2/keymap/vim.js
|
112
114
|
- lib/public/milksteak/codemirror2/lib/codemirror.css
|
@@ -435,12 +437,17 @@ files:
|
|
435
437
|
- lib/public/milksteak/wymeditor/skins/twopanels/skin.css
|
436
438
|
- lib/public/milksteak/wymeditor/skins/twopanels/skin.js
|
437
439
|
- lib/public/milksteak/wymeditor/skins/wymeditor_icon.png
|
440
|
+
- lib/views/admin.erb
|
438
441
|
- lib/views/layouts/admin.erb
|
439
442
|
- lib/views/login.erb
|
440
443
|
- milksteak.gemspec
|
444
|
+
- spec/fixtures/fragments/sample_fragment.yml
|
445
|
+
- spec/fixtures/objs/sample_obj.yml
|
441
446
|
- spec/fixtures/pages/sample_page.yml
|
442
447
|
- spec/lib/milksteak/cms_spec.rb
|
448
|
+
- spec/models/fragment_spec.rb
|
443
449
|
- spec/models/page_spec.rb
|
450
|
+
- spec/models/yml_content_spec.rb
|
444
451
|
- spec/spec_helper.rb
|
445
452
|
homepage: ''
|
446
453
|
licenses: []
|
@@ -467,7 +474,11 @@ signing_key:
|
|
467
474
|
specification_version: 3
|
468
475
|
summary: Super tiny and simple ruby-based cms
|
469
476
|
test_files:
|
477
|
+
- spec/fixtures/fragments/sample_fragment.yml
|
478
|
+
- spec/fixtures/objs/sample_obj.yml
|
470
479
|
- spec/fixtures/pages/sample_page.yml
|
471
480
|
- spec/lib/milksteak/cms_spec.rb
|
481
|
+
- spec/models/fragment_spec.rb
|
472
482
|
- spec/models/page_spec.rb
|
483
|
+
- spec/models/yml_content_spec.rb
|
473
484
|
- spec/spec_helper.rb
|