middleman-blog 3.2.0 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -1
- data/.travis.yml +5 -7
- data/CHANGELOG.md +21 -0
- data/CONTRIBUTING.md +43 -0
- data/Gemfile +22 -14
- data/Gemfile-3.0 +27 -0
- data/{LICENSE → LICENSE.md} +2 -2
- data/README.md +33 -28
- data/Rakefile +17 -1
- data/features/blog_sources.feature +13 -0
- data/features/calendar_multiblog.feature +153 -0
- data/features/multiblog.feature +51 -0
- data/features/paginate_multiblog.feature +270 -0
- data/features/summary.feature +43 -0
- data/features/support/env.rb +6 -1
- data/features/tags_multiblog.feature +125 -0
- data/features/time_zone.feature +5 -0
- data/fixtures/blog-sources-app/source/blog/2013-08-08-slug-from-filename.html.markdown +7 -0
- data/fixtures/calendar-multiblog-app/config.rb +17 -0
- data/fixtures/calendar-multiblog-app/source/blog1/2011-01-01-new-article.html.markdown +7 -0
- data/fixtures/calendar-multiblog-app/source/blog1/2011-01-02-another-article.html.markdown +8 -0
- data/fixtures/calendar-multiblog-app/source/blog2/2011-01-01-new-article.html.markdown +7 -0
- data/fixtures/calendar-multiblog-app/source/blog2/2011-01-02-another-article.html.markdown +8 -0
- data/fixtures/calendar-multiblog-app/source/calendar1.html.erb +13 -0
- data/fixtures/calendar-multiblog-app/source/calendar2.html.erb +13 -0
- data/fixtures/calendar-multiblog-app/source/index.html.erb +15 -0
- data/fixtures/calendar-multiblog-app/source/layout.erb +15 -0
- data/fixtures/default-template-app/Gemfile +6 -0
- data/fixtures/default-template-app/config.rb +35 -0
- data/fixtures/default-template-app/source/2013-04-01-new-article.html.markdown +25 -0
- data/{features/encoding.feature → fixtures/default-template-app/source/about-me.html.erb} +0 -0
- data/fixtures/default-template-app/source/archives.html.erb +10 -0
- data/fixtures/default-template-app/source/index.html.erb +11 -0
- data/fixtures/default-template-app/source/javascripts/_zepto.pjax.js +744 -0
- data/fixtures/default-template-app/source/javascripts/app.js +11 -0
- data/fixtures/default-template-app/source/javascripts/modernizr.js +1 -0
- data/fixtures/default-template-app/source/layouts/layout.erb +62 -0
- data/fixtures/default-template-app/source/stylesheets/app.css.scss +109 -0
- data/fixtures/multiblog-app/config.rb +0 -0
- data/fixtures/multiblog-app/source/blog1/2012-12-12-other-article.html.markdown +5 -0
- data/fixtures/multiblog-app/source/blog2/2011/01/01/new-article.html.markdown +6 -0
- data/fixtures/multiblog-app/source/index.html.erb +7 -0
- data/fixtures/multiblog-app/source/layout.erb +30 -0
- data/fixtures/no-title-app/config.rb +3 -0
- data/fixtures/no-title-app/source/2013-08-07.html.markdown +6 -0
- data/fixtures/no-title-app/source/2013-08-08.html.markdown +7 -0
- data/fixtures/no-title-app/source/layout.erb +13 -0
- data/fixtures/paginate-multiblog-app/config.rb +31 -0
- data/fixtures/paginate-multiblog-app/source/blog1/2011-01-01-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog1/2011-01-02-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog1/2011-01-03-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog1/2011-01-04-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog1/2011-01-05-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog1/2011-02-01-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog1/index.html.erb +27 -0
- data/fixtures/paginate-multiblog-app/source/blog2/2011-01-01-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog2/2011-01-02-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog2/2011-01-03-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog2/2011-01-04-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog2/2011-01-05-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog2/index.html.erb +27 -0
- data/fixtures/paginate-multiblog-app/source/blog3/2011-01-01-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog3/2011-01-02-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog3/2011-01-03-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog3/2011-01-04-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog3/2011-01-05-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog3/2011-02-01-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog3/2011-02-02-test-article.html.markdown +6 -0
- data/fixtures/paginate-multiblog-app/source/blog3/index.html.erb +28 -0
- data/fixtures/paginate-multiblog-app/source/calendar1.html.erb +28 -0
- data/fixtures/paginate-multiblog-app/source/calendar2.html.erb +28 -0
- data/fixtures/paginate-multiblog-app/source/calendar3.html.erb +28 -0
- data/fixtures/paginate-multiblog-app/source/layout.erb +15 -0
- data/fixtures/paginate-multiblog-app/source/tag1.html.erb +23 -0
- data/fixtures/paginate-multiblog-app/source/tag2.html.erb +23 -0
- data/fixtures/paginate-multiblog-app/source/tag3.html.erb +19 -0
- data/fixtures/summary-app/config.rb +1 -0
- data/fixtures/summary-app/source/2011-01-01-article-with-no-summary-separator-and-comments-in-the-summary.html.erb +10 -0
- data/fixtures/summary-app/source/2011-01-01-article-with-standard-summary-separator.html.markdown +7 -0
- data/fixtures/summary-app/source/2012-06-19-article-with-no-summary-separator.html.markdown +9 -0
- data/fixtures/summary-app/source/2013-05-08-article-with-custom-separator.html.markdown +7 -0
- data/fixtures/summary-app/source/index.html.erb +5 -0
- data/fixtures/tags-multiblog-app/config.rb +15 -0
- data/fixtures/tags-multiblog-app/source/blog1/2011-01-01-new-article.html.markdown +7 -0
- data/fixtures/tags-multiblog-app/source/blog1/2011-01-02-another-article.html.markdown +9 -0
- data/fixtures/tags-multiblog-app/source/blog2/2011-01-01-new-article.html.markdown +7 -0
- data/fixtures/tags-multiblog-app/source/blog2/2011-01-02-another-article.html.markdown +9 -0
- data/fixtures/tags-multiblog-app/source/index.html.erb +8 -0
- data/fixtures/tags-multiblog-app/source/layout.erb +13 -0
- data/fixtures/tags-multiblog-app/source/tag1.html.erb +7 -0
- data/fixtures/tags-multiblog-app/source/tag2.html.erb +7 -0
- data/fixtures/time-zone-app/config.rb +5 -0
- data/fixtures/time-zone-app/source/blog/2013-06-24-hello.html.erb +5 -0
- data/lib/middleman-blog.rb +9 -4
- data/lib/middleman-blog/blog_article.rb +47 -21
- data/lib/middleman-blog/blog_data.rb +11 -4
- data/lib/middleman-blog/calendar_pages.rb +40 -25
- data/lib/middleman-blog/{extension.rb → extension_3_0.rb} +20 -16
- data/lib/middleman-blog/extension_3_1.rb +208 -0
- data/lib/middleman-blog/paginator.rb +33 -7
- data/lib/middleman-blog/tag_pages.rb +26 -9
- data/lib/middleman-blog/template/shared/Gemfile.tt +4 -2
- data/lib/middleman-blog/template/source/calendar.html.erb +1 -1
- data/lib/middleman-blog/template/source/feed.xml.builder +8 -7
- data/lib/middleman-blog/template/source/index.html.erb +1 -1
- data/lib/middleman-blog/template/source/tag.html.erb +1 -1
- data/lib/middleman-blog/truncate_html.rb +10 -1
- data/lib/middleman-blog/version.rb +1 -1
- data/middleman-blog.gemspec +12 -15
- metadata +180 -14
@@ -5,6 +5,26 @@ module Middleman
|
|
5
5
|
module Blog
|
6
6
|
# A module that adds blog-article methods to Resources.
|
7
7
|
module BlogArticle
|
8
|
+
def self.extended(base)
|
9
|
+
base.class.send(:attr_accessor, :blog_controller)
|
10
|
+
end
|
11
|
+
|
12
|
+
def blog_data
|
13
|
+
if self.blog_controller
|
14
|
+
self.blog_controller.data
|
15
|
+
else
|
16
|
+
app.blog
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def blog_options
|
21
|
+
if self.blog_controller
|
22
|
+
self.blog_controller.options
|
23
|
+
else
|
24
|
+
app.blog.options
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
8
28
|
# Render this resource
|
9
29
|
# @return [String]
|
10
30
|
def render(opts={}, locs={}, &block)
|
@@ -12,15 +32,15 @@ module Middleman
|
|
12
32
|
if metadata[:options] && !metadata[:options][:layout].nil?
|
13
33
|
opts[:layout] = metadata[:options][:layout]
|
14
34
|
end
|
15
|
-
opts[:layout] =
|
35
|
+
opts[:layout] = blog_options.layout if opts[:layout].nil?
|
16
36
|
opts[:layout] = opts[:layout].to_s if opts[:layout].is_a? Symbol
|
17
37
|
end
|
18
38
|
|
19
39
|
content = super(opts, locs, &block)
|
20
40
|
|
21
41
|
unless opts[:keep_separator]
|
22
|
-
if content.match(
|
23
|
-
content.sub!(
|
42
|
+
if content.match(blog_options.summary_separator)
|
43
|
+
content.sub!(blog_options.summary_separator, "")
|
24
44
|
end
|
25
45
|
end
|
26
46
|
|
@@ -43,7 +63,7 @@ module Middleman
|
|
43
63
|
# @return [Boolean]
|
44
64
|
def published?
|
45
65
|
(data["published"] != false) and
|
46
|
-
(
|
66
|
+
(blog_options.publish_future_dated || date <= Time.current)
|
47
67
|
end
|
48
68
|
|
49
69
|
# The body of this article, in HTML. This is for
|
@@ -66,15 +86,15 @@ module Middleman
|
|
66
86
|
# desired length to trim the summary to, and the ellipsis string to use.
|
67
87
|
#
|
68
88
|
# @param [Number] length How many characters to trim the summary to.
|
69
|
-
# @param [
|
89
|
+
# @param [String] ellipsis The ellipsis string to use when content is trimmed.
|
70
90
|
# @return [String]
|
71
|
-
def summary(length=
|
91
|
+
def summary(length=blog_options.summary_length, ellipsis='...')
|
72
92
|
rendered = render(:layout => false, :keep_separator => true)
|
73
93
|
|
74
|
-
if
|
75
|
-
rendered.split(
|
76
|
-
elsif
|
77
|
-
|
94
|
+
if blog_options.summary_separator && rendered.match(blog_options.summary_separator)
|
95
|
+
rendered.split(blog_options.summary_separator).first
|
96
|
+
elsif blog_options.summary_generator
|
97
|
+
blog_options.summary_generator.call(self, rendered, length, ellipsis)
|
78
98
|
else
|
79
99
|
default_summary_generator(rendered, length, ellipsis)
|
80
100
|
end
|
@@ -83,8 +103,8 @@ module Middleman
|
|
83
103
|
def default_summary_generator(rendered, length, ellipsis)
|
84
104
|
require 'middleman-blog/truncate_html'
|
85
105
|
|
86
|
-
if rendered =~
|
87
|
-
rendered.split(
|
106
|
+
if rendered =~ blog_options.summary_separator
|
107
|
+
rendered.split(blog_options.summary_separator).first
|
88
108
|
elsif length
|
89
109
|
TruncateHTML.truncate_html(rendered, length, ellipsis)
|
90
110
|
else
|
@@ -108,9 +128,9 @@ module Middleman
|
|
108
128
|
# @param [String] The part of the path, e.g. "year", "month", "day", "title"
|
109
129
|
# @return [String]
|
110
130
|
def path_part(part)
|
111
|
-
@_path_parts ||=
|
131
|
+
@_path_parts ||= blog_data.path_matcher.match(path).captures
|
112
132
|
|
113
|
-
@_path_parts[
|
133
|
+
@_path_parts[blog_data.matcher_indexes[part]]
|
114
134
|
end
|
115
135
|
|
116
136
|
# Attempt to figure out the date of the post. The date should be
|
@@ -132,9 +152,9 @@ module Middleman
|
|
132
152
|
end
|
133
153
|
|
134
154
|
# Next figure out the date from the filename
|
135
|
-
if
|
136
|
-
|
137
|
-
|
155
|
+
if blog_options.sources.include?(":year") &&
|
156
|
+
blog_options.sources.include?(":month") &&
|
157
|
+
blog_options.sources.include?(":day")
|
138
158
|
|
139
159
|
filename_date = Time.zone.local(path_part("year").to_i, path_part("month").to_i, path_part("day").to_i)
|
140
160
|
if @_date
|
@@ -152,21 +172,27 @@ module Middleman
|
|
152
172
|
# The "slug" of the article that shows up in its URL.
|
153
173
|
# @return [String]
|
154
174
|
def slug
|
155
|
-
@_slug ||=
|
175
|
+
@_slug ||= data["slug"]
|
176
|
+
|
177
|
+
@_slug ||= if blog_options.sources.include?(":title")
|
178
|
+
path_part("title")
|
179
|
+
else
|
180
|
+
title.parameterize
|
181
|
+
end
|
156
182
|
end
|
157
183
|
|
158
184
|
# The previous (chronologically earlier) article before this one
|
159
185
|
# or nil if this is the first article.
|
160
186
|
# @return [Middleman::Sitemap::Resource]
|
161
187
|
def previous_article
|
162
|
-
|
188
|
+
blog_data.articles.find {|a| a.date < self.date }
|
163
189
|
end
|
164
|
-
|
190
|
+
|
165
191
|
# The next (chronologically later) article after this one
|
166
192
|
# or nil if this is the most recent article.
|
167
193
|
# @return [Middleman::Sitemap::Resource]
|
168
194
|
def next_article
|
169
|
-
|
195
|
+
blog_data.articles.reverse.find {|a| a.date > self.date }
|
170
196
|
end
|
171
197
|
end
|
172
198
|
end
|
@@ -16,19 +16,22 @@ module Middleman
|
|
16
16
|
# @return [Thor::CoreExt::HashWithIndifferentAccess]
|
17
17
|
attr_reader :options
|
18
18
|
|
19
|
+
attr_reader :controller
|
20
|
+
|
19
21
|
# @private
|
20
|
-
def initialize(app, options={})
|
22
|
+
def initialize(app, options={}, controller=nil)
|
21
23
|
@app = app
|
22
24
|
@options = options
|
25
|
+
@controller = controller
|
23
26
|
|
24
27
|
# A list of resources corresponding to blog articles
|
25
28
|
@_articles = []
|
26
29
|
|
27
30
|
matcher = Regexp.escape(options.sources).
|
28
31
|
sub(/^\//, "").
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
+
gsub(":year", "(\\d{4})").
|
33
|
+
gsub(":month", "(\\d{2})").
|
34
|
+
gsub(":day", "(\\d{2})").
|
32
35
|
sub(":title", "([^/]+)")
|
33
36
|
|
34
37
|
subdir_matcher = matcher.sub(/\\\.[^.]+$/, "(/.*)$")
|
@@ -93,6 +96,10 @@ module Middleman
|
|
93
96
|
if resource.path =~ path_matcher
|
94
97
|
resource.extend BlogArticle
|
95
98
|
|
99
|
+
if @controller
|
100
|
+
resource.blog_controller = controller
|
101
|
+
end
|
102
|
+
|
96
103
|
# Skip articles that are not published (in non-development environments)
|
97
104
|
next unless @app.environment == :development || resource.published?
|
98
105
|
|
@@ -6,56 +6,73 @@ module Middleman
|
|
6
6
|
class CalendarPages
|
7
7
|
class << self
|
8
8
|
# Get a path to the given calendar page, based on the :year_link, :month_link or :day_link setting.
|
9
|
-
# @param [
|
9
|
+
# @param [Hash] blog_options
|
10
10
|
# @param [Number] year
|
11
11
|
# @param [Number] month
|
12
12
|
# @param [Number] day
|
13
13
|
# @return [String]
|
14
|
-
def link(
|
14
|
+
def link(blog_options, year, month=nil, day=nil)
|
15
15
|
path = if day
|
16
|
-
|
16
|
+
blog_options.day_link.
|
17
17
|
sub(':year', year.to_s).
|
18
18
|
sub(':month', month.to_s.rjust(2,'0')).
|
19
19
|
sub(':day', day.to_s.rjust(2,'0'))
|
20
20
|
elsif month
|
21
|
-
|
21
|
+
blog_options.month_link.
|
22
22
|
sub(':year', year.to_s).
|
23
23
|
sub(':month', month.to_s.rjust(2,'0'))
|
24
24
|
else
|
25
|
-
|
25
|
+
blog_options.year_link.
|
26
26
|
sub(':year', year.to_s)
|
27
27
|
end
|
28
28
|
::Middleman::Util.normalize_path(path)
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def initialize(app)
|
32
|
+
def initialize(app, controller=nil)
|
33
33
|
@app = app
|
34
|
+
@blog_controller = controller
|
35
|
+
end
|
36
|
+
|
37
|
+
def blog_data
|
38
|
+
if @blog_controller
|
39
|
+
@blog_controller.data
|
40
|
+
else
|
41
|
+
@app.blog
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def blog_options
|
46
|
+
if @blog_controller
|
47
|
+
@blog_controller.options
|
48
|
+
else
|
49
|
+
@app.blog.options
|
50
|
+
end
|
34
51
|
end
|
35
52
|
|
36
53
|
# Update the main sitemap resource list
|
37
54
|
# @return [void]
|
38
55
|
def manipulate_resource_list(resources)
|
39
56
|
new_resources = []
|
40
|
-
# Set up date pages if the appropriate templates have been specified
|
41
|
-
@app.blog.articles.group_by {|a| a.date.year }.each do |year, year_articles|
|
42
|
-
if @app.blog.options.year_template
|
43
|
-
@app.ignore @app.blog.options.year_template
|
44
57
|
|
45
|
-
|
58
|
+
# Set up date pages if the appropriate templates have been specified
|
59
|
+
self.blog_data.articles.group_by {|a| a.date.year }.each do |year, year_articles|
|
60
|
+
if self.blog_options.year_template
|
61
|
+
path = CalendarPages.link(self.blog_options, year)
|
46
62
|
|
47
63
|
p = ::Middleman::Sitemap::Resource.new(
|
48
64
|
@app.sitemap,
|
49
65
|
path
|
50
66
|
)
|
51
|
-
p.proxy_to(
|
67
|
+
p.proxy_to(self.blog_options.year_template)
|
52
68
|
|
53
69
|
# Add metadata in local variables so it's accessible to
|
54
70
|
# later extensions
|
55
71
|
p.add_metadata :locals => {
|
56
72
|
'page_type' => 'year',
|
57
73
|
'year' => year,
|
58
|
-
'articles' => year_articles
|
74
|
+
'articles' => year_articles,
|
75
|
+
'blog_controller' => @blog_controller
|
59
76
|
}
|
60
77
|
# Add metadata in instance variables for backwards compatibility
|
61
78
|
p.add_metadata do
|
@@ -67,22 +84,21 @@ module Middleman
|
|
67
84
|
end
|
68
85
|
|
69
86
|
year_articles.group_by {|a| a.date.month }.each do |month, month_articles|
|
70
|
-
if
|
71
|
-
|
72
|
-
|
73
|
-
path = CalendarPages.link(@app, year, month)
|
87
|
+
if self.blog_options.month_template
|
88
|
+
path = CalendarPages.link(self.blog_options, year, month)
|
74
89
|
|
75
90
|
p = ::Middleman::Sitemap::Resource.new(
|
76
91
|
@app.sitemap,
|
77
92
|
path
|
78
93
|
)
|
79
|
-
p.proxy_to(
|
94
|
+
p.proxy_to(self.blog_options.month_template)
|
80
95
|
|
81
96
|
p.add_metadata :locals => {
|
82
97
|
'page_type' => 'month',
|
83
98
|
'year' => year,
|
84
99
|
'month' => month,
|
85
|
-
'articles' => month_articles
|
100
|
+
'articles' => month_articles,
|
101
|
+
'blog_controller' => @blog_controller
|
86
102
|
}
|
87
103
|
p.add_metadata do
|
88
104
|
@year = year
|
@@ -94,23 +110,22 @@ module Middleman
|
|
94
110
|
end
|
95
111
|
|
96
112
|
month_articles.group_by {|a| a.date.day }.each do |day, day_articles|
|
97
|
-
if
|
98
|
-
|
99
|
-
|
100
|
-
path = CalendarPages.link(@app, year, month, day)
|
113
|
+
if self.blog_options.day_template
|
114
|
+
path = CalendarPages.link(self.blog_options, year, month, day)
|
101
115
|
|
102
116
|
p = ::Middleman::Sitemap::Resource.new(
|
103
117
|
@app.sitemap,
|
104
118
|
path
|
105
119
|
)
|
106
|
-
p.proxy_to(
|
120
|
+
p.proxy_to(self.blog_options.day_template)
|
107
121
|
|
108
122
|
p.add_metadata :locals => {
|
109
123
|
'page_type' => 'day',
|
110
124
|
'year' => year,
|
111
125
|
'month' => month,
|
112
126
|
'day' => day,
|
113
|
-
'articles' => day_articles
|
127
|
+
'articles' => day_articles,
|
128
|
+
'blog_controller' => @blog_controller
|
114
129
|
}
|
115
130
|
p.add_metadata do
|
116
131
|
@year = year
|
@@ -24,31 +24,29 @@ module Middleman
|
|
24
24
|
:page_link,
|
25
25
|
:publish_future_dated
|
26
26
|
]
|
27
|
-
|
27
|
+
|
28
28
|
KEYS.each do |name|
|
29
29
|
attr_accessor name
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def initialize(options={})
|
33
33
|
options.each do |k,v|
|
34
34
|
self.send(:"#{k}=", v)
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
38
|
-
|
38
|
+
|
39
39
|
class << self
|
40
40
|
def registered(app, options_hash={}, &block)
|
41
41
|
require 'middleman-blog/blog_data'
|
42
42
|
require 'middleman-blog/blog_article'
|
43
43
|
require 'active_support/core_ext/time/zones'
|
44
44
|
|
45
|
-
app.set :time_zone, 'UTC'
|
46
|
-
|
47
45
|
app.send :include, Helpers
|
48
|
-
|
46
|
+
|
49
47
|
options = Options.new(options_hash)
|
50
48
|
yield options if block_given?
|
51
|
-
|
49
|
+
|
52
50
|
options.permalink ||= "/:year/:month/:day/:title.html"
|
53
51
|
options.sources ||= ":year-:month-:day-:title.html"
|
54
52
|
options.taglink ||= "tags/:tag.html"
|
@@ -90,6 +88,7 @@ module Middleman
|
|
90
88
|
# Make sure ActiveSupport's TimeZone stuff has something to work with,
|
91
89
|
# allowing people to set their desired time zone via Time.zone or
|
92
90
|
# set :time_zone
|
91
|
+
Time.zone = self.time_zone if self.respond_to?(:time_zone)
|
93
92
|
time_zone = Time.zone if Time.zone
|
94
93
|
zone_default = Time.find_zone!(time_zone || 'UTC')
|
95
94
|
unless zone_default
|
@@ -97,9 +96,14 @@ module Middleman
|
|
97
96
|
end
|
98
97
|
Time.zone_default = zone_default
|
99
98
|
|
99
|
+
ignore(options.calendar_template) if options.calendar_template
|
100
|
+
ignore(options.year_template) if options.year_template
|
101
|
+
ignore(options.month_template) if options.month_template
|
102
|
+
ignore(options.day_template) if options.day_template
|
103
|
+
|
100
104
|
# Initialize blog with options
|
101
105
|
blog(options)
|
102
|
-
|
106
|
+
|
103
107
|
sitemap.register_resource_list_manipulator(
|
104
108
|
:blog_articles,
|
105
109
|
blog,
|
@@ -117,8 +121,8 @@ module Middleman
|
|
117
121
|
)
|
118
122
|
end
|
119
123
|
|
120
|
-
if options.year_template ||
|
121
|
-
options.month_template ||
|
124
|
+
if options.year_template ||
|
125
|
+
options.month_template ||
|
122
126
|
options.day_template
|
123
127
|
|
124
128
|
require 'middleman-blog/calendar_pages'
|
@@ -167,31 +171,31 @@ module Middleman
|
|
167
171
|
# @param [String] tag
|
168
172
|
# @return [String]
|
169
173
|
def tag_path(tag)
|
170
|
-
sitemap.find_resource_by_path(TagPages.link(self, tag)).try(:url)
|
174
|
+
sitemap.find_resource_by_path(TagPages.link(self.blog.options, tag)).try(:url)
|
171
175
|
end
|
172
176
|
|
173
177
|
# Get a path to the given year-based calendar page, based on the :year_link setting.
|
174
178
|
# @param [Number] year
|
175
179
|
# @return [String]
|
176
180
|
def blog_year_path(year)
|
177
|
-
sitemap.find_resource_by_path(CalendarPages.link(self, year)).try(:url)
|
181
|
+
sitemap.find_resource_by_path(CalendarPages.link(self.blog.options, year)).try(:url)
|
178
182
|
end
|
179
183
|
|
180
184
|
# Get a path to the given month-based calendar page, based on the :month_link setting.
|
181
|
-
# @param [Number] year
|
185
|
+
# @param [Number] year
|
182
186
|
# @param [Number] month
|
183
187
|
# @return [String]
|
184
188
|
def blog_month_path(year, month)
|
185
|
-
sitemap.find_resource_by_path(CalendarPages.link(self, year, month)).try(:url)
|
189
|
+
sitemap.find_resource_by_path(CalendarPages.link(self.blog.options, year, month)).try(:url)
|
186
190
|
end
|
187
191
|
|
188
192
|
# Get a path to the given day-based calendar page, based on the :day_link setting.
|
189
|
-
# @param [Number] year
|
193
|
+
# @param [Number] year
|
190
194
|
# @param [Number] month
|
191
195
|
# @param [Number] day
|
192
196
|
# @return [String]
|
193
197
|
def blog_day_path(year, month, day)
|
194
|
-
sitemap.find_resource_by_path(CalendarPages.link(self, year, month, day)).try(:url)
|
198
|
+
sitemap.find_resource_by_path(CalendarPages.link(self.blog.options, year, month, day)).try(:url)
|
195
199
|
end
|
196
200
|
|
197
201
|
|
@@ -0,0 +1,208 @@
|
|
1
|
+
module Middleman
|
2
|
+
class BlogExtension < Extension
|
3
|
+
self.supports_multiple_instances = true
|
4
|
+
|
5
|
+
option :name, nil, 'Unique ID for telling multiple blogs apart'
|
6
|
+
option :prefix, nil, 'Prefix to mount the blog at'
|
7
|
+
option :permalink, "/:year/:month/:day/:title.html", 'HTTP path to host articles at'
|
8
|
+
option :sources, ":year-:month-:day-:title.html", 'How to extract metadata from on-disk files'
|
9
|
+
option :taglink, "tags/:tag.html", 'HTTP path to host tag pages at'
|
10
|
+
option :layout, "layout", 'Article-specific layout'
|
11
|
+
option :summary_separator, /(READMORE)/, 'How to split article summaries around a delimeter'
|
12
|
+
option :summary_length, 250, 'Length of words in automatic summaries'
|
13
|
+
option :summary_generator, nil, 'Block to definte how summaries are extracted'
|
14
|
+
option :year_link, "/:year.html", 'HTTP path for yearly archives'
|
15
|
+
option :month_link, "/:year/:month.html", 'HTTP path for monthly archives'
|
16
|
+
option :day_link, "/:year/:month/:day.html", 'HTTP path for daily archives'
|
17
|
+
option :default_extension, ".markdown", 'Default article extension'
|
18
|
+
option :calendar_template, nil, 'Template for calendar pages'
|
19
|
+
option :year_template, nil, 'Template for yearly archive pages'
|
20
|
+
option :month_template, nil, 'Template for monthyl archive pages'
|
21
|
+
option :day_template, nil, 'Template for daily archive pages'
|
22
|
+
option :tag_template, nil, 'Template for tag archive pages'
|
23
|
+
option :paginate, false, 'Whether to paginate pages'
|
24
|
+
option :per_page, 10, 'Articles per page when paginating'
|
25
|
+
option :page_link, "page/:num", 'HTTP path for paging'
|
26
|
+
option :publish_future_dated, false, 'Whether to pubish articles dated in the future'
|
27
|
+
|
28
|
+
attr_accessor :data, :uid
|
29
|
+
|
30
|
+
def initialize(app, options_hash={}, &block)
|
31
|
+
super
|
32
|
+
|
33
|
+
@uid = options.name
|
34
|
+
|
35
|
+
require 'middleman-blog/blog_data'
|
36
|
+
require 'middleman-blog/blog_article'
|
37
|
+
require 'active_support/core_ext/time/zones'
|
38
|
+
|
39
|
+
# app.set :time_zone, 'UTC'
|
40
|
+
|
41
|
+
# optional: :tag_template
|
42
|
+
# optional: :year_template
|
43
|
+
# optional: :month_template
|
44
|
+
# optional: :day_template
|
45
|
+
# Allow one setting to set all the calendar templates
|
46
|
+
if options.calendar_template
|
47
|
+
options.year_template ||= options.calendar_template
|
48
|
+
options.month_template ||= options.calendar_template
|
49
|
+
options.day_template ||= options.calendar_template
|
50
|
+
end
|
51
|
+
|
52
|
+
# If "prefix" option is specified, all other paths are relative to it.
|
53
|
+
if options.prefix
|
54
|
+
options.prefix = "/#{options.prefix}" unless options.prefix.start_with? '/'
|
55
|
+
options.permalink = File.join(options.prefix, options.permalink)
|
56
|
+
options.sources = File.join(options.prefix, options.sources)
|
57
|
+
options.taglink = File.join(options.prefix, options.taglink)
|
58
|
+
options.year_link = File.join(options.prefix, options.year_link)
|
59
|
+
options.month_link = File.join(options.prefix, options.month_link)
|
60
|
+
options.day_link = File.join(options.prefix, options.day_link)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def after_configuration
|
65
|
+
@uid ||= "blog#{@app.blog_instances.keys.length}"
|
66
|
+
|
67
|
+
@app.ignore(options.calendar_template) if options.calendar_template
|
68
|
+
@app.ignore(options.year_template) if options.year_template
|
69
|
+
@app.ignore(options.month_template) if options.month_template
|
70
|
+
@app.ignore(options.day_template) if options.day_template
|
71
|
+
|
72
|
+
@app.blog_instances[@uid.to_sym] = self
|
73
|
+
|
74
|
+
# Make sure ActiveSupport's TimeZone stuff has something to work with,
|
75
|
+
# allowing people to set their desired time zone via Time.zone or
|
76
|
+
# set :time_zone
|
77
|
+
Time.zone = app.config[:time_zone] if app.config[:time_zone]
|
78
|
+
time_zone = Time.zone if Time.zone
|
79
|
+
zone_default = Time.find_zone!(time_zone || 'UTC')
|
80
|
+
unless zone_default
|
81
|
+
raise 'Value assigned to time_zone not recognized.'
|
82
|
+
end
|
83
|
+
Time.zone_default = zone_default
|
84
|
+
|
85
|
+
# Initialize blog with options
|
86
|
+
|
87
|
+
@data = ::Middleman::Blog::BlogData.new(@app, options, self)
|
88
|
+
|
89
|
+
@app.sitemap.register_resource_list_manipulator(
|
90
|
+
:"blog_#{uid}_articles",
|
91
|
+
@data,
|
92
|
+
false
|
93
|
+
)
|
94
|
+
|
95
|
+
if options.tag_template
|
96
|
+
@app.ignore options.tag_template
|
97
|
+
|
98
|
+
require 'middleman-blog/tag_pages'
|
99
|
+
@app.sitemap.register_resource_list_manipulator(
|
100
|
+
:"blog_#{uid}_tags",
|
101
|
+
::Middleman::Blog::TagPages.new(@app, self),
|
102
|
+
false
|
103
|
+
)
|
104
|
+
end
|
105
|
+
|
106
|
+
if options.year_template || options.month_template || options.day_template
|
107
|
+
require 'middleman-blog/calendar_pages'
|
108
|
+
@app.sitemap.register_resource_list_manipulator(
|
109
|
+
:"blog_#{uid}_calendar",
|
110
|
+
::Middleman::Blog::CalendarPages.new(@app, self),
|
111
|
+
false
|
112
|
+
)
|
113
|
+
end
|
114
|
+
|
115
|
+
if options.paginate
|
116
|
+
require 'middleman-blog/paginator'
|
117
|
+
@app.sitemap.register_resource_list_manipulator(
|
118
|
+
:"blog_#{uid}_paginate",
|
119
|
+
::Middleman::Blog::Paginator.new(@app, self),
|
120
|
+
false
|
121
|
+
)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Helpers for use within templates and layouts.
|
126
|
+
helpers do
|
127
|
+
def blog_instances
|
128
|
+
@blog_instances ||= {}
|
129
|
+
end
|
130
|
+
|
131
|
+
def blog_controller(key=nil)
|
132
|
+
key ||= (current_resource && current_resource.metadata[:page]["blog"]) || blog_instances.keys.first
|
133
|
+
blog_instances[key.to_sym]
|
134
|
+
end
|
135
|
+
|
136
|
+
def blog(key=nil)
|
137
|
+
blog_controller(key).data
|
138
|
+
end
|
139
|
+
|
140
|
+
# Determine whether the currently rendering template is a blog article.
|
141
|
+
# This can be useful in layouts.
|
142
|
+
# @return [Boolean]
|
143
|
+
def is_blog_article?
|
144
|
+
!current_article.nil?
|
145
|
+
end
|
146
|
+
|
147
|
+
# Get a {Resource} with mixed in {BlogArticle} methods representing the current article.
|
148
|
+
# @return [Middleman::Sitemap::Resource]
|
149
|
+
def current_article
|
150
|
+
blog_instances.each do |key, blog|
|
151
|
+
found = blog.data.article(current_resource.path)
|
152
|
+
return found if found
|
153
|
+
end
|
154
|
+
|
155
|
+
nil
|
156
|
+
end
|
157
|
+
|
158
|
+
# Get a path to the given tag, based on the :taglink setting.
|
159
|
+
# @param [String] tag
|
160
|
+
# @return [String]
|
161
|
+
def tag_path(tag, key=nil)
|
162
|
+
sitemap.find_resource_by_path(::Middleman::Blog::TagPages.link(blog_controller(key).options, tag)).try(:url)
|
163
|
+
end
|
164
|
+
|
165
|
+
# Get a path to the given year-based calendar page, based on the :year_link setting.
|
166
|
+
# @param [Number] year
|
167
|
+
# @return [String]
|
168
|
+
def blog_year_path(year, key=nil)
|
169
|
+
sitemap.find_resource_by_path(::Middleman::Blog::CalendarPages.link(blog_controller(key).options, year)).try(:url)
|
170
|
+
end
|
171
|
+
|
172
|
+
# Get a path to the given month-based calendar page, based on the :month_link setting.
|
173
|
+
# @param [Number] year
|
174
|
+
# @param [Number] month
|
175
|
+
# @return [String]
|
176
|
+
def blog_month_path(year, month, key=nil)
|
177
|
+
sitemap.find_resource_by_path(::Middleman::Blog::CalendarPages.link(blog_controller(key).options, year, month)).try(:url)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Get a path to the given day-based calendar page, based on the :day_link setting.
|
181
|
+
# @param [Number] year
|
182
|
+
# @param [Number] month
|
183
|
+
# @param [Number] day
|
184
|
+
# @return [String]
|
185
|
+
def blog_day_path(year, month, day, key=nil)
|
186
|
+
sitemap.find_resource_by_path(::Middleman::Blog::CalendarPages.link(blog_controller(key).options, year, month, day)).try(:url)
|
187
|
+
end
|
188
|
+
|
189
|
+
# Pagination Helpers
|
190
|
+
# These are used by the template if pagination is off, to allow a single template to work
|
191
|
+
# in both modes. They get overridden by the local variables if the paginator is active.
|
192
|
+
|
193
|
+
# Returns true if pagination is turned on for this template; false otherwise.
|
194
|
+
# @return [Boolean]
|
195
|
+
def paginate; false; end
|
196
|
+
|
197
|
+
# Returns the list of articles to display on this page.
|
198
|
+
# @return [Array<Middleman::Sitemap::Resource>]
|
199
|
+
def page_articles(key=nil)
|
200
|
+
limit = (current_resource.metadata[:page]["per_page"] || 0) - 1
|
201
|
+
|
202
|
+
# "articles" local variable is populated by Calendar and Tag page generators
|
203
|
+
# If it's not set then use the complete list of articles
|
204
|
+
d = (current_resource.metadata[:locals]["articles"] || blog(key).articles)[0..limit]
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|