Class: Dimples::Site

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

Overview

A class that models a single site.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Pagination

#paginate

Constructor Details

#initialize(config = {}) ⇒ Site

Returns a new instance of Site.



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
# File 'lib/dimples/site.rb', line 19

def initialize(config = {})
  @config = Dimples::Configuration.new(config)

  @templates = {}
  @categories = {}
  @pages = []
  @posts = []
  @errors = []

  @archives = { year: {}, month: {}, day: {} }
  @latest_post = false

  @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_paths[path.to_sym] = File.join(
      @output_paths[:site], @config[:paths][path.to_sym]
    )
  end
end

Instance Attribute Details

#archivesObject

Returns the value of attribute archives.



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

def archives
  @archives
end

#categoriesObject

Returns the value of attribute categories.



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

def categories
  @categories
end

#configObject

Returns the value of attribute config.



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

def config
  @config
end

#errorsObject

Returns the value of attribute errors.



17
18
19
# File 'lib/dimples/site.rb', line 17

def errors
  @errors
end

#latest_postObject

Returns the value of attribute latest_post.



16
17
18
# File 'lib/dimples/site.rb', line 16

def latest_post
  @latest_post
end

#output_pathsObject

Returns the value of attribute output_paths.



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

def output_paths
  @output_paths
end

#pagesObject

Returns the value of attribute pages.



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

def pages
  @pages
end

#postsObject

Returns the value of attribute posts.



15
16
17
# File 'lib/dimples/site.rb', line 15

def posts
  @posts
end

#source_pathsObject

Returns the value of attribute source_paths.



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

def source_paths
  @source_paths
end

#templatesObject

Returns the value of attribute templates.



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

def templates
  @templates
end

Instance Method Details

#copy_assetsObject



254
255
256
257
258
259
260
261
262
263
# File 'lib/dimples/site.rb', line 254

def copy_assets
  if Dir.exist?(@source_paths[:public])
    Dimples.logger.debug('Copying assets...') if @config[:verbose_logging]

    path = File.join(@source_paths[:public], '.')
    FileUtils.cp_r(path, @output_paths[:site])
  end
rescue => e
  raise Errors::GenerationError, "Site assets failed to copy (#{e.message})"
end

#feed_templatesObject



250
251
252
# File 'lib/dimples/site.rb', line 250

def feed_templates
  @feed_templates ||= @templates.keys.select { |k| k =~ /^feeds\./ }
end

#generateObject



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

def generate
  scan_files
  prepare_output_directory

  generate_pages unless @pages.count.zero?

  unless @posts.count.zero?
    generate_posts
    generate_archives
    generate_categories if @config[:generation][:categories]
  end

  copy_assets
rescue Errors::RenderingError,
       Errors::PublishingError,
       Errors::GenerationError => e
  @errors << e.message
end

#generate_archivesObject



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

def generate_archives
  %w[year month day].each do |date_type|
    date_archives_sym = "#{date_type}_archives".to_sym
    next unless @config[:generation][date_archives_sym]

    @archives[date_type.to_sym].each do |date, posts|
      year, month, day = date.split('-')

      dates = { year: year }
      dates[:month] = month if month
      dates[:day] = day if day

      path = File.join(@output_paths[:archives], dates.values)

      layout = @config[:layouts][date_archives_sym]
      date_format = @config[:date_formats][date_type.to_sym]

      options = {
        context: dates,
        title: posts[0].date.strftime(date_format)
      }

      paginate(self, posts, path, layout, options)
    end
  end
end

#generate_categoriesObject



169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
# File 'lib/dimples/site.rb', line 169

def generate_categories
  if @config[:verbose_logging]
    Dimples.logger.debug_generation('category pages', @categories.length)
  end

  @categories.each_value do |category|
    path = File.join(@output_paths[:categories], category.slug)

    options = {
      context: { category: category.slug },
      title: category.name
    }

    paginate(
      self,
      category.posts,
      path,
      @config[:layouts][:category],
      options
    )
  end

  generate_category_feeds if @config[:generation][:category_feeds]
