serif 0.1.6 → 0.2

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- serif (0.1.5)
4
+ serif (0.1.6)
5
5
  liquid (~> 2.4)
6
6
  pygments.rb (~> 0.3)
7
7
  rack (~> 1.0)
@@ -18,7 +18,7 @@ GEM
18
18
  liquid (2.4.1)
19
19
  multi_json (1.5.0)
20
20
  posix-spawn (0.3.6)
21
- pygments.rb (0.3.2)
21
+ pygments.rb (0.3.3)
22
22
  posix-spawn (~> 0.3.6)
23
23
  yajl-ruby (~> 1.1.0)
24
24
  rack (1.4.1)
@@ -46,6 +46,7 @@ GEM
46
46
  tilt (~> 1.3, >= 1.3.3)
47
47
  slop (3.3.3)
48
48
  tilt (1.3.3)
49
+ timecop (0.5.5)
49
50
  yajl-ruby (1.1.0)
50
51
 
51
52
  PLATFORMS
@@ -56,3 +57,4 @@ DEPENDENCIES
56
57
  rspec (~> 2.5)
57
58
  serif!
58
59
  simplecov (~> 0.7)
60
+ timecop (~> 0.5.5)
data/README.md CHANGED
@@ -218,6 +218,19 @@ In both cases, the output is, of course:
218
218
 
219
219
  If you have a file like `feed.xml` that you wish to _not_ be contained within a layout, specify `layout: none` in the header for the file.
220
220
 
221
+ # Publishing drafts
222
+
223
+ To publish a draft, either do so through the admin interface available with `serif admin`, or add a `publish: now` header to the draft:
224
+
225
+ ```
226
+ title: A draft that will be published
227
+ publish: now
228
+
229
+ This is a draft that will be published now.
230
+ ```
231
+
232
+ On the next site generation (`serif generate`) this draft will be automatically published, using the current time as the creation timestamp.
233
+
221
234
  # Archive pages
222
235
 
223
236
  By default, archive pages are made available at `/archive/:year/month`, e.g., `/archive/2012/11`. Individual archive pages can be customised by editing the `_templates/archive_page.html` file, which is used for each month.
data/lib/serif/draft.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  module Serif
2
2
  class Draft < ContentFile
3
+ attr_reader :autopublish
4
+
3
5
  def self.dirname
4
6
  "_drafts"
5
7
  end
@@ -18,9 +20,37 @@ class Draft < ContentFile
18
20
  raise "conflict, post exists already" if File.exist?(full_published_path)
19
21
 
20
22
  set_publish_time(publish_time)
23
+
24
+ @source.headers.delete(:publish) if autopublish?
25
+
21
26
  save
22
27
 
23
28
  File.rename(path, full_published_path)
29
+
30
+ # update the path since the file has now changed
31
+ @path = Post.from_slug(site, slug).path
32
+ end
33
+
34
+ # sets the autopublish flag to the given value.
35
+ #
36
+ # if the assigned value is truthy, the "publish" header
37
+ # is set to "now", otherwise the header is removed.
38
+ def autopublish=(value)
39
+ @autopublish = value
40
+
41
+ if value
42
+ @source.headers[:publish] = "now"
43
+ else
44
+ @source.headers.delete(:publish)
45
+ end
46
+ end
47
+
48
+ # Checks the value of the "publish" header, and returns
49
+ # true if the value is "now", ignoring trailing and leading
50
+ # whitespace. Returns false, otherwise.
51
+ def autopublish?
52
+ publish_header = headers[:publish]
53
+ publish_header && publish_header.strip == "now"
24
54
  end
25
55
 
26
56
  def to_liquid
data/lib/serif/site.rb CHANGED
@@ -182,6 +182,11 @@ class Site
182
182
  files = Dir["**/*"].select { |f| f !~ /\A_/ && File.file?(f) }
183
183
 
184
184
  default_layout = Liquid::Template.parse(File.read("_layouts/default.html"))
