middleman-blog 3.4.1 → 3.5.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.
Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -6
  3. data/CHANGELOG.md +32 -1
  4. data/Gemfile +5 -9
  5. data/README.md +3 -2
  6. data/features/article_cli.feature +10 -1
  7. data/features/custom_collections.feature +11 -0
  8. data/features/language.feature +82 -0
  9. data/features/multiblog.feature +4 -2
  10. data/features/permalink-data.feature +12 -0
  11. data/features/summary.feature +13 -0
  12. data/features/support/env.rb +3 -0
  13. data/features/tags.feature +18 -1
  14. data/features/time_zone.feature +1 -1
  15. data/fixtures/custom-article-template-app/config.rb +3 -0
  16. data/fixtures/custom-article-template-app/my_custom_article.tt +7 -0
  17. data/fixtures/custom-article-template-app/source/index.html.erb +9 -0
  18. data/fixtures/custom-article-template-app/source/layout.erb +30 -0
  19. data/fixtures/custom-collections-sources-app/config.rb +11 -0
  20. data/fixtures/custom-collections-sources-app/source/articles/2011-01-02-another-article.html.markdown +8 -0
  21. data/fixtures/custom-collections-sources-app/source/category.html.erb +7 -0
  22. data/fixtures/custom-collections-sources-app/source/index.html.erb +5 -0
  23. data/fixtures/custom-collections-sources-app/source/layout.erb +13 -0
  24. data/fixtures/custom-collections-sources-app/source/news/2011-01-01-new-article.html.markdown +7 -0
  25. data/fixtures/language-app/config.rb +2 -0
  26. data/fixtures/language-app/locales/en.yml +4 -0
  27. data/fixtures/language-app/locales/ru.yml +4 -0
  28. data/fixtures/language-app/source/2013-09-07-english-article-with-lang-in-frontmatter.html.erb +6 -0
  29. data/fixtures/language-app/source/2013-09-07-russian-article-with-lang-in-frontmatter.html.erb +6 -0
  30. data/fixtures/language-app/source/en/2013-09-07-english-article-with-lang-in-path.html.erb +5 -0
  31. data/fixtures/language-app/source/layouts/layout.erb +8 -0
  32. data/fixtures/language-app/source/localizable/index.html.erb +5 -0
  33. data/fixtures/language-app/source/ru/2013-09-07-russian-article-with-lang-in-path.html.erb +5 -0
  34. data/fixtures/multiblog-app/source/blog1/index.html.erb +7 -0
  35. data/fixtures/permalink-data-app/config.rb +5 -0
  36. data/fixtures/permalink-data-app/source/index.html.erb +3 -0
  37. data/fixtures/permalink-data-app/source/layout.erb +14 -0
  38. data/fixtures/permalink-data-app/source/news/2011-01-01-new-article.html.markdown +7 -0
  39. data/fixtures/time-zone-app/source/blog/2013-06-24-hello.html.erb +1 -0
  40. data/lib/middleman-blog.rb +3 -8
  41. data/lib/middleman-blog/blog_article.rb +96 -60
  42. data/lib/middleman-blog/blog_data.rb +78 -76
  43. data/lib/middleman-blog/calendar_pages.rb +87 -119
  44. data/lib/middleman-blog/commands/article.rb +20 -14
  45. data/lib/middleman-blog/custom_pages.rb +30 -64
  46. data/lib/middleman-blog/extension.rb +175 -0
  47. data/lib/middleman-blog/helpers.rb +152 -0
  48. data/lib/middleman-blog/paginator.rb +127 -123
  49. data/lib/middleman-blog/tag_pages.rb +27 -45
  50. data/lib/middleman-blog/template.rb +17 -15
  51. data/lib/middleman-blog/template/config.tt +30 -33
  52. data/lib/middleman-blog/template/source/layout.erb +1 -0
  53. data/lib/middleman-blog/uri_templates.rb +58 -0
  54. data/lib/middleman-blog/version.rb +1 -1
  55. data/middleman-blog.gemspec +4 -1
  56. metadata +75 -9
  57. data/Gemfile-3.0 +0 -27
  58. data/lib/middleman-blog/extension_3_0.rb +0 -248
  59. data/lib/middleman-blog/extension_3_1.rb +0 -278
@@ -1,147 +1,115 @@
1
+ require 'middleman-blog/uri_templates'
2
+
1
3
  module Middleman
