Parent

Files

Jekyll::Site

Attributes

categories[RW]
config[RW]
converters[RW]
dest[RW]
exclude[RW]
future[RW]
generators[RW]
layouts[RW]
limit_posts[RW]
lsi[RW]
pages[RW]
plugins[RW]
posts[RW]
pygments[RW]
safe[RW]
source[RW]
static_files[RW]
tags[RW]
time[RW]

Public Class Methods

new(config) click to toggle source

Public: Initialize a new Site.

config - A Hash containing site configuration details.

# File lib/jekyll/site.rb, line 15
def initialize(config)
  self.config          = config.clone

  self.safe            = config['safe']
  self.source          = File.expand_path(config['source'])
  self.dest            = File.expand_path(config['destination'])
  self.plugins         = File.expand_path(config['plugins'])
  self.lsi             = config['lsi']
  self.pygments        = config['pygments']
  self.permalink_style = config['permalink'].to_sym
  self.exclude         = config['exclude'] || []
  self.future          = config['future']
  self.limit_posts     = config['limit_posts'] || nil

  self.reset
  self.setup
end

Public Instance Methods

cleanup() click to toggle source

Remove orphaned files and empty directories in destination.

Returns nothing.

# File lib/jekyll/site.rb, line 209
def cleanup
  # all files and directories in destination, including hidden ones
  dest_files = Set.new
  Dir.glob(File.join(self.dest, "**", "*"), File::FNM_DOTMATCH) do |file|
    dest_files << file unless file =~ /\/\.{1,2}$/
  end

  # files to be written
  files = Set.new
  self.posts.each do |post|
    files << post.destination(self.dest)
  end
  self.pages.each do |page|
    files << page.destination(self.dest)
  end
  self.static_files.each do |sf|
    files << sf.destination(self.dest)
  end

  # adding files' parent directories
  dirs = Set.new
  files.each { |file| dirs << File.dirname(file) }
  files.merge(dirs)

  obsolete_files = dest_files - files

  FileUtils.rm_rf(obsolete_files.to_a)
end
filter_entries(entries) click to toggle source

Filter out any files/directories that are hidden or backup files (start with "." or "#" or end with "~"), or contain site content (start with "_"), or are excluded in the site configuration, unless they are web server files such as '.htaccess'.

entries - The Array of file/directory entries to filter.

Returns the Array of filtered entries.

# File lib/jekyll/site.rb, line 306
def filter_entries(entries)
  entries = entries.reject do |e|
    unless ['.htaccess'].include?(e)
      ['.', '_', '#'].include?(e[0..0]) ||
      e[-1..-1] == '~' ||
      self.exclude.include?(e) ||
      File.symlink?(e)
    end
  end
end
generate() click to toggle source

Run each of the Generators.

Returns nothing.

# File lib/jekyll/site.rb, line 182
def generate
  self.generators.each do |generator|
    generator.generate(self)
  end
end
getConverterImpl(klass) click to toggle source

Get the implementation class for the given Converter.

klass - The Class of the Converter to fetch.

Returns the Converter instance implementing the given Converter.

# File lib/jekyll/site.rb, line 322
def getConverterImpl(klass)
  matches = self.converters.select { |c| c.class == klass }
  if impl = matches.first
    impl
  else
    raise "Converter implementation not found for #{klass}"
  end
end
post_attr_hash(post_attr) click to toggle source

Constructs a Hash of Posts indexed by the specified Post attribute.

post_attr - The String name of the Post attribute.

Examples

post_attr_hash('categories')
# => { 'tech' => [<Post A>, <Post B>],
#      'ruby' => [<Post B>] }

Returns the Hash: { attr => posts } where

attr  - One of the values for the requested attribute.
posts - The Array of Posts with the given attr value.
# File lib/jekyll/site.rb, line 266
def post_attr_hash(post_attr)
  # Build a hash map based on the specified post attribute ( post attr =>
  # array of posts ) then sort each array in reverse order.
  hash = Hash.new { |hsh, key| hsh[key] = Array.new }
  self.posts.each { |p| p.send(post_attr.to_sym).each { |t| hash[t] << p } }
  hash.values.map { |sortme| sortme.sort! { |a, b| b <=> a } }
  hash
end
process() click to toggle source

Public: Read, process, and write this Site to output.

Returns nothing.

# File lib/jekyll/site.rb, line 36
def process
  self.reset
  self.read
  self.generate
  self.render
  self.cleanup
  self.write
end
read() click to toggle source

Read Site data from disk and load it into internal data structures.

Returns nothing.

# File lib/jekyll/site.rb, line 96
def read
  self.read_layouts
  self.read_directories
end
read_directories(dir = '') click to toggle source

Recursively traverse directories to find posts, pages and static files that will become part of the site according to the rules in filter_entries.

dir - The String relative path of the directory to read.

Returns nothing.