185
+
186
+ # preprocess any drafts marked for autopublish, before grabbing the posts
187
+ # to operate on.
188
+ preprocess_autopublish_drafts
189
+
185
190
  posts = self.posts
186
191
 
187
192
  files.each do |path|
@@ -242,6 +247,18 @@ class Site
242
247
 
243
248
  private
244
249
 
250
+ # goes through all draft posts that have "publish: now" headers and
251
+ # calls #publish! on each one
252
+ def preprocess_autopublish_drafts
253
+ puts "Beginning pre-process step for drafts."
254
+ drafts.each do |d|
255
+ if d.autopublish?
256
+ puts "Autopublishing draft: #{d.title} / #{d.slug}"
257
+ d.publish!
258
+ end
259
+ end
260
+ end
261
+
245
262
  # Uses config.archive_url_format to generate pages
246
263
  # using the archive_page.html template.
247
264
  def generate_archives(layout)
data/serif.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "serif"
3
- s.version = "0.1.6"
3
+ s.version = "0.2"
4
4
  s.authors = ["Adam Prescott"]
5
5
  s.email = ["adam@aprescott.com"]
6
6
  s.homepage = "https://github.com/aprescott/serif"
@@ -28,4 +28,5 @@ Gem::Specification.new do |s|
28
28
  s.add_development_dependency("rake", "~> 0.9")
29
29
  s.add_development_dependency("rspec", "~> 2.5")
30
30
  s.add_development_dependency("simplecov", "~> 0.7")
31
+ s.add_development_dependency("timecop", "~> 0.5.5")
31
32
  end
data/test/draft_spec.rb CHANGED
@@ -44,6 +44,78 @@ describe Serif::Draft do
44
44
  # clean up
45
45
  FileUtils.rm_f(published_path)
46
46
  end
47
+
48
+ it "changes the #path to be _posts not _drafts" do
49
+ draft = D.new(@site)
50
+ draft.slug = "test-draft"
51
+ draft.title = "Some draft title"
52
+ draft.save("some content")
53
+ draft.publish!
54
+
55
+ draft.path.should == testing_dir("_posts/#{Date.today.to_s}-#{draft.slug}")
56
+ draft.delete! # still deleteable, even though it's been moved
57
+ end
58
+
59
+ it "does not write out an autopublish header if autopublish? is true" do
60
+ draft = D.new(@site)
61
+ draft.slug = "autopublish-draft"
62
+ draft.title = "Some draft title"
63
+ draft.autopublish = true
64
+ draft.save("some content")
65
+ draft.publish!
66
+
67
+ # check the header on the object has been removed
68
+ draft.autopublish?.should be_false
69
+
70
+ # check the actual file doesn't have the header
71
+ Serif::Post.from_slug(@site, draft.slug).headers[:publish].should be_nil
72
+
73
+ draft.delete!
74
+ end
75
+ end
76
+
77
+ describe "#autopublish=" do
78
+ it "sets the 'publish' header to 'now' if truthy assigned value" do
79
+ draft = D.new(@site)
80
+ draft.slug = "test-draft"
81
+ draft.title = "Some draft title"
82
+ draft.save("some content")
83
+ draft.autopublish = true
84
+
85
+ draft.headers[:publish].should == "now"
86
+
87
+ draft.delete!
88
+ end
89
+
90
+ it "removes the 'publish' header entirely if falsey assigned value" do
91
+ draft = D.new(@site)
92
+ draft.slug = "test-draft"
93
+ draft.title = "Some draft title"
94
+ draft.save("some content")
95
+ draft.autopublish = false
96
+
97
+ draft.headers.key?(:publish).should be_false
98
+
99
+ draft.delete!
100
+ end
101
+ end
102
+
103
+ describe "#autopublish?" do
104
+ it "returns true if there is a 'publish: now' header, otherwise false" do
105
+ draft = D.new(@site)
106
+ draft.autopublish?.should be_false
107
+ headers = draft.headers
108
+ draft.stub(:headers) { headers.merge(:publish => "now") }
109
+ draft.autopublish?.should be_true
110
+ end
111
+
112
+ it "ignores leading and trailing whitespace around the value of the 'publish' header" do
113
+ draft = D.new(@site)
114
+ draft.autopublish?.should be_false
115
+ headers = draft.headers
116
+ draft.stub(:headers) { headers.merge(:publish => " now ") }
117
+ draft.autopublish?.should be_true
118
+ end
47
119
  end
