dimples 2.4.1 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 4d234cd1d903091ebb32b6c1d4d70f3f192b7521
4
- data.tar.gz: 44a6e425dc98482f06af3ee642d9eea2acf43b4b
3
+ metadata.gz: ab668fba29311d490d3187f339fb6092ddce1b39
4
+ data.tar.gz: e86ce790ccd489891f8ee06d88a9cdddce099015
5
5
  SHA512:
6
- metadata.gz: a5fee8777cea08fd48484ce4c53ecf345c45e8f566f3d8b26ea8a75af155e8ee9391fb44921c0c8f0cb1229d0e868579998d576d77e9571d3ce636908725004b
7
- data.tar.gz: 2936a14e626263cfe177f09ecad4411b76a4a28f42dc06462a687b6a2374a54c21914c2860402d9ab8a9eeffbed1ee903a4eec5a5f595e7b65d528063c8066cb
6
+ metadata.gz: d41ec0a5a57ae5f1a5e7c4d31398a8a925ae78a2c956574aec11b9a7510da53b46ff8ab0fed38a6abd8c50f582a3aaf86f01a60bbe3ea9924cb1a9834dc9b12e
7
+ data.tar.gz: e975c1a286092a240a0721e7eac2a445e1b6143f9004bb668b10631716c197ddccd70b24cb5107a7281c3e837c7a32a19704043158ee704e3536301b1010290b
@@ -1,52 +1,54 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- $LOAD_PATH.unshift(File.join(__dir__, "..", "lib"))
4
+ $LOAD_PATH.unshift(File.join(__dir__, '..', 'lib'))
4
5
 
5
6
  require 'dimples'
6
7
  require 'dimples/version'
7
8
  require 'trollop'
8
9
 
9
10
  trap('SIGINT') do
10
- puts "Generation cancelled!"
11
+ puts 'Generation cancelled!'
11
12
  exit!
12
13
  end
13
14
 
14
15
  valid_commands = %w[build]
15
16
 
16
- options = Trollop::options do
17
+ options = Trollop.options do
17
18
  version "dimples v#{Dimples::VERSION}"
18
- banner <<EOS
19
- A very, very simple static site generator.
19
+ banner <<~EOS
20
+ A very, very simple static site generator.
20
21
 
21
- Usage:
22
- dimples <#{valid_commands.join('|')}> [options]
22
+ Usage:
23
+ dimples <#{valid_commands.join('|')}> [options]
23
24
 
24
- Options:
25
+ Options:
25
26
  EOS
26
- opt :config, "Config file path", type: :string
27
- opt :lib, "Library file path", default: 'lib'
28
- opt :verbose, "Verbose mode", default: false
27
+ opt :config, 'Config file path', type: :string
28
+ opt :lib, 'Library file path', default: 'lib'
29
+ opt :verbose, 'Verbose mode', default: false
29
30
  end
30
31
 
31
- Trollop::educate if ARGV.empty?
32
+ Trollop.educate if ARGV.empty?
32
33
  command = ARGV[0]
33
34
 
34
35
  unless valid_commands.include?(command)
35
- Trollop::die "Command must be '#{valid_commands.join('\', \'')}'"
36
+ Trollop.die "Command must be '#{valid_commands.join('\', \'')}'"
36
37
  end
37
38
 
38
39
  lib_path = File.join(Dir.pwd, options[:lib])
39
40
  config_path = File.join(Dir.pwd, options[:config] || 'config', 'site.yml')
40
41
 
41
- config_hash = if File.exist?(config_path)
42
+ config_hash = {}
43
+
44
+ if File.exist?(config_path)
42
45
  begin
43
- YAML.load_file(config_path) || {}
46
+ config_hash = YAML.load_file(config_path) || {}
44
47
  rescue
45
- Trollop::die "Invalid or malformed YAML config file"
48
+ Trollop.die 'Invalid or malformed YAML config file'
46
49
  end
47
- else
48
- Trollop::die "Unable to find config file" if options[:config]
49
- {}
50
+ elsif options[:config]
51
+ Trollop.die 'Unable to find config file'
50
52
  end
51
53
 
