Class: Zenweb::Site

Inherits:
Object
  • Object
show all
Includes:
Rake::DSL
Defined in:
lib/zenweb/site.rb

Overview

Holder for the entire website. Everything gets driven from here.

TODO: describe expected filesystem layout and dependency mgmt.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSite

:nodoc:



44
45
46
47
48
# File 'lib/zenweb/site.rb', line 44

def initialize # :nodoc:
  @layouts = {}
  @pages = {}
  @configs = Hash.new { |h,k| h[k] = Config.new self, k }
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(msg, *_args) ⇒ Object

Proxy object for the config. Returns a config item at msg.



136
137
138
139
# File 'lib/zenweb/site.rb', line 136

def method_missing msg, *_args
  k = msg.to_s
  config.key?(k) ? config[k] : warn("#{self.inspect} does not define #{k}")
end

Instance Attribute Details

#configsObject (readonly)

Returns all configs found via #scan



26
27
28
# File 'lib/zenweb/site.rb', line 26

def configs
  @configs
end

#layoutsObject (readonly)

Returns all known layouts found via #scan



31
32
33
# File 'lib/zenweb/site.rb', line 31

def layouts
  @layouts
end

#pagesObject (readonly)

Returns all pages found via #scan



21
22
23
# File 'lib/zenweb/site.rb', line 21

def pages
  @pages
end

Class Method Details

.binary_filesObject



211
212
213
# File 'lib/zenweb/site.rb', line 211

def self.binary_files
  @binary_files ||= %w[png jpg gif eot svg ttf woff2? ico pdf m4a t?gz]
end

.load_pluginsObject

