serif 0.4 → 0.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +29 -14
- data/README.md +28 -14
- data/bin/serif +2 -69
- data/lib/serif.rb +1 -0
- data/lib/serif/admin_server.rb +55 -26
- data/lib/serif/commands.rb +150 -0
- data/lib/serif/content_file.rb +4 -0
- data/lib/serif/draft.rb +24 -2
- data/lib/serif/errors.rb +10 -0
- data/lib/serif/post.rb +4 -3
- data/lib/serif/site.rb +73 -4
- data/rakefile +10 -0
- data/serif.gemspec +5 -3
- data/statics/skeleton/_layouts/default.html +1 -1
- data/statics/templates/admin/bookmarks.liquid +17 -13
- data/statics/templates/admin/edit_draft.liquid +1 -1
- data/statics/templates/admin/edit_post.liquid +1 -1
- data/statics/templates/admin/index.liquid +2 -2
- data/statics/templates/admin/layout.liquid +16 -0
- data/test/commands_spec.rb +77 -0
- data/test/content_file_spec.rb +32 -1
- data/test/draft_spec.rb +50 -3
- data/test/post_spec.rb +31 -2
- data/test/site_dir/_layouts/default.html +2 -0
- data/test/site_dir/_site/archive.html +2 -0
- data/test/site_dir/_site/drafts/another-sample-draft/{481da12b79709bfa0547fa9b5754c9506fbed29afd0334e07a8c95e76850.html → add25848a94509103cb492c47e3a04b7b2a56299de207155fbffec42dc4b.html} +5 -2
- data/test/site_dir/_site/drafts/sample-draft/{a986a62ad5f6edd1fcac3d08f5b461b92bcb667a2af69505230c291d405c.html → 0b6fc164b8534d5d5a9fcfc5c709265d33f1577cd0fe2f4e23042e92f0c1.html} +5 -2
- data/test/site_dir/_site/index.html +2 -0
- data/test/site_dir/_site/page-header-but-no-layout.html +2 -0
- data/test/site_dir/_site/test-archive/2012/11.html +2 -0
- data/test/site_dir/_site/test-archive/2012/12.html +2 -0
- data/test/site_dir/_site/test-archive/2013/01.html +2 -0
- data/test/site_dir/_site/test-archive/2013/03.html +2 -0
- data/test/site_dir/_site/test-archive/2399/01.html +2 -0
- data/test/site_dir/_site/test-archive/2400/01.html +2 -0
- data/test/site_dir/_site/test-blog/final-post.html +4 -1
- data/test/site_dir/_site/test-blog/penultimate-post.html +4 -1
- data/test/site_dir/_site/test-blog/post-to-be-published-on-generate.html +4 -1
- data/test/site_dir/_site/test-blog/post-with-custom-layout.html +1 -0
- data/test/site_dir/_site/test-blog/sample-post.html +4 -1
- data/test/site_dir/_site/test-blog/second-post.html +4 -1
- data/test/site_dir/_site/test-smarty-filter.html +2 -0
- data/test/site_dir/_templates/post.html +1 -0
- data/test/site_dir/_trash/1364747613-autopublish-draft +5 -0
- data/test/site_dir/_trash/{1363633154-test-draft → 1364747613-test-draft} +1 -1
- data/test/site_generation_spec.rb +40 -9
- data/test/site_spec.rb +63 -0
- data/test/test_helper.rb +9 -0
- metadata +46 -10
- data/test/site_dir/_trash/1363633154-autopublish-draft +0 -5
data/test/content_file_spec.rb
CHANGED
@@ -5,6 +5,37 @@ describe Serif::ContentFile do
|
|
5
5
|
Serif::Site.new(testing_dir)
|
6
6
|
end
|
7
7
|
|
8
|
+
describe "#basename" do
|
9
|
+
it "is the basename of the path" do
|
10
|
+
(subject.drafts + subject.posts).each do |content_file|
|
11
|
+
content_file.basename.should == File.basename(content_file.path)
|
12
|
+
end
|
13
|
+
|
14
|
+
draft = Serif::Draft.new(subject)
|
15
|
+
draft.slug = "foo"
|
16
|
+
draft.title = "foo"
|
17
|
+
|
18
|
+
# NOTE! Freezing!
|
19
|
+
Timecop.freeze(Time.parse("2013-04-03"))
|
20
|
+
|
21
|
+
draft.save
|
22
|
+
draft.publish!
|
23
|
+
post = Serif::Post.new(subject, draft.path)
|
24
|
+
|
25
|
+
begin
|
26
|
+
draft.path.should_not be_nil
|
27
|
+
post.should_not be_nil
|
28
|
+
draft.basename.should == post.basename
|
29
|
+
|
30
|
+
# NOTE! Time frozen!
|
31
|
+
post.basename.should == "2013-04-03-foo"
|
32
|
+
ensure
|
33
|
+
Timecop.return
|
34
|
+
FileUtils.rm(post.path)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
8
39
|
describe "#title=" do
|
9
40
|
it "sets the underlying header value to the assigned title" do
|
10
41
|
(subject.drafts + subject.posts).each do |content_file|
|
@@ -24,7 +55,7 @@ describe Serif::ContentFile do
|
|
24
55
|
draft.save("# Some content")
|
25
56
|
draft.publish!
|
26
57
|
|
27
|
-
post = Serif::Post.
|
58
|
+
post = Serif::Post.new(subject, draft.path)
|
28
59
|
|
29
60
|
t = Time.now
|
30
61
|
Timecop.freeze(t + 30) do
|
data/test/draft_spec.rb
CHANGED
@@ -7,6 +7,43 @@ describe Serif::Draft do
|
|
7
7
|
FileUtils.rm_rf(testing_dir("_trash"))
|
8
8
|
end
|
9
9
|
|
10
|
+
describe "#url" do
|
11
|
+
it "uses the current time for its placeholder values" do
|
12
|
+
d = D.new(@site)
|
13
|
+
d.slug = "my-blar-blar"
|
14
|
+
orig_headers = d.headers
|
15
|
+
d.stub(:headers) { orig_headers.merge(:permalink => "/foo/:year/:month/:day/:title") }
|
16
|
+
|
17
|
+
Timecop.freeze(Time.parse("2020-02-09")) do
|
18
|
+
d.url.should == "/foo/2020/02/09/my-blar-blar"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
it "can handle nil slug values" do
|
23
|
+
d = D.new(@site)
|
24
|
+
d.slug.should be_nil
|
25
|
+
orig_headers = d.headers
|
26
|
+
d.stub(:headers) { orig_headers.merge(:permalink => "/foo/:year/:month/:day/:title") }
|
27
|
+
|
28
|
+
Timecop.freeze(Time.parse("2020-02-09")) do
|
29
|
+
d.url.should == "/foo/2020/02/09/"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
it "defaults to the config file's permalink value" do
|
34
|
+
d = D.new(@site)
|
35
|
+
d.slug = "gablarhgle"
|
36
|
+
d.url.should == "/test-blog/gablarhgle"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "uses its permalink header value" do
|
40
|
+
d = D.new(@site)
|
41
|
+
d.slug = "anything"
|
42
|
+
d.stub(:headers) { { :permalink => "testage" } }
|
43
|
+
d.url.should == "testage"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
10
47
|
describe ".rename" do
|
11
48
|
it "moves the draft to a new file" do
|
12
49
|
draft = D.new(@site)
|
@@ -86,11 +123,11 @@ describe Serif::Draft do
|
|
86
123
|
published_path = testing_dir("_posts/#{Date.today.to_s}-#{draft.slug}")
|
87
124
|
|
88
125
|
begin
|
89
|
-
@site.generate
|
126
|
+
capture_stdout { @site.generate }
|
90
127
|
@site.posts.first.slug.should_not == draft.slug
|
91
128
|
@site.to_liquid["posts"].first.slug.should_not == draft.slug
|
92
129
|
draft.publish!
|
93
|
-
@site.generate
|
130
|
+
capture_stdout { @site.generate }
|
94
131
|
@site.posts.first.slug.should == draft.slug
|
95
132
|
@site.to_liquid["posts"].first.slug.should == draft.slug
|
96
133
|
rescue
|
@@ -122,7 +159,7 @@ describe Serif::Draft do
|
|
122
159
|
draft.autopublish?.should be_false
|
123
160
|
|
124
161
|
# check the actual file doesn't have the header
|
125
|
-
Serif::Post.
|
162
|
+
Serif::Post.new(@site, draft.path).headers[:publish].should be_nil
|
126
163
|
|
127
164
|
draft.delete!
|
128
165
|
end
|
@@ -186,6 +223,16 @@ describe Serif::Draft do
|
|
186
223
|
end
|
187
224
|
end
|
188
225
|
|
226
|
+
describe "#to_liquid" do
|
227
|
+
it "contains the relevant keys" do
|
228
|
+
liq = @site.drafts.sample.to_liquid
|
229
|
+
|
230
|
+
["title", "content", "slug", "type", "draft", "published", "url"].each do |e|
|
231
|
+
liq.key?(e).should be_true
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
189
236
|
describe "#save" do
|
190
237
|
it "saves the file to _drafts" do
|
191
238
|
draft = D.new(@site)
|
data/test/post_spec.rb
CHANGED
@@ -5,7 +5,7 @@ describe Serif::Post do
|
|
5
5
|
Serif::Site.new(testing_dir)
|
6
6
|
end
|
7
7
|
|
8
|
-
before :
|
8
|
+
before :each do
|
9
9
|
@posts = subject.posts
|
10
10
|
end
|
11
11
|
|
@@ -16,7 +16,7 @@ describe Serif::Post do
|
|
16
16
|
d.title = "Testing title"
|
17
17
|
d.save("# some content")
|
18
18
|
d.publish!
|
19
|
-
@temporary_post = Serif::Post.
|
19
|
+
@temporary_post = Serif::Post.new(subject, d.path)
|
20
20
|
|
21
21
|
example.run
|
22
22
|
ensure
|
@@ -24,6 +24,16 @@ describe Serif::Post do
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
describe "#from_basename" do
|
28
|
+
it "is nil if there is nothing found" do
|
29
|
+
Serif::Post.from_basename(subject, "eoijfwoifjweofej").should be_nil
|
30
|
+
end
|
31
|
+
|
32
|
+
it "takes full filename within _posts" do
|
33
|
+
Serif::Post.from_basename(subject, @temporary_post.basename).path.should == @temporary_post.path
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
27
37
|
it "uses the config file's permalink value" do
|
28
38
|
@posts.all? { |p| p.url == "/test-blog/#{p.slug}" }.should be_true
|
29
39
|
end
|
@@ -107,4 +117,23 @@ describe Serif::Post do
|
|
107
117
|
@temporary_post.autoupdate?.should be_false
|
108
118
|
end
|
109
119
|
end
|
120
|
+
|
121
|
+
describe "#to_liquid" do
|
122
|
+
it "contains the relevant keys" do
|
123
|
+
liq = subject.posts.sample.to_liquid
|
124
|
+
|
125
|
+
["title",
|
126
|
+
"created",
|
127
|
+
"updated",
|
128
|
+
"content",
|
129
|
+
"slug",
|
130
|
+
"url",
|
131
|
+
"type",
|
132
|
+
"draft",
|
133
|
+
"published",
|
134
|
+
"basename"].each do |e|
|
135
|
+
liq.key?(e).should be_true
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
110
139
|
end
|
@@ -1,14 +1,17 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<meta charset="UTF-8">
|
3
|
-
<title>My site:
|
3
|
+
<title>My site: another sample draft</title>
|
4
4
|
<h1>mysite.com</h1>
|
5
5
|
|
6
|
+
|
7
|
+
|
6
8
|
<p>draftpreviewflagexists</p>
|
9
|
+
|
7
10
|
<h2>another sample draft</h2>
|
8
11
|
|
9
12
|
<p>another-sample-draft</p>
|
10
13
|
|
11
14
|
|
12
|
-
<p><a href="http://twitter.com/share?text=another+sample+draft&url=http%3A%2F%2Fwww.mysite.com">Submit this to Twitter.</p>
|
15
|
+
<p><a href="http://twitter.com/share?text=another+sample+draft&url=http%3A%2F%2Fwww.mysite.com%2Ftest-blog%2Fanother-sample-draft">Submit this to Twitter.</p>
|
13
16
|
|
14
17
|
|
@@ -1,14 +1,17 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<meta charset="UTF-8">
|
3
|
-
<title>My site:
|
3
|
+
<title>My site: Sample draft</title>
|
4
4
|
<h1>mysite.com</h1>
|
5
5
|
|
6
|
+
|
7
|
+
|
6
8
|
<p>draftpreviewflagexists</p>
|
9
|
+
|
7
10
|
<h2>Sample draft</h2>
|
8
11
|
|
9
12
|
<p>Just a sample draft.</p>
|
10
13
|
|
11
14
|
|
12
|
-
<p><a href="http://twitter.com/share?text=Sample+draft&url=http%3A%2F%2Fwww.mysite.com">Submit this to Twitter.</p>
|
15
|
+
<p><a href="http://twitter.com/share?text=Sample+draft&url=http%3A%2F%2Fwww.mysite.com%2Ftest-blog%2Fsample-draft">Submit this to Twitter.</p>
|
13
16
|
|
14
17
|
|
@@ -1,9 +1,12 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<meta charset="UTF-8">
|
3
|
-
<title>My site:
|
3
|
+
<title>My site: Final post</title>
|
4
4
|
<h1>mysite.com</h1>
|
5
5
|
|
6
|
+
<p>post_page flag set for layout</p>
|
6
7
|
|
8
|
+
|
9
|
+
<p>post_page flag set for template</p>
|
7
10
|
<h2>Final post</h2>
|
8
11
|
|
9
12
|
<p>The final post in the blog</p>
|
@@ -1,9 +1,12 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<meta charset="UTF-8">
|
3
|
-
<title>My site:
|
3
|
+
<title>My site: Penultimate post</title>
|
4
4
|
<h1>mysite.com</h1>
|
5
5
|
|
6
|
+
<p>post_page flag set for layout</p>
|
6
7
|
|
8
|
+
|
9
|
+
<p>post_page flag set for template</p>
|
7
10
|
<h2>Penultimate post</h2>
|
8
11
|
|
9
12
|
<p>Penultimate post</p>
|
@@ -1,9 +1,12 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<meta charset="UTF-8">
|
3
|
-
<title>My site:
|
3
|
+
<title>My site: Some draft title</title>
|
4
4
|
<h1>mysite.com</h1>
|
5
5
|
|
6
|
+
<p>post_page flag set for layout</p>
|
6
7
|
|
8
|
+
|
9
|
+
<p>post_page flag set for template</p>
|
7
10
|
<h2>Some draft title</h2>
|
8
11
|
|
9
12
|
<p>some content</p>
|
@@ -1,9 +1,12 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<meta charset="UTF-8">
|
3
|
-
<title>My site:
|
3
|
+
<title>My site: Sample post</title>
|
4
4
|
<h1>mysite.com</h1>
|
5
5
|
|
6
|
+
<p>post_page flag set for layout</p>
|
6
7
|
|
8
|
+
|
9
|
+
<p>post_page flag set for template</p>
|
7
10
|
<h2>Sample post</h2>
|
8
11
|
|
9
12
|
<p>Just a sample post.</p>
|
@@ -1,9 +1,12 @@
|
|
1
1
|
<!doctype html>
|
2
2
|
<meta charset="UTF-8">
|
3
|
-
<title>My site:
|
3
|
+
<title>My site: Second post</title>
|
4
4
|
<h1>mysite.com</h1>
|
5
5
|
|
6
|
+
<p>post_page flag set for layout</p>
|
6
7
|
|
8
|
+
|
9
|
+
<p>post_page flag set for template</p>
|
7
10
|
<h2>Second post</h2>
|
8
11
|
|
9
12
|
<p>Second post.</p>
|
@@ -10,6 +10,12 @@ describe Serif::Site do
|
|
10
10
|
end
|
11
11
|
|
12
12
|
describe "site generation" do
|
13
|
+
it "raises PostConflictError if there are conflicts" do
|
14
|
+
# not nil, the value is unimportant
|
15
|
+
subject.stub(:conflicts) { [] }
|
16
|
+
expect { capture_stdout { subject.generate } }.to raise_error(Serif::PostConflictError)
|
17
|
+
end
|
18
|
+
|
13
19
|
it "uses the permalinks in the config file for site generation" do
|
14
20
|
capture_stdout { subject.generate }
|
15
21
|
File.exist?(testing_dir("_site/test-blog/sample-post.html")).should be_true
|
@@ -69,12 +75,35 @@ describe Serif::Site do
|
|
69
75
|
|
70
76
|
d = Serif::Draft.from_slug(subject, "sample-draft")
|
71
77
|
preview_contents = File.read(testing_dir("_site/#{subject.private_url(d)}.html"))
|
72
|
-
preview_contents =~ preview_flag_pattern
|
78
|
+
(preview_contents =~ preview_flag_pattern).should be_true
|
73
79
|
|
74
80
|
# does not exist on live published pages
|
75
81
|
(File.read(testing_dir("_site/test-blog/second-post.html")) =~ preview_flag_pattern).should be_false
|
76
82
|
end
|
77
83
|
|
84
|
+
it "sets a post_page flag for regular posts" do
|
85
|
+
capture_stdout { subject.generate }
|
86
|
+
d = Serif::Post.from_basename(subject, "2013-01-01-second-post")
|
87
|
+
d.should_not be_nil
|
88
|
+
contents = File.read(testing_dir("_site#{d.url}.html"))
|
89
|
+
|
90
|
+
# available to the post layout file
|
91
|
+
(contents =~ /post_page flag set for template/).should be_true
|
92
|
+
|
93
|
+
# available in the layout file itself
|
94
|
+
(contents =~ /post_page flag set for layout/).should be_true
|
95
|
+
|
96
|
+
# not set for regular pages
|
97
|
+
(File.read(testing_dir("_site/index.html")) =~ /post_page flag set for template/).should be_false
|
98
|
+
(File.read(testing_dir("_site/index.html")) =~ /post_page flag set for layout/).should be_false
|
99
|
+
|
100
|
+
# not set for drafts
|
101
|
+
d = Serif::Draft.from_slug(subject, "sample-draft")
|
102
|
+
preview_contents = File.read(testing_dir("_site/#{subject.private_url(d)}.html"))
|
103
|
+
(preview_contents =~ /post_page flag set for template/).should be_false
|
104
|
+
(preview_contents =~ /post_page flag set for layout/).should be_false
|
105
|
+
end
|
106
|
+
|
78
107
|
it "creates draft preview files" do
|
79
108
|
capture_stdout { subject.generate }
|
80
109
|
|
@@ -107,7 +136,7 @@ describe Serif::Site do
|
|
107
136
|
d.save("# some content")
|
108
137
|
d.publish!
|
109
138
|
|
110
|
-
@temporary_post = Serif::Post.
|
139
|
+
@temporary_post = Serif::Post.new(subject, d.path)
|
111
140
|
@temporary_post.autoupdate = true
|
112
141
|
@temporary_post.save
|
113
142
|
|
@@ -121,13 +150,13 @@ describe Serif::Site do
|
|
121
150
|
t = Time.now + 30
|
122
151
|
Timecop.freeze(t) do
|
123
152
|
capture_stdout { subject.generate }
|
124
|
-
Serif::Post.
|
153
|
+
Serif::Post.from_basename(subject, @temporary_post.basename).updated.to_i.should == t.to_i
|
125
154
|
end
|
126
155
|
end
|
127
156
|
end
|
128
157
|
|
129
158
|
context "for drafts with a publish: now header" do
|
130
|
-
before :
|
159
|
+
before :each do
|
131
160
|
@time = Time.utc(2012, 12, 21, 15, 30, 00)
|
132
161
|
|
133
162
|
draft = Serif::Draft.new(subject)
|
@@ -151,12 +180,14 @@ describe Serif::Site do
|
|
151
180
|
Timecop.freeze(@time)
|
152
181
|
end
|
153
182
|
|
154
|
-
after :
|
183
|
+
after :each do
|
155
184
|
Timecop.return
|
156
185
|
|
157
|
-
# the generate processes creates its own set of instances,
|
158
|
-
#
|
159
|
-
|
186
|
+
# the generate processes creates its own set of instances, and we're
|
187
|
+
# publishing a draft marked as autopublish, so our @post instance
|
188
|
+
# has a #path value which is for the draft, not for the newly published
|
189
|
+
# post. thus, we need to clobber.
|
190
|
+
FileUtils.rm(*Dir[testing_dir("_posts/*-#{@post.slug}")])
|
160
191
|
end
|
161
192
|
|
162
193
|
it "places the file in the published posts folder" do
|
@@ -166,7 +197,7 @@ describe Serif::Site do
|
|
166
197
|
|
167
198
|
it "marks the creation time as the current time" do
|
168
199
|
capture_stdout { subject.generate }
|
169
|
-
|
200
|
+
subject.posts.find { |p| p.slug == @post.slug }.created.to_i.should == @time.to_i
|
170
201
|
end
|
171
202
|
end
|
172
203
|
end
|