52
54
  config_hash['verbose_logging'] = true if options[:verbose]
@@ -58,7 +60,7 @@ if Dir.exist?(lib_path)
58
60
  end
59
61
  end
60
62
 
61
- site_klass = config.class_override(:site) || Dimples::Site
63
+ site_klass = config.class_override(:site) || Dimples.Site
62
64
  site = site_klass.new(config)
63
65
 
64
66
  case command.to_sym
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  $LOAD_PATH.unshift(__dir__)
2
4
 
3
5
  require 'benchmark'
@@ -20,6 +22,7 @@ require 'dimples/post'
20
22
  require 'dimples/site'
21
23
  require 'dimples/template'
22
24
 
25
+ # A static site generator.
23
26
  module Dimples
24
27
  class << self
25
28
  def logger
@@ -1,13 +1,17 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A class that models a single interview category.
2
5
  class Category
3
6
  attr_accessor :name
4
7
  attr_accessor :slug
5
8
  attr_accessor :posts
6
9
 
7
- def initialize(name, slug)
8
- @name = name
9
- @slug = slug
10
- @posts = []
10
+ def initialize(site, slug)
11
+ @site = site
12
+ @slug = slug
13
+ @name = @site.config['category_names'][slug] || slug.capitalize
14
+ @posts = []
11
15
  end
12
16
  end
13
17
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A class that models a site's configuration.
2
5
  class Configuration
3
6
  def initialize(config = {})
4
7
  @settings = Dimples::Configuration.default_settings
@@ -17,16 +20,14 @@ module Dimples
17
20
  end
18
21
 
19
22
  def class_override(type)
20
- klass = @settings['class_overrides']["#{type}"]
23
+ klass = @settings['class_overrides'][type.to_s]
21
24
  Object.const_get(klass) unless klass.nil?
22
25
  end
23
26
 
24
27
  def self.default_settings
