serif 0.1.6 → 0.2

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/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