serif 0.4 → 0.5
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 +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/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
serif (0.
|
4
|
+
serif (0.4)
|
5
5
|
liquid (~> 2.4)
|
6
6
|
nokogiri (~> 1.5)
|
7
7
|
rack (~> 1.0)
|
@@ -15,37 +15,50 @@ PATH
|
|
15
15
|
GEM
|
16
16
|
remote: http://rubygems.org/
|
17
17
|
specs:
|
18
|
-
|
18
|
+
colorize (0.5.8)
|
19
|
+
coveralls (0.6.3)
|
20
|
+
colorize
|
21
|
+
multi_json (~> 1.3)
|
22
|
+
rest-client
|
23
|
+
simplecov (>= 0.7)
|
24
|
+
thor
|
25
|
+
diff-lcs (1.2.2)
|
26
|
+
json (1.7.7)
|
19
27
|
liquid (2.5.0)
|
20
|
-
|
21
|
-
|
28
|
+
mime-types (1.22)
|
29
|
+
multi_json (1.7.2)
|
30
|
+
nokogiri (1.5.9)
|
22
31
|
rack (1.5.2)
|
23
32
|
rack-protection (1.5.0)
|
24
33
|
rack
|
25
34
|
rake (0.9.6)
|
35
|
+
rdoc (4.0.1)
|
36
|
+
json (~> 1.4)
|
26
37
|
redcarpet (2.2.2)
|
27
38
|
redhead (0.0.8)
|
39
|
+
rest-client (1.6.7)
|
40
|
+
mime-types (>= 1.16)
|
28
41
|
reverse_markdown (0.4.4)
|
29
42
|
nokogiri
|
30
43
|
rouge (0.3.2)
|
31
44
|
thor
|
32
|
-
rspec (2.
|
33
|
-
rspec-core (~> 2.
|
34
|
-
rspec-expectations (~> 2.
|
35
|
-
rspec-mocks (~> 2.
|
36
|
-
rspec-core (2.
|
37
|
-
rspec-expectations (2.
|
38
|
-
diff-lcs (
|
39
|
-
rspec-mocks (2.
|
45
|
+
rspec (2.13.0)
|
46
|
+
rspec-core (~> 2.13.0)
|
47
|
+
rspec-expectations (~> 2.13.0)
|
48
|
+
rspec-mocks (~> 2.13.0)
|
49
|
+
rspec-core (2.13.1)
|
50
|
+
rspec-expectations (2.13.0)
|
51
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
52
|
+
rspec-mocks (2.13.0)
|
40
53
|
simplecov (0.7.1)
|
41
54
|
multi_json (~> 1.0)
|
42
55
|
simplecov-html (~> 0.7.1)
|
43
56
|
simplecov-html (0.7.1)
|
44
|
-
sinatra (1.4.
|
57
|
+
sinatra (1.4.2)
|
45
58
|
rack (~> 1.5, >= 1.5.2)
|
46
59
|
rack-protection (~> 1.4)
|
47
60
|
tilt (~> 1.3, >= 1.3.4)
|
48
|
-
thor (0.
|
61
|
+
thor (0.18.1)
|
49
62
|
tilt (1.3.6)
|
50
63
|
timecop (0.6.1)
|
51
64
|
timeout_cache (0.0.2)
|
@@ -54,7 +67,9 @@ PLATFORMS
|
|
54
67
|
ruby
|
55
68
|
|
56
69
|
DEPENDENCIES
|
70
|
+
coveralls
|
57
71
|
rake (~> 0.9)
|
72
|
+
rdoc (~> 4.0.0)
|
58
73
|
rspec (~> 2.5)
|
59
74
|
serif!
|
60
75
|
simplecov (~> 0.7)
|
data/README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
# Serif
|
2
2
|
|
3
|
-
[](https://travis-ci.org/aprescott/serif)
|
3
|
+
[](https://travis-ci.org/aprescott/serif) [](https://codeclimate.com/github/aprescott/serif) [](https://coveralls.io/r/aprescott/serif)
|
4
4
|
|
5
|
-
Serif is a
|
5
|
+
Serif is a static site generator and blogging system powered by markdown files and an optional admin interface complete with drag-and-drop image uploading. ([Check out the simple video demo](https://docs.google.com/open?id=0BxPQpxGSOOyKS1J4MmlnM3JIaXM).)
|
6
6
|
|
7
|
-
|
7
|
+
Serif releases you from managing a file system so you can focus on writing content.
|
8
|
+
|
9
|
+
Having problems with Serif? [Open an issue on GitHub](https://github.com/aprescott/serif/issues), use the [Serif Google Group](https://groups.google.com/forum/#!forum/serif-rb), or [join the Freenode#serif IRC channel](irc://irc.freenode.net/serif).
|
8
10
|
|
9
11
|
## First time use
|
10
12
|
|
@@ -177,9 +179,24 @@ Something something.
|
|
177
179
|
End of the post
|
178
180
|
```
|
179
181
|
|
182
|
+
### Headers
|
183
|
+
|
180
184
|
The headers are similar to Jekyll's YAML front matter, but here there are no formatting requirements beyond `Key: value` pairs. Header names are case-insensitive (so `title` is the same as `Title`), but values are not.
|
181
185
|
|
182
|
-
|
186
|
+
File headers like `Title: Some title` can contain any header, but certain headers have special meaning in Serif.
|
187
|
+
|
188
|
+
Header name | Meaning
|
189
|
+
----------- |:-------
|
190
|
+
`Created` | For a post, timestamp for when it was first published. Must be a string that Ruby's `Time` class can parse. Means nothing for drafts.
|
191
|
+
`Updated` | For a post, timestamp for when it was last updated. Must be a string that Ruby's `Time` class can parse. Means nothing for drafts.
|
192
|
+
`Title` | Title for the draft or post.
|
193
|
+
`Update` | For a post, When given the value of `now` (i.e., `Update: now`), the `Updated` timestamp will be updated on the next site generation. Means nothing for drafts.
|
194
|
+
`Publish` | For a draft, when given the value of `now` (i.e., `Publish: now`), the draft will be published on the next site generation (and the `Created` set appropriately). Means nothing for a post.
|
195
|
+
`Permalink` | For a post, overrides the default permalink value defined in `_config.yml`. **Note that this is interpolated**, so `:title` in the permalink value will be replaced according to regular permalink rules. Means nothing for a draft.
|
196
|
+
|
197
|
+
Note that while it is possible for you to manually handle timestamp values, it is recommended that you rely on using the value of `now` for `Update` and `Publish`.
|
198
|
+
|
199
|
+
If you change the `permalink` value for a published post, you will break any inbound URLs as well as, e.g., any feeds that rely on the URL as a unique persistent ID.
|
183
200
|
|
184
201
|
## `_templates`
|
185
202
|
|
@@ -217,6 +234,8 @@ Placeholder | Value
|
|
217
234
|
`:month` | Month as given in the filename, e.g., "01"
|
218
235
|
`:day` | Day as given in the filename, e.g., "28"
|
219
236
|
|
237
|
+
<b>NOTE</b>: if you change the permalink value, you will break existing URLs for published posts, in addition to, e.g., any feed ID values that depend on the post URL never changing.
|
238
|
+
|
220
239
|
### Admin drag-and-drop upload path
|
221
240
|
|
222
241
|
The `image_upload_path` configuration setting is an _absolute path_ and will be relative to the base directory of your site, used in the admin interface to control where files are sent. The default value is `/images/:timestamp_:name`. Similar to permalinks, the following placeholders are available:
|
@@ -283,7 +302,7 @@ On the next site generation (`serif generate`) this draft will be automatically
|
|
283
302
|
|
284
303
|
# Updating posts
|
285
304
|
|
286
|
-
When you update a
|
305
|
+
When you update a post, 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 published post after making your changes:
|
287
306
|
|
288
307
|
```
|
289
308
|
title: My blog post
|
@@ -470,6 +489,7 @@ These should be available in any template:
|
|
470
489
|
* `{{ site.latest_update_time }}` --- a [Ruby `Time`](http://ruby-doc.org/core/Time.html) instance for the latest time that any post was updated. Useful for RSS/Atom feeds.
|
471
490
|
* `{{ site.archives }}` --- a nested hash structure that groups posts by month. See above for how to use it.
|
472
491
|
* `{{ draft_preview }}` -- Set to true if this is part of generating a draft preview.
|
492
|
+
* `{{ post_page }}` -- Set to true if this is part of generating a regular published post.
|
473
493
|
|
474
494
|
## Post variables
|
475
495
|
|
@@ -483,6 +503,7 @@ Name | Value
|
|
483
503
|
`post.created` | A [Ruby `Time`](http://ruby-doc.org/core/Time.html) instance for the time the post was first published.
|
484
504
|
`post.updated` | A [Ruby `Time`](http://ruby-doc.org/core/Time.html) instance for the time the post was last updated.
|
485
505
|
`post.content` | The raw post content. Example use: `{{ post.content | markdown }}`.
|
506
|
+
`post.foo` | The value of the `Foo` header, e.g., if `Foo: my special header` is in the source file, `post.foo` is `my special header`. All headers are merged into the `{{ post }}` variable for you to use in templates.
|
486
507
|
|
487
508
|
## Variables available within post templates
|
488
509
|
|
@@ -511,6 +532,7 @@ Variable | Value
|
|
511
532
|
* `./bin/serif {dev,admin,generate}` to run Serif commands.
|
512
533
|
* `rake test` to run the tests.
|
513
534
|
* Unit tests are written in RSpec.
|
535
|
+
* `rake docs` will generate HTML documentation in `docs/`. Open `docs/index.html` in a browser to start.
|
514
536
|
|
515
537
|
## Directory structure
|
516
538
|
|
@@ -519,15 +541,7 @@ Variable | Value
|
|
519
541
|
|
520
542
|
# Changes and what's new
|
521
543
|
|
522
|
-
|
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.
|
544
|
+
See `CHANGELOG`.
|
531
545
|
|
532
546
|
# Planned features
|
533
547
|
|
data/bin/serif
CHANGED
@@ -2,73 +2,6 @@
|
|
2
2
|
|
3
3
|
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
4
4
|
|
5
|
-
require "
|
5
|
+
require "serif/commands"
|
6
6
|
|
7
|
-
|
8
|
-
# need to cd to the directory before requiring the admin
|
9
|
-
# server, because otherwise Dir.pwd won't be right when
|
10
|
-
# the admin server class is defined at require time.
|
11
|
-
FileUtils.cd(source_dir)
|
12
|
-
require "serif"
|
13
|
-
require "serif/admin_server"
|
14
|
-
|
15
|
-
server = Serif::AdminServer.new(source_dir)
|
16
|
-
server.start
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize_dev_server(source_dir)
|
20
|
-
FileUtils.cd(source_dir)
|
21
|
-
require "serif"
|
22
|
-
require "serif/server"
|
23
|
-
|
24
|
-
server = Serif::DevelopmentServer.new(source_dir)
|
25
|
-
server.start
|
26
|
-
end
|
27
|
-
|
28
|
-
def generate_site(source_dir)
|
29
|
-
require "serif"
|
30
|
-
|
31
|
-
site = Serif::Site.new(source_dir)
|
32
|
-
site.generate
|
33
|
-
end
|
34
|
-
|
35
|
-
def verify_directory(dir)
|
36
|
-
unless Dir.exist?(dir)
|
37
|
-
puts "No such directory: #{dir}'"
|
38
|
-
exit 1
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
def produce_skeleton(dir)
|
43
|
-
if !Dir[File.join(dir, "*")].empty?
|
44
|
-
abort "Directory is not empty."
|
45
|
-
end
|
46
|
-
|
47
|
-
FileUtils.cd(File.join(File.dirname(__FILE__), "..", "statics", "skeleton"))
|
48
|
-
files = Dir["*"]
|
49
|
-
files.each do |f|
|
50
|
-
FileUtils.cp_r(f, dir, verbose: true)
|
51
|
-
end
|
52
|
-
|
53
|
-
generate_site(dir)
|
54
|
-
|
55
|
-
puts
|
56
|
-
puts "*** NOTE ***"
|
57
|
-
puts
|
58
|
-
puts "You should now edit the username and password in _config.yml"
|
59
|
-
puts
|
60
|
-
end
|
61
|
-
|
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)
|
74
|
-
end
|
7
|
+
Serif::Commands.new(ARGV).process
|
data/lib/serif.rb
CHANGED
data/lib/serif/admin_server.rb
CHANGED
@@ -19,6 +19,10 @@ class AdminServer
|
|
19
19
|
[username, password] == [site.config.admin_username, site.config.admin_password]
|
20
20
|
end
|
21
21
|
|
22
|
+
before do
|
23
|
+
@conflicts = site.conflicts
|
24
|
+
end
|
25
|
+
|
22
26
|
# multiple public folders??
|
23
27
|
get "/admin/js/:file" do |file|
|
24
28
|
assets_dir = File.join(File.dirname(__FILE__), "..", "..", "statics", "assets", "js")
|
@@ -34,7 +38,7 @@ class AdminServer
|
|
34
38
|
posts = site.posts.sort_by { |p| p.created }.reverse
|
35
39
|
drafts = site.drafts.sort_by { |p| File.mtime(p.path) }.reverse
|
36
40
|
|
37
|
-
liquid :index, locals: { posts: posts, drafts: drafts }
|
41
|
+
liquid :index, locals: { conflicts: @conflicts, posts: posts, drafts: drafts }
|
38
42
|
end
|
39
43
|
|
40
44
|
get "/admin/edit/?" do
|
@@ -42,7 +46,7 @@ class AdminServer
|
|
42
46
|
end
|
43
47
|
|
44
48
|
get "/admin/bookmarks" do
|
45
|
-
liquid :bookmarks, locals: {
|
49
|
+
liquid :bookmarks, locals: { conflicts: @conflicts }
|
46
50
|
end
|
47
51
|
|
48
52
|
get "/admin/quick-draft" do
|
@@ -76,21 +80,36 @@ class AdminServer
|
|
76
80
|
draft = Draft.new(site)
|
77
81
|
draft.title = title
|
78
82
|
draft.slug = slug
|
79
|
-
draft.save(markdown)
|
80
83
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
84
|
+
# if the draft itself has no conflict, save it,
|
85
|
+
# otherwise show the new draft page with an error.
|
86
|
+
#
|
87
|
+
# if, after saving the draft because of no conflict,
|
88
|
+
# there is actually an overall site conflict, then
|
89
|
+
# keep on trucking so it doesn't interrupt the user.
|
90
|
+
if site.conflicts(draft)
|
91
|
+
liquid :new_draft, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), post: draft, error_message: "There is a conflict on this draft." }
|
85
92
|
else
|
86
|
-
|
93
|
+
draft.save(markdown)
|
94
|
+
|
95
|
+
begin
|
96
|
+
site.generate
|
97
|
+
rescue PostConflictError => e
|
98
|
+
puts "Site has conflicts, skipping generation for now."
|
99
|
+
end
|
100
|
+
|
101
|
+
if params[:edit] == "1"
|
102
|
+
redirect to("/admin/edit/drafts/#{slug}")
|
103
|
+
else
|
104
|
+
redirect to(url)
|
105
|
+
end
|
87
106
|
end
|
88
107
|
end
|
89
108
|
|
90
109
|
get "/admin/new/draft" do
|
91
110
|
content = Draft.new(site)
|
92
111
|
autofocus = "slug"
|
93
|
-
liquid :new_draft, locals: { images_path: site.config.image_upload_path.gsub(/"/, '\"'), post: content, autofocus: autofocus }
|
112
|
+
liquid :new_draft, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), post: content, autofocus: autofocus }
|
94
113
|
end
|
95
114
|
|
96
115
|
post "/admin/new/draft" do
|
@@ -109,13 +128,18 @@ class AdminServer
|
|
109
128
|
autofocus = "title" unless params[:title]
|
110
129
|
autofocus = "slug" unless params[:slug]
|
111
130
|
|
112
|
-
liquid :new_draft, locals: { images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content, autofocus: autofocus }
|
131
|
+
liquid :new_draft, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content, autofocus: autofocus }
|
113
132
|
else
|
114
133
|
if Draft.exist?(site, params[:slug])
|
115
|
-
|
134
|
+
error_message = "Draft already eixsts with the given slug #{params[:slug]}."
|
135
|
+
liquid :new_draft, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content, autofocus: autofocus }
|
116
136
|
else
|
117
137
|
content.save(params[:markdown])
|
118
|
-
|
138
|
+
begin
|
139
|
+
site.generate
|
140
|
+
rescue PostConflictError => e
|
141
|
+
puts "Cannot generate. Skipping for now."
|
142
|
+
end
|
119
143
|
redirect to("/admin")
|
120
144
|
end
|
121
145
|
end
|
@@ -155,7 +179,10 @@ class AdminServer
|
|
155
179
|
error_message = "You must pick a URL to use"
|
156
180
|
end
|
157
181
|
|
158
|
-
liquid :edit_draft, locals: { images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content, private_url: site.private_url(content) }
|
182
|
+
liquid :edit_draft, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content, private_url: site.private_url(content) }
|
183
|
+
elsif (conflicts = site.conflicts)
|
184
|
+
error_message = "The site has a conflict and cannot be generated."
|
185
|
+
liquid :edit_draft, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content, private_url: site.private_url(content) }
|
159
186
|
else
|
160
187
|
content.save(params[:markdown])
|
161
188
|
|
@@ -172,7 +199,7 @@ class AdminServer
|
|
172
199
|
end
|
173
200
|
|
174
201
|
post "/admin/edit/posts" do
|
175
|
-
content = Post.
|
202
|
+
content = Post.from_basename(site, params[:original_basename])
|
176
203
|
|
177
204
|
params[:markdown] = params[:markdown].strip
|
178
205
|
params[:title] = params[:title].strip
|
@@ -183,7 +210,10 @@ class AdminServer
|
|
183
210
|
error_message = "Content must not be blank." if params[:markdown].empty?
|
184
211
|
error_message = "Title must not be blank." if params[:title].empty?
|
185
212
|
|
186
|
-
liquid :edit_post, locals: { images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content }
|
213
|
+
liquid :edit_post, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content }
|
214
|
+
elsif (conflicts = site.conflicts)
|
215
|
+
error_message = "The site has a conflict and cannot be generated."
|
216
|
+
liquid :edit_post, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), error_message: error_message, post: content }
|
187
217
|
else
|
188
218
|
content.save(params[:markdown])
|
189
219
|
site.generate
|
@@ -192,19 +222,18 @@ class AdminServer
|
|
192
222
|
end
|
193
223
|
end
|
194
224
|
|
195
|
-
get "/admin/edit/:
|
225
|
+
get "/admin/edit/posts/:basename" do
|
226
|
+
redirect to("/admin") unless params[:basename]
|
227
|
+
|
228
|
+
content = Post.from_basename(site, params[:basename])
|
229
|
+
liquid :edit_post, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), post: content, autofocus: "markdown" }
|
230
|
+
end
|
231
|
+
|
232
|
+
get "/admin/edit/drafts/:slug" do
|
196
233
|
redirect to("/admin") unless params[:slug]
|
197
234
|
|
198
|
-
|
199
|
-
|
200
|
-
liquid :edit_post, locals: { images_path: site.config.image_upload_path.gsub(/"/, '\"'), post: content, autofocus: "markdown" }
|
201
|
-
elsif params[:type] == "drafts"
|
202
|
-
content = Draft.from_slug(site, params[:slug])
|
203
|
-
liquid :edit_draft, locals: { images_path: site.config.image_upload_path.gsub(/"/, '\"'), post: content, autofocus: "markdown", private_url: site.private_url(content) }
|
204
|
-
else
|
205
|
-
response.status = 404
|
206
|
-
return "Nope"
|
207
|
-
end
|
235
|
+
content = Draft.from_slug(site, params[:slug])
|
236
|
+
liquid :edit_draft, locals: { conflicts: @conflicts, images_path: site.config.image_upload_path.gsub(/"/, '\"'), post: content, autofocus: "markdown", private_url: site.private_url(content) }
|
208
237
|
end
|
209
238
|
|
210
239
|
post "/admin/delete/?" do
|
@@ -0,0 +1,150 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "serif"
|
3
|
+
require "serif/server"
|
4
|
+
|
5
|
+
module Serif
|
6
|
+
class Commands
|
7
|
+
def initialize(argv)
|
8
|
+
@argv = argv.dup
|
9
|
+
end
|
10
|
+
|
11
|
+
def process
|
12
|
+
command = @argv.shift
|
13
|
+
case command
|
14
|
+
when "-h", "--help", nil
|
15
|
+
print_help
|
16
|
+
exit 0
|
17
|
+
when "admin"
|
18
|
+
initialize_admin_server(Dir.pwd)
|
19
|
+
when "generate"
|
20
|
+
generate_site(Dir.pwd)
|
21
|
+
when "dev"
|
22
|
+
initialize_dev_server(Dir.pwd)
|
23
|
+
when "new"
|
24
|
+
produce_skeleton(Dir.pwd)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize_admin_server(source_dir)
|
29
|
+
# need to cd to the directory before requiring the admin
|
30
|
+
# server, because otherwise Dir.pwd won't be right when
|
31
|
+
# the admin server class is defined at require time.
|
32
|
+
FileUtils.cd(source_dir)
|
33
|
+
require "serif/admin_server"
|
34
|
+
|
35
|
+
server = Serif::AdminServer.new(source_dir)
|
36
|
+
server.start
|
37
|
+
end
|
38
|
+
|
39
|
+
def initialize_dev_server(source_dir)
|
40
|
+
FileUtils.cd(source_dir)
|
41
|
+
|
42
|
+
server = Serif::DevelopmentServer.new(source_dir)
|
43
|
+
server.start
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_site(source_dir)
|
47
|
+
|
48
|
+
site = Serif::Site.new(source_dir)
|
49
|
+
|
50
|
+
begin
|
51
|
+
site.generate
|
52
|
+
rescue Serif::PostConflictError => e
|
53
|
+
puts "Error! Unable to generate because there is a conflict."
|
54
|
+
puts
|
55
|
+
puts "Conflicts at:"
|
56
|
+
puts
|
57
|
+
|
58
|
+
site.conflicts.each do |url, ary|
|
59
|
+
puts url
|
60
|
+
ary.each do |e|
|
61
|
+
puts "\t#{e.path}"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
exit 1
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def verify_directory(dir)
|
70
|
+
unless Dir.exist?(dir)
|
71
|
+
puts "No such directory: #{dir}'"
|
72
|
+
exit 1
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def produce_skeleton(dir)
|
77
|
+
if !Dir[File.join(dir, "*")].empty?
|
78
|
+
abort "Directory is not empty."
|
79
|
+
end
|
80
|
+
|
81
|
+
FileUtils.cd(File.join(File.dirname(__FILE__), "..", "..", "statics", "skeleton"))
|
82
|
+
files = Dir["*"]
|
83
|
+
files.each do |f|
|
84
|
+
FileUtils.cp_r(f, dir, verbose: true)
|
85
|
+
end
|
86
|
+
|
87
|
+
generate_site(dir)
|
88
|
+
|
89
|
+
puts
|
90
|
+
puts "*** NOTE ***"
|
91
|
+
puts
|
92
|
+
puts "You should now edit the username and password in _config.yml"
|
93
|
+
puts
|
94
|
+
end
|
95
|
+
|
96
|
+
def print_help
|
97
|
+
puts <<-END_HELP
|
98
|
+
USAGE
|
99
|
+
|
100
|
+
serif [-h | --help]
|
101
|
+
serif [COMMAND]
|
102
|
+
|
103
|
+
OPTIONS
|
104
|
+
|
105
|
+
-h, --help Display this help message and exit immediately.
|
106
|
+
|
107
|
+
COMMANDS
|
108
|
+
|
109
|
+
serif generate Generate the site in the current directory.
|
110
|
+
|
111
|
+
serif new Create a site skeleton to get started. Will
|
112
|
+
only run if the current directory is empty.
|
113
|
+
|
114
|
+
serif admin Start the admin server on localhost:4567.
|
115
|
+
|
116
|
+
serif dev Start a simple dev server on localhost:8000.
|
117
|
+
Serves up the generated static files, but loads
|
118
|
+
some files (like CSS) from source (instead of
|
119
|
+
out of the _site/ directory).
|
120
|
+
|
121
|
+
ENVIRONMENT VARIABLES
|
122
|
+
|
123
|
+
ENV Set to 'production' if the command is being run
|
124
|
+
as part of serving up a live site.
|
125
|
+
|
126
|
+
$ ENV=production serif generate
|
127
|
+
|
128
|
+
$ ENV=production serif admin
|
129
|
+
|
130
|
+
Note that this by and large doesn't change much,
|
131
|
+
but in future it may provide extra features.
|
132
|
+
|
133
|
+
The main benefit is that the `file_digest` tag
|
134
|
+
will return a hex digest of the given file's
|
135
|
+
contents only when ENV is set to production.
|
136
|
+
|
137
|
+
EXAMPLES
|
138
|
+
|
139
|
+
$ serif generate
|
140
|
+
|
141
|
+
Generate the site.
|
142
|
+
|
143
|
+
$ serif admin
|
144
|
+
|
145
|
+
Start the admin server on localhost:4567.
|
146
|
+
|
147
|
+
END_HELP
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|