dimples 3.0.0 → 3.0.1

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: 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