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:



46
47
48
49
50
# File 'lib/zenweb/site.rb', line 46

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.



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

def method_missing msg, *args
  config[msg.to_s] || warn("#{self.inspect} does not define #{msg}")
end

Instance Attribute Details

#configsObject (readonly)

Returns all configs found via #scan



28
29
30
# File 'lib/zenweb/site.rb', line 28

def configs
  @configs
end

#layoutsObject (readonly)

Returns all known layouts found via #scan



33
34
35
# File 'lib/zenweb/site.rb', line 33

def layouts
  @layouts
end

#pagesObject (readonly)

Returns all pages found via #scan



23
24
25
# File 'lib/zenweb/site.rb', line 23

def pages
  @pages
end

Class Method Details

.binary_filesObject



192
193
194
# File 'lib/zenweb/site.rb', line 192

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

.load_pluginsObject

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



38
39
40
41
42
# File 'lib/zenweb/site.rb', line 38

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

.text_filesObject



196
197
198
# File 'lib/zenweb/site.rb', line 196

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/...], ...]


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
84
85
# File 'lib/zenweb/site.rb', line 59

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.



90
91
92
# File 'lib/zenweb/site.rb', line 90

def config
  configs["_config.yml"]
end

#fix_subpagesObject

:nodoc:



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/zenweb/site.rb', line 208

def fix_subpages # :nodoc:
  parents = {}
  @pages.values.select(&:index?).each do |p|
    parents[File.dirname p.path] = p
  end

  @pages.values.each do |p|
    path = File.dirname p.path
    path = File.dirname path if p.index?

    parent = parents[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)
      sorted = sorted.reverse if sorted.first.dated_path?
      p.subpages.replace sorted
    end
  end
end

#generateObject

Generates the website by invoking the ‘site’ task.



97
98
99
# File 'lib/zenweb/site.rb', line 97

def generate
  task(:site).invoke
end

#html_pagesObject

Returns a list of all known html pages.



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

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

#inspectObject

:nodoc:



108
109
110
# File 'lib/zenweb/site.rb', line 108

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

#layout(name) ⇒ Object

Returns a layout named name.



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

def layout name
  @layouts[name]
end

#pages_by_dateObject

Returns all pages (with titles) sorted by date.



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

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.



138
139
140
141
142
143
144
145
146
147
# File 'lib/zenweb/site.rb', line 138

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.



156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/zenweb/site.rb', line 156

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 }

  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

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

  fix_subpages
end

#stale?Boolean

Returns:

  • (Boolean)


204
205
206
# File 'lib/zenweb/site.rb', line 204

def stale?
  not stale_pages.empty?
end

#stale_pagesObject



200
201
202
# File 'lib/zenweb/site.rb', line 200

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.



237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
# File 'lib/zenweb/site.rb', line 237

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