2
4
  module Blog
3
-
4
5
  # A sitemap plugin that adds month/day/year pages to the sitemap
5
6
  # based on the dates of blog articles.
6
7
  class CalendarPages
7
- class << self
8
- # Get a path to the given calendar page, based on the :year_link, :month_link or :day_link setting.
9
- # @param [Hash] blog_options
10
- # @param [Number] year
11
- # @param [Number] month
12
- # @param [Number] day
13
- # @return [String]
14
- def link(blog_options, year, month=nil, day=nil)
15
- path = if day
16
- blog_options.day_link.
17
- sub(':year', year.to_s).
18
- sub(':month', month.to_s.rjust(2,'0')).
19
- sub(':day', day.to_s.rjust(2,'0'))
20
- elsif month
21
- blog_options.month_link.
22
- sub(':year', year.to_s).
23
- sub(':month', month.to_s.rjust(2,'0'))
24
- else
25
- blog_options.year_link.
26
- sub(':year', year.to_s)
27
- end
28
- ::Middleman::Util.normalize_path(path)
29
- end
30
- end
8
+ include UriTemplates
31
9
 
32
- def initialize(app, controller=nil)
33
- @app = app
34
- @blog_controller = controller
35
- end
10
+ def initialize(app, blog_controller)
11
+ @sitemap = app.sitemap
12
+ @blog_controller = blog_controller
13
+ @blog_data = blog_controller.data
36
14
 
37
- def blog_data
38
- if @blog_controller
39
- @blog_controller.data
40
- else
41
- @app.blog
42
- end
15
+ blog_options = blog_controller.options
16
+ @day_link_template = uri_template blog_options.day_link
17
+ @month_link_template = uri_template blog_options.month_link
18
+ @year_link_template = uri_template blog_options.year_link
19
+ @day_template = blog_options.day_template
20
+ @month_template = blog_options.month_template
21
+ @year_template = blog_options.year_template
43
22
  end
44
23
 
45
- def blog_options
46
- if @blog_controller
47
- @blog_controller.options
48
- else
49
- @app.blog.options
50
- end
24
+ # Get a path to the given calendar page, based on the :year_link, :month_link or :day_link setting.
25
+ # @param [Number] year
26
+ # @param [Number] month
27
+ # @param [Number] day
28
+ # @return [String]
29
+ def link(year, month=nil, day=nil)
30
+ template = if day
31
+ @day_link_template
32
+ elsif month
33
+ @month_link_template
34
+ else
35
+ @year_link_template
36
+ end
37
+
38
+ apply_uri_template template, date_to_params(Date.new(year, month || 1, day || 1))
51
39
  end
52
-
40
+
53
41
  # Update the main sitemap resource list
54
- # @return [void]
42
+ # @return [Array<Middleman::Sitemap::Resource>]
55
43
  def manipulate_resource_list(resources)
56
44
  new_resources = []
57
45
 
58
46
  # 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)
62
-
63
- p = ::Middleman::Sitemap::Resource.new(
64
- @app.sitemap,
65
- path
66
- )
67
- p.proxy_to(self.blog_options.year_template)
68
-
69
- # Add metadata in local variables so it's accessible to
70
- # later extensions
71
- p.add_metadata :locals => {
72
- 'page_type' => 'year',
73
- 'year' => year,
74
- 'articles' => year_articles,
75
- 'blog_controller' => @blog_controller
76
- }
77
- # Add metadata in instance variables for backwards compatibility
78
- p.add_metadata do
79
- @year = year
80
- @articles = year_articles
81
- end
82
-
83
- new_resources << p
47
+ @blog_data.articles.group_by {|a| a.date.year }.each do |year, year_articles|
48
+ if @year_template
49
+ new_resources << year_page_resource(year, year_articles)
84
50
  end
85
-
86
- year_articles.group_by {|a| a.date.month }.each do |month, month_articles|
87
- if self.blog_options.month_template
88
- path = CalendarPages.link(self.blog_options, year, month)
89
-
90
- p = ::Middleman::Sitemap::Resource.new(
91
- @app.sitemap,
92
- path
93
- )
94
- p.proxy_to(self.blog_options.month_template)
95
-
96
- p.add_metadata :locals => {
97
- 'page_type' => 'month',
98
- 'year' => year,
99
- 'month' => month,
100
- 'articles' => month_articles,
101
- 'blog_controller' => @blog_controller
102
- }
103
- p.add_metadata do
104
- @year = year
105
- @month = month
106
- @articles = month_articles
107
- end
108
51
 