# File lib/jekyll/site.rb, line 124
def read_directories(dir = '')
  base = File.join(self.source, dir)
  entries = Dir.chdir(base) { filter_entries(Dir['*']) }

  self.read_posts(dir)

  entries.each do |f|
    f_abs = File.join(base, f)
    f_rel = File.join(dir, f)
    if File.directory?(f_abs)
      next if self.dest.sub(/\/$/, '') == f_abs
      read_directories(f_rel)
    elsif !File.symlink?(f_abs)
      first3 = File.open(f_abs) { |fd| fd.read(3) }
      if first3 == "---"
        # file appears to have a YAML header so process it as a page
        pages << Page.new(self, self.source, dir, f)
      else
        # otherwise treat it as a static file
        static_files << StaticFile.new(self, self.source, dir, f)
      end
    end
  end
end
read_layouts(dir = '') click to toggle source

Read all the files in <source>/<dir>/_layouts and create a new Layout object with each one.

Returns nothing.

# File lib/jekyll/site.rb, line 105
def read_layouts(dir = '')
  base = File.join(self.source, dir, "_layouts")
  return unless File.exists?(base)
  entries = []
  Dir.chdir(base) { entries = filter_entries(Dir['*.*']) }

  entries.each do |f|
    name = f.split(".")[0..-2].join(".")
    self.layouts[name] = Layout.new(self, base, f)
  end
end
read_posts(dir) click to toggle source

Read all the files in <source>/<dir>/_posts and create a new Post object with each one.

dir - The String relative path of the directory to read.

Returns nothing.

# File lib/jekyll/site.rb, line 155
def read_posts(dir)
  base = File.join(self.source, dir, '_posts')
  return unless File.exists?(base)
  entries = Dir.chdir(base) { filter_entries(Dir['**/*']) }

  # first pass processes, but does not yet render post content
  entries.each do |f|
    if Post.valid?(f)
      post = Post.new(self, self.source, dir, f)

      if post.published && (self.future || post.date <= self.time)
        self.posts << post
        post.categories.each { |c| self.categories[c] << post }
        post.tags.each { |c| self.tags[c] << post }
      end
    end
  end

  self.posts.sort!

  # limit the posts if :limit_posts option is set
  self.posts = self.posts[-limit_posts, limit_posts] if limit_posts
end
render() click to toggle source

Render the site to the destination.

Returns nothing.

# File lib/jekyll/site.rb, line 191
def render
  self.posts.each do |post|
    post.render(self.layouts, site_payload)
  end

  self.pages.each do |page|
    page.render(self.layouts, site_payload)
  end

  self.categories.values.map { |ps| ps.sort! { |a, b| b <=> a } }
  self.tags.values.map { |ps| ps.sort! { |a, b| b <=> a } }
rescue Errno::ENOENT => e
  # ignore missing layout dir
end
reset() click to toggle source

Reset Site details.

Returns nothing

# File lib/jekyll/site.rb, line 48
def reset
  self.time            = if self.config['time']
                           Time.parse(self.config['time'].to_s)
                         else
                           Time.now
                         end
  self.layouts         = {}
  self.posts           = []
  self.pages           = []
  self.static_files    = []
  self.categories      = Hash.new { |hash, key| hash[key] = [] }
  self.tags            = Hash.new { |hash, key| hash[key] = [] }

  if !self.limit_posts.nil? && self.limit_posts < 1
    raise ArgumentError, "Limit posts must be nil or >= 1"
  end
end
setup() click to toggle source

Load necessary libraries, plugins, converters, and generators.

Returns nothing.

# File lib/jekyll/site.rb, line 69
def setup
  require 'classifier' if self.lsi

  # If safe mode is off, load in any Ruby files under the plugins
  # directory.
  unless self.safe
    Dir[File.join(self.plugins, "**/*.rb")].each do |f|
      require f
    end
  end

  self.converters = Jekyll::Converter.subclasses.select do |c|
    !self.safe || c.safe
  end.map do |c|
    c.new(self.config)
  end

  self.generators = Jekyll::Generator.subclasses.select do |c|
    !self.safe || c.safe
  end.map do |c|
    c.new(self.config)
  end
end
site_payload() click to toggle source

The Hash payload containing site-wide data.

Returns the Hash: { "site" => data } where data is a Hash with keys:

"time"       - The Time as specified in the configuration or the
               current time if none was specified.
"posts"      - The Array of Posts, sorted chronologically by post date
               and then title.
"pages"      - The Array of all Pages.
"html_pages" - The Array of HTML Pages.
"categories" - The Hash of category values and Posts.
               See Site#post_attr_hash for type info.
"tags"       - The Hash of tag values and Posts.
               See Site#post_attr_hash for type info.
# File lib/jekyll/site.rb, line 288
def site_payload
  {"site" => self.config.merge({
      "time"       => self.time,
      "posts"      => self.posts.sort { |a, b| b <=> a },
      "pages"      => self.pages,
      "html_pages" => self.pages.reject { |page| !page.html? },
      "categories" => post_attr_hash('categories'),
      "tags"       => post_attr_hash('tags')})}
end
write() click to toggle source

Write static files, pages, and posts.

Returns nothing.

# File lib/jekyll/site.rb, line 241
def write
  self.posts.each do |post|
    post.write(self.dest)
  end
  self.pages.each do |page|
    page.write(self.dest)
  end
  self.static_files.each do |sf|
    sf.write(self.dest)
  end
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.