dimples 3.0.0 → 3.0.1

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: a4cee778dfaf4073d4f09fa374b884e684916696
4
- data.tar.gz: 269d2ba199c54bc6c5cb66094ab38069896de042
3
+ metadata.gz: 3decb7a769a50beb4f4abcff1f8a2480dba31cda
4
+ data.tar.gz: ef0f049510c3d0a437e80938aa88a9185491c300
5
5
  SHA512:
6
- metadata.gz: 7d333b6cf6d9475d643e4e8ae47b5b1777ef598489afaaa5e9eb795e97a773fd84010c182176ba90cffc5c4d0cf7cacf676c9ac63a806d964509e41c25f9531b
7
- data.tar.gz: 1bd4720fdfc2d8d506110aff782e1307580f4e90f7f9e6c0d8bcc3244a202c06f64d65bc748f7867a1a30814aa189bb8b78510f96700c7abd1a8532979e20483
6
+ metadata.gz: f217f218f00afa0410927923b6f08e32ee8c1e8a5a1b2b636f6904007a9f44392b201ebc76f649d0bed1394061f1f4cd3875d5d8fc2bf2bbde0afc6733559711
7
+ data.tar.gz: 9ed527729cca08f35cea1f5229890cd7d31b78959e27d67d4977ec9fe681a7840227d1444b1361bf43b26436573bd6c9d8f3abf66c8d7fa83aaa870361061813
@@ -8,15 +8,16 @@ require 'logger'
8
8
  require 'tilt'
9
9
  require 'yaml'
10
10
 
11
+ require 'dimples/frontable'
12
+ require 'dimples/renderable'
13
+
11
14
  require 'dimples/category'
12
15
  require 'dimples/configuration'
13
16
  require 'dimples/errors'
14
- require 'dimples/frontable'
15
17
  require 'dimples/logger'
16
18
  require 'dimples/page'
17
19
  require 'dimples/pagination'
18
20
  require 'dimples/post'
19
- require 'dimples/renderer'
20
21
  require 'dimples/site'
21
22
  require 'dimples/template'
22
23
 
@@ -3,28 +3,23 @@
3
3
  module Dimples
4
4
  # A mixin class that handles reading and parsing front matter from a file.
5
5
  module Frontable
6
- def read_with_front_matter(path)
7
- contents = File.read(path)
8
- matches = contents.match(/^(-{3}\n.*?\n?)^(-{3}*$\n?)/m)
6
+ METADATA_KEYS = %w[title layout extension summary categories].freeze
9
7
 
10
- if matches
11
- metadata = YAML.safe_load(matches[1])
12
- contents = matches.post_match.strip
8
+ def read_with_front_matter
9
+ @contents = File.read(@path)
13
10
 
14
- apply_metadata(metadata) if metadata
15
- end
11
+ matches = @contents.match(/^(-{3}\n.*?\n?)^(-{3}*$\n?)/m)
12
+ return if matches.nil?
16
13
 
17
- contents
18
- end
14
+ metadata = YAML.safe_load(matches[1])
19
15
 
20
- def apply_metadata(metadata)
21
16
  metadata.each_pair do |key, value|
22
- unless respond_to?(key.to_sym)
23
- self.class.send(:attr_accessor, key.to_sym)
17
+ if METADATA_KEYS.include?(key) && respond_to?("#{key}=")
18
+ send("#{key}=", value)
24
19
  end
25
-
26
- send("#{key}=", value)
27
20
  end
21
+
22
+ @contents = matches.post_match.strip
28
23
  end
29
24
  end
30
25
  end
@@ -4,6 +4,7 @@ module Dimples
4
4
  # A class that models a single site page.
5
5
  class Page
6
6
  include Frontable
7
+ include Renderable
7
8
 
8
9
  attr_accessor :path
9
10
  attr_accessor :title
@@ -11,7 +12,7 @@ module Dimples
11
12
  attr_accessor :extension
12
13
  attr_accessor :layout
13
14
  attr_accessor :contents
14
- attr_accessor :rendered_contents
15
+ attr_accessor :output_directory
15
16
 
16
17
  def initialize(site, path = nil)
17
18
  @site = site
@@ -20,45 +21,36 @@ module Dimples
20
21
 
21
22
  if @path
22
23
  @filename = File.basename(@path, File.extname(@path))