109
- new_resources << p
52
+ year_articles.group_by {|a| a.date.month }.each do |month, month_articles|
53
+ if @month_template
54
+ new_resources << month_page_resource(year, month, month_articles)
110
55
  end
111
-
56
+
112
57
  month_articles.group_by {|a| a.date.day }.each do |day, day_articles|
113
- if self.blog_options.day_template
114
- path = CalendarPages.link(self.blog_options, year, month, day)
115
-
116
- p = ::Middleman::Sitemap::Resource.new(
117
- @app.sitemap,
118
- path
119
- )
120
- p.proxy_to(self.blog_options.day_template)
121
-
122
- p.add_metadata :locals => {
123
- 'page_type' => 'day',
124
- 'year' => year,
125
- 'month' => month,
126
- 'day' => day,
127
- 'articles' => day_articles,
128
- 'blog_controller' => @blog_controller
129
- }
130
- p.add_metadata do
131
- @year = year
132
- @month = month
133
- @day = day
134
- @articles = day_articles
135
- end
136
-
137
- new_resources << p
58
+ if @day_template
59
+ new_resources << day_page_resource(year, month, day, day_articles)
138
60
  end
139
61
  end
140
62
  end
141
63
  end
142
64
 
143
65
  resources + new_resources
144
- end
66
+ end
67
+
68
+ private
69
+
70
+ def year_page_resource(year, year_articles)
71
+ Sitemap::Resource.new(@sitemap, link(year)).tap do |p|
72
+ p.proxy_to(@year_template)
73
+
74
+ # Add metadata in local variables so it's accessible to
75
+ # later extensions
76
+ p.add_metadata locals: {
77
+ 'page_type' => 'year',
78
+ 'year' => year,
79
+ 'articles' => year_articles,
80
+ 'blog_controller' => @blog_controller
81
+ }
82
+ end
83
+ end
84
+
85
+ def month_page_resource(year, month, month_articles)
86
+ Sitemap::Resource.new(@sitemap, link(year, month)).tap do |p|
87
+ p.proxy_to(@month_template)
88
+
89
+ p.add_metadata locals: {
90
+ 'page_type' => 'month',
91
+ 'year' => year,
92
+ 'month' => month,
93
+ 'articles' => month_articles,
94
+ 'blog_controller' => @blog_controller
95
+ }
96
+ end
97
+ end
98
+
99
+ def day_page_resource(year, month, day, day_articles)
100
+ Sitemap::Resource.new(@sitemap, link(year, month, day)).tap do |p|
101
+ p.proxy_to(@day_template)
102
+
103
+ p.add_metadata locals: {
104
+ 'page_type' => 'day',
105
+ 'year' => year,
106
+ 'month' => month,
107
+ 'day' => day,
108
+ 'articles' => day_articles,
109
+ 'blog_controller' => @blog_controller
110
+ }
111
+ end
112
+ end
145
113
  end
146
114
  end
147
115
  end
@@ -1,20 +1,20 @@
1
- require 'middleman-core/cli'
1
+ require 'middleman-core/cli'
2
2
  require 'date'
3
+ require 'middleman-blog/uri_templates'
3
4
 
4
5
  module Middleman
5
6
  module Cli
6
7
  # This class provides an "article" command for the middleman CLI.
7
8
  class Article < Thor
8
9
  include Thor::Actions
10
+ include Blog::UriTemplates
9
11
 
10
12
  check_unknown_options!
11
13
 
12
14
  namespace :article
13
15
 
14
- # Template files are relative to this file
15
- # @return [String]
16
16
  def self.source_root
17
- File.dirname(__FILE__)
17
+ ENV['MM_ROOT']
18
18
  end
19
19
 
20
20
  # Tell Thor to exit with a nonzero exit code on failure
@@ -24,24 +24,31 @@ module Middleman
24
24
 
25
25
  desc "article TITLE", "Create a new blog article"
26
26
  method_option "date",
