serif 0.2.3 → 0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +2 -0
- data/README.md +72 -7
- data/lib/serif/admin_server.rb +1 -1
- data/lib/serif/config.rb +1 -1
- data/lib/serif/content_file.rb +9 -2
- data/lib/serif/draft.rb +5 -0
- data/lib/serif/site.rb +20 -5
- data/lib/serif.rb +1 -0
- data/rakefile +28 -0
- data/serif.gemspec +3 -2
- data/statics/assets/js/attachment.js +33 -0
- data/test/draft_spec.rb +33 -0
- data/test/filters_spec.rb +17 -0
- data/test/site_dir/_site/drafts/another-sample-draft/{cdc8037ed098e34a19fc6671ab652f908dd94009ff642d4e5ee80fa566fa.html → f340ff2dd6aa78f819d547ee908fe7410e6153559b47265dcbc58598bb4a.html} +0 -0
- data/test/site_dir/_site/drafts/sample-draft/{f828e5f22d76b04c586e90680ac814e6b233d3d380f6be6975beba75081b.html → ed883ce827f757888e2900ce0e155a960cb45f832fcc24791c054013b71c.html} +0 -0
- data/test/site_dir/_site/index.html +3 -3
- data/test/site_dir/_site/test-smarty-filter.html +8 -0
- data/test/site_dir/_trash/1361224983-autopublish-draft +5 -0
- data/test/site_dir/_trash/{1361047797-test-draft → 1361224983-test-draft} +1 -1
- data/test/site_dir/test-smarty-filter.html +3 -0
- data/test/site_generation_spec.rb +5 -0
- metadata +24 -6
- data/test/site_dir/_trash/1361047797-autopublish-draft +0 -5
data/Gemfile.lock
CHANGED
@@ -10,6 +10,7 @@ PATH
|
|
10
10
|
redhead (~> 0.0.8)
|
11
11
|
sinatra (~> 1.3)
|
12
12
|
slop (~> 3.3)
|
13
|
+
timeout_cache
|
13
14
|
|
14
15
|
GEM
|
15
16
|
remote: http://rubygems.org/
|
@@ -47,6 +48,7 @@ GEM
|
|
47
48
|
slop (3.4.3)
|
48
49
|
tilt (1.3.3)
|
49
50
|
timecop (0.5.9.2)
|
51
|
+
timeout_cache (0.0.2)
|
50
52
|
yajl-ruby (1.1.0)
|
51
53
|
|
52
54
|
PLATFORMS
|
data/README.md
CHANGED
@@ -6,7 +6,16 @@ Serif is a file-based blogging engine intended for simple sites. It compiles Mar
|
|
6
6
|
|
7
7
|
# Changes and what's new
|
8
8
|
|
9
|
-
## Latest release
|
9
|
+
## Latest release (v0.3)
|
10
|
+
|
11
|
+
* Add some caching to improve performance of post generation. (#29)
|
12
|
+
* Remove super-linear performance cost of file_digest, reducing site generation time by > 85% for 50+ posts. (#30 -- charts available in the issue)
|
13
|
+
* Make `site` available to both preview templates and archive templates. (c3e2f28)
|
14
|
+
* Intelligently add blank lines before the markdown image text strings. (#27)
|
15
|
+
* Add a `smarty` filter to do smarty processing without full Markdown. (#28)
|
16
|
+
* Fix broken URL renames for drafts in the admin interface. (#31)
|
17
|
+
|
18
|
+
## v0.2.3
|
10
19
|
|
11
20
|
* Support drag-and-drop image uploading in the admin interface, with customisable paths. (#18)
|
12
21
|
* Generate private preview files for drafts, and generate the site on every draft change. (#19, #24)
|
@@ -29,6 +38,7 @@ See `CHANGELOG` for more.
|
|
29
38
|
* [Customising the admin interface](#customising-the-admin-interface)
|
30
39
|
* [Custom tags](#custom-tags)
|
31
40
|
* [Template variables](#template-variables)
|
41
|
+
* [Developing Serif](#developing-serif)
|
32
42
|
|
33
43
|
# Intro
|
34
44
|
|
@@ -61,6 +71,8 @@ The quickest way to get changes contributed:
|
|
61
71
|
3. Check out a branch on the latest master for your change: `git checkout -b master new-feature` --- do not make changes on `master`! Make sure that anything added or changed has a test in the `test/` directory. Use the existing files as examples. All tests for new/changed behaviour should pass.
|
62
72
|
4. [Send a pull request on GitHub](https://help.github.com/articles/fork-a-repo), including a description of what you've changed. (Note: your contribution will be assumed to be under the same terms of the project by default.)
|
63
73
|
|
74
|
+
For more info on development, see the section at the bottom of this README.
|
75
|
+
|
64
76
|
# Basics
|
65
77
|
|
66
78
|
## First time use
|
@@ -218,7 +230,7 @@ admin:
|
|
218
230
|
username: username
|
219
231
|
password: password
|
220
232
|
permalink: /blog/:year/:month/:title
|
221
|
-
|
233
|
+
image_upload_path: /images/:timestamp_:name
|
222
234
|
```
|
223
235
|
|
224
236
|
If a permalink setting is not given in the configuration, the default is `/:title`. There are the following options available for permalinks:
|
@@ -232,7 +244,7 @@ Placeholder | Value
|
|
232
244
|
|
233
245
|
### Admin drag-and-drop upload path
|
234
246
|
|
235
|
-
The `
|
247
|
+
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:
|
236
248
|
|
237
249
|
Placeholder | Value
|
238
250
|
----------- |:-----
|
@@ -243,13 +255,13 @@ Placeholder | Value
|
|
243
255
|
`:name` | Original filename string of the image being uploaded
|
244
256
|
`:timestamp`| Unix timestamp, e.g., "1361057832685"
|
245
257
|
|
246
|
-
Any slashes in `
|
258
|
+
Any slashes in `image_upload_path` are converted to directories.
|
247
259
|
|
248
260
|
## Other files
|
249
261
|
|
250
262
|
Any other file in the directory's root will be copied over exactly as-is, with two caveats.
|
251
263
|
|
252
|
-
First, `images/` is used for the drag-and-drop file uploads from the admin interface. Files are named with `<
|
264
|
+
First, `images/` (by default) is used for the drag-and-drop file uploads from the admin interface. Files are named with `<timestamp>_ <name>.<extension>`. This is configurable, see the section on configuration.
|
253
265
|
|
254
266
|
Second, for any file ending in `.html` or `.xml`:
|
255
267
|
|
@@ -386,14 +398,54 @@ The admin interface is intended to be a minimal place to focus on writing conten
|
|
386
398
|
/* more customisation below */
|
387
399
|
```
|
388
400
|
|
389
|
-
# Custom tags
|
401
|
+
# Custom tags and filters
|
390
402
|
|
391
|
-
These tags can be used in templates. For example:
|
403
|
+
These tags can be used in templates, in addition to the [standard Liquid filters and tags](https://github.com/Shopify/liquid/wiki/Liquid-for-Designers). For example:
|
392
404
|
|
393
405
|
```
|
406
|
+
{{ post.title | smarty }}
|
407
|
+
|
408
|
+
{{ post.content | markdown }}
|
409
|
+
|
394
410
|
{% file_digest foo.css prefix:- %}
|
395
411
|
```
|
396
412
|
|
413
|
+
## List of filters
|
414
|
+
|
415
|
+
* `date` with `'now'`
|
416
|
+
|
417
|
+
This is a standard filter, but there is a [workaround](https://github.com/Shopify/liquid/pull/117) for
|
418
|
+
`{{ 'now' | date: "%Y" }}` to work, so you can use this in templates.
|
419
|
+
|
420
|
+
* `markdown`
|
421
|
+
|
422
|
+
e.g., `{{ post.content | markdown }}`.
|
423
|
+
|
424
|
+
This runs the given input through a Markdown + SmartyPants renderer, with fenced codeblocks enabled.
|
425
|
+
|
426
|
+
* `strip`
|
427
|
+
|
428
|
+
Strips trailing and leading whitespace.
|
429
|
+
|
430
|
+
e.g., `{{ " hello " | strip }}` will render as `hello`.
|
431
|
+
|
432
|
+
* `xmlschema`
|
433
|
+
|
434
|
+
e.g., `{{ post.created | xmlschema }}`.
|
435
|
+
|
436
|
+
Takes a Time value and returns an ISO8601-format string, as per Ruby's `Time#xmlschema` definition.
|
437
|
+
|
438
|
+
Example output: 2013-02-16T23:55:22+01:00
|
439
|
+
|
440
|
+
If the time value is in UTC: 2013-02-16T22:55:22Z
|
441
|
+
|
442
|
+
* `encode_uri_component`
|
443
|
+
|
444
|
+
e.g., `example.com/foo?url=http://mysite.com{{ post.url | encode_uri_component }}`
|
445
|
+
|
446
|
+
Intended to provide the functionality of JavaScript's `encode_uri_component()` function. Essentially:
|
447
|
+
encodes the entire input so it is usable as a query string parameter.
|
448
|
+
|
397
449
|
## List of tags
|
398
450
|
|
399
451
|
* `file_digest <path> [prefix:<prefix>]`
|
@@ -415,3 +467,16 @@ These are available on individual post pages, in `_template/post.html`.
|
|
415
467
|
* `{{ post }}` --- the post being processed. Allows access to variables like `post.url`, `post.title`, `post.slug`, `post.created` and `post.content`.
|
416
468
|
* `{{ prev_post }}` --- the post published chronologically before `post`.
|
417
469
|
* `{{ next_post }}` --- the post published chronologically after `post`.
|
470
|
+
|
471
|
+
# Developing Serif
|
472
|
+
|
473
|
+
## Broad outline
|
474
|
+
|
475
|
+
* `./bin/serif {dev,admin,generate}` to run Serif commands.
|
476
|
+
* `rake test` to run the tests.
|
477
|
+
* Unit tests are written in RSpec.
|
478
|
+
|
479
|
+
## Directory structure
|
480
|
+
|
481
|
+
* `lib/serif/` is generally where files go.
|
482
|
+
* `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`.
|
data/lib/serif/admin_server.rb
CHANGED
@@ -87,7 +87,7 @@ class AdminServer
|
|
87
87
|
# not the new one that was attempted to be saved.
|
88
88
|
content = Draft.from_slug(site, params[:original_slug])
|
89
89
|
else
|
90
|
-
Draft.rename(params[:original_slug], params[:slug])
|
90
|
+
Draft.rename(site, params[:original_slug], params[:slug])
|
91
91
|
|
92
92
|
# re-load after the rename
|
93
93
|
content = Draft.from_slug(site, params[:slug])
|
data/lib/serif/config.rb
CHANGED
data/lib/serif/content_file.rb
CHANGED
@@ -49,6 +49,8 @@ class ContentFile
|
|
49
49
|
else
|
50
50
|
@source.headers[:title] = new_title
|
51
51
|
end
|
52
|
+
|
53
|
+
@cached_headers = nil
|
52
54
|
end
|
53
55
|
|
54
56
|
def draft?
|
@@ -82,7 +84,9 @@ class ContentFile
|
|
82
84
|
end
|
83
85
|
|
84
86
|
def headers
|
85
|
-
return
|
87
|
+
return @cached_headers if @cached_headers
|
88
|
+
|
89
|
+
return (@cached_headers = {}) unless @source
|
86
90
|
|
87
91
|
headers = @source.headers
|
88
92
|
converted_headers = {}
|
@@ -97,7 +101,7 @@ class ContentFile
|
|
97
101
|
converted_headers[key] = value
|
98
102
|
end
|
99
103
|
|
100
|
-
converted_headers
|
104
|
+
@cached_headers = converted_headers
|
101
105
|
end
|
102
106
|
|
103
107
|
def save(markdown = nil)
|
@@ -131,10 +135,12 @@ class ContentFile
|
|
131
135
|
|
132
136
|
def set_publish_time(time)
|
133
137
|
@source.headers[:created] = time.xmlschema
|
138
|
+
@cached_headers = nil
|
134
139
|
end
|
135
140
|
|
136
141
|
def set_updated_time(time)
|
137
142
|
@source.headers[:updated] = time.xmlschema
|
143
|
+
@cached_headers = nil
|
138
144
|
end
|
139
145
|
|
140
146
|
private
|
@@ -143,6 +149,7 @@ class ContentFile
|
|
143
149
|
source = File.read(path).gsub(/\r?\n/, "\n")
|
144
150
|
source.force_encoding("UTF-8")
|
145
151
|
@source = Redhead::String[source]
|
152
|
+
@cached_headers = nil
|
146
153
|
end
|
147
154
|
end
|
148
155
|
end
|
data/lib/serif/draft.rb
CHANGED
@@ -6,6 +6,11 @@ class Draft < ContentFile
|
|
6
6
|
"_drafts"
|
7
7
|
end
|
8
8
|
|
9
|
+
def self.rename(site, original_slug, new_slug)
|
10
|
+
raise if File.exist?("#{site.directory}/#{dirname}/#{new_slug}")
|
11
|
+
File.rename("#{site.directory}/#{dirname}/#{original_slug}", "#{site.directory}/#{dirname}/#{new_slug}")
|
12
|
+
end
|
13
|
+
|
9
14
|
def delete!
|
10
15
|
FileUtils.mkdir_p("#{site.directory}/_trash")
|
11
16
|
File.rename(@path, File.expand_path("#{site.directory}/_trash/#{Time.now.to_i}-#{slug}"))
|
data/lib/serif/site.rb
CHANGED
@@ -30,6 +30,11 @@ module Filters
|
|
30
30
|
CGI.escape(string)
|
31
31
|
end
|
32
32
|
|
33
|
+
def smarty(text)
|
34
|
+
text.gsub!('`', '\\\\`')
|
35
|
+
Redcarpet::Render::SmartyPants.render(text)
|
36
|
+
end
|
37
|
+
|
33
38
|
def markdown(body)
|
34
39
|
Redcarpet::Markdown.new(Serif::MarkupRenderer, fenced_code_blocks: true).render(body).strip
|
35
40
|
end
|
@@ -105,7 +110,7 @@ class Site
|
|
105
110
|
end
|
106
111
|
|
107
112
|
def config
|
108
|
-
Serif::Config.new(File.join(@source_directory, "_config.yml"))
|
113
|
+
@config ||= Serif::Config.new(File.join(@source_directory, "_config.yml"))
|
109
114
|
end
|
110
115
|
|
111
116
|
def site_path(path)
|
@@ -221,7 +226,12 @@ class Site
|
|
221
226
|
end
|
222
227
|
|
223
228
|
def to_liquid
|
224
|
-
|
229
|
+
@liquid_cache_store ||= TimeoutCache.new
|
230
|
+
|
231
|
+
cached_value = @liquid_cache_store[:liquid]
|
232
|
+
return cached_value if cached_value
|
233
|
+
|
234
|
+
@liquid_cache_store[:liquid] = {
|
225
235
|
"posts" => posts,
|
226
236
|
"latest_update_time" => latest_update_time,
|
227
237
|
"archive" => self.class.stringify_keys(archives),
|
@@ -273,8 +283,12 @@ class Site
|
|
273
283
|
if layout_option == "none"
|
274
284
|
f.puts Liquid::Template.parse(file.to_s).render!("site" => self)
|
275
285
|
else
|
276
|
-
|
277
|
-
|
286
|
+
if layout_option == :default
|
287
|
+
layout = default_layout
|
288
|
+
else
|
289
|
+
layout_file = File.join(self.directory, "_layouts", "#{layout_option}.html")
|
290
|
+
layout = Liquid::Template.parse(File.read(layout_file))
|
291
|
+
end
|
278
292
|
f.puts layout.render!("site" => self, "page" => { "title" => [title].compact }, "content" => Liquid::Template.parse(file.to_s).render!("site" => self))
|
279
293
|
end
|
280
294
|
end
|
@@ -356,6 +370,7 @@ class Site
|
|
356
370
|
|
357
371
|
File.open(live_preview_file + ".html", "w") do |f|
|
358
372
|
f.puts layout.render!(
|
373
|
+
"site" => self,
|
359
374
|
"draft_preview" => true,
|
360
375
|
"page" => { "title" => [ "Draft Preview", draft.title ] },
|
361
376
|
"content" => template.render!("site" => self, "post" => draft)
|
@@ -391,7 +406,7 @@ class Site
|
|
391
406
|
FileUtils.mkdir_p(archive_path)
|
392
407
|
|
393
408
|
File.open(File.join(archive_path, "index.html"), "w") do |f|
|
394
|
-
f.puts layout.render!("content" => template.render!("site" => self, "month" => month, "posts" => posts))
|
409
|
+
f.puts layout.render!("site" => self, "content" => template.render!("site" => self, "month" => month, "posts" => posts))
|
395
410
|
end
|
396
411
|
end
|
397
412
|
end
|
data/lib/serif.rb
CHANGED
data/rakefile
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require "rake"
|
2
|
+
require "time"
|
2
3
|
require "rspec/core/rake_task"
|
4
|
+
require "benchmark"
|
3
5
|
|
4
6
|
RSpec::Core::RakeTask.new(:test) do |t|
|
5
7
|
t.rspec_opts = "-I test --color --format nested"
|
@@ -9,3 +11,29 @@ RSpec::Core::RakeTask.new(:test) do |t|
|
|
9
11
|
end
|
10
12
|
|
11
13
|
task :default => :test
|
14
|
+
|
15
|
+
task :stress, [:n] do |t, args|
|
16
|
+
iterations = args[:n] || 250
|
17
|
+
iterations = iterations.to_i
|
18
|
+
|
19
|
+
d = Dir.pwd
|
20
|
+
cd "/tmp"
|
21
|
+
rm_rf ".test-site"
|
22
|
+
mkdir ".test-site"
|
23
|
+
cd ".test-site"
|
24
|
+
`#{d}/bin/serif new`
|
25
|
+
|
26
|
+
File.open("_layouts/default.html", "a") { |f| f.puts "\n\ndigest: {% file_digest style.css prefix:- %}" }
|
27
|
+
File.open("style.css", "w") { |f| f.puts("body {}") }
|
28
|
+
|
29
|
+
iterations.times do |n|
|
30
|
+
File.open("_posts/#{Date.today + n}-sample-post-#{n}", "w") do |f|
|
31
|
+
f.puts %Q{title: sample-post
|
32
|
+
created: #{(Time.now + 60*n).xmlschema}
|
33
|
+
|
34
|
+
Dummy content #{n}}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
puts Benchmark.realtime { system({ "ENV" => ENV["ENV"] }, "#{d}/bin/serif generate") }
|
39
|
+
end
|
data/serif.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "serif"
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.3"
|
4
4
|
s.authors = ["Adam Prescott"]
|
5
5
|
s.email = ["adam@aprescott.com"]
|
6
6
|
s.homepage = "https://github.com/aprescott/serif"
|
@@ -20,7 +20,8 @@ Gem::Specification.new do |s|
|
|
20
20
|
"sinatra", "~> 1.3",
|
21
21
|
"redhead", "~> 0.0.8",
|
22
22
|
"liquid", "~> 2.4",
|
23
|
-
"slop", "~> 3.3"
|
23
|
+
"slop", "~> 3.3",
|
24
|
+
"timeout_cache"
|
24
25
|
].each_slice(2) do |name, version|
|
25
26
|
s.add_runtime_dependency(name, version)
|
26
27
|
end
|
@@ -67,6 +67,39 @@ var createAttachment = function(file, element) {
|
|
67
67
|
});
|
68
68
|
|
69
69
|
var absText = '![' + file.name + '](' + finalName + ')';
|
70
|
+
|
71
|
+
// for some reason this is necessary to avoid the following
|
72
|
+
// giving an undefined result:
|
73
|
+
//
|
74
|
+
// 1. load a new draft page with an empty textarea
|
75
|
+
// 2. at this point element.value is undefined.
|
76
|
+
// 3. drag an image, calling insertAtCaret
|
77
|
+
// 4. element.value (3) in this method is still undefined (confusing!)
|
78
|
+
// 5. in the browser console, $("[data-attachify]").get(0).value
|
79
|
+
// is correct. (confusing!)
|
80
|
+
// 6. on a _second drag_, element.value is undefined (very confusing)
|
81
|
+
// 7. in the same second drag event, $(element).get(0).value is
|
82
|
+
// correct, hence this "reloading" to allow element.value
|
83
|
+
// below to not be undefined.
|
84
|
+
element = $(element).get(0);
|
85
|
+
|
86
|
+
if (typeof element.value != "undefined") {
|
87
|
+
var pos = element.selectionStart;
|
88
|
+
var text = element.value;
|
89
|
+
var before = text.slice(0, pos);
|
90
|
+
var after = text.slice(pos);
|
91
|
+
|
92
|
+
// if there is only a single newline, add one more for a blank
|
93
|
+
// line.
|
94
|
+
if (/[^\n]\n$/.test(before)) {
|
95
|
+
absText = "\n" + absText;
|
96
|
+
// if there aren't two new lines, add a full two
|
97
|
+
} else if (! /\n\n$/.test(before)) {
|
98
|
+
absText = "\n\n" + absText;
|
99
|
+
}
|
100
|
+
|
101
|
+
}
|
102
|
+
|
70
103
|
$(element).insertAtCaret(absText);
|
71
104
|
};
|
72
105
|
|
data/test/draft_spec.rb
CHANGED
@@ -7,6 +7,39 @@ describe Serif::Draft do
|
|
7
7
|
FileUtils.rm_rf(testing_dir("_trash"))
|
8
8
|
end
|
9
9
|
|
10
|
+
describe ".rename" do
|
11
|
+
it "moves the draft to a new file" do
|
12
|
+
draft = D.new(@site)
|
13
|
+
draft.slug = "test-draft"
|
14
|
+
draft.title = "Some draft title"
|
15
|
+
draft.save("some content")
|
16
|
+
|
17
|
+
D.rename(@site, "test-draft", "foo-bar")
|
18
|
+
d = D.from_slug(@site, "foo-bar")
|
19
|
+
d.should_not be_nil
|
20
|
+
File.exist?(testing_dir("_drafts/foo-bar")).should be_true
|
21
|
+
|
22
|
+
d.delete!
|
23
|
+
end
|
24
|
+
|
25
|
+
it "raises if there is an existing draft" do
|
26
|
+
draft = D.new(@site)
|
27
|
+
draft.slug = "test-draft"
|
28
|
+
draft.title = "Some draft title"
|
29
|
+
draft.save("some content")
|
30
|
+
|
31
|
+
draft2 = D.new(@site)
|
32
|
+
draft2.slug = "test-draft-2"
|
33
|
+
draft2.title = "Some draft title"
|
34
|
+
draft2.save("some content")
|
35
|
+
|
36
|
+
expect { D.rename(@site, draft2.slug, draft.slug) }.to raise_error
|
37
|
+
|
38
|
+
draft.delete!
|
39
|
+
draft2.delete!
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
10
43
|
describe "#delete!" do
|
11
44
|
it "moves the file to _trash" do
|
12
45
|
draft = D.new(@site)
|
data/test/filters_spec.rb
CHANGED
@@ -18,6 +18,23 @@ describe Serif::Filters do
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
+
describe "#smarty" do
|
22
|
+
it "runs the input through a SmartyPants processor" do
|
23
|
+
subject.smarty("Testing").should == "Testing"
|
24
|
+
subject.smarty("Testing's").should == "Testing’s"
|
25
|
+
subject.smarty("\"Testing\" some \"text's\" input...").should == "“Testing” some “text’s” input…"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "does not do any markdown processing" do
|
29
|
+
subject.smarty("# Heading").should == "# Heading"
|
30
|
+
subject.smarty("Testing `code blocks` input").should == "Testing `code blocks` input"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "deals with HTML appropriately" do
|
34
|
+
subject.smarty("<p>Testing's <span>span</span> testing</p>").should == "<p>Testing’s <span>span</span> testing</p>"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
21
38
|
describe "#encode_uri_component" do
|
22
39
|
it "percent-encodes various characters for use in a URI" do
|
23
40
|
{
|
File without changes
|
File without changes
|
@@ -9,10 +9,10 @@
|
|
9
9
|
|
10
10
|
<ul>
|
11
11
|
|
12
|
-
<li><a href="/test-blog/second-post">Second post</a> (posted 2013-01-01T00:00:
|
12
|
+
<li><a href="/test-blog/second-post">Second post</a> (posted 2013-01-01T00:00:00Z)</li>
|
13
13
|
|
14
|
-
<li><a href="/test-blog/post-to-be-published-on-generate">Some draft title</a> (posted 2012-12-21T15:30:
|
14
|
+
<li><a href="/test-blog/post-to-be-published-on-generate">Some draft title</a> (posted 2012-12-21T15:30:00Z)</li>
|
15
15
|
|
16
|
-
<li><a href="/test-blog/sample-post">Sample post</a> (posted 2012-11-21T17:07:
|
16
|
+
<li><a href="/test-blog/sample-post">Sample post</a> (posted 2012-11-21T17:07:09Z)</li>
|
17
17
|
|
18
18
|
</ul>
|
@@ -23,6 +23,11 @@ describe Serif::Site do
|
|
23
23
|
File.read("_site/page-alt-layout.html").lines.first.should =~ /<h1.+?>Alternate layout<\/h1>/
|
24
24
|
end
|
25
25
|
|
26
|
+
it "supports a smarty filter" do
|
27
|
+
subject.generate
|
28
|
+
File.read("_site/test-smarty-filter.html").should =~ /testing’s for a “heading’s” `with code` in it…/
|
29
|
+
end
|
30
|
+
|
26
31
|
it "correctly handles file_digest calls" do
|
27
32
|
subject.generate
|
28
33
|
|
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.
|
4
|
+
version: '0.3'
|
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: 2013-02-
|
12
|
+
date: 2013-02-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -139,6 +139,22 @@ dependencies:
|
|
139
139
|
- - ~>
|
140
140
|
- !ruby/object:Gem::Version
|
141
141
|
version: '3.3'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: timeout_cache
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :runtime
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
142
158
|
- !ruby/object:Gem::Dependency
|
143
159
|
name: rake
|
144
160
|
requirement: !ruby/object:Gem::Requirement
|
@@ -261,8 +277,8 @@ files:
|
|
261
277
|
- test/site_dir/_site/test-archive/2013/01/index.html
|
262
278
|
- test/site_dir/_site/test-archive/2012/12/index.html
|
263
279
|
- test/site_dir/_site/test-archive/2012/11/index.html
|
264
|
-
- test/site_dir/_site/drafts/another-sample-draft/
|
265
|
-
- test/site_dir/_site/drafts/sample-draft/
|
280
|
+
- test/site_dir/_site/drafts/another-sample-draft/f340ff2dd6aa78f819d547ee908fe7410e6153559b47265dcbc58598bb4a.html
|
281
|
+
- test/site_dir/_site/drafts/sample-draft/ed883ce827f757888e2900ce0e155a960cb45f832fcc24791c054013b71c.html
|
266
282
|
- test/site_dir/_site/index.html
|
267
283
|
- test/site_dir/_site/file-digest-test.html
|
268
284
|
- test/site_dir/_site/page-alt-layout.html
|
@@ -271,11 +287,13 @@ files:
|
|
271
287
|
- test/site_dir/_site/test-blog/post-to-be-published-on-generate.html
|
272
288
|
- test/site_dir/_site/test-blog/second-post.html
|
273
289
|
- test/site_dir/_site/test-blog/sample-post.html
|
290
|
+
- test/site_dir/_site/test-smarty-filter.html
|
274
291
|
- test/site_dir/_site/archive.html
|
275
|
-
- test/site_dir/_trash/
|
276
|
-
- test/site_dir/_trash/
|
292
|
+
- test/site_dir/_trash/1361224983-test-draft
|
293
|
+
- test/site_dir/_trash/1361224983-autopublish-draft
|
277
294
|
- test/site_dir/_posts/2012-01-05-sample-post
|
278
295
|
- test/site_dir/_posts/2013-01-01-second-post
|
296
|
+
- test/site_dir/test-smarty-filter.html
|
279
297
|
- test/site_dir/_layouts/alt-layout.html
|
280
298
|
- test/site_dir/_layouts/default.html
|
281
299
|
- test/site_dir/archive.html
|