class PlainSite::Site

Attributes

_cur_page_dir[RW]
assets_path[R]
data_path[R]
dest[R]
local[R]
root[R]
templates_path[R]

Public Class Methods

new(root) click to toggle source

Params root - The String root path of site,must be an exists path

# File lib/PlainSite/Site.rb, line 32
def initialize(root)
  @root= File.realpath root
  @dest= @root
  @src_path=File.join(@root,'_src')
  @data_path=File.join(@src_path,'data')
  @routes_rb=File.join(@src_path,'routes.rb')
  @templates_path=File.join(@src_path,'templates')
  @assets_path=File.join(@src_path,'assets')
  @config_file= File.join(@src_path,'config.yml')
  @extensions= File.join(@src_path,'extensions')

  @_cur_page_dir = ''

  load_extensions
  create_pygments_css
end

Public Instance Methods

build(opts={}) click to toggle source

Build static pages all - The Boolean value to force build all posts.Default only build updated posts. dest - The String path of destination directory includes - The String[] path of posts or templates to force regeneration

# File lib/PlainSite/Site.rb, line 129
def build(opts={})
  @local=opts[:local]
  @dest= opts[:dest] if opts[:dest]
  includes= opts[:includes]
  if includes && ! includes.empty?
    includes.map! &(File.method :realpath)
  else
    includes=nil
  end


  files=diff_files includes

  if opts[:all] || files.nil?
    render_task.render
  else
    render_task.render(files)
  end
  copy_assets
end
clean() click to toggle source

Clean isolated files under dest directory If file is neither generated by `routes.rb` nor copied from `_src/assets/`,it will be deleted.

# File lib/PlainSite/Site.rb, line 152
def clean
  isolated_files.each do |f|
    File.delete f
  end
end
config() click to toggle source

The Hash config defined if config.yml

# File lib/PlainSite/Site.rb, line 59
def config
  return @config if @config
  @config = (File.exists? @config_file) ? (YAML.safe_load_file @config_file) : {}
end
data() click to toggle source

Return the Category object represents _site/data

# File lib/PlainSite/Site.rb, line 71
def data
  return @data if @data
  @data=Data::Category.new @data_path,self
end
diff_files(includes=nil) click to toggle source

Get diff_files

Return Hash Structure: {

updated_posts:[],
updated_templates:[],
has_deleted_posts:Bool

}

# File lib/PlainSite/Site.rb, line 243
def diff_files(includes=nil)
  deleted_posts=[]
  begin
    repo=Git.open @root
    files=%w(untracked added changed).map {|m|(repo.status.send m).keys}.flatten
    files.map! {|f|File.join @root,f}
    deleted_posts=repo.status.deleted.keys.map {|f|File.join @root,f}
    deleted_posts.select! do |f|
      f.start_with? @data_path
    end
  rescue Git::GitExecuteError,ArgumentError => e
    $stderr.puts("\nMaybe site root is not a valid git repository:#{@root}. Error: " + e.to_s)
    return nil if includes.nil?
  end
  files||=[]
  files.concat includes if includes
  files=files.group_by do |f|
    if f.start_with? @data_path+'/'
      :updated_posts
    elsif f.start_with? @templates_path+'/'
      :updated_templates
    else
      :unrelated
    end
  end
  files.delete :unrelated
  files[:has_deleted_posts]= ! deleted_posts.empty?
  files
end
init_scaffold(override=false) click to toggle source

Init site structure

# File lib/PlainSite/Site.rb, line 77
def init_scaffold(override=false)
  Utils.merge_folder SCAFFOLD_DIR,@root,override
  reload
end
isolated_files() click to toggle source
# File lib/PlainSite/Site.rb, line 158
def isolated_files
  all_path= render_task.all_urlpath.map do |p|
    File.join @dest,p
  end
  files= (Dir.glob "#{@dest}/*")
  files.reject! {|f| f==@src_path} # Skip src
  _isolated_files= files.reduce([]) do |a,f|
    if File.directory? f
      # concat is not pure
      a.concat (Dir.glob "#{f}/**/**")
    else
      a.push f
    end
    next a
  end
  _isolated_files.select! do |f|
    next false if all_path.include? f
    f=File.join @assets_path,f[@dest.length..-1]
    not (File.exists? f)  # Keep static assets
  end

  return _isolated_files
end
method_missing(name,*args,&block) click to toggle source

Access config.yml data through site's property

Calls superclass method
# File lib/PlainSite/Site.rb, line 65
def method_missing(name,*args,&block)
  return config[name.to_s] if args.empty? && block.nil? && (config.key? name.to_s)
  super
end
newpost(p,title) click to toggle source

Create a new post file

