middleman-blog 4.0.2 → 4.1.0
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.
- checksums.yaml +5 -5
- data/.github/workflows/ci.yml +25 -0
- data/.github/workflows/stale.yml +21 -0
- data/CHANGELOG.md +72 -60
- data/Gemfile +16 -26
- data/README.md +20 -36
- data/Rakefile +15 -19
- data/features/summary.feature +3 -6
- data/features/support/env.rb +9 -10
- data/features/support/time_steps.rb +13 -14
- data/features/tags.feature +5 -1
- data/fixtures/article-dirs-app/config-directory-indexes.rb +4 -2
- data/fixtures/article-dirs-app/config-permalink-with-dot.rb +4 -2
- data/fixtures/article-dirs-app/config.rb +4 -2
- data/fixtures/blog-sources-app/config.rb +3 -4
- data/fixtures/blog-sources-no-date-app/config.rb +3 -4
- data/fixtures/blog-sources-no-day-app/config.rb +3 -4
- data/fixtures/blog-sources-no-title-app/config.rb +2 -3
- data/fixtures/blog-sources-subdirs-app/config.rb +4 -5
- data/fixtures/calendar-and-tag-app/config-directory-indexes.rb +5 -3
- data/fixtures/calendar-and-tag-app/config.rb +6 -4
- data/fixtures/calendar-app/config-directory-indexes.rb +6 -6
- data/fixtures/calendar-app/config-only-year.rb +8 -8
- data/fixtures/calendar-app/config.rb +6 -6
- data/fixtures/calendar-multiblog-app/config.rb +14 -12
- data/fixtures/custom-article-template-app/config.rb +2 -0
- data/fixtures/custom-collections-app/config-blog-prefix.rb +9 -7
- data/fixtures/custom-collections-app/config-directory-indexes.rb +8 -6
- data/fixtures/custom-collections-app/config.rb +8 -6
- data/fixtures/custom-collections-multiblog-app/config.rb +16 -14
- data/fixtures/custom-collections-sources-app/config.rb +7 -5
- data/fixtures/custom-permalinks-app/config-directory-indexes.rb +5 -3
- data/fixtures/custom-permalinks-app/config.rb +5 -3
- data/fixtures/filename-date-app/config.rb +3 -1
- data/fixtures/future-date-app/config.rb +4 -2
- data/fixtures/indexes-app/config.rb +4 -2
- data/fixtures/lang-path-app/config.rb +4 -2
- data/fixtures/language-app/config.rb +3 -1
- data/fixtures/layouts-app/config.rb +3 -1
- data/fixtures/paginate-app/config-directory-indexes.rb +13 -13
- data/fixtures/paginate-app/config-paginate-off.rb +13 -13
- data/fixtures/paginate-app/config.rb +13 -13
- data/fixtures/paginate-multiblog-app/config.rb +15 -13
- data/fixtures/permalink-app/config.rb +4 -5
- data/fixtures/preview-app/config.rb +4 -2
- data/fixtures/published-app/config.rb +4 -2
- data/fixtures/summary-app/config.rb +2 -0
- data/fixtures/tags-app/config-directory-indexes.rb +7 -5
- data/fixtures/tags-app/config-filters.rb +2 -0
- data/fixtures/tags-app/config-no-tags.rb +2 -0
- data/fixtures/tags-app/config.rb +7 -5
- data/fixtures/tags-app/source/blog/2011-01-01-new-article.html.markdown +1 -1
- data/fixtures/tags-app/source/blog/2011-01-02-another-article.html.markdown +1 -0
- data/fixtures/tags-multiblog-app/config.rb +12 -10
- data/fixtures/time-zone-app/config.rb +2 -0
- data/lib/middleman-blog/blog_article.rb +20 -41
- data/lib/middleman-blog/blog_data.rb +22 -33
- data/lib/middleman-blog/calendar_pages.rb +16 -20
- data/lib/middleman-blog/commands/article.rb +54 -61
- data/lib/middleman-blog/commands/article.tt +2 -2
- data/lib/middleman-blog/custom_pages.rb +10 -9
- data/lib/middleman-blog/extension.rb +22 -19
- data/lib/middleman-blog/helpers.rb +18 -25
- data/lib/middleman-blog/paginator.rb +8 -5
- data/lib/middleman-blog/tag_pages.rb +13 -23
- data/lib/middleman-blog/truncate_html.rb +14 -11
- data/lib/middleman-blog/uri_templates.rb +37 -17
- data/lib/middleman-blog/version.rb +3 -3
- data/lib/middleman-blog.rb +7 -7
- data/lib/middleman_extension.rb +3 -1
- data/middleman-blog.gemspec +16 -23
- data/spec/spec_helper.rb +3 -4
- data/spec/uri_templates_spec.rb +24 -29
- metadata +15 -37
- data/.travis.yml +0 -38
- data/fixtures/default-template-app/Gemfile +0 -6
- data/fixtures/default-template-app/config.rb +0 -35
- data/fixtures/default-template-app/source/2013-04-01-new-article.html.markdown +0 -25
- data/fixtures/default-template-app/source/about-me.html.erb +0 -0
- data/fixtures/default-template-app/source/archives.html.erb +0 -10
- data/fixtures/default-template-app/source/index.html.erb +0 -11
- data/fixtures/default-template-app/source/javascripts/_zepto.pjax.js +0 -744
- data/fixtures/default-template-app/source/javascripts/app.js +0 -11
- data/fixtures/default-template-app/source/javascripts/modernizr.js +0 -1
- data/fixtures/default-template-app/source/layouts/layout.erb +0 -62
- data/fixtures/default-template-app/source/stylesheets/app.css.scss +0 -109
- /data/{CONTRIBUTING.md → .github/CONTRIBUTING.md} +0 -0
- /data/{ISSUE_TEMPLATE.md → .github/ISSUE_TEMPLATE.md} +0 -0
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'middleman-blog/uri_templates'
|
2
4
|
|
3
5
|
module Middleman
|
4
6
|
module Blog
|
5
|
-
|
6
7
|
# This adds new summary pages for arbitrarily defined blog article properties
|
7
8
|
class CustomPages
|
8
9
|
include UriTemplates
|
@@ -26,9 +27,9 @@ module Middleman
|
|
26
27
|
end
|
27
28
|
|
28
29
|
def manipulate_resource_list(resources)
|
29
|
-
articles_by_property = @blog_data.articles
|
30
|
-
|
31
|
-
|
30
|
+
articles_by_property = @blog_data.articles
|
31
|
+
.select { |a| a.data[property] }
|
32
|
+
.group_by { |a| a.data[property] }
|
32
33
|
resources + articles_by_property.map do |property_value, articles|
|
33
34
|
build_resource(link(property_value), property_value, articles)
|
34
35
|
end
|
@@ -40,13 +41,13 @@ module Middleman
|
|
40
41
|
articles = articles.sort_by(&:date).reverse
|
41
42
|
Sitemap::ProxyResource.new(@sitemap, path, @page_template).tap do |p|
|
42
43
|
p.add_metadata locals: {
|
43
|
-
|
44
|
-
property
|
45
|
-
|
46
|
-
|
44
|
+
'page_type' => property.to_s,
|
45
|
+
property => value,
|
46
|
+
'articles' => articles,
|
47
|
+
'blog_controller' => @blog_controller
|
47
48
|
}
|
48
49
|
end
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
52
|
-
end
|
53
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/core_ext/time/zones'
|
2
4
|
require 'middleman-blog/blog_data'
|
3
5
|
require 'middleman-blog/blog_article'
|
@@ -39,7 +41,7 @@ module Middleman
|
|
39
41
|
option :publish_future_dated, false, 'Whether articles with a date in the future should be considered published'
|
40
42
|
option :custom_collections, {}, 'Hash of custom frontmatter properties to collect articles on and their options (link, template)'
|
41
43
|
option :preserve_locale, false, 'Use the global Middleman I18n.locale instead of the lang in the article\'s frontmatter'
|
42
|
-
option :new_article_template, File.expand_path('
|
44
|
+
option :new_article_template, File.expand_path('commands/article.tt', __dir__), 'Path (relative to project root) to an ERb template that will be used to generate new articles from the "middleman article" command.'
|
43
45
|
option :default_extension, '.markdown', 'Default template extension for articles (used by "middleman article")'
|
44
46
|
|
45
47
|
# @return [BlogData] blog data for this blog, which has all information about the blog articles
|
@@ -61,9 +63,9 @@ module Middleman
|
|
61
63
|
attr_reader :custom_pages
|
62
64
|
|
63
65
|
# Helpers for use within templates and layouts.
|
64
|
-
self.defined_helpers = [
|
66
|
+
self.defined_helpers = [Middleman::Blog::Helpers]
|
65
67
|
|
66
|
-
def initialize(app, options_hash={}, &block)
|
68
|
+
def initialize(app, options_hash = {}, &block)
|
67
69
|
super
|
68
70
|
|
69
71
|
@custom_pages = {}
|
@@ -79,18 +81,18 @@ module Middleman
|
|
79
81
|
end
|
80
82
|
|
81
83
|
# If "prefix" option is specified, all other paths are relative to it.
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
84
|
+
return unless options.prefix
|
85
|
+
|
86
|
+
options.prefix = "/#{options.prefix}" unless options.prefix.start_with? '/'
|
87
|
+
options.permalink = File.join(options.prefix, options.permalink)
|
88
|
+
options.sources = File.join(options.prefix, options.sources)
|
89
|
+
options.taglink = File.join(options.prefix, options.taglink)
|
90
|
+
options.year_link = File.join(options.prefix, options.year_link)
|
91
|
+
options.month_link = File.join(options.prefix, options.month_link)
|
92
|
+
options.day_link = File.join(options.prefix, options.day_link)
|
93
|
+
|
94
|
+
options.custom_collections.each_value do |opts|
|
95
|
+
opts[:link] = File.join(options.prefix, opts[:link])
|
94
96
|
end
|
95
97
|
end
|
96
98
|
|
@@ -99,7 +101,7 @@ module Middleman
|
|
99
101
|
found_name = nil
|
100
102
|
|
101
103
|
app.extensions[:blog].values.each_with_index do |ext, i|
|
102
|
-
found_name = "blog#{i+1}" if ext == self
|
104
|
+
found_name = "blog#{i + 1}" if ext == self
|
103
105
|
end
|
104
106
|
|
105
107
|
found_name
|
@@ -113,15 +115,16 @@ module Middleman
|
|
113
115
|
@app.ignore(options.day_template) if options.day_template
|
114
116
|
@app.ignore options.tag_template if options.tag_template
|
115
117
|
|
118
|
+
ActiveSupport.to_time_preserves_timezone = :zone
|
119
|
+
|
116
120
|
# Make sure ActiveSupport's TimeZone stuff has something to work with,
|
117
121
|
# allowing people to set their desired time zone via Time.zone or
|
118
122
|
# set :time_zone
|
119
123
|
Time.zone = app.config[:time_zone] if app.config[:time_zone]
|
120
124
|
time_zone = Time.zone || 'UTC'
|
121
125
|
zone_default = Time.find_zone!(time_zone)
|
122
|
-
unless zone_default
|
123
|
-
|
124
|
-
end
|
126
|
+
raise 'Value assigned to time_zone not recognized.' unless zone_default
|
127
|
+
|
125
128
|
Time.zone_default = zone_default
|
126
129
|
|
127
130
|
# Initialize blog with options
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Middleman
|
2
4
|
module Blog
|
3
5
|
# Blog-related helpers that are available to the Middleman application in +config.rb+ and in templates.
|
@@ -26,25 +28,21 @@ module Middleman
|
|
26
28
|
#
|
27
29
|
# @param [Symbol, String] blog_name Optional name of the blog to get a controller for.
|
28
30
|
# @return [BlogExtension]
|
29
|
-
def blog_controller(blog_name=nil)
|
31
|
+
def blog_controller(blog_name = nil)
|
30
32
|
if !blog_name && current_resource
|
31
33
|
blog_name = current_resource.metadata[:page][:blog]
|
32
34
|
|
33
|
-
|
35
|
+
unless blog_name
|
34
36
|
blog_controller = current_resource.blog_controller if current_resource.respond_to?(:blog_controller)
|
35
37
|
return blog_controller if blog_controller
|
36
38
|
end
|
37
39
|
end
|
38
40
|
|
39
41
|
# In multiblog situations, force people to specify the blog
|
40
|
-
if !blog_name && blog_instances.size > 1
|
41
|
-
raise "You have more than one blog so you must either use the flag --blog (ex. --blog 'myBlog') when calling this method, or add blog: [blog_name] to your page's frontmatter"
|
42
|
-
end
|
42
|
+
raise "You have more than one blog so you must either use the flag --blog (ex. --blog 'myBlog') when calling this method, or add blog: [blog_name] to your page's frontmatter" if !blog_name && blog_instances.size > 1
|
43
43
|
|
44
44
|
# Warn if a non-existent blog name provided
|
45
|
-
if blog_name && !blog_instances.
|
46
|
-
raise "Non-existent blog name provided: #{blog_name}."
|
47
|
-
end
|
45
|
+
raise "Non-existent blog name provided: #{blog_name}." if blog_name && !blog_instances.key?(blog_name.to_sym)
|
48
46
|
|
49
47
|
blog_name ||= blog_instances.keys.first
|
50
48
|
blog_instances[blog_name.to_sym]
|
@@ -56,7 +54,7 @@ module Middleman
|
|
56
54
|
# @param [Symbol, String] blog_name Optional name of the blog to get data for.
|
57
55
|
# Blogs can be named as an option or will default to 'blog0', 'blog1', etc..
|
58
56
|
# @return [BlogData]
|
59
|
-
def blog(blog_name=nil)
|
57
|
+
def blog(blog_name = nil)
|
60
58
|
blog_controller(blog_name).data
|
61
59
|
end
|
62
60
|
|
@@ -71,18 +69,14 @@ module Middleman
|
|
71
69
|
# @return [BlogArticle]
|
72
70
|
def current_article
|
73
71
|
article = current_resource
|
74
|
-
|
75
|
-
article
|
76
|
-
else
|
77
|
-
nil
|
78
|
-
end
|
72
|
+
article if article.is_a?(BlogArticle)
|
79
73
|
end
|
80
74
|
|
81
75
|
# Get a path to the given tag page, based on the +taglink+ blog setting.
|
82
76
|
# @param [String] tag
|
83
77
|
# @param [Symbol, String] blog_name Optional name of the blog to use.
|
84
78
|
# @return [String]
|
85
|
-
def tag_path(tag, blog_name=nil)
|
79
|
+
def tag_path(tag, blog_name = nil)
|
86
80
|
build_url blog_controller(blog_name).tag_pages.link(tag)
|
87
81
|
end
|
88
82
|
|
@@ -90,7 +84,7 @@ module Middleman
|
|
90
84
|
# @param [Number] year
|
91
85
|
# @param [Symbol, String] blog_name Optional name of the blog to use.
|
92
86
|
# @return [String]
|
93
|
-
def blog_year_path(year, blog_name=nil)
|
87
|
+
def blog_year_path(year, blog_name = nil)
|
94
88
|
build_url blog_controller(blog_name).calendar_pages.link(year)
|
95
89
|
end
|
96
90
|
|
@@ -99,7 +93,7 @@ module Middleman
|
|
99
93
|
# @param [Number] month
|
100
94
|
# @param [Symbol, String] blog_name Optional name of the blog to use.
|
101
95
|
# @return [String]
|
102
|
-
def blog_month_path(year, month, blog_name=nil)
|
96
|
+
def blog_month_path(year, month, blog_name = nil)
|
103
97
|
build_url blog_controller(blog_name).calendar_pages.link(year, month)
|
104
98
|
end
|
105
99
|
|
@@ -109,7 +103,7 @@ module Middleman
|
|
109
103
|
# @param [Number] day
|
110
104
|
# @param [Symbol, String] blog_name Optional name of the blog to use.
|
111
105
|
# @return [String]
|
112
|
-
def blog_day_path(year, month, day, blog_name=nil)
|
106
|
+
def blog_day_path(year, month, day, blog_name = nil)
|
113
107
|
build_url blog_controller(blog_name).calendar_pages.link(year, month, day)
|
114
108
|
end
|
115
109
|
|
@@ -123,13 +117,13 @@ module Middleman
|
|
123
117
|
# Returns the list of articles to display on this particular page (when using pagination).
|
124
118
|
# @param [Symbol, String] blog_name Optional name of the blog to use.
|
125
119
|
# @return [Array<Middleman::Sitemap::Resource>]
|
126
|
-
def page_articles(blog_name=nil)
|
120
|
+
def page_articles(blog_name = nil)
|
127
121
|
meta = current_resource.metadata
|
128
122
|
limit = current_resource.data[:per_page]
|
129
123
|
|
130
124
|
# "articles" local variable is populated by Calendar and Tag page generators
|
131
125
|
# If it's not set then use the complete list of articles
|
132
|
-
articles = meta[:locals][
|
126
|
+
articles = meta[:locals]['articles'] || blog(blog_name).articles
|
133
127
|
|
134
128
|
limit ? articles.first(limit) : articles
|
135
129
|
end
|
@@ -142,12 +136,11 @@ module Middleman
|
|
142
136
|
# @param [Symbol] property Custom property which is being used to collect articles on
|
143
137
|
# @private
|
144
138
|
def self.generate_custom_helper(property)
|
145
|
-
define_method :"#{property}_path" do |value, blog_name=nil|
|
139
|
+
define_method :"#{property}_path" do |value, blog_name = nil|
|
146
140
|
custom_pages = blog_controller(blog_name).custom_pages
|
147
141
|
|
148
|
-
|
149
|
-
|
150
|
-
end
|
142
|
+
raise "This blog does not know about the custom property #{property.inspect}" unless custom_pages.key?(property)
|
143
|
+
|
151
144
|
build_url custom_pages[property].link(value)
|
152
145
|
end
|
153
146
|
end
|
@@ -159,4 +152,4 @@ module Middleman
|
|
159
152
|
end
|
160
153
|
end
|
161
154
|
end
|
162
|
-
end
|
155
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'middleman-blog/uri_templates'
|
2
4
|
|
3
5
|
module Middleman
|
@@ -7,7 +9,7 @@ module Middleman
|
|
7
9
|
class Paginator
|
8
10
|
include UriTemplates
|
9
11
|
|
10
|
-
def initialize(
|
12
|
+
def initialize(app, blog_controller)
|
11
13
|
@app = app
|
12
14
|
@blog_controller = blog_controller
|
13
15
|
@per_page = blog_controller.options.per_page
|
@@ -33,8 +35,8 @@ module Middleman
|
|
33
35
|
# "articles" local variable is populated by Calendar and Tag page generators
|
34
36
|
# If it's not set then use the complete list of articles
|
35
37
|
# TODO: Some way to allow the frontmatter to specify the article filter?
|
36
|
-
articles = md[:locals][
|
37
|
-
articles.select!{|article| article.lang == md[:options][:locale]} if md.fetch(:options, false)
|
38
|
+
articles = md[:locals]['articles'] || @blog_controller.data.articles
|
39
|
+
articles.select! { |article| article.lang == md[:options][:locale] } if md.fetch(:options, false) && md[:options].fetch(:locale, false)
|
38
40
|
|
39
41
|
# Allow blog.per_page and blog.page_link to be overridden in the frontmatter
|
40
42
|
per_page = md[:page][:per_page] || @per_page
|
@@ -72,8 +74,9 @@ module Middleman
|
|
72
74
|
# Does this resource match the blog controller for this paginator?
|
73
75
|
# @return [Boolean]
|
74
76
|
def match_blog(res, md)
|
75
|
-
res_controller = md[:locals][
|
77
|
+
res_controller = md[:locals]['blog_controller'] || (res.respond_to?(:blog_controller) && res.blog_controller)
|
76
78
|
return false if res_controller && res_controller != @blog_controller
|
79
|
+
|
77
80
|
override_controller = md[:page][:blog]
|
78
81
|
return false if override_controller && override_controller.to_s != @blog_controller.name.to_s
|
79
82
|
|
@@ -148,7 +151,7 @@ module Middleman
|
|
148
151
|
else
|
149
152
|
page_url = apply_uri_template page_link, num: page_num
|
150
153
|
index_re = %r{(^|/)#{Regexp.escape(@app.config[:index_file])}$}
|
151
|
-
if res.path
|
154
|
+
if res.path&.match?(index_re)
|
152
155
|
res.path.sub(index_re, "\\1#{page_url}/#{@app.config[:index_file]}")
|
153
156
|
else
|
154
157
|
res.path.sub(%r{(^|/)([^/]*)\.([^/]*)$}, "\\1\\2/#{page_url}.\\3")
|
@@ -1,15 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'middleman-blog/uri_templates'
|
2
4
|
|
3
5
|
module Middleman
|
4
|
-
|
5
6
|
module Blog
|
6
|
-
|
7
7
|
##
|
8
8
|
# A sitemap resource manipulator that adds a tag page to the sitemap for
|
9
9
|
# each tag in the associated blog
|
10
10
|
##
|
11
11
|
class TagPages
|
12
|
-
|
13
12
|
include UriTemplates
|
14
13
|
|
15
14
|
##
|
@@ -18,7 +17,7 @@ module Middleman
|
|
18
17
|
# @param app [Object] Middleman app
|
19
18
|
# @param blog_controller [Object] Blog controller
|
20
19
|
##
|
21
|
-
def initialize(
|
20
|
+
def initialize(app, blog_controller)
|
22
21
|
@sitemap = app.sitemap
|
23
22
|
@blog_controller = blog_controller
|
24
23
|
@tag_link_template = uri_template blog_controller.options.taglink
|
@@ -33,8 +32,8 @@ module Middleman
|
|
33
32
|
# @param tag [String] Tag name
|
34
33
|
# @return [String] Safe Tag URL
|
35
34
|
##
|
36
|
-
def link(
|
37
|
-
apply_uri_template @tag_link_template, tag: safe_parameterize(
|
35
|
+
def link(tag)
|
36
|
+
apply_uri_template @tag_link_template, tag: safe_parameterize(tag)
|
38
37
|
end
|
39
38
|
|
40
39
|
##
|
@@ -43,14 +42,12 @@ module Middleman
|
|
43
42
|
# @param resources [Object] Tag name
|
44
43
|
# @return [void]
|
45
44
|
##
|
46
|
-
def manipulate_resource_list(
|
47
|
-
|
45
|
+
def manipulate_resource_list(resources)
|
48
46
|
return resources unless @generate_tag_pages
|
49
47
|
|
50
|
-
resources + @blog_data.tags.map do |
|
51
|
-
tag_page_resource(
|
48
|
+
resources + @blog_data.tags.map do |tag, articles|
|
49
|
+
tag_page_resource(tag, articles)
|
52
50
|
end
|
53
|
-
|
54
51
|
end
|
55
52
|
|
56
53
|
private
|
@@ -64,27 +61,20 @@ module Middleman
|
|
64
61
|
#
|
65
62
|
# @todo Can we inject the correct locale into the metadata here
|
66
63
|
##
|
67
|
-
def tag_page_resource(
|
68
|
-
|
69
|
-
Sitemap::ProxyResource.new( @sitemap, link( tag ), @tag_template ).tap do | p |
|
70
|
-
|
64
|
+
def tag_page_resource(tag, articles)
|
65
|
+
Sitemap::ProxyResource.new(@sitemap, link(tag), @tag_template).tap do |p|
|
71
66
|
# Detect "formatted" tag in first article - trying to guess the correct format to show
|
72
67
|
# tagname = articles.first.tags.detect { |article_tag| safe_parameterize(article_tag) == tag }
|
73
68
|
|
74
69
|
# Add metadata in local variables so it's accessible to later extensions
|
75
70
|
p.add_metadata locals: {
|
76
|
-
'page_type'
|
77
|
-
'tagname'
|
78
|
-
'articles'
|
71
|
+
'page_type' => 'tag',
|
72
|
+
'tagname' => tag,
|
73
|
+
'articles' => articles,
|
79
74
|
'blog_controller' => @blog_controller
|
80
75
|
}
|
81
|
-
|
82
76
|
end
|
83
|
-
|
84
77
|
end
|
85
|
-
|
86
78
|
end
|
87
|
-
|
88
79
|
end
|
89
|
-
|
90
80
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
begin
|
2
|
-
require
|
4
|
+
require 'nokogiri'
|
3
5
|
rescue LoadError
|
4
6
|
raise "Nokogiri is required for blog post summaries. Add 'nokogiri' to your Gemfile."
|
5
7
|
end
|
@@ -13,7 +15,7 @@ module TruncateHTML
|
|
13
15
|
doc.inner_html
|
14
16
|
end
|
15
17
|
|
16
|
-
def self.truncate_at_length(text, max_length, ellipsis =
|
18
|
+
def self.truncate_at_length(text, max_length, ellipsis = '...')
|
17
19
|
ellipsis_length = ellipsis.length
|
18
20
|
text = text.encode('UTF-8') if text.respond_to?(:encode)
|
19
21
|
doc = Nokogiri::HTML::DocumentFragment.parse text
|
@@ -31,12 +33,14 @@ module NokogiriTruncator
|
|
31
33
|
module NodeWithChildren
|
32
34
|
def truncate(max_length, ellipsis)
|
33
35
|
return self if inner_text.length <= max_length
|
34
|
-
|
36
|
+
|
37
|
+
truncated_node = dup
|
35
38
|
truncated_node.children.remove
|
36
39
|
|
37
|
-
|
40
|
+
children.each do |node|
|
38
41
|
remaining_length = max_length - truncated_node.inner_text.length
|
39
42
|
break if remaining_length <= 0
|
43
|
+
|
40
44
|
truncated_node.add_child node.truncate(remaining_length, ellipsis)
|
41
45
|
end
|
42
46
|
truncated_node
|
@@ -46,7 +50,7 @@ module NokogiriTruncator
|
|
46
50
|
module TextNode
|
47
51
|
def truncate(max_length, ellipsis)
|
48
52
|
# Don't break in the middle of a word
|
49
|
-
trimmed_content = content.match(/(.{1,#{max_length}}
|
53
|
+
trimmed_content = content.match(/(.{1,#{max_length}}\w*)/m).to_s
|
50
54
|
trimmed_content << ellipsis if trimmed_content.length < content.length
|
51
55
|
|
52
56
|
Nokogiri::XML::Text.new(trimmed_content, parent)
|
@@ -54,15 +58,14 @@ module NokogiriTruncator
|
|
54
58
|
end
|
55
59
|
|
56
60
|
module CommentNode
|
57
|
-
def truncate(*
|
61
|
+
def truncate(*_args)
|
58
62
|
# Don't truncate comments, since they aren't visible
|
59
63
|
self
|
60
64
|
end
|
61
65
|
end
|
62
|
-
|
63
66
|
end
|
64
67
|
|
65
|
-
Nokogiri::HTML::DocumentFragment.
|
66
|
-
Nokogiri::XML::Element.
|
67
|
-
Nokogiri::XML::Text.
|
68
|
-
Nokogiri::XML::Comment.
|
68
|
+
Nokogiri::HTML::DocumentFragment.include NokogiriTruncator::NodeWithChildren
|
69
|
+
Nokogiri::XML::Element.include NokogiriTruncator::NodeWithChildren
|
70
|
+
Nokogiri::XML::Text.include NokogiriTruncator::TextNode
|
71
|
+
Nokogiri::XML::Comment.include NokogiriTruncator::CommentNode
|
@@ -1,15 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'addressable/template'
|
4
|
+
require 'active_support/all'
|
2
5
|
require 'middleman-core/util'
|
3
6
|
require 'active_support/inflector'
|
4
7
|
require 'active_support/inflector/transliterate'
|
5
8
|
|
6
9
|
module Middleman
|
7
|
-
|
8
10
|
module Blog
|
9
|
-
|
10
11
|
# Handy methods for dealing with URI templates. Mix into whatever class.
|
11
12
|
module UriTemplates
|
12
|
-
|
13
13
|
module_function
|
14
14
|
|
15
15
|
##
|
@@ -22,9 +22,7 @@ module Middleman
|
|
22
22
|
##
|
23
23
|
def uri_template(tmpl_src)
|
24
24
|
# Support the RFC6470 templates directly if people use them
|
25
|
-
if tmpl_src.include?(':')
|
26
|
-
tmpl_src = tmpl_src.gsub(/:([A-Za-z0-9]+)/, '{\1}')
|
27
|
-
end
|
25
|
+
tmpl_src = tmpl_src.gsub(/:([A-Za-z0-9]+)/, '{\1}') if tmpl_src.include?(':')
|
28
26
|
|
29
27
|
Addressable::Template.new ::Middleman::Util.normalize_path(tmpl_src)
|
30
28
|
end
|
@@ -52,15 +50,40 @@ module Middleman
|
|
52
50
|
template.extract(path, BlogTemplateProcessor)
|
53
51
|
end
|
54
52
|
|
55
|
-
##
|
56
53
|
# Parametrize a string preserving any multi-byte characters
|
57
54
|
# Reimplementation of this, preserves un-transliterate-able multibyte chars.
|
58
55
|
#
|
59
56
|
# @see http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
def safe_parameterize(str, sep = '-')
|
58
|
+
# Remove ending ?
|
59
|
+
str = str.to_s.gsub(/\?$/, '')
|
60
|
+
|
61
|
+
# Reimplementation of http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html#method-i-parameterize that preserves un-transliterate-able multibyte chars.
|
62
|
+
parameterized_string = ::ActiveSupport::Inflector.transliterate(str.to_s).downcase
|
63
|
+
parameterized_string.gsub!(/[^a-z0-9\-_?]+/, sep)
|
64
|
+
|
65
|
+
# Check for multibytes and sub back in
|
66
|
+
parameterized_string.chars.to_a.each_with_index do |char, i|
|
67
|
+
next unless char == '?' && str[i].bytes.count != 1
|
68
|
+
|
69
|
+
parameterized_string[i] = str[i]
|
70
|
+
end
|
71
|
+
|
72
|
+
re_sep = ::Regexp.escape(sep)
|
73
|
+
|
74
|
+
# No more than one of the separator in a row.
|
75
|
+
parameterized_string.gsub!(/#{re_sep}{2,}/, sep)
|
76
|
+
|
77
|
+
# Remove leading/trailing separator.
|
78
|
+
parameterized_string.gsub!(/^#{re_sep}|#{re_sep}$/, '')
|
79
|
+
|
80
|
+
# Replace all _ with -
|
81
|
+
parameterized_string.tr!('_', '-')
|
82
|
+
|
83
|
+
# Delete all ?
|
84
|
+
parameterized_string.delete!('?')
|
85
|
+
|
86
|
+
parameterized_string
|
64
87
|
end
|
65
88
|
|
66
89
|
##
|
@@ -71,7 +94,7 @@ module Middleman
|
|
71
94
|
# @return [Hash] parameters
|
72
95
|
##
|
73
96
|
def date_to_params(date)
|
74
|
-
|
97
|
+
{
|
75
98
|
year: date.year.to_s,
|
76
99
|
month: date.month.to_s.rjust(2, '0'),
|
77
100
|
day: date.day.to_s.rjust(2, '0')
|
@@ -81,13 +104,12 @@ module Middleman
|
|
81
104
|
##
|
82
105
|
#
|
83
106
|
##
|
84
|
-
def extract_directory_path(
|
107
|
+
def extract_directory_path(article_path)
|
85
108
|
uri = Addressable::URI.parse article_path
|
86
109
|
|
87
110
|
# Remove file extension from the article path
|
88
|
-
|
111
|
+
uri.path.gsub(uri.extname, '')
|
89
112
|
end
|
90
|
-
|
91
113
|
end
|
92
114
|
|
93
115
|
##
|
@@ -106,7 +128,5 @@ module Middleman
|
|
106
128
|
end
|
107
129
|
end
|
108
130
|
end
|
109
|
-
|
110
131
|
end
|
111
|
-
|
112
132
|
end
|
data/lib/middleman-blog.rb
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
|
2
|
-
require "middleman-blog/version"
|
1
|
+
# frozen_string_literal: true
|
3
2
|
|
4
|
-
|
3
|
+
require 'middleman-core'
|
4
|
+
require 'middleman-blog/version'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
::Middleman::BlogExtension
|
6
|
+
::Middleman::Extensions.register(:blog) do
|
7
|
+
require 'middleman-blog/extension'
|
8
|
+
require 'middleman-blog/commands/article'
|
10
9
|
|
10
|
+
::Middleman::BlogExtension
|
11
11
|
end
|
data/lib/middleman_extension.rb
CHANGED
data/middleman-blog.gemspec
CHANGED
@@ -1,25 +1,18 @@
|
|
1
|
-
|
2
|
-
$:.push File.expand_path('../lib', __FILE__)
|
3
|
-
require 'middleman-blog/version'
|
4
|
-
|
5
|
-
Gem::Specification.new do |s|
|
6
|
-
|
7
|
-
s.name = 'middleman-blog'
|
8
|
-
s.version = Middleman::Blog::VERSION
|
9
|
-
s.platform = Gem::Platform::RUBY
|
10
|
-
s.authors = ['Thomas Reynolds', 'Ben Hollis', 'Ian Warner']
|
11
|
-
s.email = ['me@tdreyno.com', 'ben@benhollis.net', 'ian.warner@drykiss.com']
|
12
|
-
s.homepage = 'https://github.com/middleman/middleman-blog'
|
13
|
-
s.summary = %q{ Blog engine for Middleman }
|
14
|
-
s.description = %q{ Blog engine for Middleman }
|
15
|
-
s.license = 'MIT'
|
16
|
-
s.files = `git ls-files -z`.split("\0")
|
17
|
-
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split("\0")
|
18
|
-
s.require_paths = ['lib']
|
19
|
-
s.required_ruby_version = '>= 2.0.0'
|
20
|
-
|
21
|
-
s.add_dependency('middleman-core', ['~> 4.0'])
|
22
|
-
s.add_dependency('tzinfo', ['>= 0.3.0'])
|
23
|
-
s.add_dependency('addressable', ['~> 2.3'])
|
1
|
+
require "./lib/middleman-blog/version"
|
24
2
|
|
3
|
+
Gem::Specification.new do | s |
|
4
|
+
s.name = "middleman-blog"
|
5
|
+
s.version = Middleman::Blog::VERSION
|
6
|
+
s.platform = Gem::Platform::RUBY
|
7
|
+
s.authors = [ "Thomas Reynolds", "Ben Hollis", "Ian Warner" ]
|
8
|
+
s.email = [ "me@tdreyno.com", "ben@benhollis.net", "ian.warner@drykiss.com" ]
|
9
|
+
s.homepage = "https://github.com/middleman/middleman-blog"
|
10
|
+
s.summary = %q{ Blog engine for Middleman }
|
11
|
+
s.description = %q{ Blog engine for Middleman }
|
12
|
+
s.license = "MIT"
|
13
|
+
s.files = `git ls-files -z`.split( "\0" )
|
14
|
+
s.test_files = `git ls-files -z -- {fixtures,features}/*`.split( "\0" )
|
15
|
+
s.add_dependency("middleman-core", ">= 4.0.0")
|
16
|
+
s.add_dependency("tzinfo", ">= 0.3.0")
|
17
|
+
s.add_dependency("addressable", "~> 2.3")
|
25
18
|
end
|
data/spec/spec_helper.rb
CHANGED