23
- @contents = read_with_front_matter(@path)
24
+ @output_directory = File.dirname(@path).gsub(
25
+ @site.source_paths[:pages],
26
+ @site.output_paths[:site]
27
+ )
28
+
29
+ read_with_front_matter
24
30
  else
25
31
  @filename = 'index'
26
32
  @contents = ''
33
+ @output_directory = @site.output_paths[:site]
27
34
  end
28
35
  end
29
36
 
30
- def output_path(parent_path)
31
- parts = [parent_path]
32
-
33
- unless @path.nil?
34
- parts << File.dirname(@path).gsub(@site.source_paths[:pages], '')
35
- end
36
-
37
- parts << "#{@filename}.#{@extension}"
38
-
39
- File.join(parts)
40
- end
41
-
42
- def render(context = {})
43
- renderer.render(context)
44
- end
45
-
46
- def renderer
47
- @renderer ||= Renderer.new(@site, self)
37
+ def output_path
38
+ File.join(@output_directory, "#{@filename}.#{@extension}")
48
39
  end
49
40
 
50
- def write(path, context = {})
51
- output = context ? render(context) : contents
52
- parent_path = File.dirname(path)
41
+ def write(context = {})
42
+ FileUtils.mkdir_p(@output_directory) unless Dir.exist?(@output_directory)
53
43
 
54
- FileUtils.mkdir_p(parent_path) unless Dir.exist?(parent_path)
55
-
56
- File.open(path, 'w+') do |file|
57
- file.write(output)
44
+ File.open(output_path, 'w+') do |file|
45
+ file.write(context ? render(context) : contents)
58
46
  end
59
47
  rescue SystemCallError => e
60
48
  error_message = "Failed to write #{path} (#{e.message})"
61
49
  raise Errors::PublishingError, error_message
62
50
  end
51
+
52
+ def inspect
53
+ "#<Dimples::Page @output_path=#{output_path}>"
54
+ end
63
55
  end
64
56
  end
@@ -12,19 +12,21 @@ module Dimples
12
12
 
13
13
  pager.each do |index, page_items|
14
14
  page = Dimples::Page.new(site)
15
- page.layout = layout
16
15
 
16
+ page.output_directory = if index == 1
17
+ path
18
+ else
19
+ File.join(path, "page#{index}")
20
+ end
21
+
22
+ page.layout = layout
17
23
  page.title = options[:title] || site.templates[layout].title
18
24
  page.extension = options[:extension] if options[:extension]
19
25
 
20
- output_path = page.output_path(
21
- index != 1 ? File.join(path, "page#{index}") : path
22
- )
23
-
24
26
  context[:items] = page_items
25
27
  context[:pagination] = pager.to_h
26
28
 
27
- page.write(output_path, context)
29
+ page.write(context)
28
30
  end
29
31
  end
30
32
 
@@ -56,7 +58,7 @@ module Dimples
56
58
  def step_to(page)
57
59
  @current_page = (1..@page_count).cover?(page) ? page : 1
58
60
  @previous_page = (@current_page - 1).positive? ? @current_page - 1 : nil
59
- @next_page = (@current_page + 1) <= @page_count ? @current_page + 1 : nil
61
+ @next_page = @current_page + 1 <= @page_count ? @current_page + 1 : nil
60
62
 
61
63
  @current_page
62
64
  end
@@ -76,7 +78,7 @@ module Dimples
76
78
 
77
79
  def to_h
