lib/vitrine.rb in vitrine-0.0.11 vs lib/vitrine.rb in vitrine-0.0.12

- old
+ new

@@ -6,88 +6,25 @@ require_relative 'version' require_relative 'atomic_write' require_relative 'sourcemaps' -module Vitrine - DEFAULTS = { root: Dir.getwd, port: 4000, host: '127.0.0.1' } - - def self.check_dirs_present! - views = DEFAULTS[:root] + '/views' - unless File.exist?(views) and File.directory?(views) - $stderr.puts "WARNING: `views' directory not found under the current tree, you might want to create it" - end - - public_dir = DEFAULTS[:root] + '/public' - unless File.exist?(public_dir) and File.directory?(public_dir) - $stderr.puts "ERROR: `public' directory not found under the current tree, you should create it. Vitrine won't run without it" - exit 1 - end - end - - # Run the server, largely stolen from Serve - def self.run(options = DEFAULTS) - check_dirs_present! - - app = Rack::Builder.new do - use Rack::ShowStatus - use Rack::ShowExceptions - - guardfile_path = options[:root] + '/Guardfile' - if File.exist?(guardfile_path) - $stderr.puts "Attaching LiveReload via Guardfile at #{guardfile_path.inspect}" - # Assume livereload is engaged - use Rack::LiveReload - else - $stderr.puts "No Guardfile found, so there won't be any livereload injection" - end - - vitrine = Vitrine::App.new - vitrine.settings.set :root, options[:root] - run vitrine - end - - begin - # Try Thin - thin = Rack::Handler.get('thin') - thin.run app, :Port => options[:port], :Host => options[:address] do |server| - puts "Thin #{Thin::VERSION::STRING} available at http://#{options[:address]}:#{options[:port]}" - end - rescue LoadError - begin - # Then Mongrel - mongrel = Rack::Handler.get('mongrel') - mongrel.run app, :Port => options[:port], :Host => options[:address] do |server| - puts "Mongrel #{Mongrel::Const::MONGREL_VERSION} available at http://#{options[:address]}:#{options[:port]}" - end - rescue LoadError - # Then WEBrick - puts "Install Mongrel or Thin for better performance." - webrick = Rack::Handler.get('webrick') - webrick.run app, :Port => options[:port], :Host => options[:address] do |server| - trap("INT") { server.shutdown } - end - end - end - end -end - -require 'rack-livereload' - # A little idiosyncrastic asset server. # Does very simple things: # * sensible detector for default pages (they render from Sinatra view templates) # * automatic compilation of CoffeeScript and SASS assets - just request them with .js and .css # and Vitrine will find them and compile them for you on the spot class Vitrine::App < Sinatra::Base set :static, true + set :show_exceptions, false set :raise_errors, true - set :root, File.expand_path(File.dirname(__FILE__)) - set :views, lambda { File.join(settings.root, "views") } - set :public_dir, lambda { File.join(settings.root, "public") } + # Sets whether Vitrine will output messages about dynamic assets + set :silent, true + set :public_folder, ->{ File.join(settings.root, 'public') } + # For extensionless things try to pick out the related templates # from the views directory, and render them with a default layout. # If no template is found fallback to halting on 404 # so that Vitrine can be cascaded from. get /^([^\.]+)$/ do | extensionless_path | @@ -99,12 +36,15 @@ render_template_or_static(extensionless_path) end def render_template_or_static(extensionless_path) probable_html = extensionless_path + "/index.html" - html_path = File.join(settings.public_dir, probable_html) + + html_path = File.join(settings.public_folder, probable_html) if File.exist? html_path + # Might want to investigate... + # https://github.com/elitheeli/sinatra-index/blob/master/lib/sinatra-index.rb send_file html_path else render_template(extensionless_path) end end @@ -127,19 +67,23 @@ end # Try the first template that has been found template_path = possibilites.shift - # If nothing is found just bail + # If nothing is found try downstream or bail unless template_path err = possible_globs.map{|e| e.inspect }.join(', ') - halt 404, "No template found - tried #{err}" + if @app + return forward + else + halt 404, "No template found - tried #{err}, and no downstream Rack handler present" + end end relative_path = Pathname.new(template_path).relative_path_from(Pathname.new(settings.views)) - # $stderr.puts "-> #{extensionless_path.inspect} : Rendering via template #{relative_path.to_s.inspect}" + log "-> #{extensionless_path.inspect} : Rendering via template #{relative_path.to_s.inspect}" locals = {} # Auto-pick the template engine out of the extension template_engine = File.extname(template_path).gsub(/^\./, '') render(template_engine, File.read(template_path), :layout => get_layout, :locals => locals) @@ -151,10 +95,11 @@ begin content_type 'text/css', :charset => 'utf-8' # TODO: has no handling for .sass scss_source_path = File.join(settings.root, 'public', "#{basename}.scss") mtime_cache(scss_source_path) do + # TODO: Examine http://sass-lang.com/documentation/file.SASS_REFERENCE.html Sass.compile_file(scss_source_path, cache_location: '/tmp/vitrine/sass-cache') end rescue Errno::ENOENT # Missing SCSS halt 404, "No such CSS or SCSS file found" rescue Exception => e # CSS syntax error or something alike @@ -216,11 +161,11 @@ etag File.mtime(p) File.read(p) else yield.tap do | body | Vitrine.atomic_write(p) do |f| - # $stderr.puts "---> Recompiling #{path} for #{request.path_info}" + log "---> Recompiling #{path} for #{request.path_info}" f.write body end etag File.mtime(p) end end @@ -229,6 +174,9 @@ def get_layout layouts = Dir.glob(File.join(settings.views, 'layout.*')) layouts.any? ? :layout : false end + def log(msg) + $stderr.puts(msg) unless settings.silent? + end end \ No newline at end of file