Class: Dimples::Site

Inherits:
Object
  • Object
show all
Defined in:
lib/dimples/site.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = {}) ⇒ Site

Returns a new instance of Site.



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/dimples/site.rb', line 15

def initialize(config = {})
  @source_paths = {}
  @output_paths = {}
  @templates = {}
  @categories = {}
  @archives = { year: {}, month: {}, day: {} }

  @pages = []
  @posts = []

  @latest_post = false

  @page_class = Dimples::Page
  @post_class = Dimples::Post

  @config = Dimples::Configuration.new(config)
  @generation_options = default_generation_options

  @source_paths[:root] = File.expand_path(@config['source_path'])
  @output_paths[:site] = File.expand_path(@config['destination_path'])

  %w(pages posts public templates).each do |path|
    @source_paths[path.to_sym] = File.join(@source_paths[:root], path)
  end

  %w(archives posts categories).each do |path|
    output_path = File.join(@output_paths[:site], @config['paths'][path])
    @output_paths[path.to_sym] = output_path
  end
end

Instance Attribute Details

#archivesObject

Returns the value of attribute archives.



8
9
10
# File 'lib/dimples/site.rb', line 8

def archives
  @archives
end

#categoriesObject

Returns the value of attribute categories.



7
8
9
# File 'lib/dimples/site.rb', line 7

def categories
  @categories
end

#configObject

Returns the value of attribute config.



5
6
7
# File 'lib/dimples/site.rb', line 5

def config
  @config
end

#latest_postObject

Returns the value of attribute latest_post.



11
12
13
# File 'lib/dimples/site.rb', line 11

def latest_post
  @latest_post
end

#output_pathsObject

Returns the value of attribute output_paths.



4
5
6
# File 'lib/dimples/site.rb', line 4

def output_paths
  @output_paths
end

#page_classObject

Returns the value of attribute page_class.



12
13
14
# File 'lib/dimples/site.rb', line 12

def page_class
  @page_class
end

#pagesObject

Returns the value of attribute pages.



9
10
11
# File 'lib/dimples/site.rb', line 9

def pages
  @pages
end

#post_classObject

Returns the value of attribute post_class.



13
14
15
# File 'lib/dimples/site.rb', line 13

def post_class
  @post_class
end

#postsObject

Returns the value of attribute posts.



10
11
12
# File 'lib/dimples/site.rb', line 10

def posts
  @posts
end

#source_pathsObject

Returns the value of attribute source_paths.



3
4
5
# File 'lib/dimples/site.rb', line 3

def source_paths
  @source_paths
end

#templatesObject

Returns the value of attribute templates.



6
7
8
# File 'lib/dimples/site.rb', line 6

def templates
  @templates
end

Instance Method Details

#archive_day(year, month, day) ⇒ Object



133
134
135
# File 'lib/dimples/site.rb', line 133

def archive_day(year, month, day)
  @archives[:day]["#{year}/#{month}/#{day}"] ||= []
end

#archive_month(year, month) ⇒ Object



129
130
131
# File 'lib/dimples/site.rb', line 129

def archive_month(year, month)
  @archives[:month]["#{year}/#{month}"] ||= []
end

#archive_year(year) ⇒ Object



125
126
127
# File 'lib/dimples/site.rb', line 125

def archive_year(year)
  @archives[:year][year] ||= []
end

#build_pagination(index, page_count, item_count, path) ⇒ Object



281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
# File 'lib/dimples/site.rb', line 281

def build_pagination(index, page_count, item_count, path)
  pagination = {
    page: index,
    pages: page_count,
    post_count: item_count,
    path: path
  }

  if (pagination[:page] - 1) > 0
    pagination[:previous_page] = pagination[:page] - 1
  end

  if (pagination[:page] + 1) <= pagination[:pages]
    pagination[:next_page] = pagination[:page] + 1
  end

  if pagination[:previous_page]
    pagination[:previous_page_url] = pagination[:path]

    if pagination[:previous_page] != 1
      page_string = "page#{pagination[:previous_page]}"
      pagination[:previous_page_url] += page_string
    end
  end

  if pagination[:next_page]
    page_string = "#{pagination[:path]}page#{pagination[:next_page]}"
    pagination[:next_page_url] = page_string
  end

  pagination