Loads all files matching “zenweb/plugins/*.rb”.



36
37
38
39
40
# File 'lib/zenweb/site.rb', line 36

def self.load_plugins
  Gem.find_files("zenweb/plugins/*.rb").each do |path|
    require path
  end
end

.text_filesObject



215
216
217
# File 'lib/zenweb/site.rb', line 215

def self.text_files
  @text_files ||= %w[txt html css js]
end

Instance Method Details

#categoriesObject

Returns a magic hash that groups up all the pages by category (directory). The hash has extra accessor methods on it to make grabbing what you want a bit cleaner. eg:

site.categories.blog # => [Page[blog/...], ...]


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
# File 'lib/zenweb/site.rb', line 57

def categories
  @categories ||=
    begin
      h = Hash.new { |h2,k| h2[k] = [] }

      def h.method_missing msg, *args
        if self.has_key? msg.to_s then
          self[msg.to_s]
        else
          super
        end
      end

      pages.each do |url, page|
        dir = url.split(/\//).first
        next unless File.directory? dir and dir !~ /^_/
        next if url =~ /index.html/ or url !~ /html/
        h[dir] << page
      end

      h.keys.each do |dir|
        h[dir] = h[dir].sort_by { |p| [-p.date.to_i, p.title ] }
      end

      h
    end
end

#configObject

Return the top level config.



88
89
90
# File 'lib/zenweb/site.rb', line 88

def config
  configs["_config.yml"]
end

#fix_subpagesObject

:nodoc:



227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/zenweb/site.rb', line 227

def fix_subpages # :nodoc:
  # TODO: push most of this down to page
  parents = {}

  @pages.values.select(&:index?).each do |p|
    parents[p.url] = p
  end

  @pages.values.each do |p|
    path = p.parent_url

    parent = nil
    begin
      path = File.join File.dirname(path), "index.html"
      parent = parents[path]
      path = File.dirname path
    end until parent or path == "/"

    next unless parent and parent != p and p.url =~ /html$/

    p.parent = parent
    parent.subpages << p
  end

  @pages.values.each do |p|
    unless p.subpages.empty? then
      sorted = p.subpages.sort_by(&:clean_url)
      p.subpages.replace sorted
    end
  end
end

#generateObject

Generates the website by invoking the ‘site’ task.



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

def generate
  task(:site).invoke
end

#html_page_map(&map) ⇒ Object

Return a list of all pages my applying map to all html_pages and cleaning up the results.



103
104
105
# File 'lib/zenweb/site.rb', line 103

def html_page_map &map
  html_pages.map(&map).flatten.uniq.compact
end

#html_pagesObject

Returns a list of all known html pages.



110
111
112
# File 'lib/zenweb/site.rb', line 110

def html_pages
  self.pages.values.select { |p| p.url_path =~ /\.html/ }
end

#inspectObject

:nodoc:



114
115
116
# File 'lib/zenweb/site.rb', line 114

def inspect # :nodoc:
  "Site[#{pages.size} pages, #{configs.size} configs]"
end

#layout(name) ⇒ Object

Returns a layout named name.



121
122
123
# File 'lib/zenweb/site.rb', line 121

def layout name
  name and (@layouts[name] or raise "unknown layout #{name.inspect}")
end

Return a list of HTML links after applying map to all html pages and cleaning the results.



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

def link_list &map
  html_page_map(&map).map(&:link_html)
end

#pages_by_dateObject

Returns all pages (with titles) sorted by date.



144
145
146
147
148
# File 'lib/zenweb/site.rb', line 144

def pages_by_date
  # page.config["title"] avoids the warning
  html_pages.select {|page| page.config["title"] }.
    sort_by { |page| [-page.date.to_i, page.title] }
end

#pages_by_urlObject

Returns a hash mapping page url to page.



153
154
155
156
157
158
159
160
161
162
# File 'lib/zenweb/site.rb', line 153

def pages_by_url
  unless defined? @pages_by_url then
    h = {}
    pages.each do |_,p|
      h[p.url] = p
    end
    @pages_by_url = h
  end
  @pages_by_url
end

#scanObject

Scans the directory tree and finds all relevant pages, configs, layouts, etc.

TODO: talk about expected directory structure and extra naming enhancements.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/zenweb/site.rb', line 171

def scan
  excludes = %w[~ Rakefile] + Array(config["exclude"])

  top = Dir["*"] - excludes
  files = top.select { |path| File.file? path }
  files += Dir["{#{top.join(",")}}/**/*"].reject { |f| not File.file? f }
  files.reject! { |f| f.include? "/_" }

  renderers_re = Page.renderers_re

  files.each do |path|
    case path
    when /(?:#{excludes.join '|'})$/
      # ignore
    when /^_layout/ then
      name = File.basename(path).sub(/\..+$/, '')
      @layouts[name] = Page.new self, path
    when /^_/ then
      next
    when /\.yml$/ then
      @configs[path] = Config.new self, path
    when /\.(?:#{self.class.binary_files.join("|")})$/ then
      @pages[path] = Page.new self, path, self.config
    when /\.(?:#{self.class.text_files.join("|")})$/, renderers_re then
      @pages[path] = Page.new self, path
    else
      warn "unknown file type: #{path}" if Rake.application.options.trace
    end
  end

  $website = self # HACK
  task(:virtual_pages).invoke

  t = Time.now
  @pages.reject! { |path, page| page.date && page.date > t } unless
    ENV["ALL"]

  fix_subpages
end

#stale?Boolean

Returns:

  • (Boolean)


223
224
225
# File 'lib/zenweb/site.rb', line 223

def stale?
  not stale_pages.empty?
end

#stale_pagesObject



219
220
221
# File 'lib/zenweb/site.rb', line 219

def stale_pages
  pages.values.find_all(&:stale?)
end

#wireObject

Wire up all the configs and pages. Invokes :extra_wirings to allow you to add extra manual dependencies.



263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
# File 'lib/zenweb/site.rb', line 263

def wire
  directory ".site"
  task :site => ".site"

  configs.each do |path, config|
    config.wire
  end

  pages.each do |path, page|
    page.wire
  end

  $website = self # HACK
  task(:extra_wirings).invoke
end