dimples 2.4.1 → 2.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.
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