end

#copy_assetsObject



247
248
249
250
251
252
253
254
# File 'lib/dimples/site.rb', line 247

def copy_assets
  if Dir.exist?(@source_paths[:public])
    path = File.join(@source_paths[:public], '.')
    FileUtils.cp_r(path, @output_paths[:site])
  end
rescue => e
  raise "Failed to copy site assets (#{e})"
end

#generate(options = {}) ⇒ Object



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/dimples/site.rb', line 46

def generate(options = {})
  @generation_options.merge!(options)

  prepare_site
  scan_files
  generate_files
  copy_assets

# rescue Errors::RenderingError => e
#   puts "Error: Failed to render #{e.file}: #{e.message}"
# rescue Errors::PublishingError => e
#   puts "Error: Failed to publish #{e.file}: #{e.message}"
# rescue => e
#   puts "Error: #{e.backtrace}"
end

#generate_archivesObject



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
# File 'lib/dimples/site.rb', line 198

def generate_archives
  %w(year month day).each do |date_type|
    if @config['generation']["#{date_type}_archives"]
      layout = @config['layouts']["#{date_type}_archives"]

      @archives[date_type.to_sym].each_value do |posts|
        title = posts[0].date.strftime(@config['date_formats'][date_type])
        paths = [@output_paths[:archives], posts[0].year]
        dates = { year: posts[0].year }

        case date_type
        when 'month'
          paths << posts[0].month
          dates[:month] = posts[0].month
        when 'day'
          paths.concat([posts[0].month, posts[0].day])
          dates.merge(month: posts[0].month, day: posts[0].day)
        end

        paginate(posts: posts, title: title, paths: paths, layout: layout, context: dates)
      end
    end
  end
end

#generate_categoriesObject



183
184
185
186
187
# File 'lib/dimples/site.rb', line 183

def generate_categories
  @categories.each do |slug, posts|
    generate_category(slug, posts)
  end
end

#generate_category(slug, posts) ⇒ Object



189
190
191
192
193
194
195
196
# File 'lib/dimples/site.rb', line 189

def generate_category(slug, posts)
  name = @config['category_names'][slug] || slug.capitalize
  paths = [@output_paths[:categories], slug]
  layout = @config['layouts']['category']
  context = { category: slug }

  paginate(posts: posts, title: name, paths: paths, layout: layout, context: context)
end

#generate_category_feedsObject



238
239
240
241
242
243
244
245
# File 'lib/dimples/site.rb', line 238

def generate_category_feeds
  @categories.each do |slug, posts|
    path = File.join(@output_paths[:categories], slug)
    posts = posts[0..@config['pagination']['per_page'] - 1]

    generate_feed(path, posts: posts, category: slug)
  end
end

#generate_feed(path, options) ⇒ Object



223
224
225
226
227
228
229
230
231
# File 'lib/dimples/site.rb', line 223

def generate_feed(path, options)
  feed = @page_class.new(self)

  feed.filename = 'feed'
  feed.extension = 'atom'
  feed.layout = 'feed'

  feed.write(path, options)
end

#generate_filesObject



146
147
148
149
150
151
152
153
154
# File 'lib/dimples/site.rb', line 146

def generate_files
  generate_posts
  generate_pages
  generate_archives

  generate_categories if @config['generation']['categories']
  generate_posts_feed if @config['generation']['feed']
  generate_category_feeds if @config['generation']['category_feeds']
end

#generate_page(page) ⇒ Object



179
180
181
# File 'lib/dimples/site.rb', line 179

def generate_page(page)
  page.write(@output_paths[:site])
end

#generate_pagesObject



173
174
175
176
177
# File 'lib/dimples/site.rb', line 173

def generate_pages
  @pages.each do |page|
    generate_page(page)
  end
end

#generate_post(post) ⇒ Object



169
170
171
# File 'lib/dimples/site.rb', line 169

