Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Fetching contributors…

Cannot retrieve contributors at this time

file 93 lines (79 sloc) 2.288 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93
module Raptor
  class PlaintextResponder
    def initialize(text)
      @text = text
    end

    def respond(route, subject, injector)
      Rack::Response.new(@text)
    end
  end

  class ActionRedirectResponder
    def initialize(app, target)
      @app = app
      @target = target
    end

    def respond(route, subject, injector)
      path = resource_path(route, subject)
      RedirectResponder.new(path).respond(route, subject, injector)
    end

    def resource_path(route, subject)
      path = route.neighbor_named(@target).path
      if subject
        path = path.gsub(/:\w+/) do |match|
          # XXX: Untrusted send
          subject.send(match.sub(/^:/, '')).to_s
        end
      end
      path
    end
  end

  class RedirectResponder
    def initialize(location)
      @location = location
    end

    def respond(route, subject, injector)
      response = Rack::Response.new
      Raptor.log("Redirecting to #{@location}")
      response.status = 302
      response["Location"] = @location
      response
    end
  end

  class TemplateResponder
    def initialize(app, presenter_name, template_path, path)
      @app = app
      @presenter_name = presenter_name
      @template_path = template_path
      @path = path
    end

    def self.action_template(app, presenter_name, parent_path, template_name)
      # XXX: Support multiple template directories
      template_path = "#{parent_path}/#{template_name}"
      new(app,
          presenter_name,
          template_path,
          parent_path)
    end

    def respond(route, subject, injector)
      presenter = create_presenter(subject, injector)
      context = Raptor::ViewContext.new(presenter, injector)
      Rack::Response.new(render(context))
    end

    def render(presenter)
      @layout ||= FindsLayouts.find(@path)
      @template ||= Template.from_path(template_path)
      @layout.render(@template, presenter)
    end

    def template_path
      "#{@template_path}.html.erb"
    end

    def create_presenter(subject, injector)
      injector = injector.add_subject(subject)
      injector.call(presenter_class.method(:new))
    end

    def presenter_class
      constant_name = Raptor::Util.camel_case(@presenter_name)
      @app.presenters.fetch(constant_name)
    end
  end

end
Something went wrong with that request. Please try again.