27
- :aliases => "-d",
28
- :desc => "The date to create the post with (defaults to now)"
27
+ aliases: "-d",
28
+ desc: "The date to create the post with (defaults to now)"
29
+ method_option "lang",
30
+ aliases: "-l",
31
+ desc: "The language to create the post with (defaults to I18n.default_locale if avaliable)"
32
+ method_option "blog",
33
+ aliases: "-b",
34
+ desc: "The name of the blog to creat the post inside (for multi-blog apps, defaults to the only blog in single-blog apps)"
29
35
  def article(title)
30
36
  shared_instance = ::Middleman::Application.server.inst
31
37
 
32
38
  # This only exists when the config.rb sets it!
33
39
  if shared_instance.respond_to? :blog
34
40
  @title = title
35
- @slug = title.parameterize
41
+ @slug = safe_parameterize(title)
36
42
  @date = options[:date] ? Time.zone.parse(options[:date]) : Time.zone.now
43
+ @lang = options[:lang] || ( I18n.default_locale if defined? I18n )
37
44
 
38
- article_path = shared_instance.blog.options.sources.
39
- sub(':year', @date.year.to_s).
40
- sub(':month', @date.month.to_s.rjust(2,'0')).
41
- sub(':day', @date.day.to_s.rjust(2,'0')).
42
- sub(':title', @slug)
45
+ blog_inst = shared_instance.blog(options[:blog])
43
46
 
44
- template "article.tt", File.join(shared_instance.source_dir, article_path + shared_instance.blog.options.default_extension)
47
+ path_template = blog_inst.source_template
48
+ params = date_to_params(@date).merge(lang: @lang.to_s, title: @slug)
49
+ article_path = apply_uri_template path_template, params
50
+
51
+ template blog_inst.options.new_article_template, File.join(shared_instance.source_dir, article_path + blog_inst.options.default_extension)
45
52
  else
46
53
  raise Thor::Error.new "You need to activate the blog extension in config.rb before you can create an article"
47
54
  end
@@ -49,4 +56,3 @@ module Middleman
49
56
  end
50
57
  end
51
58
  end
52
-
@@ -1,85 +1,51 @@
1
+ require 'middleman-blog/uri_templates'
2
+
1
3
  module Middleman
2
4
  module Blog
3
5
 
6
+ # This adds new summary pages for arbitrarily defined blog article properties
4
7
  class CustomPages
8
+ include UriTemplates
5
9
 
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
10
+ attr_reader :property
19
11
 
20
- attr_reader :property, :app, :blog_controller
21
-
22
- def initialize(property, app, controller = nil)
23
- @property = property
24
- @app = app
12
+ def initialize(property, app, controller, options)
13
+ @property = property
14
+ @sitemap = app.sitemap
25
15
  @blog_controller = controller
16
+ @blog_data = controller.data
17
+ @link_template = uri_template options[:link]
18
+ @page_template = options[:template]
26
19
  end
27
20
 
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
21
+ # Return a path to the page for this property value.
22
+ #
23
+ # @param [String] value
24
+ def link(value)
25
+ apply_uri_template @link_template, property => safe_parameterize(value)
46
26
  end
47
27
 
48
28
  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)
29
+ articles_by_property = @blog_data.articles.group_by { |a| a.metadata[:page][property.to_s] }
30
+ resources + articles_by_property.map do |property_value, articles|
31
+ build_resource(link(property_value), property_value, articles)
54
32
  end
55
-
56
- resources + new_resources
57
33
  end
58
34
 
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
- }
35
+ private
68
36
 
69
- prop_name = property
70
- p.add_metadata do
71
- instance_variable_set("@#{prop_name}", value)
72
- @articles = property_articles
37
+ def build_resource(path, value, articles)
38
+ articles = articles.sort_by(&:date).reverse
39
+ Sitemap::Resource.new(@sitemap, path).tap do |p|
40
+ p.proxy_to(@page_template)
41
+ p.add_metadata locals: {
42
+ "page_type" => property.to_s,
43
+ property => value,
44
+ "articles" => articles,
45
+ "blog_controller" => @blog_controller
46
+ }
73
47
  end
74
-
75
- p
76
- end
77
-
78
- def template_for_page
79
- blog_options.custom_collections[property][:template]
80
48
  end
81
-
82
49
  end
83
-
84
50
  end
85
51
  end