48
120
 
49
121
  describe "#save" do
@@ -5,6 +5,10 @@
5
5
 
6
6
 
7
7
 
8
+ <h1>
9
+ <a href="/test-archive/2012/12">December 2012</a>
10
+ </h1>
11
+
8
12
  <h1>
9
13
  <a href="/test-archive/2012/11">November 2012</a>
10
14
  </h1>
@@ -5,10 +5,12 @@
5
5
 
6
6
  <h2>Posts</h2>
7
7
 
8
- <p>There are 1 posts:</p>
8
+ <p>There are 2 posts:</p>
9
9
 
10
10
  <ul>
11
11
 
12
+ <li><a href="/test-blog/post-to-be-published-on-generate">Some draft title</a> (posted 2012-12-21T15:30:00+00:00)</li>
13
+
12
14
  <li><a href="/test-blog/sample-post">Sample post</a> (posted 2012-11-21T17:07:09+00:00)</li>
13
15
 
14
16
  </ul>
@@ -0,0 +1,14 @@
1
+ <!doctype html>
2
+ <meta charset="UTF-8">
3
+ <title>My site: </title>
4
+ <h1>mysite.com</h1>
5
+
6
+ <h1>Dec 2012 (1)</h1>
7
+
8
+ <ul>
9
+
10
+ <li>
11
+ <a href="/test-blog/post-to-be-published-on-generate">Some draft title</a>
12
+ </li>
13
+
14
+ </ul>
@@ -0,0 +1,10 @@
1
+ <!doctype html>
2
+ <meta charset="UTF-8">
3
+ <title>My site: Posts - Some draft title</title>
4
+ <h1>mysite.com</h1>
5
+
6
+ <h2>Some draft title</h2>
7
+
8
+ <p>some content</p>
9
+
10
+ <p><a href="http://twitter.com/share?text=Some+draft+title&amp;url=http%3A%2F%2Fwww.mysite.com%2Ftest-blog%2Fpost-to-be-published-on-generate">Submit this to Twitter.</p>
@@ -0,0 +1,4 @@
1
+ title: Some draft title
2
+ Created: 2013-01-02T14:34:37+00:00
3
+
4
+ some content
@@ -9,16 +9,62 @@ describe Serif::Site do
9
9
  FileUtils.rm_rf(testing_dir("_site"))
10
10
  end
11
11
 
12
- it "uses the permalinks in the config file for site generation" do
13
- subject.generate
14
- File.exist?(testing_dir("_site/test-blog/sample-post.html")).should be_true
15
- end
12
+ describe "site generation" do
13
+ it "uses the permalinks in the config file for site generation" do
14
+ subject.generate
15
+ File.exist?(testing_dir("_site/test-blog/sample-post.html")).should be_true
16
+ end
17
+
18
+ it "reads the layout header for a non-post file and uses the appropriate layout file" do
19
+ subject.generate
20
+
21
+ # check it actually got generated
22
+ File.exist?(testing_dir("_site/page-alt-layout.html")).should be_true
23
+ File.read("_site/page-alt-layout.html").lines.first.should =~ /<h1.+?>Alternate layout<\/h1>/
24
+ end
25
+
26
+ context "for drafts with a publish: now header" do
27
+ before :all do
28
+ @time = Time.utc(2012, 12, 21, 15, 30, 00)
29
+
30
+ draft = D.new(subject)
31
+ draft.slug = "post-to-be-published-on-generate"
32
+ draft.title = "Some draft title"
33
+ draft.autopublish = true
34
+ draft.save("some content")
35
+
36
+ @post = Serif::Draft.from_slug(subject, draft.slug)
37
+ @post.should_not be_nil
38
+
39
+ # verifies that the header has actually been written to the file, since
40
+ # we round-trip the save and load.
41
+ @post.autopublish?.should be_true
42
+
43
+ # Site#generate creates a backup of the site directory in /tmp
44
+ # and uses a timestamp, which is now fixed across all tests,
45
+ # so we have to remove it first.
46
+ FileUtils.rm_rf("/tmp/_site.2012-12-21-15-30-00")
47
+
48
+ Timecop.freeze(@time)
49
+ end
50
+
51
+ after :all do
52
+ Timecop.return
53
+
54
+ # the generate processes creates its own set of instances, so the
55
+ # value of #path here would be stale if we were to call @post.path
56
+ FileUtils.rm(Serif::Post.from_slug(subject, @post.slug).path)
57
+ end
16
58
 
