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.



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

def initialize(config)
  @config = config

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

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

  @post_class = @config.class_override(:post) || Dimples::Post

  @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.



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.



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

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

#post_classObject

Returns the value of attribute post_class.



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

def post_class
  @post_class
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



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

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



244
245
246
# File 'lib/dimples/site.rb', line 244

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

#generateObject



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
# File 'lib/dimples/site.rb', line 47

def generate
  scan_templates
  scan_pages
  scan_posts

  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



191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/dimples/site.rb', line 191

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

    @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_type}_archives"]

      options = {
        context: dates,
        title: posts[0].date.strftime(@config['date_formats'][date_type])
      }

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

#generate_categoriesObject



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

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



235
236
237
238
239
240
241
242
# File 'lib/dimples/site.rb', line 235

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



215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/dimples/site.rb', line 215

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



158
159
160
161
162
163
164
# File 'lib/dimples/site.rb', line 158

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

  @pages.each(&:write)
end

#generate_postsObject



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

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



230
231
232
233
# File 'lib/dimples/site.rb', line 230

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

#generated?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/dimples/site.rb', line 69

def generated?
  @errors.count.zero?
end

#inspectObject



259
260
261
262
263
# File 'lib/dimples/site.rb', line 259

def inspect
  "#<Dimples::Site " \
  "@source_paths=#{@source_paths} " \
  "@output_paths=#{@output_paths}>"
end

#prepare_output_directoryObject



130
131
132
133
134
135
136
137
138
139
# File 'lib/dimples/site.rb', line 130

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_page(path) ⇒ Object



95
96
97
# File 'lib/dimples/site.rb', line 95

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

#scan_pagesObject



89
90
91
92
93
# File 'lib/dimples/site.rb', line 89

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

#scan_post(path) ⇒ Object



117
118
119
120
121
122
123
124
125
126
127
128
# File 'lib/dimples/site.rb', line 117

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



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

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



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/dimples/site.rb', line 73

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.gsub(@source_paths[:templates], '')[1..-1]
      slug = relative_path.gsub(File::SEPARATOR, '.') + ".#{template.slug}"
    end

    @templates[slug] = template
  end
end