end

#generate_category_feedsObject



241
242
243
244
245
246
247
248
# File 'lib/dimples/site.rb', line 241

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

    generate_feeds(path, posts: posts, category: category.slug)
  end
end

#generate_feeds(path, context) ⇒ Object



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

def generate_feeds(path, context)
  feed_templates.each do |format|
    next unless @templates[format]

    feed = Dimples::Page.new(self)

    feed.output_directory = path
    feed.filename = 'feed'
    feed.extension = @templates[format].slug
    feed.layout = format

    feed.write(context)
  end
end

#generate_pagesObject



161
162
163
164
165
166
167
# File 'lib/dimples/site.rb', line 161

def generate_pages
  if @config[:verbose_logging]
    Dimples.logger.debug_generation('pages', @pages.length)
  end

  @pages.each(&:write)
end

#generate_postsObject



144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
# File 'lib/dimples/site.rb', line 144

def generate_posts
  if @config[:verbose_logging]
    Dimples.logger.debug_generation('posts', @posts.length)
  end

  @posts.each(&:write)

  paginate(
    self,
    @posts,
    @output_paths[:archives],
    @config[:layouts][:posts]
  )

  generate_posts_feeds if @config[:generation][:feeds]
end

#generate_posts_feedsObject



236
237
238
239
# File 'lib/dimples/site.rb', line 236

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

#generated?Boolean

Returns:

  • (Boolean)


64
65
66
# File 'lib/dimples/site.rb', line 64

def generated?
  @errors.count.zero?
end

#inspectObject



265
266
267
268
269
# File 'lib/dimples/site.rb', line 265

def inspect
  "#<#{self.class} " \
  "@source_paths=#{@source_paths} " \
  "@output_paths=#{@output_paths}>"
end

#prepare_output_directoryObject



133
134
135
136
137
138
139
140
141
142
# File 'lib/dimples/site.rb', line 133

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

  Dir.mkdir(@output_paths[:site])
rescue => e
  error_message = "Couldn't prepare the output directory (#{e.message})"
  raise Errors::GenerationError, error_message
end

#scan_filesObject



68
69
70
71
72
73
74
# File 'lib/dimples/site.rb', line 68

def scan_files
  Dimples.logger.debug('Scanning files...') if @config[:verbose_logging]

  scan_templates
  scan_pages
  scan_posts
end

#scan_page(path) ⇒ Object



98
99
100
# File 'lib/dimples/site.rb', line 98

def scan_page(path)
  Dimples::Page.new(self, path)
end

#scan_pagesObject



92
93
94
95
96
# File 'lib/dimples/site.rb', line 92

def scan_pages
  Dir.glob(File.join(@source_paths[:pages], '**', '*.*')).each do |path|
    @pages << scan_page(path)
  end
end

#scan_post(path) ⇒ Object



120
121
122
123
124
125
126
127
128
129
130
131
# File 'lib/dimples/site.rb', line 120

def scan_post(path)
  post_class.new(self, path).tap do |post|
    post.categories&.each do |slug|
      @categories[slug] ||= Dimples::Category.new(self, slug)
      @categories[slug].posts << post
    end

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

#scan_postsObject



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/dimples/site.rb', line 102

def scan_posts
  Dir.glob(File.join(@source_paths[:posts], '*.*')).reverse_each do |path|
    @posts << scan_post(path)
  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



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/dimples/site.rb', line 76

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

    parent_path = File.dirname(path)
    if parent_path == @source_paths[:templates]
      slug = template.slug
    else
      relative_path = parent_path.sub(@source_paths[:templates], '')[1..-1]
      slug = relative_path.sub(File::SEPARATOR, '.') + ".#{template.slug}"
    end

    @templates[slug] = template
  end
end