17
- it "reads the layout header for a non-post file and uses the appropriate layout file" do
18
- subject.generate
59
+ it "places the file in the published posts folder" do
60
+ subject.generate
61
+ File.exist?(testing_dir("_site/test-blog/#{@post.slug}.html")).should be_true
62
+ end
19
63
 
20
- # check it actually got generated
21
- File.exist?(testing_dir("_site/page-alt-layout.html")).should be_true
22
- File.read("_site/page-alt-layout.html").lines.first.should =~ /<h1.+?>Alternate layout<\/h1>/
64
+ it "marks the creation time as the current time" do
65
+ subject.generate
66
+ Serif::Post.from_slug(subject, @post.slug).created.should == @time
67
+ end
68
+ end
23
69
  end
24
70
  end
data/test/test_helper.rb CHANGED
@@ -8,6 +8,7 @@ require "fileutils"
8
8
  require "pathname"
9
9
  require "time"
10
10
  require "date"
11
+ require "timecop"
11
12
 
12
13
  def testing_dir(path = nil)
13
14
  full_path = File.join(File.dirname(__FILE__), "site_dir")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serif
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: '0.2'
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-12-17 00:00:00.000000000 Z
12
+ date: 2013-01-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -187,6 +187,22 @@ dependencies:
187
187
  - - ~>
188
188
  - !ruby/object:Gem::Version
189
189
  version: '0.7'
190
+ - !ruby/object:Gem::Dependency
191
+ name: timecop
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ~>
196
+ - !ruby/object:Gem::Version
197
+ version: 0.5.5
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ~>
204
+ - !ruby/object:Gem::Version
205
+ version: 0.5.5
190
206
  description: Serif is a simple file-based blogging system which generates static content
191
207
  and allows dynamic editing through an interface.
192
208
  email:
@@ -196,59 +212,62 @@ executables:
196
212
  extensions: []
197
213
  extra_rdoc_files: []
198
214
  files:
199
- - lib/serif/content_file.rb
200
- - lib/serif/server.rb
201
- - lib/serif/markup_renderer.rb
215
+ - lib/serif.rb
202
216
  - lib/serif/post.rb
203
- - lib/serif/config.rb
204
217
  - lib/serif/admin_server.rb
218
+ - lib/serif/server.rb
219
+ - lib/serif/config.rb
205
220
  - lib/serif/draft.rb
221
+ - lib/serif/markup_renderer.rb
206
222
  - lib/serif/site.rb
207
- - lib/serif.rb
208
- - statics/templates/admin/new_draft.liquid
209
- - statics/templates/admin/edit_draft.liquid
210
- - statics/templates/admin/layout.liquid
211
- - statics/templates/admin/index.liquid
212
- - statics/templates/admin/edit_post.liquid
223
+ - lib/serif/content_file.rb
213
224
  - statics/skeleton/index.html
214
- - statics/skeleton/_templates/archive_page.html
215
225
  - statics/skeleton/_templates/post.html
216
- - statics/skeleton/_drafts/sample-draft
226
+ - statics/skeleton/_templates/archive_page.html
217
227
  - statics/skeleton/_config.yml
218
- - statics/skeleton/_posts/2012-01-05-sample-post
219
228
  - statics/skeleton/_layouts/default.html