# File lib/PlainSite/Site.rb, line 83
def newpost(p,title)
  ext=File.extname p
  unless ext.empty? || (Data::Post.extname_ok? p)
    raise Exception,"Unsupported file type:#{ext}.Supported extnames:"+Data::Post.extnames.join(",")
  end

  name=File.basename p,ext
  ext='.'+Data::Post.extnames[0] unless ext
  name= "#{name}#{ext}"

  if Data::Post::DATE_NAME_RE =~ name
    date=''
  else
    date="date: #{Date.today}\n"
  end

  if p['/']
    path=File.join @data_path,(File.dirname p)
    FileUtils.mkdir_p  path
  else
    path=@data_path
  end
  path="#{path}/#{name}"
  File.open(path,'wb') do |f|
    f.write "---\ntitle: #{title}\n#{date}---\n\n#{title}\n====="
  end
  path
end
reload() click to toggle source

Reload,clean cached instance variables read from file

# File lib/PlainSite/Site.rb, line 50
def reload
  @config=nil
  @render_task=nil
  @data=nil
  create_pygments_css
  load_extensions
end
route(opt) click to toggle source

Config route specified data with ordered template and url path. See: RenderTask#route

# File lib/PlainSite/Site.rb, line 114
def route(opt)
  render_task.route(opt)
end
serve(opts={}) click to toggle source

Run a preview server on localhost:1990

# File lib/PlainSite/Site.rb, line 183
def serve(opts={})
  host=opts[:host] || 'localhost'
  port=opts[:port] || '1990'
  origin_url=config['url']

  Listen.to(@src_path) do |m, a, d|
    puts "\nReloaded!\n"
    self.reload
  end

  server = WEBrick::HTTPServer.new(Port:port,BindAddress:'0.0.0.0')
  server.mount_proc '/' do |req,res|
    url= req.path_info
    url= '/index.html' if url=='/'
    res.status=404 if url=='/404.html'
    prevent_caching(res)
    static_file=File.join @assets_path,url
    if (File.exists? static_file) && !(File.directory? static_file)
      serve_static server,static_file,req,res
      next
    end
    config['url']= "http://#{host}:#{port}"
    result=render_task.render_url url
    config['url']=origin_url
    if result
      res.body=result
      res['Content-Type']='text/html'
      if req.request_method == 'HEAD'
        res['Content-Length'] = 0
      end
      next
    end
    static_file=File.join @dest,url
    if File.exists? static_file
      serve_static server,static_file,req,res
      next
    end
    res.status=301
    res['Location']='/404.html'
  end
  t = Thread.new { server.start }

  quitServer = proc { exit;server.shutdown }
  trap('INT',quitServer)
  trap('TERM',quitServer)

  puts "\nServer running on http://#{host}:#{port}/\n"
  t.join

end
url_for(x) click to toggle source

Get the url for object obj - The Post|PageListPage|Category|String Return the String url prefix with site root url(site.url) or relative path if build –local

# File lib/PlainSite/Site.rb, line 121
def url_for(x)
  render_task.url_for(x)
end

Private Instance Methods

copy_assets() click to toggle source

Copy _src/assets to dest root directory

# File lib/PlainSite/Site.rb, line 299
def copy_assets
  Utils.merge_folder @assets_path,@dest,true
end
create_pygments_css() click to toggle source
# File lib/PlainSite/Site.rb, line 311
def create_pygments_css
  return unless config['code_highlight'] && config['code_highlight']['engine']=='pygments'
  cls='.highlight'
  css_list=config['code_highlight']['pygments_css_list']
  css_list= css_list.each_pair.to_a if css_list
  css_list=[:native,'/css/pygments.css'] unless css_list
  css_list.each do |a|
    style,css_path=a
    css_path=File.join @assets_path,css_path
    next if File.exists? css_path
    FileUtils.mkdir_p File.dirname(css_path)
    css_content=Pygments.css(cls,style:style)
    File.open(css_path,'wb') do |f|
      f.write css_content
    end
  end
end
load_extensions() click to toggle source
# File lib/PlainSite/Site.rb, line 303
def load_extensions
  if File.directory? @extensions
    (Dir.glob "#{@extensions}/*.rb").each do |f|
      load f
    end
  end
end
prevent_caching(res) click to toggle source
# File lib/PlainSite/Site.rb, line 289
def prevent_caching(res)
  res['ETag']          = nil
  res['Last-Modified'] = Time.now + 100**4
  res['Cache-Control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
  res['Pragma']        = 'no-cache'
  res['Expires']       = Time.now - 100**4
end
render_task() click to toggle source
# File lib/PlainSite/Site.rb, line 275
def render_task
  return @render_task if @render_task
  @render_task=RenderTask.new self

  $site=self
  load @routes_rb,true
  @render_task
end
serve_static(server,static_file,req,res) click to toggle source
# File lib/PlainSite/Site.rb, line 284
def serve_static(server,static_file,req,res)
  handler=WEBrick::HTTPServlet::DefaultFileHandler.new server,static_file
  handler.do_GET req,res
end