def generate_post(post)
  post.write(@output_paths[:posts])
end

#generate_postsObject



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/dimples/site.rb', line 156

def generate_posts
  @posts.each do |post|
    generate_post(post)
  end

  if @config['generation']['paginated_posts']
    paths = [@output_paths[:archives]]
    layout = @config['layouts']['posts']

    paginate(posts: @posts, paths: paths, layout: layout)
  end
end

#generate_posts_feedObject



233
234
235
236
# File 'lib/dimples/site.rb', line 233

def generate_posts_feed
  posts = @posts[0..@config['pagination']['per_page'] - 1]
  generate_feed(@output_paths[:site], posts: posts)
end

#paginate(posts:, title: nil, paths:, layout: false, context: {}) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# File 'lib/dimples/site.rb', line 256

def paginate(posts:, title: nil, paths:, layout: false, context: {})
  raise "'#{layout}' template not found" unless @templates.key?(layout)

  per_page = @config['pagination']['per_page']
  page_count = (posts.length.to_f / per_page.to_i).ceil

  page_path = paths[0].gsub(@output_paths[:site], '') + '/'
  page_path += paths[1..-1].join('/') + '/' if paths.length > 1

  (1..page_count).each do |index|
    page = @page_class.new(self)

    page.layout = layout
    page.title = title || @templates[layout].title

    pagination = build_pagination(index, page_count, posts.count, page_path)
    output_path = File.join(paths, index != 1 ? "page#{index}" : '')

    context[:posts] = posts.slice((index - 1) * per_page, per_page)
    context[:pagination] = pagination

    page.write(output_path, context)
  end
end

#prepare_page(page) ⇒ Object



140
141
# File 'lib/dimples/site.rb', line 140

def prepare_page(page)
end

#prepare_post(post) ⇒ Object



143
144
# File 'lib/dimples/site.rb', line 143

def prepare_post(post)
end

#prepare_siteObject



62
63
64
65
66
67
68
69
70
# File 'lib/dimples/site.rb', line 62

def prepare_site
  if Dir.exist?(@output_paths[:site])
    FileUtils.remove_dir(@output_paths[:site])
  end

  Dir.mkdir(@output_paths[:site])
rescue => e
  raise "Failed to prepare the site directory (#{e})"
end

#prepare_template(template) ⇒ Object



137
138
# File 'lib/dimples/site.rb', line 137

def prepare_template(template)
end

#scan_filesObject



72
73
74
75
76
# File 'lib/dimples/site.rb', line 72

def scan_files
  scan_templates
  scan_pages
  scan_posts
end

#scan_pagesObject



86
87
88
89
90
91
92
# File 'lib/dimples/site.rb', line 86

def scan_pages
  Dir.glob(File.join(@source_paths[:pages], '**', '*.*')).each do |path|
    page = @page_class.new(self, path)
    prepare_page(page)
    @pages << page
  end
end

#scan_postsObject



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/dimples/site.rb', line 94

def scan_posts
  Dir.glob(File.join(@source_paths[:posts], '*.*')).reverse_each do |path|
    post = @post_class.new(self, path)
    next if !@generation_options[:include_drafts] && post.draft

    prepare_post(post)

    post.categories.each do |slug|
      (@categories[slug] ||= []) << post
    end

    archive_year(post.year) << post
    archive_month(post.year, post.month) << post
    archive_day(post.year, post.month, post.day) << post

    @posts << post
  end

  @posts.each_index do |index|
    if index - 1 >= 0
      @posts[index].next_post = @posts.fetch(index - 1, nil)
    end

    if index + 1 < @posts.count
      @posts[index].previous_post = @posts.fetch(index + 1, nil)
    end
  end

  @latest_post = @posts.first
end

#scan_templatesObject



78
79
80
81
82
83
84
# File 'lib/dimples/site.rb', line 78

def scan_templates
  Dir.glob(File.join(@source_paths[:templates], '**', '*.*')).each do |path|
    template = Dimples::Template.new(self, path)
    prepare_template(template)
    @templates[template.slug] = template
  end
end