serif 0.3.3 → 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/Gemfile.lock +12 -9
- data/README.md +57 -32
- data/bin/serif +12 -27
- data/lib/serif/admin_server.rb +48 -0
- data/lib/serif/content_file.rb +23 -29
- data/lib/serif/draft.rb +2 -4
- data/lib/serif/post.rb +30 -0
- data/lib/serif/site.rb +34 -26
- data/serif.gemspec +4 -3
- data/statics/skeleton/_config.yml +2 -46
- data/statics/templates/admin/bookmarks.liquid +56 -0
- data/statics/templates/admin/layout.liquid +4 -2
- data/test/config_spec.rb +7 -0
- data/test/draft_spec.rb +14 -0
- data/test/filters_spec.rb +5 -1
- data/test/markup_renderer_spec.rb +4 -0
- data/test/post_spec.rb +89 -0
- data/test/site_dir/_site/drafts/another-sample-draft/{9094f3a34ce2ecfe188ad813e0d3229d2488350fb0c5bca4f8b4bcfe7b11.html → 481da12b79709bfa0547fa9b5754c9506fbed29afd0334e07a8c95e76850.html} +1 -0
- data/test/site_dir/_site/drafts/sample-draft/{359dca7a7237a1317c5e8ac2d3a01cd29db433f4caeb0b2209484ca09a7a.html → a986a62ad5f6edd1fcac3d08f5b461b92bcb667a2af69505230c291d405c.html} +1 -0
- data/test/site_dir/_site/test-archive/2012/{11/index.html → 11.html} +0 -0
- data/test/site_dir/_site/test-archive/2012/{12/index.html → 12.html} +0 -0
- data/test/site_dir/_site/test-archive/2013/{01/index.html → 01.html} +0 -0
- data/test/site_dir/_site/test-archive/2013/{03/index.html → 03.html} +0 -0
- data/test/site_dir/_site/test-archive/2399/{01/index.html → 01.html} +0 -0
- data/test/site_dir/_site/test-archive/2400/{01/index.html → 01.html} +0 -0
- data/test/site_dir/_site/test-blog/final-post.html +1 -0
- data/test/site_dir/_site/test-blog/penultimate-post.html +1 -0
- data/test/site_dir/_site/test-blog/post-to-be-published-on-generate.html +1 -0
- data/test/site_dir/_site/test-blog/post-with-custom-layout.html +1 -0
- data/test/site_dir/_site/test-blog/sample-post.html +1 -0
- data/test/site_dir/_site/test-blog/second-post.html +1 -0
- data/test/site_dir/_trash/1363633154-autopublish-draft +5 -0
- data/test/site_dir/_trash/{1363284991-test-draft → 1363633154-test-draft} +1 -1
- data/test/site_generation_spec.rb +39 -11
- data/test/site_spec.rb +28 -0
- data/test/test_helper.rb +33 -1
- metadata +34 -17
- data/test/site_dir/_trash/1363284991-autopublish-draft +0 -5
data/Gemfile.lock
CHANGED
|
@@ -3,12 +3,13 @@ PATH
|
|
|
3
3
|
specs:
|
|
4
4
|
serif (0.3.3)
|
|
5
5
|
liquid (~> 2.4)
|
|
6
|
+
nokogiri (~> 1.5)
|
|
6
7
|
rack (~> 1.0)
|
|
7
8
|
redcarpet (~> 2.2)
|
|
8
9
|
redhead (~> 0.0.8)
|
|
10
|
+
reverse_markdown (~> 0.4.3)
|
|
9
11
|
rouge (~> 0.3.2)
|
|
10
12
|
sinatra (~> 1.3)
|
|
11
|
-
slop (~> 3.3)
|
|
12
13
|
timeout_cache
|
|
13
14
|
|
|
14
15
|
GEM
|
|
@@ -17,12 +18,15 @@ GEM
|
|
|
17
18
|
diff-lcs (1.1.3)
|
|
18
19
|
liquid (2.5.0)
|
|
19
20
|
multi_json (1.6.1)
|
|
21
|
+
nokogiri (1.5.6)
|
|
20
22
|
rack (1.5.2)
|
|
21
23
|
rack-protection (1.5.0)
|
|
22
24
|
rack
|
|
23
25
|
rake (0.9.6)
|
|
24
26
|
redcarpet (2.2.2)
|
|
25
27
|
redhead (0.0.8)
|
|
28
|
+
reverse_markdown (0.4.4)
|
|
29
|
+
nokogiri
|
|
26
30
|
rouge (0.3.2)
|
|
27
31
|
thor
|
|
28
32
|
rspec (2.12.0)
|
|
@@ -37,14 +41,13 @@ GEM
|
|
|
37
41
|
multi_json (~> 1.0)
|
|
38
42
|
simplecov-html (~> 0.7.1)
|
|
39
43
|
simplecov-html (0.7.1)
|
|
40
|
-
sinatra (1.
|
|
41
|
-
rack (~> 1.
|
|
42
|
-
rack-protection (~> 1.
|
|
43
|
-
tilt (~> 1.3, >= 1.3.
|
|
44
|
-
slop (3.4.4)
|
|
44
|
+
sinatra (1.4.1)
|
|
45
|
+
rack (~> 1.5, >= 1.5.2)
|
|
46
|
+
rack-protection (~> 1.4)
|
|
47
|
+
tilt (~> 1.3, >= 1.3.4)
|
|
45
48
|
thor (0.17.0)
|
|
46
|
-
tilt (1.3.
|
|
47
|
-
timecop (0.
|
|
49
|
+
tilt (1.3.6)
|
|
50
|
+
timecop (0.6.1)
|
|
48
51
|
timeout_cache (0.0.2)
|
|
49
52
|
|
|
50
53
|
PLATFORMS
|
|
@@ -55,4 +58,4 @@ DEPENDENCIES
|
|
|
55
58
|
rspec (~> 2.5)
|
|
56
59
|
serif!
|
|
57
60
|
simplecov (~> 0.7)
|
|
58
|
-
timecop (~> 0.
|
|
61
|
+
timecop (~> 0.6.1)
|
data/README.md
CHANGED
|
@@ -6,24 +6,22 @@ Serif is a file-based blogging engine intended for simple sites. It compiles Mar
|
|
|
6
6
|
|
|
7
7
|
Having problems with Serif? [Open an issue on GitHub](https://github.com/aprescott/serif/issues), or use the [Serif Google Group](https://groups.google.com/forum/#!forum/serif-rb)
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
## First time use
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
To get started with Serif based on a site skeleton:
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
```bash
|
|
14
|
+
gem install serif # install serif
|
|
15
|
+
cd path/to/some/place # go to where you'll be creating your site directory
|
|
16
|
+
serif new # create an initial site skeleton
|
|
16
17
|
|
|
17
|
-
|
|
18
|
+
# ... edit your files how you want them ...
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
* Support custom layouts for posts as well as non-post files. (#35)
|
|
23
|
-
* Drag-and-drop image uploads no longer use exclusively `rw-------` permissions, now rely on umask. (605487d98)
|
|
24
|
-
* (v0.3.2) Fix caching problems caused by #30, allowing the most recently published to appear in files that use `site.posts`. (#36)
|
|
20
|
+
serif generate # generate the site based on the source files
|
|
21
|
+
serif dev # serve up the site for local testing purposes
|
|
22
|
+
```
|
|
25
23
|
|
|
26
|
-
|
|
24
|
+
Now visit <http://localhost:8000/> to view the site.
|
|
27
25
|
|
|
28
26
|
# Contents of this README
|
|
29
27
|
|
|
@@ -32,13 +30,15 @@ See `CHANGELOG` for more.
|
|
|
32
30
|
* [Basic usage](#basics)
|
|
33
31
|
* [Content and site structure](#content-and-site-structure)
|
|
34
32
|
* [Publishing drafts](#publishing-drafts)
|
|
33
|
+
* [Updating posts](#updating-posts)
|
|
35
34
|
* [Archive pages](#archive-pages)
|
|
36
35
|
* [Configuration](#configuration)
|
|
37
36
|
* [Deploying](#deploying)
|
|
38
37
|
* [Customising the admin interface](#customising-the-admin-interface)
|
|
39
|
-
* [Custom tags](#custom-tags)
|
|
38
|
+
* [Custom tags and filters](#custom-tags-and-filters)
|
|
40
39
|
* [Template variables](#template-variables)
|
|
41
40
|
* [Developing Serif](#developing-serif)
|
|
41
|
+
* [Changes and what's new](#changes-and-whats-new)
|
|
42
42
|
* [Planned features](#planned-features)
|
|
43
43
|
|
|
44
44
|
# Intro
|
|
@@ -67,23 +67,6 @@ For more info on development, see the section at the bottom of this README.
|
|
|
67
67
|
|
|
68
68
|
# Basics
|
|
69
69
|
|
|
70
|
-
## First time use
|
|
71
|
-
|
|
72
|
-
To get started with Serif based on a site skeleton:
|
|
73
|
-
|
|
74
|
-
```bash
|
|
75
|
-
gem install serif # install serif
|
|
76
|
-
cd path/to/some/place # go to where you'll be creating your site directory
|
|
77
|
-
serif new # create an initial site skeleton
|
|
78
|
-
|
|
79
|
-
# ... edit your files how you want them ...
|
|
80
|
-
|
|
81
|
-
serif generate # generate the site based on the source files
|
|
82
|
-
serif dev # serve up the site for local testing purposes
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
Now visit <http://localhost:8000/> to view the site.
|
|
86
|
-
|
|
87
70
|
## Installing
|
|
88
71
|
|
|
89
72
|
Installation is via [RubyGems](https://rubygems.org/). If you don't have Ruby installed, I recommend using [RVM](https://rvm.io/).
|
|
@@ -298,6 +281,26 @@ This is a draft that will be published now.
|
|
|
298
281
|
|
|
299
282
|
On the next site generation (`serif generate`) this draft will be automatically published, using the current time as the creation timestamp.
|
|
300
283
|
|
|
284
|
+
# Updating posts
|
|
285
|
+
|
|
286
|
+
When you update a draft, you need to remember to change the updated time. As luck would have it, Serif takes care of timestamps for you! Just use a header of `update: now` at the top of your post:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
title: My blog post
|
|
290
|
+
Created: 2013-01-01T12:01:30+00:00
|
|
291
|
+
update: now
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
Now the next time the site is generated, the timestamp will be updated:
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
title: My blog post
|
|
298
|
+
Created: 2013-01-01T12:01:30+00:00
|
|
299
|
+
Updated: 2013-03-18T19:03:30+00:00
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Admin users: this is all done for you.
|
|
303
|
+
|
|
301
304
|
# Archive pages
|
|
302
305
|
|
|
303
306
|
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.
|
|
@@ -491,6 +494,16 @@ Variable | Value
|
|
|
491
494
|
`prev_post` | The post published chronologically before `post`.
|
|
492
495
|
`next_post` | The post published chronologically after `post`.
|
|
493
496
|
|
|
497
|
+
## Archive page variables
|
|
498
|
+
|
|
499
|
+
These are set when processing archive pages.
|
|
500
|
+
|
|
501
|
+
Variable | Value
|
|
502
|
+
-------------- |:-----
|
|
503
|
+
`month` | The month for the archive page being rendered. This is a Ruby `Date` instance.
|
|
504
|
+
`posts` | The list of posts for the month. Ordered by most-recently-published-first.
|
|
505
|
+
`archive_page` | A flag set to `true`.
|
|
506
|
+
|
|
494
507
|
# Developing Serif
|
|
495
508
|
|
|
496
509
|
## Broad outline
|
|
@@ -504,6 +517,18 @@ Variable | Value
|
|
|
504
517
|
* `lib/serif/` is generally where files go.
|
|
505
518
|
* `test/` contains the test files. Any new files should have `require "test_helper"` at the top of the, which pulls in `test/test_helper.rb`.
|
|
506
519
|
|
|
520
|
+
# Changes and what's new
|
|
521
|
+
|
|
522
|
+
## Latest release (v0.4)
|
|
523
|
+
|
|
524
|
+
## v0.3.3
|
|
525
|
+
|
|
526
|
+
* Allow drag-and-drop to work on posts as well as drafts. (9ea3bebf)
|
|
527
|
+
* `serif new` no longer creates a sample published post (#37) and generates immediately. (#39)
|
|
528
|
+
* Pygments.rb is replaced with Rouge for code highlighting. (#34)
|
|
529
|
+
|
|
530
|
+
See `CHANGELOG` for more.
|
|
531
|
+
|
|
507
532
|
# Planned features
|
|
508
533
|
|
|
509
534
|
Some things I'm hoping to implement one day:
|
|
@@ -511,4 +536,4 @@ Some things I'm hoping to implement one day:
|
|
|
511
536
|
1. Custom hooks to fire after particular events, such as minifying CSS after publish, or committing changes and pushing to a git repository.
|
|
512
537
|
2. Simple Markdown pages instead of plain HTML for non-post content.
|
|
513
538
|
3. Automatically detecting file changes and regenerating the site.
|
|
514
|
-
4. Adding custom Liquid filters and tags.
|
|
539
|
+
4. Adding custom Liquid filters and tags.
|
data/bin/serif
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
|
4
4
|
|
|
5
5
|
require "fileutils"
|
|
6
|
-
require "slop"
|
|
7
6
|
|
|
8
7
|
def initialize_admin_server(source_dir)
|
|
9
8
|
# need to cd to the directory before requiring the admin
|
|
@@ -60,30 +59,16 @@ def produce_skeleton(dir)
|
|
|
60
59
|
puts
|
|
61
60
|
end
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
on :dev do
|
|
77
|
-
add_callback :empty do
|
|
78
|
-
initialize_dev_server(Dir.pwd)
|
|
79
|
-
end
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
on :new do
|
|
83
|
-
add_callback :empty do
|
|
84
|
-
produce_skeleton(Dir.pwd)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
62
|
+
command = ARGV.shift
|
|
63
|
+
args = ARGV
|
|
64
|
+
|
|
65
|
+
case command
|
|
66
|
+
when "admin"
|
|
67
|
+
initialize_admin_server(Dir.pwd)
|
|
68
|
+
when "generate"
|
|
69
|
+
generate_site(Dir.pwd)
|
|
70
|
+
when "dev"
|
|
71
|
+
initialize_dev_server(Dir.pwd)
|
|
72
|
+
when "new"
|
|
73
|
+
produce_skeleton(Dir.pwd)
|
|
87
74
|
end
|
|
88
|
-
|
|
89
|
-
commands.parse
|
data/lib/serif/admin_server.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
require "sinatra/base"
|
|
2
2
|
require "fileutils"
|
|
3
|
+
require "nokogiri"
|
|
4
|
+
require "reverse_markdown"
|
|
3
5
|
|
|
4
6
|
module Serif
|
|
5
7
|
class AdminServer
|
|
@@ -39,6 +41,52 @@ class AdminServer
|
|
|
39
41
|
redirect to("/admin"), 301
|
|
40
42
|
end
|
|
41
43
|
|
|
44
|
+
get "/admin/bookmarks" do
|
|
45
|
+
liquid :bookmarks, locals: { base_url: request.base_url }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
get "/admin/quick-draft" do
|
|
49
|
+
url = params[:url]
|
|
50
|
+
html_content = params[:content].strip
|
|
51
|
+
|
|
52
|
+
title = params[:title]
|
|
53
|
+
|
|
54
|
+
# delete anything nonprintable
|
|
55
|
+
title = title.gsub(/[^\x20-\x7E]/, "")
|
|
56
|
+
|
|
57
|
+
# sanitise the HTML title into something we can use as a temporary slug
|
|
58
|
+
slug = title.split(" ").first(5).join(" ").gsub(/[^\w-]/, "-").gsub(/--+/, '-').gsub(/^-|-$/, '')
|
|
59
|
+
slug.downcase!
|
|
60
|
+
|
|
61
|
+
if html_content.empty?
|
|
62
|
+
markdown = "[#{title}](#{url.gsub(")", "\\)")})"
|
|
63
|
+
else
|
|
64
|
+
# parse the document fragment and remove any empty nodes.
|
|
65
|
+
document = Nokogiri::HTML::DocumentFragment.parse(html_content)
|
|
66
|
+
document.traverse { |p| p.remove if p.text && p.text.strip.empty? }
|
|
67
|
+
html_content = document.to_html
|
|
68
|
+
|
|
69
|
+
html_content = "<blockquote>#{html_content}</blockquote>"
|
|
70
|
+
markdown = ReverseMarkdown.parse(html_content, github_style_code_blocks: true)
|
|
71
|
+
|
|
72
|
+
# markdown URLs need to have any )s escaped
|
|
73
|
+
markdown = "[#{title}](#{url.gsub(")", "\\)")}):\n\n#{markdown}"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
draft = Draft.new(site)
|
|
77
|
+
draft.title = title
|
|
78
|
+
draft.slug = slug
|
|
79
|
+
draft.save(markdown)
|
|
80
|
+
|
|
81
|
+
site.generate
|
|
82
|
+
|
|
83
|
+
if params[:edit] == "1"
|
|
84
|
+
redirect to("/admin/edit/drafts/#{slug}")
|
|
85
|
+
else
|
|
86
|
+
redirect to(url)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
42
90
|
get "/admin/new/draft" do
|
|
43
91
|
content = Draft.new(site)
|
|
44
92
|
autofocus = "slug"
|
data/lib/serif/content_file.rb
CHANGED
|
@@ -3,10 +3,6 @@
|
|
|
3
3
|
# which contains the contents of a post, be it in
|
|
4
4
|
# draft form or otherwise.
|
|
5
5
|
#
|
|
6
|
-
# A ContentFile can determine its type based on
|
|
7
|
-
# the presence or absence of a "published"
|
|
8
|
-
# timestamp value.
|
|
9
|
-
#
|
|
10
6
|
|
|
11
7
|
module Serif
|
|
12
8
|
class ContentFile
|
|
@@ -33,18 +29,16 @@ class ContentFile
|
|
|
33
29
|
# if we're adding a slug and there's no path yet, then create the path.
|
|
34
30
|
# this will run for new drafts
|
|
35
31
|
|
|
36
|
-
|
|
37
|
-
@path = File.expand_path("#{site.directory}/#{self.class.dirname}/#{@slug}")
|
|
38
|
-
end
|
|
32
|
+
@path ||= File.expand_path("#{site.directory}/#{self.class.dirname}/#{@slug}")
|
|
39
33
|
end
|
|
40
34
|
|
|
41
35
|
def title
|
|
42
|
-
return nil if
|
|
36
|
+
return nil if !@source
|
|
43
37
|
headers[:title]
|
|
44
38
|
end
|
|
45
39
|
|
|
46
40
|
def title=(new_title)
|
|
47
|
-
if
|
|
41
|
+
if !@source
|
|
48
42
|
@source = Redhead::String["title: #{new_title}\n\n"]
|
|
49
43
|
else
|
|
50
44
|
@source.headers[:title] = new_title
|
|
@@ -62,24 +56,16 @@ class ContentFile
|
|
|
62
56
|
end
|
|
63
57
|
|
|
64
58
|
def content(include_headers = false)
|
|
65
|
-
include_headers ? "#{
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def new?
|
|
69
|
-
!@source
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def raw_headers
|
|
73
|
-
@source.headers.to_s
|
|
59
|
+
include_headers ? "#{@source.headers.to_s}\n\n#{@source.to_s}" : @source.to_s
|
|
74
60
|
end
|
|
75
61
|
|
|
76
62
|
def created
|
|
77
|
-
return nil if
|
|
63
|
+
return nil if !@source
|
|
78
64
|
headers[:created].utc
|
|
79
65
|
end
|
|
80
66
|
|
|
81
67
|
def updated
|
|
82
|
-
return nil if
|
|
68
|
+
return nil if !@source
|
|
83
69
|
(headers[:updated] || created).utc
|
|
84
70
|
end
|
|
85
71
|
|
|
@@ -105,18 +91,19 @@ class ContentFile
|
|
|
105
91
|
end
|
|
106
92
|
|
|
107
93
|
def save(markdown = nil)
|
|
108
|
-
markdown ||= content if
|
|
94
|
+
markdown ||= content if @source
|
|
109
95
|
|
|
110
96
|
save_path = path || "#{self.class.dirname}/#{@slug}"
|
|
111
97
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
98
|
+
# TODO: when a draft is being saved, it will call set_publish_time
|
|
99
|
+
# and then the #save call will execute this line, which will mean
|
|
100
|
+
# there is a very, very slight difference (fraction of a second)
|
|
101
|
+
# between the update time of a brand new published post and the
|
|
102
|
+
# creation time.
|
|
103
|
+
set_updated_time(Time.now)
|
|
104
|
+
|
|
118
105
|
File.open(save_path, "w") do |f|
|
|
119
|
-
f.puts %Q{#{
|
|
106
|
+
f.puts %Q{#{@source.headers.to_s}
|
|
120
107
|
|
|
121
108
|
#{markdown}}.strip
|
|
122
109
|
end
|
|
@@ -135,11 +122,18 @@ class ContentFile
|
|
|
135
122
|
|
|
136
123
|
def set_publish_time(time)
|
|
137
124
|
@source.headers[:created] = time.xmlschema
|
|
138
|
-
|
|
125
|
+
headers_changed!
|
|
139
126
|
end
|
|
140
127
|
|
|
141
128
|
def set_updated_time(time)
|
|
142
129
|
@source.headers[:updated] = time.xmlschema
|
|
130
|
+
headers_changed!
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Invalidates the cached headers entirely.
|
|
134
|
+
#
|
|
135
|
+
# Any methods which alter headers should call this.
|
|
136
|
+
def headers_changed!
|
|
143
137
|
@cached_headers = nil
|
|
144
138
|
end
|
|
145
139
|
|
data/lib/serif/draft.rb
CHANGED
|
@@ -36,18 +36,16 @@ class Draft < ContentFile
|
|
|
36
36
|
@path = Post.from_slug(site, slug).path
|
|
37
37
|
end
|
|
38
38
|
|
|
39
|
-
# sets the autopublish flag to the given value.
|
|
40
|
-
#
|
|
41
39
|
# if the assigned value is truthy, the "publish" header
|
|
42
40
|
# is set to "now", otherwise the header is removed.
|
|
43
41
|
def autopublish=(value)
|
|
44
|
-
@autopublish = value
|
|
45
|
-
|
|
46
42
|
if value
|
|
47
43
|
@source.headers[:publish] = "now"
|
|
48
44
|
else
|
|
49
45
|
@source.headers.delete(:publish)
|
|
50
46
|
end
|
|
47
|
+
|
|
48
|
+
headers_changed!
|
|
51
49
|
end
|
|
52
50
|
|
|
53
51
|
# Checks the value of the "publish" header, and returns
|
data/lib/serif/post.rb
CHANGED
|
@@ -27,6 +27,36 @@ class Post < ContentFile
|
|
|
27
27
|
output
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
# if the assigned value is truthy, the "update" header
|
|
31
|
+
# is set to "now", otherwise the header is removed.
|
|
32
|
+
def autoupdate=(value)
|
|
33
|
+
if value
|
|
34
|
+
@source.headers[:update] = "now"
|
|
35
|
+
else
|
|
36
|
+
@source.headers.delete(:update)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
headers_changed!
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# returns true if the post has been marked as needing a
|
|
43
|
+
# new updated timestamp header.
|
|
44
|
+
#
|
|
45
|
+
# this is based on the presence of an "update: now" header.
|
|
46
|
+
def autoupdate?
|
|
47
|
+
update_header = headers[:update]
|
|
48
|
+
update_header && update_header.strip == "now"
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Updates the updated timestamp and saves the contents.
|
|
52
|
+
#
|
|
53
|
+
# If there is an "update" header (see autoupdate?), it is deleted.
|
|
54
|
+
def update!
|
|
55
|
+
@source.headers.delete(:update)
|
|
56
|
+
set_updated_time(Time.now)
|
|
57
|
+
save
|
|
58
|
+
end
|
|
59
|
+
|
|
30
60
|
def self.all(site)
|
|
31
61
|
files = Dir[File.join(site.directory, dirname, "*")].select { |f| File.file?(f) }.map { |f| File.expand_path(f) }
|
|
32
62
|
files.map { |f| new(site, f) }
|