lib/brochure/application.rb in brochure-0.2.0 vs lib/brochure/application.rb in brochure-0.3.0

- old
+ new

@@ -1,39 +1,58 @@ module Brochure class Application - attr_reader :app_root, :helper_root, :template_root, :asset_root + attr_reader :app_root, :template_root, :asset_root, :plugin_root, :assigns - def initialize(root) - @app_root = File.expand_path(root) - @helper_root = File.join(@app_root, "app", "helpers") - @template_root = File.join(@app_root, "app", "templates") - @asset_root = File.join(@app_root, "public") + def initialize(root, options = {}) + @app_root = File.expand_path(root) + @template_root = File.join(@app_root, "templates") + @asset_root = File.join(@app_root, "public") + @plugin_root = File.join(@app_root, "vendor", "plugins") - @template_trail = Hike::Trail.new(@app_root) - @template_trail.extensions.replace(Tilt.mappings.keys.sort) - @template_trail.paths.push(@template_root) + @assigns = options[:assigns] || {} + helpers.push(*options[:helpers]) if options[:helpers] + initialize_plugins + end - @context_class = Context.for(helpers) - @templates = {} + def initialize_plugins + plugins.each do |plugin_root| + template_trail.paths.push(File.join(plugin_root, "templates")) + end end + def template_trail + @template_trail ||= Hike::Trail.new(app_root).tap do |trail| + trail.extensions.replace(Tilt.mappings.keys.sort) + trail.paths.push(template_root) + end + end + + def context_class + @context_class ||= Context.for(helpers) + end + + def templates + @templates ||= {} + end + def helpers - @helpers ||= Dir[File.join(@helper_root, "**", "*.rb")].map do |helper_path| - base_name = helper_path[(@helper_root.length + 1)..-1][/(.*?)\.rb$/, 1] - module_names = base_name.split("/").map { |n| Brochure.camelize(n) } - load helper_path - module_names.inject(Kernel) { |mod, name| mod.const_get(name) } + @helpers ||= [] + end + + def plugins + @plugins ||= Dir[File.join(plugin_root, "*")].select do |entry| + File.directory?(entry) end end def call(env) if forbidden?(env["PATH_INFO"]) forbidden elsif template = find_template(env["PATH_INFO"][/[^.]+/]) success render_template(template, env) else - not_found + not_found(env) end end def forbidden?(path) path[".."] || File.basename(path)[/^_/] @@ -51,29 +70,29 @@ end end def find_template_path(logical_path) candidates = [logical_path + ".html", logical_path + "/index.html"] - @template_trail.find(*candidates) + template_trail.find(*candidates) end def find_partial_path(logical_path) path_parts = logical_path.split("/") partial_path = (path_parts[0..-2] + ["_" + path_parts[-1]]).join("/") - @template_trail.find(partial_path + ".html") + template_trail.find(partial_path + ".html") end def template_for(template_path) if Brochure.development? Tilt.new(template_path) else - @templates[template_path] ||= Tilt.new(template_path) + templates[template_path] ||= Tilt.new(template_path) end end def render_template(template, env, locals = {}) - context = @context_class.new(self, env) + context = context_class.new(self, env, assigns) template.render(context, locals) end def respond_with(status, body, content_type = "text/html, charset=utf-8") headers = { @@ -85,10 +104,18 @@ def success(body) respond_with 200, body end - def not_found + def not_found(env) + if template = find_template("404") + respond_with 404, render_template(template, env) + else + default_not_found + end + end + + def default_not_found respond_with 404, <<-HTML <!DOCTYPE html> <html><head><title>Not Found</title></head> <body><h1>404 Not Found</h1></body></html> HTML