229
+ - statics/skeleton/_posts/2012-01-05-sample-post
230
+ - statics/skeleton/_drafts/sample-draft
220
231
  - statics/skeleton/archive.html
232
+ - statics/templates/admin/new_draft.liquid
233
+ - statics/templates/admin/edit_draft.liquid
234
+ - statics/templates/admin/layout.liquid
235
+ - statics/templates/admin/edit_post.liquid
236
+ - statics/templates/admin/index.liquid
221
237
  - statics/assets/js/mousetrap.min.js
222
238
  - statics/assets/js/jquery.autosize.js
223
239
  - bin/serif
224
240
  - test/test_helper.rb
225
- - test/filters_spec.rb
226
- - test/config_spec.rb
227
- - test/liquid_filter_date_extension_spec.rb
241
+ - test/post_spec.rb
228
242
  - test/site_spec.rb
229
243
  - test/draft_spec.rb
230
- - test/markup_renderer_spec.rb
244
+ - test/config_spec.rb
231
245
  - test/site_dir/index.html
232
- - test/site_dir/_templates/archive_page.html
233
246
  - test/site_dir/_templates/post.html
247
+ - test/site_dir/_templates/archive_page.html
248
+ - test/site_dir/_config.yml
249
+ - test/site_dir/_layouts/default.html
250
+ - test/site_dir/_layouts/alt-layout.html
251
+ - test/site_dir/_posts/2012-01-05-sample-post
252
+ - test/site_dir/page-alt-layout.html
234
253
  - test/site_dir/_drafts/another-sample-draft
235
254
  - test/site_dir/_drafts/sample-draft
236
- - test/site_dir/page-alt-layout.html
237
- - test/site_dir/page-header-but-no-layout.html
238
- - test/site_dir/_config.yml
239
- - test/site_dir/_site/test-archive/2012/11/index.html
255
+ - test/site_dir/_site/test-blog/sample-post.html
256
+ - test/site_dir/_site/test-blog/post-to-be-published-on-generate.html
240
257
  - test/site_dir/_site/index.html
241
258
  - test/site_dir/_site/page-alt-layout.html
259
+ - test/site_dir/_site/test-archive/2012/11/index.html
260
+ - test/site_dir/_site/test-archive/2012/12/index.html
242
261
  - test/site_dir/_site/page-header-but-no-layout.html
243
- - test/site_dir/_site/test-blog/sample-post.html
244
262
  - test/site_dir/_site/archive.html
245
- - test/site_dir/_trash/1355714650-test-draft
246
- - test/site_dir/_posts/2012-01-05-sample-post
247
- - test/site_dir/_layouts/alt-layout.html
248
- - test/site_dir/_layouts/default.html
263
+ - test/site_dir/_trash/1357137277-autopublish-draft
264
+ - test/site_dir/_trash/1357137277-test-draft
265
+ - test/site_dir/page-header-but-no-layout.html
249
266
  - test/site_dir/archive.html
267
+ - test/markup_renderer_spec.rb
268
+ - test/liquid_filter_date_extension_spec.rb
250
269
  - test/site_generation_spec.rb
251
- - test/post_spec.rb
270
+ - test/filters_spec.rb
252
271
  - serif.gemspec
253
272
  - rakefile
254
273
  - LICENSE
@@ -281,11 +300,11 @@ specification_version: 3
281
300
  summary: Simple file-based blogging system.
282
301
  test_files:
283
302
  - test/test_helper.rb
284
- - test/filters_spec.rb
285
- - test/config_spec.rb
286
- - test/liquid_filter_date_extension_spec.rb
303
+ - test/post_spec.rb
287
304
  - test/site_spec.rb
288
305
  - test/draft_spec.rb
306
+ - test/config_spec.rb
289
307
  - test/markup_renderer_spec.rb
308
+ - test/liquid_filter_date_extension_spec.rb
290
309
  - test/site_generation_spec.rb
291
- - test/post_spec.rb
310
+ - test/filters_spec.rb