78
80
  output = {
79
- page: @current_page,
81
+ current_page: @current_page,
80
82
  page_count: @page_count,
81
83
  item_count: @items.count,
82
84
  url: @url
@@ -3,8 +3,9 @@
3
3
  module Dimples
4
4
  # A class that models a single site post.
5
5
  class Post < Page
6
- attr_accessor :categories
7
6
  attr_accessor :slug
7
+ attr_accessor :summary
8
+ attr_accessor :categories
8
9
  attr_accessor :year
9
10
  attr_accessor :month
10
11
  attr_accessor :day
@@ -24,6 +25,11 @@ module Dimples
24
25
  @layout = @site.config['layouts']['post']
25
26
 
26
27
  self.date = Time.mktime(parts[1], parts[2], parts[3])
28
+
29
+ @output_directory = File.join(
30
+ @date.strftime(@site.output_paths[:posts]),
31
+ @slug.to_s
32
+ )
27
33
  end
28
34
 
29
35
  def date=(date)
@@ -34,9 +40,8 @@ module Dimples
34
40
  @day = @date.strftime('%d')
35
41
  end
36
42
 
37
- def output_path(parent_path)
38
- parent_path = @date.strftime(parent_path) if parent_path.match?(/%/)
39
- File.join([parent_path, @slug.to_s, "#{@filename}.#{@extension}"])
43
+ def inspect
44
+ "#<Dimples::Post @slug=#{@slug} @output_path=#{output_path}>"
40
45
  end
41
46
  end
42
47
  end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Dimples
4
+ # A mixin class that allows a document to render via Tilt.
5
+ module Renderable
6
+ attr_accessor :rendered_contents
7
+
8
+ def render(context = {}, body = nil)
9
+ context[:site] ||= @site
10
+ context[:this] ||= self
11
+ context[:type] ||= self.class.name.split('::').last.downcase.to_sym
12
+
13
+ scope = Object.new.tap do |s|
14
+ context.each_pair do |key, value|
15
+ s.instance_variable_set("@#{key}".to_sym, value)
16
+ end
17
+ end
18
+
19
+ output = rendering_engine.render(scope) { body }.strip
20
+ @rendered_contents = output
21
+
22
+ if @site.templates[layout]
23
+ @site.templates[layout].render(context, output)
24
+ else
25
+ output
26
+ end
27
+ end
28
+
29
+ def rendering_engine
30
+ @rendering_engine ||= begin
31
+ callback = proc { contents }
32
+
33
+ if @path
34
+ ext = File.extname(@path)[1..-1]
35
+ options = @site.config['rendering'][ext] || {}
36
+ Tilt.new(@path, options, &callback)
37
+ else
38
+ Tilt::StringTemplate.new(&callback)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -31,18 +31,13 @@ module Dimples
31
31
 
32
32
  @post_class = @config.class_override(:post) || Dimples::Post
33
33
 
34
- @source_paths = {
35
- root: File.expand_path(@config['source_path'])
36
- }
34
+ @source_paths = { root: File.expand_path(@config['source_path']) }
35
+ @output_paths = { site: File.expand_path(@config['destination_path']) }
37
36
 
38
37
  %w[pages posts public templates].each do |path|
39
38
  @source_paths[path.to_sym] = File.join(@source_paths[:root], path)
40
39
  end
41
40
 
42
- @output_paths = {
43
- site: File.expand_path(@config['destination_path'])
44
- }
45
-
46
41
  %w[archives posts categories].each do |path|
47
42
  output_path = File.join(@output_paths[:site], @config['paths'][path])
48
43
  @output_paths[path.to_sym] = output_path
@@ -50,8 +45,20 @@ module Dimples
50
45
  end
51
46
 
52
47
  def generate
53
- scan_files
54
- generate_files
48
+ scan_templates
49
+ scan_pages
50
+ scan_posts
51
+
52
+ prepare_output_directory
53
+
54
+ generate_pages unless @pages.count.zero?
55
+
56
+ unless @posts.count.zero?
57
+ generate_posts
58
+ generate_archives
59
+ generate_categories if @config['generation']['categories']
60
+ end
61
+
55
62
  copy_assets
56
63
  rescue Errors::RenderingError,
57
64
  Errors::PublishingError,
@@ -63,12 +70,6 @@ module Dimples
63
70
  @errors.count.zero?
64
71
  end
65
72
 
66
- def scan_files
67
- scan_templates
68
- scan_pages
69
- scan_posts
70
- end
71
-
72
73
  def scan_templates
73
74
  Dir.glob(File.join(@source_paths[:templates], '**', '*.*')).each do |path|
74
75
  template = Dimples::Template.new(self, path)
@@ -137,48 +138,29 @@ module Dimples
137
138
  raise Errors::GenerationError, error_message
138
139
  end
139
140
 
140
- def generate_files
141
- prepare_output_directory
142
-
143
- generate_pages unless @pages.count.zero?
144
-
145
- return if @posts.count.zero?
146
-
147
- generate_posts
148
- generate_archives
149
- generate_categories if @config['generation']['categories']
150
- end
151
-
152
141
  def generate_posts
153
142
  if @config['verbose_logging']
154
143
  Dimples.logger.debug_generation('posts', @posts.length)
155
144
  end
156
145
 
157
- @posts.each do |post|
158
- generate_post(post)
159
- end
146
+ @posts.each(&:write)
160
147
 
161
- paginate(self, @posts, @output_paths[:archives], @config['layouts']['posts'])
148
+ paginate(
149
+ self,
150
+ @posts,
151
+ @output_paths[:archives],
152
+ @config['layouts']['posts']
153
+ )
162
154
 
163
155
  generate_posts_feeds if @config['generation']['feeds']
164
156
  end
165
157
 
166
- def generate_post(post)
167
- post.write(post.output_path(@output_paths[:posts]))
168
- end
169
-
170
158
  def generate_pages
171
159
  if @config['verbose_logging']
172
160
  Dimples.logger.debug_generation('pages', @pages.length)
173
161
  end
174
162
 
175
- @pages.each do |page|
176
- generate_page(page)
177
- end
178
- end
179
-
180
- def generate_page(page)
181
- page.write(page.output_path(@output_paths[:site]))
163
+ @pages.each(&:write)
182
164
  end
183
165
 
184
166
  def generate_categories
@@ -187,61 +169,61 @@ module Dimples
187
169
  end
188
170
 
189
171
  @categories.each_value do |category|
190
- generate_category(category)
191
- end
192
-
193
- generate_category_feeds if @config['generation']['category_feeds']
194
- end
172
+ path = File.join(@output_paths[:categories], category.slug)
195
173
 
196
- def generate_category(category)
197
- path = File.join(@output_paths[:categories], category.slug)
174
+ options = {
175
+ context: { category: category.slug },
176
+ title: category.name
177
+ }
198
178
 
199
- options = {
200
- context: { category: category.slug },
201
- title: category.name
202
- }
179
+ paginate(
180
+ self,
181
+ category.posts,
182
+ path,
183
+ @config['layouts']['category'],
184
+ options
185
+ )
186
+ end
203
187
 
204
- paginate(self, category.posts, path, @config['layouts']['category'], options)
188
+ generate_category_feeds if @config['generation']['category_feeds']
205
189
  end
206
190
 
207
191
  def generate_archives
208
192
  %w[year month day].each do |date_type|
209
- if @config['generation']["#{date_type}_archives"]
210
- generate_archive_posts(date_type)
211
- end
212
- end
213
- end
193
+ next unless @config['generation']["#{date_type}_archives"]
214
194
 
215
- def generate_archive_posts(date_type)
216
- @archives[date_type.to_sym].each do |date, posts|
217
- year, month, day = date.split('/')
195
+ @archives[date_type.to_sym].each do |date, posts|
196
+ year, month, day = date.split('/')
218
197
 
219
- dates = { year: year }
220
- dates[:month] = month if month
221
- dates[:day] = day if day
198
+ dates = { year: year }
199
+ dates[:month] = month if month
200
+ dates[:day] = day if day
222
201
 
223
- path = File.join(@output_paths[:archives], dates.values)
202
+ path = File.join(@output_paths[:archives], dates.values)
203
+ layout = @config['layouts']["#{date_type}_archives"]
224
204
 
225
- options = {
226
- context: dates,
227
- title: posts[0].date.strftime(@config['date_formats'][date_type])
228
- }
205
+ options = {
206
+ context: dates,
207
+ title: posts[0].date.strftime(@config['date_formats'][date_type])
208
+ }
229
209
 
230
- paginate(self, posts, path, @config['layouts']["#{date_type}_archives"], options)
210
+ paginate(self, posts, path, layout, options)
211
+ end
231
212
  end
232
213
  end
233
214
 
234
- def generate_feeds(path, options)
215
+ def generate_feeds(path, context)
235
216
  feed_templates.each do |format|
236
217
  next unless @templates[format]
237
218
 
238
219
  feed = Dimples::Page.new(self)
239
220
 
221
+ feed.output_directory = path
240
222
  feed.filename = 'feed'
241
223
  feed.extension = @templates[format].slug
242
224
  feed.layout = format
243
225
 
244
- feed.write(feed.output_path(path), options)
226
+ feed.write(context)
245
227
  end
246
228
  end
247
229
 
@@ -259,6 +241,10 @@ module Dimples
259
241
  end
260
242
  end
261
243
 
244
+ def feed_templates
245
+ @feed_templates ||= @templates.keys.select { |k| k =~ /^feeds\./ }
246
+ end
247
+
262
248
  def copy_assets
263
249
  if Dir.exist?(@source_paths[:public])
264
250
  Dimples.logger.debug('Copying assets...') if @config['verbose_logging']
@@ -270,6 +256,12 @@ module Dimples
270
256
  raise Errors::GenerationError, "Site assets failed to copy (#{e.message})"
271
257
  end
272
258
 
259
+ def inspect
260
+ "#<Dimples::Site " \
261
+ "@source_paths=#{@source_paths} " \
262
+ "@output_paths=#{@output_paths}>"
263
+ end
264
+
273
265
  private
274
266
 
275
267
  def archive_year(year)
@@ -283,9 +275,5 @@ module Dimples
283
275
  def archive_day(year, month, day)
284
276
  @archives[:day]["#{year}/#{month}/#{day}"] ||= []
285
277
  end
286
-
287
- def feed_templates
288
- @feed_templates ||= @templates.keys.select { |k| k =~ /^feeds\./ }
289
- end
290
278
  end
291
279
  end
@@ -4,28 +4,24 @@ module Dimples
4
4
  # A class that models a single template.
5
5
  class Template
6
6
  include Frontable
7
+ include Renderable
7
8
 
8
9
  attr_accessor :path
9
10
  attr_accessor :title
10
11
  attr_accessor :slug
11
12
  attr_accessor :layout
12
13
  attr_accessor :contents
13
- attr_accessor :rendered_contents
14
14
 
15
15
  def initialize(site, path)
16
16
  @site = site
17
17
  @slug = File.basename(path, File.extname(path))
18
18
  @path = path
19
19
 
20
- @contents = read_with_front_matter(path)
20
+ read_with_front_matter
21
21
  end
22
22
 
23
- def render(context = {}, body = nil)
24
- renderer.render(context, body)
25
- end
26
-
27
- def renderer
28
- @renderer ||= Renderer.new(@site, self)
23
+ def inspect
24
+ "#<Dimples::Template @slug=#{@slug} @path=#{@path}>"
29
25
  end
30
26
  end
31
27
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Dimples
4
- VERSION = '3.0.0'
4
+ VERSION = '3.0.1'
5
5
  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: 3.0.0
4
+ version: 3.0.1
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-08-24 00:00:00.000000000 Z
11
+ date: 2017-08-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: tilt
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0.14'
111
+ - !ruby/object:Gem::Dependency
112
+ name: timecop
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: 0.9.1
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: 0.9.1
111
125
  - !ruby/object:Gem::Dependency
112
126
  name: codeclimate-test-reporter
113
127
  requirement: !ruby/object:Gem::Requirement
@@ -146,7 +160,7 @@ files:
146
160
  - lib/dimples/page.rb
147
161
  - lib/dimples/pagination.rb
148
162
  - lib/dimples/post.rb
149
- - lib/dimples/renderer.rb
163
+ - lib/dimples/renderable.rb
150
164
  - lib/dimples/site.rb
151
165
  - lib/dimples/template.rb
152
166
  - lib/dimples/version.rb
@@ -1,43 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Dimples
4
- # A class that renders the contents of a document into markup.
5
- class Renderer
6
- def initialize(site, source)
7
- @site = site
8
- @source = source
9
-
10
- callback = proc { @source.contents }
11
-
12
- @engine = if @source.path
13
- ext = File.extname(@source.path)[1..-1]
14
- options = @site.config['rendering'][ext] || {}
15
- Tilt.new(@source.path, options, &callback)
16
- else
17
- Tilt::StringTemplate.new(&callback)
18
- end
19
- end
20
-
21
- def render(context = {}, body = nil)
22
- output = @engine.render(scope(context)) { body }.strip
23
- @source.rendered_contents = output
24
-
25
- template = @site.templates[@source.layout]
26
- output = template.render(context, output) unless template.nil?
27
-
28
- output
29
- end
30
-
31
- def scope(context = {})
32
- context[:site] ||= @site
33
- context[:this] ||= @source
34
- context[:type] ||= @source.class.name.split('::').last.downcase.to_sym
35
-
36
- Object.new.tap do |scope|
37
- context.each_pair do |key, value|
38
- scope.instance_variable_set("@#{key}".to_sym, value)
39
- end
40
- end
41
- end
42
- end
43
- end