25
- current_path = Dir.pwd
26
-
27
28
  {
28
- 'source_path' => current_path,
29
- 'destination_path' => File.join(current_path, 'site'),
29
+ 'source_path' => Dir.pwd,
30
+ 'destination_path' => File.join(Dir.pwd, 'site'),
30
31
  'verbose_logging' => false,
31
32
  'class_overrides' => { site: nil, post: nil, page: nil },
32
33
  'rendering' => {},
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
2
4
  module Errors
3
5
  class PublishingError < StandardError
@@ -1,20 +1,18 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A mixin class that handles reading and parsing front matter from a file.
2
5
  module Frontable
3
- def read_with_yaml(path)
4
- if File.extname(path) == '.yml'
5
- contents = ''
6
- metadata = YAML.load_file(path)
7
- else
8
- contents = File.read(path)
9
- matches = contents.match(/^(-{3}\n.*?\n?)^(-{3}*$\n?)/m)
6
+ def read_with_front_matter(path)
7
+ contents = File.read(path)
8
+ matches = contents.match(/^(-{3}\n.*?\n?)^(-{3}*$\n?)/m)
10
9
 
11
- if matches
12
- metadata = YAML.load(matches[1])
13
- contents = matches.post_match.strip
14
- end
15
- end
10
+ if matches
11
+ metadata = YAML.safe_load(matches[1])
12
+ contents = matches.post_match.strip
16
13
 
17
- apply_metadata(metadata) if metadata
14
+ apply_metadata(metadata) if metadata
15
+ end
18
16
 
19
17
  contents
20
18
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A simple Logger subclass.
2
5
  class Logger < Logger
3
6
  def initialize(*)
4
7
  super
@@ -14,13 +17,14 @@ module Dimples
14
17
  end
15
18
  end
16
19
 
20
+ # A simple Logger formatting subclass.
17
21
  class LogFormatter < Logger::Formatter
18
- def self.call(severity, time, program_name, message)
19
- prefix = case severity
20
- when "ERROR"
21
- "\033[31mError:\033[0m "
22
+ def self.call(severity, _time, _program_name, message)
23
+ case severity
24
+ when 'ERROR'
25
+ prefix = "\033[31mError:\033[0m "
22
26
  when 'DEBUG'
23
- "\033[93m- "
27
+ prefix = "\033[93m- "
24
28
  end
25
29
 
26
30
  "#{prefix}#{message}\033[0m\n"
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A class that models a single site page.
2
5
  class Page
3
6
  include Frontable
4
7
  include Writeable
@@ -20,7 +23,7 @@ module Dimples
20
23
 
21
24
  if @path
22
25
  @filename = File.basename(@path, File.extname(@path))
23
- @contents = read_with_yaml(@path)
26
+ @contents = read_with_front_matter(@path)
24
27
  else
25
28
  @filename = 'index'
26
29
  @contents = ''
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A class that models a single site post.
2
5
  class Post
3
6
  include Frontable
4
7
  include Writeable
@@ -13,42 +16,41 @@ module Dimples
13
16
  attr_accessor :layout
14
17
  attr_accessor :contents
15
18
  attr_accessor :slug
16
- attr_accessor :date
17
19
  attr_accessor :year
18
20
  attr_accessor :month
19
21
  attr_accessor :day
20
22
  attr_accessor :rendered_contents
21
23
  attr_accessor :previous_post
22
24
  attr_accessor :next_post
23
- attr_accessor :draft
25
+ attr_reader :date
26
+
27
+ FILENAME_DATE = /(\d{4})-(\d{2})-(\d{2})-(.+)/
24
28
 
25
29
  def initialize(site, path)
26
30
  @site = site
27
31
  @path = path
28
-
29
32
  @filename = 'index'
30
33
  @extension = 'html'
31
34
 
32
- date_format = /(\d{4})-(\d{2})-(\d{2})-(.+)/
33
- parts = File.basename(path, File.extname(path)).match(date_format)
35
+ parts = File.basename(path, File.extname(path)).match(FILENAME_DATE)
34
36
 
35
37
  @slug = parts[4]
36
- @date = Time.mktime(parts[1], parts[2], parts[3])
38
+ self.date = Time.mktime(parts[1], parts[2], parts[3])
37
39
 
38
40
  @layout = @site.config['layouts']['post']
39
- @categories = {}
41
+ @contents = read_with_front_matter(path)
42
+ end
40
43
 
41
- @draft = false
44
+ def date=(date)
45
+ @date = date
42
46
 
43
47
  @year = @date.strftime('%Y')
44
48
  @month = @date.strftime('%m')
45
49
  @day = @date.strftime('%d')
46
-
47
- @contents = read_with_yaml(path)
48
50
  end
49
51
 
50
52
  def output_path(parent_path)
51
- parent_path = @date.strftime(parent_path) if parent_path =~ /%/
53
+ parent_path = @date.strftime(parent_path) if parent_path.match?(/%/)
52
54
  File.join([parent_path, @slug.to_s, "#{@filename}.#{@extension}"])
53
55
  end
54
56
  end
@@ -1,21 +1,22 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A mixin class that handles rendering via a Tilt template.
2
5
  module Renderable
3
6
  def render(context = {}, body = nil, use_layout = true)
4
- begin
5
- output = renderer.render(build_scope(context)) { body }.strip
6
- @rendered_contents = output
7
- rescue RuntimeError, TypeError, NoMethodError, SyntaxError, NameError => e
8
- sanitised_error_name = e.class.to_s.gsub(/([A-Z])/, " \\1").strip.downcase
9
- error_message = "Unable to render #{@path || "a dynamic #{self.class}"} (#{sanitised_error_name})"
10
-
11
- raise Errors::RenderingError.new(error_message)
12
- end
7
+ output = renderer.render(build_scope(context)) { body }.strip
8
+ @rendered_contents = output
13
9
 
14
10
  if use_layout && defined?(@layout) && @site.templates[@layout]
15
11
  output = @site.templates[@layout].render(context, output)
16
12
  end
17
13
 
18
14
  output
15
+ rescue => e
16
+ error_name = e.class.to_s.gsub(/([A-Z])/, ' \\1').strip.downcase
17
+ error_message = "Unable to render #{@path || self.class} (#{error_name})"
18
+
19
+ raise Errors::RenderingError.new, error_message
19
20
  end
20
21
 
21
22
  def build_scope(context)
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A class that models a single site.
2
5
  class Site
3
6
  attr_accessor :source_paths
4
7
  attr_accessor :output_paths
@@ -14,32 +17,40 @@ module Dimples
14
17
  attr_accessor :errors
15
18
 
16
19
  def initialize(config)
17
- @source_paths = {}
18
- @output_paths = {}
20
+ @config = config
21
+
19
22
  @templates = {}
20
23
  @categories = {}
21
- @archives = { year: {}, month: {}, day: {} }
22
-
23
24
  @pages = []
24
25
  @posts = []
26
+ @errors = []
25
27
 
28
+ @archives = { year: {}, month: {}, day: {} }
26
29
  @latest_post = false
27
30
 
28
- @config = config
29
-
30
31
  @page_class = @config.class_override(:page) || Dimples::Page
31
32
  @post_class = @config.class_override(:post) || Dimples::Post
32
33
 
33
- @source_paths[:root] = File.expand_path(@config['source_path'])
34
- @output_paths[:site] = File.expand_path(@config['destination_path'])
34
+ set_source_paths
35
+ set_output_paths
36
+ end
35
37
 
36
- @errors = []
38
+ def set_source_paths
39
+ @source_paths = {
40
+ root: File.expand_path(@config['source_path'])
41
+ }
37
42
 
38
- %w(pages posts public templates).each do |path|
43
+ %w[pages posts public templates].each do |path|
39
44
  @source_paths[path.to_sym] = File.join(@source_paths[:root], path)
40
45
  end
46
+ end
41
47
 
42
- %w(archives posts categories).each do |path|
48
+ def set_output_paths
49
+ @output_paths = {
50
+ site: File.expand_path(@config['destination_path'])
51
+ }
52
+
53
+ %w[archives posts categories].each do |path|
43
54
  output_path = File.join(@output_paths[:site], @config['paths'][path])
44
55
  @output_paths[path.to_sym] = output_path
45
56
  end
@@ -50,12 +61,14 @@ module Dimples
50
61
  scan_files
51
62
  generate_files
52
63
  copy_assets
53
- rescue Errors::RenderingError, Errors::PublishingError, Errors::GenerationError => e
64
+ rescue Errors::RenderingError,
65
+ Errors::PublishingError,
66
+ Errors::GenerationError => e
54
67
  @errors << e.message
55
68
  end
56
69
 
57
70
  def generated?
58
- @errors.count == 0
71
+ @errors.count.zero?
59
72
  end
60
73
 
61
74
  private
@@ -67,7 +80,8 @@ module Dimples
67
80
 
68
81
  Dir.mkdir(@output_paths[:site])
69
82
  rescue => e
70
- raise Errors::GenerationError("Couldn't prepare the output directory (#{e.message})")
83
+ error_message = "Couldn't prepare the output directory (#{e.message})"
84
+ raise Errors::GenerationError, error_message
71
85
  end
72
86
 
73
87
  def scan_files
@@ -85,39 +99,25 @@ module Dimples
85
99
 
86
100
  def scan_pages
87
101
  Dir.glob(File.join(@source_paths[:pages], '**', '*.*')).each do |path|
88
- page = @page_class.new(self, path)
89
- @pages << page
102
+ @pages << scan_page(path)
90
103
  end
91
104
  end
92
105
 
106
+ def scan_page(path)
107
+ @page_class.new(self, path)
108
+ end
109
+
93
110
  def scan_posts
94
111
  Dir.glob(File.join(@source_paths[:posts], '*.*')).reverse_each do |path|
95
- post = @post_class.new(self, path)
96
-
97
- next if post.draft
98
-
99
- post.categories.each do |slug|
100
- unless @categories[slug]
101
- name = @config['category_names'][slug] || slug.capitalize
102
- @categories[slug] = Dimples::Category.new(name, slug)
103
- end
104
-
105
- @categories[slug].posts << post
106
- end
107
-
108
- archive_year(post.year) << post
109
- archive_month(post.year, post.month) << post
110
- archive_day(post.year, post.month, post.day) << post
111
-
112
- @posts << post
112
+ @posts << scan_post(path)
113
113
  end
114
114
 
115
115
  @posts.each_index do |index|
116
- if index - 1 >= 0
116
+ if (index - 1) >= 0
117
117
  @posts[index].next_post = @posts.fetch(index - 1, nil)
118
118
  end
119
119
 
120
- if index + 1 < @posts.count
120
+ if (index + 1) < @posts.count
121
121
  @posts[index].previous_post = @posts.fetch(index + 1, nil)
122
122
  end
123
123
  end
@@ -125,6 +125,23 @@ module Dimples
125
125
  @latest_post = @posts.first
126
126
  end
127
127
 
128
+ def scan_post(path)
129
+ @post_class.new(self, path).tap do |post|
130
+ post.categories.each do |slug|
131
+ @categories[slug] ||= Dimples::Category.new(self, slug)
132
+ @categories[slug].posts << post
133
+ end
134
+
135
+ add_post_to_archives(post)
136
+ end
137
+ end
138
+
139
+ def add_post_to_archives(post)
140
+ archive_year(post.year) << post
141
+ archive_month(post.year, post.month) << post
142
+ archive_day(post.year, post.month, post.day) << post
143
+ end
144
+
128
145
  def archive_year(year)
129
146
  @archives[:year][year] ||= []
130
147
  end
@@ -138,31 +155,29 @@ module Dimples
138
155
  end
139
156
 
140
157
  def generate_files
141
- unless @pages.empty?
142
- generate_pages
143
- end
158
+ generate_pages unless @pages.count.zero?
144
159
 
145
- unless @posts.empty?
146
- generate_posts
147
- generate_archives
160
+ return if @posts.count.zero?
148
161
 
149
- generate_categories if @config['generation']['categories']
150
- generate_posts_feeds if @config['generation']['feeds']
151
- generate_category_feeds if @config['generation']['category_feeds']
152
- end
162
+ generate_posts
163
+ generate_archives
164
+ generate_categories if @config['generation']['categories']
153
165
  end
154
166
 
155
167
  def generate_posts
156
- Dimples.logger.debug_generation('posts', @posts.length) if @config['verbose_logging']
168
+ if @config['verbose_logging']
169
+ Dimples.logger.debug_generation('posts', @posts.length)
170
+ end
157
171
 
158
172
  @posts.each do |post|
159
173
  generate_post(post)
160
174
  end
161
175
 
162
- paths = [@output_paths[:archives]]
163
176
  layout = @config['layouts']['posts']
164
177
 
165
- paginate(posts: @posts, paths: paths, layout: layout)
178
+ paginate(posts: @posts, path: @output_paths[:archives], layout: layout)
179
+
180
+ generate_posts_feeds if @config['generation']['feeds']
166
181
  end
167
182
 
168
183
  def generate_post(post)
@@ -170,7 +185,9 @@ module Dimples
170
185
  end
171
186
 
172
187
  def generate_pages
173
- Dimples.logger.debug_generation('pages', @pages.length) if @config['verbose_logging']
188
+ if @config['verbose_logging']
189
+ Dimples.logger.debug_generation('pages', @pages.length)
190
+ end
174
191
 
175
192
  @pages.each do |page|
176
193
  generate_page(page)
@@ -182,63 +199,73 @@ module Dimples
182
199
  end
183
200
 
184
201
  def generate_categories
185
- Dimples.logger.debug_generation('category pages', @categories.length) if @config['verbose_logging']
202
+ if @config['verbose_logging']
203
+ Dimples.logger.debug_generation('category pages', @categories.length)
204
+ end
186
205
 
187
206
  @categories.each_value do |category|
188
207
  generate_category(category)
189
208
  end
209
+
210
+ generate_category_feeds if @config['generation']['category_feeds']
190
211
  end
191
212
 
192
213
  def generate_category(category)
193
- paths = [@output_paths[:categories], category.slug]
194
- layout = @config['layouts']['category']
195
- context = { category: category.slug }
214
+ params = {
215
+ posts: category.posts,
216
+ title: category.name,
217
+ path: File.join(@output_paths[:categories], category.slug),
218
+ layout: @config['layouts']['category'],
219
+ context: { category: category.slug }
220
+ }
196
221
 
197
- paginate(posts: category.posts, title: category.name, paths: paths, layout: layout, context: context)
222
+ paginate(params)
198
223
  end
199
224
 
200
225
  def generate_archives
201
- %w(year month day).each do |date_type|
226
+ %w[year month day].each do |date_type|
202
227
  if @config['generation']["#{date_type}_archives"]
203
- date_type_sym = date_type.to_sym
204
-
205
- if @config['verbose_logging']
206
- Dimples.logger.debug_generation("#{date_type} archives", @archives[date_type_sym].count)
207
- end
208
-
209
- layout = @config['layouts']["#{date_type}_archives"]
210
-
211
- @archives[date_type_sym].each_value do |posts|
212
- title = posts[0].date.strftime(@config['date_formats'][date_type])
213
- paths = [@output_paths[:archives], posts[0].year]
214
- dates = { year: posts[0].year }
215
-
216
- case date_type
217
- when 'month'
218
- paths << posts[0].month
219
- dates[:month] = posts[0].month
220
- when 'day'
221
- paths.concat([posts[0].month, posts[0].day])
222
- dates.merge(month: posts[0].month, day: posts[0].day)
223
- end
224
-
225
- paginate(posts: posts, title: title, paths: paths, layout: layout, context: dates)
226
- end
228
+ generate_archive_posts(date_type)
227
229
  end
228
230
  end
229
231
  end
230
232
 
233
+ def generate_archive_posts(date_type)
234
+ @archives[date_type.to_sym].each_value do |posts|
235
+ post = posts[0]
236
+
237
+ dates = case date_type
238
+ when 'year'
239
+ { year: post.year }
240
+ when 'month'
241
+ { year: post.year, month: post.month }
242
+ when 'day'
243
+ { year: post.year, month: post.month, day: post.day }
244
+ end
245
+
246
+ params = {
247
+ posts: posts,
248
+ title: post.date.strftime(@config['date_formats'][date_type]),
249
+ path: File.join(@output_paths[:archives], dates.values),
250
+ layout: @config['layouts']["#{date_type}_archives"],
251
+ context: dates
252
+ }
253
+
254
+ paginate(params)
255
+ end
256
+ end
257
+
231
258
  def generate_feeds(path, options)
232
259
  @config['feed_formats'].each do |format|
233
- if @templates[format]
234
- feed = @page_class.new(self)
260
+ next unless @templates[format]
235
261
 
236
- feed.filename = 'feed'
237
- feed.extension = format
238
- feed.layout = format
262
+ feed = @page_class.new(self)
239
263
 
240
- feed.write(feed.output_path(path), options)
241
- end
264
+ feed.filename = 'feed'
265
+ feed.extension = format
266
+ feed.layout = format
267
+
268
+ feed.write(feed.output_path(path), options)
242
269
  end
243
270
  end
244
271
 
@@ -252,64 +279,52 @@ module Dimples
252
279
  path = File.join(@output_paths[:categories], category.slug)
253
280
  posts = category.posts[0..@config['pagination']['per_page'] - 1]
254
281
 
255
- generate_feeds(path, posts: category.posts, category: category.slug)
282
+ generate_feeds(path, posts: posts, category: category.slug)
256
283
  end
257
284
  end
258
285
 
259
286
  def copy_assets
260
287
  if Dir.exist?(@source_paths[:public])
261
- Dimples.logger.debug("Copying assets...") if @config['verbose_logging']
288
+ Dimples.logger.debug('Copying assets...') if @config['verbose_logging']
262
289
 
263
290
  path = File.join(@source_paths[:public], '.')
264
291
  FileUtils.cp_r(path, @output_paths[:site])
265
292
  end
266
293
  rescue => e
267
- raise Errors::GenerationError.new("Site assets failed to copy (#{e.message})")
294
+ raise Errors::GenerationError, "Site assets failed to copy (#{e.message})"
268
295
  end
269
296
 
270
- def paginate(posts:, title: nil, paths:, layout: false, context: {})
271
- raise Errors::GenerationError.new("'#{layout}' template not found during pagination") unless @templates.key?(layout)
272
-
297
+ def paginate(posts:, title: nil, path:, layout: false, context: {})
273
298
  per_page = @config['pagination']['per_page']
274
- page_count = (posts.length.to_f / per_page.to_i).ceil
275
-
276
- page_path = paths[0].gsub(@output_paths[:site], '') + '/'
277
- page_path += paths[1..-1].join('/') + '/' if paths.length > 1
299
+ pages = (posts.length.to_f / per_page.to_i).ceil
300
+ url = path.gsub(@output_paths[:site], '') + '/'
278
301
 
279
- (1..page_count).each do |index|
302
+ (1..pages).each do |index|
280
303
  page = @page_class.new(self)
281
304
 
282
305
  page.layout = layout
283
306
  page.title = title || @templates[layout].title
284
307
 
285
- pagination = build_pagination(index, page_count, posts.count, page_path)
286
- output_path = File.join(paths, index != 1 ? "page#{index}" : '')
308
+ output_path = File.join(path, index != 1 ? "page#{index}" : '')
287
309
 
288
310
  context[:posts] = posts.slice((index - 1) * per_page, per_page)
289
- context[:pagination] = pagination
311
+ context[:pagination] = build_pagination(index, pages, posts.count, url)
290
312
 
291
313
  page.write(page.output_path(output_path), context)
292
314
  end
293
315
  end
294
316
 
295
- def build_pagination(index, page_count, item_count, path)
317
+ def build_pagination(index, pages, item_count, url)
296
318
  pagination = {
297
319
  page: index,
298
- pages: page_count,
320
+ pages: pages,
299
321
  post_count: item_count,
300
- path: path
322
+ url: url
301
323
  }
302
324
 
303
- if (pagination[:page] - 1) > 0
304
- pagination[:previous_page] = pagination[:page] - 1
305
- end
306
-
307
- if (pagination[:page] + 1) <= pagination[:pages]
308
- pagination[:next_page] = pagination[:page] + 1
309
- end
310
-
311
- if pagination[:previous_page]
312
- pagination[:previous_page_url] = pagination[:path]
325
+ if (index - 1).positive?
326
+ pagination[:previous_page] = index - 1
327
+ pagination[:previous_page_url] = url
313
328
 
314
329
  if pagination[:previous_page] != 1
315
330
  page_string = "page#{pagination[:previous_page]}"
@@ -317,8 +332,9 @@ module Dimples
317
332
  end
318
333
  end
319
334
 
320
- if pagination[:next_page]
321
- page_string = "#{pagination[:path]}page#{pagination[:next_page]}"
335
+ if (index + 1) <= pages
336
+ pagination[:next_page] = index + 1
337
+ page_string = "#{url}page#{pagination[:next_page]}"
322
338
  pagination[:next_page_url] = page_string
323
339
  end
324
340
 
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A class that models a single template.
2
5
  class Template
3
6
  include Frontable
4
7
  include Renderable
@@ -14,7 +17,7 @@ module Dimples
14
17
  @slug = File.basename(path, File.extname(path))
15
18
  @path = path
16
19
 
17
- @contents = read_with_yaml(path)
20
+ @contents = read_with_front_matter(path)
18
21
  end
19
22
  end
20
23
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
2
- VERSION = '2.4.1'.freeze
4
+ VERSION = '2.5.0'
3
5
  end
@@ -1,4 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Dimples
4
+ # A mixin class that neatly handles writing out a file.
2
5
  module Writeable
3
6
  def write(path, context = {})
4
7
  output = context ? render(context) : contents
@@ -10,7 +13,8 @@ module Dimples
10
13
  file.write(output)
11
14
  end
12
15
  rescue SystemCallError => e
13
- raise Errors::PublishingError.new("Failed to write #{path} (#{e.message})")
16
+ error_message = "Failed to write #{path} (#{e.message})"
17
+ raise Errors::PublishingError, error_message
14
18
  end
15
19
  end
16
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dimples
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 2.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel Bogan
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-21 00:00:00.000000000 Z
11
+ date: 2017-05-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tilt