middleman-blog 3.3.0 → 3.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +1 -2
- data/Gemfile-3.0 +1 -1
- data/features/custom_collections.feature +70 -0
- data/features/custom_collections_multiblog.feature +58 -0
- data/features/custom_permalinks_feature.feature +33 -0
- data/features/tags_multiblog.feature +28 -2
- data/fixtures/calendar-and-tag-app/config-directory-indexes.rb +0 -1
- data/fixtures/calendar-app/config-directory-indexes.rb +0 -1
- data/fixtures/custom-collections-app/config-blog-prefix.rb +13 -0
- data/fixtures/custom-collections-app/config-directory-indexes.rb +13 -0
- data/fixtures/custom-collections-app/config.rb +12 -0
- data/fixtures/custom-collections-app/source/blog/2011-01-01-new-article.html.markdown +8 -0
- data/fixtures/custom-collections-app/source/blog/2011-01-02-another-article.html.markdown +9 -0
- data/fixtures/custom-collections-app/source/category.html.erb +7 -0
- data/fixtures/custom-collections-app/source/index.html.erb +5 -0
- data/fixtures/custom-collections-app/source/layout.erb +13 -0
- data/fixtures/custom-collections-multiblog-app/config.rb +27 -0
- data/fixtures/custom-collections-multiblog-app/source/blog1/2011-01-01-new-article.html.markdown +7 -0
- data/fixtures/custom-collections-multiblog-app/source/blog1/2011-01-02-another-article.html.markdown +7 -0
- data/fixtures/custom-collections-multiblog-app/source/blog2/2011-01-01-new-article.html.markdown +7 -0
- data/fixtures/custom-collections-multiblog-app/source/blog2/2011-01-02-another-article.html.markdown +7 -0
- data/fixtures/custom-collections-multiblog-app/source/category1.html.erb +7 -0
- data/fixtures/custom-collections-multiblog-app/source/category2.html.erb +7 -0
- data/fixtures/custom-collections-multiblog-app/source/index.html.erb +8 -0
- data/fixtures/custom-collections-multiblog-app/source/layout.erb +13 -0
- data/fixtures/custom-permalinks-app/config-directory-indexes.rb +7 -0
- data/fixtures/custom-permalinks-app/config.rb +5 -0
- data/fixtures/custom-permalinks-app/source/blog/2011-01-01-new-article.html.markdown +7 -0
- data/fixtures/custom-permalinks-app/source/blog/2011-01-02-another-article.html.markdown +7 -0
- data/fixtures/custom-permalinks-app/source/blog/2011-01-03-third-article.html.markdown +7 -0
- data/fixtures/custom-permalinks-app/source/index.html.erb +3 -0
- data/fixtures/custom-permalinks-app/source/layout.erb +13 -0
- data/fixtures/indexes-app/config.rb +0 -1
- data/fixtures/layouts-app/config.rb +0 -2
- data/fixtures/multiblog-app/source/index.html.erb +1 -3
- data/fixtures/paginate-app/config-directory-indexes.rb +0 -1
- data/fixtures/tags-app/config-directory-indexes.rb +0 -1
- data/fixtures/tags-app/config.rb +1 -1
- data/fixtures/tags-multiblog-app/config.rb +1 -1
- data/fixtures/tags-multiblog-app/source/blog1/frontmatter_blog_tags.html.erb +9 -0
- data/fixtures/tags-multiblog-app/source/blog1/named_blog_tags.html.erb +5 -0
- data/fixtures/tags-multiblog-app/source/blog2/frontmatter_blog_tags.html.erb +9 -0
- data/fixtures/tags-multiblog-app/source/blog2/named_blog_tags.html.erb +5 -0
- data/lib/middleman-blog/blog_article.rb +7 -2
- data/lib/middleman-blog/blog_data.rb +37 -20
- data/lib/middleman-blog/custom_pages.rb +85 -0
- data/lib/middleman-blog/extension_3_0.rb +28 -1
- data/lib/middleman-blog/extension_3_1.rb +71 -1
- data/lib/middleman-blog/paginator.rb +2 -2
- data/lib/middleman-blog/template/source/feed.xml.builder +1 -1
- data/lib/middleman-blog/template/source/layout.erb +1 -0
- data/lib/middleman-blog/version.rb +1 -1
- data/middleman-blog.gemspec +1 -2
- metadata +67 -18
@@ -0,0 +1,8 @@
|
|
1
|
+
<% blog(:blog_name_1).articles[0...12].each do |article| %>
|
2
|
+
<li><a href="<%= article.url %>"><%= article.title %></a> <time><%= article.date.strftime('%b %e') %></time></li>
|
3
|
+
<% end %>
|
4
|
+
<% blog(:blog_name_2).articles[0...12].each do |article| %>
|
5
|
+
<li><a href="<%= article.url %>"><%= article.title %></a> <time><%= article.date.strftime('%b %e') %></time></li>
|
6
|
+
<% end %>
|
7
|
+
Category Path1: '<%= category_path("ruby-on-rails", :blog_name_1) %>'
|
8
|
+
Category Path2: '<%= category_path("javascript", :blog_name_2) %>'
|
@@ -1,7 +1,5 @@
|
|
1
|
-
<p>Default blog length: <%= blog.articles.length %></p>
|
2
|
-
|
3
1
|
<p>blog_number_1 length: <%= blog(:blog_number_1).articles.length %></p>
|
4
2
|
<p>blog_number_1 title: <%= blog(:blog_number_1).articles[0].data.title %></p>
|
5
3
|
|
6
4
|
<p>blog_number_2 length: <%= blog("blog_number_2").articles.length %></p>
|
7
|
-
<p>blog_number_2 title: <%= blog("blog_number_2").articles[0].data.title %></p>
|
5
|
+
<p>blog_number_2 title: <%= blog("blog_number_2").articles[0].data.title %></p>
|
data/fixtures/tags-app/config.rb
CHANGED
@@ -129,7 +129,6 @@ module Middleman
|
|
129
129
|
# @return [String]
|
130
130
|
def path_part(part)
|
131
131
|
@_path_parts ||= blog_data.path_matcher.match(path).captures
|
132
|
-
|
133
132
|
@_path_parts[blog_data.matcher_indexes[part]]
|
134
133
|
end
|
135
134
|
|
@@ -176,8 +175,10 @@ module Middleman
|
|
176
175
|
|
177
176
|
@_slug ||= if blog_options.sources.include?(":title")
|
178
177
|
path_part("title")
|
179
|
-
|
178
|
+
elsif title
|
180
179
|
title.parameterize
|
180
|
+
else
|
181
|
+
raise "Can't generate a slug for #{path} because it has no :title in its path pattern or title/slug in its frontmatter."
|
181
182
|
end
|
182
183
|
end
|
183
184
|
|
@@ -194,6 +195,10 @@ module Middleman
|
|
194
195
|
def next_article
|
195
196
|
blog_data.articles.reverse.find {|a| a.date > self.date }
|
196
197
|
end
|
198
|
+
|
199
|
+
def inspect
|
200
|
+
"#<Middleman::Blog::BlogArticle: #{data.inspect}>"
|
201
|
+
end
|
197
202
|
end
|
198
203
|
end
|
199
204
|
end
|
@@ -7,7 +7,7 @@ module Middleman
|
|
7
7
|
# A regex for matching blog article source paths
|
8
8
|
# @return [Regex]
|
9
9
|
attr_reader :path_matcher
|
10
|
-
|
10
|
+
|
11
11
|
# A hash of indexes into the path_matcher captures
|
12
12
|
# @return [Hash]
|
13
13
|
attr_reader :matcher_indexes
|
@@ -18,6 +18,8 @@ module Middleman
|
|
18
18
|
|
19
19
|
attr_reader :controller
|
20
20
|
|
21
|
+
DEFAULT_PERMALINK_COMPONENTS = [:year, :month, :day, :title]
|
22
|
+
|
21
23
|
# @private
|
22
24
|
def initialize(app, options={}, controller=nil)
|
23
25
|
@app = app
|
@@ -26,7 +28,7 @@ module Middleman
|
|
26
28
|
|
27
29
|
# A list of resources corresponding to blog articles
|
28
30
|
@_articles = []
|
29
|
-
|
31
|
+
|
30
32
|
matcher = Regexp.escape(options.sources).
|
31
33
|
sub(/^\//, "").
|
32
34
|
gsub(":year", "(\\d{4})").
|
@@ -105,24 +107,17 @@ module Middleman
|
|
105
107
|
|
106
108
|
# compute output path:
|
107
109
|
# substitute date parts to path pattern
|
108
|
-
resource.destination_path =
|
109
|
-
sub(':year', resource.date.year.to_s).
|
110
|
-
sub(':month', resource.date.month.to_s.rjust(2,'0')).
|
111
|
-
sub(':day', resource.date.day.to_s.rjust(2,'0')).
|
112
|
-
sub(':title', resource.slug)
|
113
|
-
|
114
|
-
resource.destination_path = Middleman::Util.normalize_path(resource.destination_path)
|
110
|
+
resource.destination_path = Middleman::Util.normalize_path parse_permalink_options(resource)
|
115
111
|
|
116
112
|
@_articles << resource
|
117
113
|
|
118
114
|
elsif resource.path =~ @subdir_matcher
|
119
115
|
match = $~.captures
|
120
116
|
|
121
|
-
article_path = options.sources
|
122
|
-
|
123
|
-
sub(
|
124
|
-
|
125
|
-
sub(':title', match[@matcher_indexes["title"]])
|
117
|
+
article_path = options.sources
|
118
|
+
%w(year month day title).each do |token|
|
119
|
+
article_path = article_path.sub(":#{token}", match[@matcher_indexes[token]]) if @matcher_indexes[token]
|
120
|
+
end
|
126
121
|
|
127
122
|
article = @app.sitemap.find_resource_by_path(article_path)
|
128
123
|
raise "Article for #{resource.path} not found" if article.nil?
|
@@ -133,11 +128,7 @@ module Middleman
|
|
133
128
|
|
134
129
|
# The subdir path is the article path with the index file name
|
135
130
|
# or file extension stripped off.
|
136
|
-
resource.destination_path =
|
137
|
-
sub(':year', article.date.year.to_s).
|
138
|
-
sub(':month', article.date.month.to_s.rjust(2,'0')).
|
139
|
-
sub(':day', article.date.day.to_s.rjust(2,'0')).
|
140
|
-
sub(':title', article.slug).
|
131
|
+
resource.destination_path = parse_permalink_options(article).
|
141
132
|
sub(/(\/#{@app.index_file}$)|(\.[^.]+$)|(\/$)/, match[@matcher_indexes["path"]])
|
142
133
|
|
143
134
|
resource.destination_path = Middleman::Util.normalize_path(resource.destination_path)
|
@@ -145,9 +136,35 @@ module Middleman
|
|
145
136
|
|
146
137
|
used_resources << resource
|
147
138
|
end
|
148
|
-
|
139
|
+
|
149
140
|
used_resources
|
150
141
|
end
|
142
|
+
|
143
|
+
def parse_permalink_options(resource)
|
144
|
+
permalink = options.permalink.
|
145
|
+
sub(':year', resource.date.year.to_s).
|
146
|
+
sub(':month', resource.date.month.to_s.rjust(2, '0')).
|
147
|
+
sub(':day', resource.date.day.to_s.rjust(2, '0')).
|
148
|
+
sub(':title', resource.slug)
|
149
|
+
|
150
|
+
custom_permalink_components.each do |component|
|
151
|
+
permalink = permalink.sub(":#{component}", resource.data[component].parameterize)
|
152
|
+
end
|
153
|
+
|
154
|
+
permalink
|
155
|
+
end
|
156
|
+
|
157
|
+
def custom_permalink_components
|
158
|
+
permalink_url_components.reject { |component| DEFAULT_PERMALINK_COMPONENTS.include? component.to_sym }
|
159
|
+
end
|
160
|
+
|
161
|
+
def permalink_url_components
|
162
|
+
options.permalink.scan(/:([A-Za-z0-9]+)/).flatten
|
163
|
+
end
|
164
|
+
|
165
|
+
def inspect
|
166
|
+
"#<Middleman::Blog::BlogData: #{articles.inspect}>"
|
167
|
+
end
|
151
168
|
end
|
152
169
|
end
|
153
170
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Middleman
|
2
|
+
module Blog
|
3
|
+
|
4
|
+
class CustomPages
|
5
|
+
|
6
|
+
class << self
|
7
|
+
|
8
|
+
# Return a path to the given property / value pair
|
9
|
+
#
|
10
|
+
# @param [Hash] blog_options
|
11
|
+
# @param [String|Symbol] property Frontmatter property used to collect on
|
12
|
+
# @param [String| value Frontmatter value for the given article for the given property
|
13
|
+
def link(blog_options, property, value)
|
14
|
+
link_template = blog_options.custom_collections[property][:link]
|
15
|
+
::Middleman::Util.normalize_path(link_template.sub(":#{property}", value.parameterize))
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
attr_reader :property, :app, :blog_controller
|
21
|
+
|
22
|
+
def initialize(property, app, controller = nil)
|
23
|
+
@property = property
|
24
|
+
@app = app
|
25
|
+
@blog_controller = controller
|
26
|
+
end
|
27
|
+
|
28
|
+
def blog_data
|
29
|
+
if blog_controller
|
30
|
+
blog_controller.data
|
31
|
+
else
|
32
|
+
app.blog
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def blog_options
|
37
|
+
if blog_controller
|
38
|
+
blog_controller.options
|
39
|
+
else
|
40
|
+
app.blog.options
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def articles
|
45
|
+
blog_data.articles
|
46
|
+
end
|
47
|
+
|
48
|
+
def manipulate_resource_list(resources)
|
49
|
+
new_resources = []
|
50
|
+
|
51
|
+
articles.group_by { |a| a.data[property] }.each do |property_value, property_articles|
|
52
|
+
path = CustomPages.link(blog_options, property, property_value)
|
53
|
+
new_resources << build_resource(path, property_value, property_articles)
|
54
|
+
end
|
55
|
+
|
56
|
+
resources + new_resources
|
57
|
+
end
|
58
|
+
|
59
|
+
def build_resource(path, value, property_articles)
|
60
|
+
p = ::Middleman::Sitemap::Resource.new(app.sitemap, path)
|
61
|
+
p.proxy_to(template_for_page)
|
62
|
+
p.add_metadata :locals => {
|
63
|
+
"page_type" => property,
|
64
|
+
"#{property}" => value,
|
65
|
+
"articles" => property_articles,
|
66
|
+
"blog_controller" => blog_controller
|
67
|
+
}
|
68
|
+
|
69
|
+
prop_name = property
|
70
|
+
p.add_metadata do
|
71
|
+
instance_variable_set("@#{prop_name}", value)
|
72
|
+
@articles = property_articles
|
73
|
+
end
|
74
|
+
|
75
|
+
p
|
76
|
+
end
|
77
|
+
|
78
|
+
def template_for_page
|
79
|
+
blog_options.custom_collections[property][:template]
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
end
|
@@ -22,7 +22,8 @@ module Middleman
|
|
22
22
|
:paginate,
|
23
23
|
:per_page,
|
24
24
|
:page_link,
|
25
|
-
:publish_future_dated
|
25
|
+
:publish_future_dated,
|
26
|
+
:custom_collections
|
26
27
|
]
|
27
28
|
|
28
29
|
KEYS.each do |name|
|
@@ -61,6 +62,7 @@ module Middleman
|
|
61
62
|
options.per_page ||= 10
|
62
63
|
options.page_link ||= "page/:num"
|
63
64
|
options.publish_future_dated ||= false
|
65
|
+
options.custom_collections ||= {}
|
64
66
|
|
65
67
|
# optional: :tag_template
|
66
68
|
# optional: :year_template
|
@@ -82,6 +84,10 @@ module Middleman
|
|
82
84
|
options.year_link = File.join(options.prefix, options.year_link)
|
83
85
|
options.month_link = File.join(options.prefix, options.month_link)
|
84
86
|
options.day_link = File.join(options.prefix, options.day_link)
|
87
|
+
|
88
|
+
options.custom_collections.each do |key, opts|
|
89
|
+
opts[:link] = File.join(options.prefix, opts[:link])
|
90
|
+
end
|
85
91
|
end
|
86
92
|
|
87
93
|
app.after_configuration do
|
@@ -141,6 +147,27 @@ module Middleman
|
|
141
147
|
false
|
142
148
|
)
|
143
149
|
end
|
150
|
+
|
151
|
+
if options.custom_collections
|
152
|
+
require 'middleman-blog/custom_pages'
|
153
|
+
options.custom_collections.each do |property, options|
|
154
|
+
ignore options[:template]
|
155
|
+
sitemap.register_resource_list_manipulator(
|
156
|
+
:"blog_#{property}",
|
157
|
+
CustomPages.new(property, self),
|
158
|
+
false
|
159
|
+
)
|
160
|
+
|
161
|
+
m = Module.new
|
162
|
+
m.module_eval(%Q{
|
163
|
+
def #{property}_path(value, key = nil)
|
164
|
+
sitemap.find_resource_by_path(CustomPages.link(self.blog.options, :#{property}, value)).try(:url)
|
165
|
+
end
|
166
|
+
})
|
167
|
+
|
168
|
+
self.class.send(:include, m)
|
169
|
+
end
|
170
|
+
end
|
144
171
|
end
|
145
172
|
end
|
146
173
|
alias :included :registered
|