class PlainSite::Site
Attributes
Public Class Methods
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 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 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
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
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
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 site structure
# File lib/PlainSite/Site.rb, line 77 def init_scaffold(override=false) Utils.merge_folder SCAFFOLD_DIR,@root,override reload end
# 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
Access config.yml data through site's property
# 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
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,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
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
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
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 _src/assets to dest root directory
# File lib/PlainSite/Site.rb, line 299 def copy_assets Utils.merge_folder @assets_path,@dest,true end
# 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
# 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
# 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
# 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
# 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