middleman-blog 4.0.0 → 4.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/features/summary.feature +30 -4
- data/fixtures/paginate-app/source/_pager.erb +15 -0
- data/fixtures/paginate-app/source/partial-paging.html.erb +5 -0
- data/lib/middleman-blog.rb +1 -0
- data/lib/middleman-blog/blog_article.rb +15 -13
- data/lib/middleman-blog/blog_data.rb +19 -4
- data/lib/middleman-blog/commands/article.rb +78 -0
- data/lib/middleman-blog/commands/article.tt +6 -0
- data/lib/middleman-blog/extension.rb +1 -0
- data/lib/middleman-blog/truncate_html.rb +12 -1
- data/lib/middleman-blog/uri_templates.rb +1 -1
- data/lib/middleman-blog/version.rb +1 -1
- data/middleman-blog.gemspec +1 -1
- metadata +10 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6437136847c6ca3dfc732f0585d154969a140967
|
4
|
+
data.tar.gz: 7d6a917c2f463b52a95a6b1e5c5fc73ff4e0b120
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6b27cbe706b043afb84067b974bdf574bf70e006abb0c111b006c12e9a489f114255456a2152a13d68ae816b3abd9eb02c77c4efc16b5833fcc902ca45106180
|
7
|
+
data.tar.gz: 2b26df677ed97f8806102ae623b7d193820e44175b64d7a1d5bbda4b9c48897ddbf39f6f823ba66f1a6020659304010d788978dd7f668a0ece97a6e77faaecba
|
data/features/summary.feature
CHANGED
@@ -2,9 +2,9 @@ Feature: Article summary generation
|
|
2
2
|
Scenario: Article has no summary separator
|
3
3
|
Given the Server is running at "summary-app"
|
4
4
|
When I go to "/index.html"
|
5
|
-
Then I should see "Summary from article with separator
|
5
|
+
Then I should see "<p>Summary from article with separator.</p>"
|
6
6
|
Then I should not see "Extended part from article with separator."
|
7
|
-
Then I should see "Summary from article with no separator
|
7
|
+
Then I should see "<p>Summary from article with no separator.</p>"
|
8
8
|
Then I should not see "Extended part from article with no separator."
|
9
9
|
|
10
10
|
Scenario: Article has custom summary separator
|
@@ -17,7 +17,11 @@ Feature: Article summary generation
|
|
17
17
|
"""
|
18
18
|
Given the Server is running at "summary-app"
|
19
19
|
When I go to "/index.html"
|
20
|
-
Then I should see
|
20
|
+
Then I should see:
|
21
|
+
"""
|
22
|
+
<p>Summary from article with custom separator.
|
23
|
+
</p>
|
24
|
+
"""
|
21
25
|
Then I should not see "Extended part from article with custom separator."
|
22
26
|
Then I should see "Extended part from article with separator."
|
23
27
|
|
@@ -32,7 +36,7 @@ Feature: Article summary generation
|
|
32
36
|
Given the Server is running at "summary-app"
|
33
37
|
When I go to "/index.html"
|
34
38
|
Then I should see "This is my summary, and I like it"
|
35
|
-
Then I should see "Summary from article"
|
39
|
+
Then I should not see "Summary from article"
|
36
40
|
Then I should not see "Summary from article with no separator"
|
37
41
|
Then I should not see "Extended part from article"
|
38
42
|
|
@@ -54,3 +58,25 @@ Feature: Article summary generation
|
|
54
58
|
When I go to "/index.html"
|
55
59
|
Then I should see "Extended part from article with no separator."
|
56
60
|
Then I should not see "Extended part from article with separator."
|
61
|
+
|
62
|
+
Scenario: Summary limited by length only
|
63
|
+
Given a fixture app "summary-app"
|
64
|
+
And a file named "config.rb" with:
|
65
|
+
"""
|
66
|
+
activate :blog
|
67
|
+
"""
|
68
|
+
And a file named "source/index.html.erb" with:
|
69
|
+
"""
|
70
|
+
<% @i = 0 %>
|
71
|
+
<% blog.articles.each do |article| %>
|
72
|
+
<article>
|
73
|
+
<%= article.summary(7, (@i += 1).to_s) %>
|
74
|
+
</article>
|
75
|
+
<% end %>
|
76
|
+
"""
|
77
|
+
Given the Server is running at "summary-app"
|
78
|
+
When I go to "/index.html"
|
79
|
+
Then I should see "Summary1"
|
80
|
+
Then I should see "Summary2"
|
81
|
+
Then I should see "Summary3"
|
82
|
+
Then I should see "Summary4"
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Paginate: <%= paginate %>
|
2
|
+
Article Count: <%= page_articles.size %>
|
3
|
+
<% if paginate %>
|
4
|
+
Page Num: <%= page_number %>
|
5
|
+
Num Pages: <%= num_pages %>
|
6
|
+
Per Page: <%= per_page %>
|
7
|
+
Page Start: <%= page_start %>
|
8
|
+
Page End: <%= page_end %>
|
9
|
+
Next Page: '<%= next_page.url if next_page %>'
|
10
|
+
Prev Page: '<%= prev_page.url if prev_page %>'
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<% page_articles.each do |article| %>
|
14
|
+
<li><a href="<%= article.url %>"><%= article.title %></a> <time><%= article.date.strftime('%b %e') %></time></li>
|
15
|
+
<% end %>
|
data/lib/middleman-blog.rb
CHANGED
@@ -73,26 +73,24 @@ module Middleman
|
|
73
73
|
render layout: false
|
74
74
|
end
|
75
75
|
|
76
|
-
# The summary for this article, in HTML.
|
77
|
-
# everything before the summary separator (set via the blog option
|
78
|
-
# +summary_separator+ and defaulting to "READMORE") or the first
|
79
|
-
# +summary_length+ characters of the post.
|
76
|
+
# The summary for this article, in HTML.
|
80
77
|
#
|
81
78
|
# The blog option +summary_generator+ can be set to a +Proc+ in order to provide
|
82
79
|
# custom summary generation. The +Proc+ is provided
|
83
80
|
# the rendered content of the article (without layout), the
|
84
81
|
# desired length to trim the summary to, and the ellipsis string to use.
|
85
|
-
# Otherwise the {#default_summary_generator} will be used
|
82
|
+
# Otherwise the {#default_summary_generator} will be used, which returns either
|
83
|
+
# everything before the summary separator (set via the blog option
|
84
|
+
# +summary_separator+ and defaulting to "READMORE") if it is found,
|
85
|
+
# or the first +summary_length+ characters of the post.
|
86
86
|
#
|
87
87
|
# @param [Number] length How many characters to trim the summary to.
|
88
88
|
# @param [String] ellipsis The ellipsis string to use when content is trimmed.
|
89
89
|
# @return [String]
|
90
|
-
def summary(length=
|
90
|
+
def summary(length=nil, ellipsis='...')
|
91
91
|
rendered = render layout: false, keep_separator: true
|
92
92
|
|
93
|
-
if blog_options.
|
94
|
-
rendered.split(blog_options.summary_separator).first
|
95
|
-
elsif blog_options.summary_generator
|
93
|
+
if blog_options.summary_generator
|
96
94
|
blog_options.summary_generator.call(self, rendered, length, ellipsis)
|
97
95
|
else
|
98
96
|
default_summary_generator(rendered, length, ellipsis)
|
@@ -107,11 +105,15 @@ module Middleman
|
|
107
105
|
# @param [Integer] length The length in characters to truncate to.
|
108
106
|
# -1 or +nil+ will return the whole article.
|
109
107
|
def default_summary_generator(rendered, length, ellipsis)
|
110
|
-
if
|
111
|
-
|
112
|
-
|
108
|
+
if length && length >= 0
|
109
|
+
require 'middleman-blog/truncate_html'
|
110
|
+
TruncateHTML.truncate_at_length(rendered, length, ellipsis)
|
111
|
+
elsif blog_options.summary_separator && rendered.match(blog_options.summary_separator)
|
112
|
+
require 'middleman-blog/truncate_html'
|
113
|
+
TruncateHTML.truncate_at_separator(rendered, blog_options.summary_separator)
|
114
|
+
elsif blog_options.summary_length && blog_options.summary_length > 0
|
113
115
|
require 'middleman-blog/truncate_html'
|
114
|
-
TruncateHTML.
|
116
|
+
TruncateHTML.truncate_at_length(rendered, blog_options.summary_length, ellipsis)
|
115
117
|
else
|
116
118
|
rendered
|
117
119
|
end
|
@@ -8,6 +8,8 @@ module Middleman
|
|
8
8
|
class BlogData
|
9
9
|
include UriTemplates
|
10
10
|
|
11
|
+
DEFAULT_FILTER = proc {|a| a}
|
12
|
+
|
11
13
|
# A URITemplate for the source file path relative to :source_dir
|
12
14
|
# @return [URITemplate]
|
13
15
|
attr_reader :source_template
|
@@ -27,6 +29,11 @@ module Middleman
|
|
27
29
|
# A list of resources corresponding to blog articles
|
28
30
|
@_articles = []
|
29
31
|
|
32
|
+
@_parsed_url_cache = {
|
33
|
+
source: {},
|
34
|
+
subdir: {}
|
35
|
+
}
|
36
|
+
|
30
37
|
@source_template = uri_template options.sources
|
31
38
|
@permalink_template = uri_template options.permalink
|
32
39
|
@subdir_template = uri_template options.sources.sub(/\.[^.]+$/, "/{+path}")
|
@@ -36,7 +43,7 @@ module Middleman
|
|
36
43
|
# A list of all blog articles, sorted by descending date
|
37
44
|
# @return [Array<Middleman::Sitemap::Resource>]
|
38
45
|
def articles
|
39
|
-
@_articles.sort_by(&:date).reverse
|
46
|
+
@_articles.select(&(options.filter || DEFAULT_FILTER)).sort_by(&:date).reverse
|
40
47
|
end
|
41
48
|
|
42
49
|
# A list of all blog articles with the given language,
|
@@ -70,6 +77,14 @@ module Middleman
|
|
70
77
|
tags
|
71
78
|
end
|
72
79
|
|
80
|
+
def extract_source_params(path)
|
81
|
+
@_parsed_url_cache[:source][path] ||= extract_params(@source_template, path)
|
82
|
+
end
|
83
|
+
|
84
|
+
def extract_subdir_params(path)
|
85
|
+
@_parsed_url_cache[:subdir][path] ||= extract_params(@subdir_template, path)
|
86
|
+
end
|
87
|
+
|
73
88
|
# Updates' blog articles destination paths to be the
|
74
89
|
# permalink.
|
75
90
|
# @return [void]
|
@@ -84,7 +99,7 @@ module Middleman
|
|
84
99
|
next
|
85
100
|
end
|
86
101
|
|
87
|
-
if (params =
|
102
|
+
if (params = extract_source_params(resource.path))
|
88
103
|
article = convert_to_article(resource)
|
89
104
|
next unless publishable?(article)
|
90
105
|
|
@@ -98,7 +113,7 @@ module Middleman
|
|
98
113
|
|
99
114
|
@_articles << article
|
100
115
|
|
101
|
-
elsif (params =
|
116
|
+
elsif (params = extract_subdir_params(resource.path))
|
102
117
|
# It's not an article, but it's thhe companion files for an article
|
103
118
|
# (in a subdirectory named after the article)
|
104
119
|
# figure out the matching article for this subdirectory file
|
@@ -167,7 +182,7 @@ module Middleman
|
|
167
182
|
resource.blog_controller = controller
|
168
183
|
|
169
184
|
if !options.preserve_locale && (locale = resource.locale || resource.lang)
|
170
|
-
resource.add_metadata options: { lang: locale,
|
185
|
+
resource.add_metadata options: { lang: locale, locale: locale }, locals: { lang: locale, locale: locale }
|
171
186
|
end
|
172
187
|
|
173
188
|
resource
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'middleman-core/cli'
|
2
|
+
require 'date'
|
3
|
+
require 'middleman-blog/uri_templates'
|
4
|
+
|
5
|
+
module Middleman
|
6
|
+
module Cli
|
7
|
+
# This class provides an "article" command for the middleman CLI.
|
8
|
+
class Article < ::Thor::Group
|
9
|
+
include Thor::Actions
|
10
|
+
include Blog::UriTemplates
|
11
|
+
|
12
|
+
check_unknown_options!
|
13
|
+
|
14
|
+
# Template files are relative to this file
|
15
|
+
# @return [String]
|
16
|
+
def self.source_root
|
17
|
+
File.dirname(__FILE__)
|
18
|
+
end
|
19
|
+
|
20
|
+
argument :title, type: :string
|
21
|
+
|
22
|
+
class_option "date",
|
23
|
+
aliases: "-d",
|
24
|
+
desc: "The date to create the post with (defaults to now)"
|
25
|
+
class_option "lang",
|
26
|
+
desc: "Deprecated, use locale"
|
27
|
+
class_option "locale",
|
28
|
+
aliases: "-l",
|
29
|
+
desc: "The locale to create the post with (defaults to I18n.default_locale if avaliable)"
|
30
|
+
class_option "blog",
|
31
|
+
aliases: "-b",
|
32
|
+
desc: "The name of the blog to create the post inside (for multi-blog apps, defaults to the only blog in single-blog apps)"
|
33
|
+
def article
|
34
|
+
config = ::Middleman::Cli.config
|
35
|
+
|
36
|
+
@title = title
|
37
|
+
@slug = safe_parameterize(title)
|
38
|
+
@date = options[:date] ? ::Time.zone.parse(options[:date]) : Time.zone.now
|
39
|
+
@lang = options[:lang] || options[:locale] || (::I18n.default_locale if defined? ::I18n )
|
40
|
+
|
41
|
+
app = ::Middleman::Application.new do
|
42
|
+
config[:mode] = :config
|
43
|
+
config[:disable_sitemap] = true
|
44
|
+
config[:watcher_disable] = true
|
45
|
+
config[:exit_before_ready] = true
|
46
|
+
end
|
47
|
+
|
48
|
+
blog_inst = if options[:blog]
|
49
|
+
app.extensions[:blog][options[:blog]]
|
50
|
+
else
|
51
|
+
app.extensions[:blog].values.first
|
52
|
+
end
|
53
|
+
|
54
|
+
unless blog_inst
|
55
|
+
msg = "Could not find an active blog instance"
|
56
|
+
msg << " named #{options[:blog]}" if options[:blog]
|
57
|
+
throw msg
|
58
|
+
end
|
59
|
+
|
60
|
+
path_template = blog_inst.data.source_template
|
61
|
+
params = date_to_params(@date).merge(lang: @lang.to_s, locale: @locale.to_s, title: @slug)
|
62
|
+
article_path = apply_uri_template path_template, params
|
63
|
+
|
64
|
+
template blog_inst.options.new_article_template, File.join(app.source_dir, article_path + blog_inst.options.default_extension)
|
65
|
+
end
|
66
|
+
|
67
|
+
protected
|
68
|
+
|
69
|
+
def blog_instance(key)
|
70
|
+
return nil unless app.extensions[:blog]
|
71
|
+
return app.extensions[:blog][key]
|
72
|
+
end
|
73
|
+
|
74
|
+
# Add to CLI
|
75
|
+
Base.register(self, 'article', 'article TITLE [options]', 'Create a new blog article')
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -34,6 +34,7 @@ module Middleman
|
|
34
34
|
option :generate_tag_pages, true, 'Whether to generate tag pages.'
|
35
35
|
option :paginate, false, 'Whether to paginate lists of articles'
|
36
36
|
option :per_page, 10, 'Number of articles per page when paginating'
|
37
|
+
option :filter, nil, 'A proc that can be used to select articles that should be published based on user-defined criteria'
|
37
38
|
option :page_link, 'page/{num}', 'Path to append for additional pages when paginating'
|
38
39
|
option :publish_future_dated, false, 'Whether articles with a date in the future should be considered published'
|
39
40
|
option :custom_collections, {}, 'Hash of custom frontmatter properties to collect articles on and their options (link, template)'
|
@@ -7,7 +7,18 @@ end
|
|
7
7
|
# Taken and modified from http://madebydna.com/all/code/2010/06/04/ruby-helper-to-cleanly-truncate-html.html
|
8
8
|
# MIT license
|
9
9
|
module TruncateHTML
|
10
|
-
def self.
|
10
|
+
def self.truncate_at_separator(text, separator)
|
11
|
+
text = text.encode('UTF-8') if text.respond_to?(:encode)
|
12
|
+
doc = Nokogiri::HTML::DocumentFragment.parse text
|
13
|
+
length = doc.inner_text =~ Regexp.new(separator)
|
14
|
+
if length
|
15
|
+
doc.truncate(length - 1, '').inner_html
|
16
|
+
else
|
17
|
+
text
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.truncate_at_length(text, max_length, ellipsis = "...")
|
11
22
|
ellipsis_length = ellipsis.length
|
12
23
|
text = text.encode('UTF-8') if text.respond_to?(:encode)
|
13
24
|
doc = Nokogiri::HTML::DocumentFragment.parse text
|
@@ -41,7 +41,7 @@ module Middleman
|
|
41
41
|
# @param [Addressable::Template] template
|
42
42
|
# @param [String] path
|
43
43
|
def extract_params(template, path)
|
44
|
-
|
44
|
+
template.extract(path, BlogTemplateProcessor)
|
45
45
|
end
|
46
46
|
|
47
47
|
# Parameterize a string preserving any multibyte characters
|
data/middleman-blog.gemspec
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: middleman-blog
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.0.
|
4
|
+
version: 4.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas Reynolds
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-04-12 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: middleman-core
|
@@ -45,14 +45,14 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 2.
|
48
|
+
version: '2.3'
|
49
49
|
type: :runtime
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 2.
|
55
|
+
version: '2.3'
|
56
56
|
description: Blog engine for Middleman
|
57
57
|
email:
|
58
58
|
- me@tdreyno.com
|
@@ -244,6 +244,7 @@ files:
|
|
244
244
|
- fixtures/paginate-app/config-directory-indexes.rb
|
245
245
|
- fixtures/paginate-app/config-paginate-off.rb
|
246
246
|
- fixtures/paginate-app/config.rb
|
247
|
+
- fixtures/paginate-app/source/_pager.erb
|
247
248
|
- fixtures/paginate-app/source/blog/2011-01-01-test-article.html.markdown
|
248
249
|
- fixtures/paginate-app/source/blog/2011-01-02-test-article.html.markdown
|
249
250
|
- fixtures/paginate-app/source/blog/2011-01-03-test-article.html.markdown
|
@@ -255,6 +256,7 @@ files:
|
|
255
256
|
- fixtures/paginate-app/source/category.html.erb
|
256
257
|
- fixtures/paginate-app/source/index.html.erb
|
257
258
|
- fixtures/paginate-app/source/layout.erb
|
259
|
+
- fixtures/paginate-app/source/partial-paging.html.erb
|
258
260
|
- fixtures/paginate-app/source/tag.html.erb
|
259
261
|
- fixtures/paginate-multiblog-app/config.rb
|
260
262
|
- fixtures/paginate-multiblog-app/source/blog1/2011-01-01-test-article.html.markdown
|
@@ -333,6 +335,8 @@ files:
|
|
333
335
|
- lib/middleman-blog/blog_article.rb
|
334
336
|
- lib/middleman-blog/blog_data.rb
|
335
337
|
- lib/middleman-blog/calendar_pages.rb
|
338
|
+
- lib/middleman-blog/commands/article.rb
|
339
|
+
- lib/middleman-blog/commands/article.tt
|
336
340
|
- lib/middleman-blog/custom_pages.rb
|
337
341
|
- lib/middleman-blog/extension.rb
|
338
342
|
- lib/middleman-blog/helpers.rb
|
@@ -543,6 +547,7 @@ test_files:
|
|
543
547
|
- fixtures/paginate-app/config-directory-indexes.rb
|
544
548
|
- fixtures/paginate-app/config-paginate-off.rb
|
545
549
|
- fixtures/paginate-app/config.rb
|
550
|
+
- fixtures/paginate-app/source/_pager.erb
|
546
551
|
- fixtures/paginate-app/source/blog/2011-01-01-test-article.html.markdown
|
547
552
|
- fixtures/paginate-app/source/blog/2011-01-02-test-article.html.markdown
|
548
553
|
- fixtures/paginate-app/source/blog/2011-01-03-test-article.html.markdown
|
@@ -554,6 +559,7 @@ test_files:
|
|
554
559
|
- fixtures/paginate-app/source/category.html.erb
|
555
560
|
- fixtures/paginate-app/source/index.html.erb
|
556
561
|
- fixtures/paginate-app/source/layout.erb
|
562
|
+
- fixtures/paginate-app/source/partial-paging.html.erb
|
557
563
|
- fixtures/paginate-app/source/tag.html.erb
|
558
564
|
- fixtures/paginate-multiblog-app/config.rb
|
559
565
|
- fixtures/paginate-multiblog-app/source/blog1/2011-01-01-test-article.html.markdown
|