@@ -0,0 +1,175 @@
1
+ require 'active_support/core_ext/time/zones'
2
+ require 'middleman-blog/blog_data'
3
+ require 'middleman-blog/blog_article'
4
+ require 'middleman-blog/helpers'
5
+
6
+ module Middleman
7
+ class BlogExtension < Extension
8
+ self.supports_multiple_instances = true
9
+
10
+ option :name, nil, 'Unique ID for telling multiple blogs apart'
11
+ option :prefix, nil, 'Prefix to mount the blog at (modifies permalink, sources, taglink, year_link, month_link, day_link to start with the prefix)'
12
+ option :permalink, '/{year}/{month}/{day}/{title}.html', 'Path articles are generated at. Tokens can be omitted or duplicated, and you can use tokens defined in article frontmatter.'
13
+ option :sources, '{year}-{month}-{day}-{title}.html', 'Pattern for matching source blog articles (no template extensions)'
14
+ option :taglink, 'tags/{tag}.html', 'Path tag pages are generated at.'
15
+ option :layout, 'layout', 'Article-specific layout'
16
+ option :summary_separator, /(READMORE)/, 'Regex or string that delimits the article summary from the rest of the article.'
17
+ option :summary_length, 250, 'Truncate summary to be <= this number of characters. Set to -1 to disable summary truncation.'
18
+ option :summary_generator, nil, 'A block that defines how summaries are extracted. It will be passed the rendered article content, max summary length, and ellipsis string as arguments.'
19
+ option :year_link, '/{year}.html', 'Path yearly archive pages are generated at.'
20
+ option :month_link, '/{year}/{month}.html', 'Path monthly archive pages are generated at.'
21
+ option :day_link, '/{year}/{month}/{day}.html', 'Path daily archive pages are generated at.'
22
+ option :calendar_template, nil, 'Template path (no template extension) for calendar pages (year/month/day archives).'
23
+ option :year_template, nil, 'Template path (no template extension) for yearly archive pages. Defaults to the :calendar_template.'
24
+ option :month_template, nil, 'Template path (no template extension) for monthly archive pages. Defaults to the :calendar_template.'
25
+ option :day_template, nil, 'Template path (no template extension) for daily archive pages. Defaults to the :calendar_template.'
26
+ option :tag_template, nil, 'Template path (no template extension) for tag archive pages.'
27
+ option :paginate, false, 'Whether to paginate lists of articles'
28
+ option :per_page, 10, 'Number of articles per page when paginating'
29
+ option :page_link, 'page/{num}', 'Path to append for additional pages when paginating'
30
+ option :publish_future_dated, false, 'Whether articles with a date in the future should be considered published'
31
+ option :custom_collections, {}, 'Hash of custom frontmatter properties to collect articles on and their options (link, template)'
32
+ option :preserve_locale, false, 'Use the global Middleman I18n.locale instead of the lang in the article\'s frontmatter'
33
+ option :new_article_template, File.expand_path('../commands/article.tt', __FILE__), 'Path (relative to project root) to an ERb template that will be used to generate new articles from the "middleman article" command.'
34
+ option :default_extension, '.markdown', 'Default template extension for articles (used by "middleman article")'
35
+
36
+ # @return [BlogData] blog data for this blog, which has all information about the blog articles
37
+ attr_reader :data
38
+
39
+ # @return [Symbol] the name of this blog (autogenerated if not provided).
40
+ attr_reader :name
41
+
42
+ # @return [TagPages] tag page handler for this blog
43
+ attr_reader :tag_pages
44
+
45
+ # @return [CalendarPages] calendar page handler for this blog
46
+ attr_reader :calendar_pages
47
+
48
+ # @return [Paginator] pagination handler for this blog
49
+ attr_reader :paginator
50
+
51
+ # @return [Hash<CustomPages>] custom pages handlers for this blog, indexed by property name
52
+ attr_reader :custom_pages
53
+
54
+ # Helpers for use within templates and layouts.
55
+ self.defined_helpers = [ Middleman::Blog::Helpers ]
56
+
57
+ def initialize(app, options_hash={}, &block)
58
+ super
59
+
60
+ @custom_pages = {}
61
+
62
+ # NAME is the name of this particular blog, and how you reference it from #blog_controller or frontmatter.
63
+ @name = options.name.to_sym if options.name
64
+
65
+ # Allow one setting to set all the calendar templates
66
+ if options.calendar_template
67
+ options.year_template ||= options.calendar_template
68
+ options.month_template ||= options.calendar_template
69
+ options.day_template ||= options.calendar_template
70
+ end
71
+
72
+ # If "prefix" option is specified, all other paths are relative to it.
73
+ if options.prefix
74
+ options.prefix = "/#{options.prefix}" unless options.prefix.start_with? '/'
75
+ options.permalink = File.join(options.prefix, options.permalink)
76
+ options.sources = File.join(options.prefix, options.sources)
77
+ options.taglink = File.join(options.prefix, options.taglink)
78
+ options.year_link = File.join(options.prefix, options.year_link)
79
+ options.month_link = File.join(options.prefix, options.month_link)
80
+ options.day_link = File.join(options.prefix, options.day_link)
81
+
82
+ options.custom_collections.each do |key, opts|
83
+ opts[:link] = File.join(options.prefix, opts[:link])
84
+ end
85
+ end
86
+ end
87
+
88
+ def after_configuration
89
+ @name ||= :"blog#{@app.blog_instances.keys.length}"
90
+
91
+ # TODO: break up into private methods?
92
+
93
+ @app.ignore(options.calendar_template) if options.calendar_template
94
+ @app.ignore(options.year_template) if options.year_template
95
+ @app.ignore(options.month_template) if options.month_template
96
+ @app.ignore(options.day_template) if options.day_template
97
+ @app.ignore options.tag_template if options.tag_template
98
+
99
+ @app.blog_instances[@name] = self
100
+
101
+ # Make sure ActiveSupport's TimeZone stuff has something to work with,
102
+ # allowing people to set their desired time zone via Time.zone or
103
+ # set :time_zone
104
+ Time.zone = app.config[:time_zone] if app.config[:time_zone]
105
+ time_zone = Time.zone || 'UTC'
106
+ zone_default = Time.find_zone!(time_zone)
107
+ unless zone_default
108
+ raise 'Value assigned to time_zone not recognized.'
109
+ end
110
+ Time.zone_default = zone_default
111
+
112
+ # Initialize blog with options
113
+ @data = Blog::BlogData.new(@app, self, options)
114
+
115
+ @app.sitemap.register_resource_list_manipulator(:"blog_#{name}_articles", @data, false)
116
+
117
+ if options.tag_template
118
+ @app.ignore options.tag_template
119
+
120
+ require 'middleman-blog/tag_pages'
121
+ @tag_pages = Blog::TagPages.new(@app, self)
122
+ @app.sitemap.register_resource_list_manipulator(:"blog_#{name}_tags", @tag_pages, false)
123
+ end
124
+
125
+ if options.year_template || options.month_template || options.day_template
126
+ require 'middleman-blog/calendar_pages'
127
+ @calendar_pages = Blog::CalendarPages.new(@app, self)
128
+ @app.sitemap.register_resource_list_manipulator(:"blog_#{name}_calendar", @calendar_pages, false)
129
+ end
130
+
131
+ if options.paginate
132
+ require 'middleman-blog/paginator'
133
+ @paginator = Blog::Paginator.new(@app, self)
134
+ @app.sitemap.register_resource_list_manipulator(:"blog_#{name}_paginate", @paginator, false)
135
+ end
136
+
137
+ if options.custom_collections
138
+ require 'middleman-blog/custom_pages'
139
+ register_custom_pages
140
+ end
141
+ end
142
+
143
+ private
144
+
145
+ # Register any custom page collections that may be set in the config
146
+ #
147
+ # A custom resource list manipulator will be generated for each key in the
148
+ # custom collections hash.
149
+ #
150
+ # The following will collect posts on the "category" frontmatter property:
151
+ # ```
152
+ # activate :blog do |blog|
153
+ # blog.custom_collections = {
154
+ # category: {
155
+ # link: "/categories/:category.html",
156
+ # template: "/category.html"
157
+ # }
158
+ # }
159
+ # end
160
+ # ```
161
+ #
162
+ # Category pages in the example above will use the category.html as a template file
163
+ # and it will be ignored when building.
164
+ def register_custom_pages
165
+ options.custom_collections.each do |property, options|
166
+ @app.ignore options[:template]
167
+
168
+ @custom_pages[property] = Blog::CustomPages.new(property, @app, self, options)
169
+ @app.sitemap.register_resource_list_manipulator(:"blog_#{name}_#{property}", @custom_pages[property], false)
170
+
171
+ Blog::Helpers.generate_custom_helper(property)
172
+ end
173
+ end
174
+ end
175
+ end