lib/hyperloop/application.rb in hyperloop-0.0.2 vs lib/hyperloop/application.rb in hyperloop-0.0.3

- old
+ new

@@ -1,45 +1,85 @@ -require 'rack' +require "rack" +require "sprockets" +require "yui/compressor" module Hyperloop class Application include Rack::Utils def initialize(root=nil) - @root = root - @views_path = File.join([@root, 'app/views'].compact) + @root = root + @view_registry = View::Registry.new(@root) end # Rack call interface. def call(env) request = Rack::Request.new(env) response = Response.new - path = view_path(request) - if File.exist?(path) - # If there's a file at the view path, use its data as the response body. - data = File.read(path) + if self.class.asset_path?(request.path) && asset = assets[normalized_asset_path(request.path)] + # If the path is for an asset, find the specified asset and use its data + # as the response body. + response["Content-Type"] = asset.content_type + response.write(asset.source) + elsif view = @view_registry.find_template_view(normalized_request_path(request.path)) + # If there's a view at the path, use its data as the response body. + data = view.render(request) response.write(data) else - # If there's no file at the view path, 404. + # If there's no view at the path, 404. response.status = 404 end response.finish end private - # Internal: Get the view path for the specified request. + # Internal: Is the specified path for assets? # - # request - Rack::Request to get the view path for. + # path - Path to check. # - # Returns a String. - def view_path(request) - path = File.join(@views_path, request.path).chomp('/') + # Returns a boolean. + def self.asset_path?(path) + path =~ /^\/assets\/(images|javascripts|stylesheets)\// + end - # If we're currently pointing to a directory, get index in it. - path = File.join(path, 'index') if Dir.exist?(path) - path + '.html' + # Internal: The sprockets environment for the app. + # + # Returns a Sprockets::Environment. + def assets + @assets ||= Sprockets::Environment.new do |env| + env.append_path(File.join(@root, "app", "assets")) + env.append_path(File.join(@root, "vendor", "assets")) + + # compress everything in production + if ENV["RACK_ENV"] == "production" + env.js_compressor = YUI::JavaScriptCompressor.new(:munge => true) + env.css_compressor = YUI::CssCompressor.new + end + end + end + + # Internal: Get a normalized version of the specified asset path. + # + # path - Asset path to normalize + # + # Returns a string. + def normalized_asset_path(path) + path.sub(/^\/assets\//, "") + end + + # Internal: Get a normalized version of the specified request path. + # + # path - Request path to normalize + # + # Returns a string. + def normalized_request_path(path) + if path == "/" + path + else + path.chomp("/") + end end end end