Class: Togo::Dispatch

Inherits:
Object
  • Object
show all
Defined in:
lib/togo/dispatch/dispatch.rb

Direct Known Subclasses

Admin

Constant Summary collapse

HANDLERS =
%w(thin mongrel webrick)

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ Dispatch

Returns a new instance of Dispatch.



29
30
31
32
33
34
# File 'lib/togo/dispatch/dispatch.rb', line 29

def initialize(opts = {})
  @view_path = opts[:view_path] || 'views'
  @path_prefix = opts[:path_prefix]
  @path_prefix_regexp = Regexp.new("^#{@path_prefix}")
  #ENV['RACK_ENV'] = (opts[:environment] || :development) if not ENV['RACK_ENV']
end

Class Attribute Details

.configObject

Returns the value of attribute config.



123
124
125
# File 'lib/togo/dispatch/dispatch.rb', line 123

def config
  @config
end

.routesObject

Returns the value of attribute routes.



123
124
125
# File 'lib/togo/dispatch/dispatch.rb', line 123

def routes
  @routes
end

Instance Attribute Details

#paramsObject (readonly)

Returns the value of attribute params.



27
28
29
# File 'lib/togo/dispatch/dispatch.rb', line 27

def params
  @params
end

#requestObject (readonly)

Returns the value of attribute request.



27
28
29
# File 'lib/togo/dispatch/dispatch.rb', line 27

def request
  @request
end

#responseObject (readonly)

Returns the value of attribute response.



27
28
29
# File 'lib/togo/dispatch/dispatch.rb', line 27

def response
  @response
end

Class Method Details

.answer(type, route, &block) ⇒ Object



147
148
149
150
151
152
153
154
155
156
# File 'lib/togo/dispatch/dispatch.rb', line 147

def answer(type, route, &block)
  method_name = "__#{type.downcase}#{clean_path(route)}"
  k = []
  p = route.gsub(/(:\w+)/){|m| k << m[1..-1]; "([^?/#&]+)"}
  r = [/^#{p}$/,k,method_name]
  if not routes[type].rindex{|t| t[0] == r[0]}
    routes[type].push(r)
    define_method(method_name, &block)
  end
end

.before(&block) ⇒ Object



158
159
160
# File 'lib/togo/dispatch/dispatch.rb', line 158

def before(&block)
  define_method("__before",&block)
end

.clean_path(path) ⇒ Object



162
163
164
# File 'lib/togo/dispatch/dispatch.rb', line 162

def clean_path(path)
  path.gsub(/\/|\./, '__')
end

.configure(opts = {}) ⇒ Object



166
167
168
# File 'lib/togo/dispatch/dispatch.rb', line 166

def configure(opts = {})
  config.merge!(opts)
end

.get(route, &block) ⇒ Object



139
140
141
# File 'lib/togo/dispatch/dispatch.rb', line 139

def get(route, &block)
  answer('GET', route, &block)
end

.handlerObject



108
109
110
111
112
113
114
115
116
# File 'lib/togo/dispatch/dispatch.rb', line 108

def self.handler
  HANDLERS.each do |h|
    begin
      return Rack::Handler.get(h)
    rescue
    end
  end
  puts "Could not find any handlers to run. Please be sure your requested handler is installed."
end

.inherited(subclass) ⇒ Object



125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/togo/dispatch/dispatch.rb', line 125

def inherited(subclass)
  subclass.routes = {}
  subclass.send(:include, Rack::Utils)
  %w{GET POST}.each{|v| subclass.routes[v] = []}
  subclass.config = {
    :path_prefix => '',
    :public_path => 'public',
    :static_urls => ['/css','/js','/img'],
    :port => 8080,
    :host => '127.0.0.1',
    :environment => :development
  }
end

.post(route, &block) ⇒ Object



143
144
145
# File 'lib/togo/dispatch/dispatch.rb', line 143

def post(route, &block)
  answer('POST', route, &block)
end

.run!(opts = {}) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/togo/dispatch/dispatch.rb', line 170

def run!(opts = {})
  opts = config.dup.merge!(opts)
  builder = Rack::Builder.new
  if opts[:environment].to_sym == :development
    puts "Showing exceptions and using reloader for Development..."
    builder.use Rack::ShowExceptions
    builder.use opts[:reloader] if opts[:reloader]
  end
  if opts[:routes] and opts[:routes].is_a?(Array)
    opts[:routes].each do |r|
      send(r[:type].to_sym, r[:path]) do
        erb r[:template].to_sym
      end
    end
  end
  builder.use Togo::Static, :urls => opts[:static_urls], :root => opts[:public_path], :path_prefix => opts[:path_prefix]
  if opts[:sessions] or opts[:auth_model]
    builder.use Rack::Session::Cookie
    opts[:sessions] = true
  end
  builder.run new(opts)
  if opts[:standalone]
    opts[:handler].run(builder.to_app, :Port => opts[:port], :Host => opts[:host])
  else
    builder.to_app
  end
end

Instance Method Details

#answer(type, path) ⇒ Object



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
# File 'lib/togo/dispatch/dispatch.rb', line 52

def answer(type,path)
  method = nil
  @params = symbolize_keys(@request.GET.dup.merge!(@request.POST.dup))
  path = path.gsub(@path_prefix_regexp,'')
  path = '/' if path == ''
  self.class.routes[type].each do |p,k,m|
    if match = p.match(path)
      method = m
      @params.merge!(k.zip(match.captures.to_a).inject({}){|o,v| o.merge!(v[0].to_sym => v[1])}) unless k.empty?
      break
    end
  end
  if method.nil?
    @response.status = 404
    @response.write("404 Not Found")
  else
    begin
      __before if defined? __before
      @response.write(send(method)) unless [301, 302].include?(@response.status)
    rescue => detail
      @response.status = 500
      @response.write(["Error: #{detail}",$!.backtrace.join("<br />\n")].join("<br />\n"))
    end
  end
  flash.sweep!
end

#call(env) ⇒ Object



40
41
42
# File 'lib/togo/dispatch/dispatch.rb', line 40

def call(env)
  dup.call!(env)
end

#call!(env) ⇒ Object



44
45
46
47
48
49
50
# File 'lib/togo/dispatch/dispatch.rb', line 44

def call!(env)
  @request = Rack::Request.new(env)
  @response = Rack::Response.new

  answer(@request.env['REQUEST_METHOD'], @request.path_info)
  @response.finish
end

#configObject



118
119
120
# File 'lib/togo/dispatch/dispatch.rb', line 118

def config
  self.class.send(:config)
end

#environment?(name) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
# File 'lib/togo/dispatch/dispatch.rb', line 96

def environment?(name)
  ENV['RACK_ENV'] == name.to_sym
end

#erb(content, opts = {}, &block) ⇒ Object



79
80
81
82
83
84
85
86
87
88
# File 'lib/togo/dispatch/dispatch.rb', line 79

def erb(content, opts = {}, &block)
  if content.is_a?(Symbol)
    content = File.open(File.join(@view_path,"#{content}.erb")).read
  end
  result = Erubis::Eruby.new(content).result(binding)
  if not block_given? and opts[:layout] != false
    result = erb(:layout){ result }
  end
  result
end

#flashObject



104
105
106
# File 'lib/togo/dispatch/dispatch.rb', line 104

def flash
  session[:flash] ||= FlashHash.new
end

#redirect(location, opts = {}) ⇒ Object



90
91
92
93
94
# File 'lib/togo/dispatch/dispatch.rb', line 90

def redirect(location, opts = {})
  @response.status = (opts[:status] || 301)
  @response.headers['Location'] = [@path_prefix, location].join
  @response.finish
end

#sessionObject



100
101
102
# File 'lib/togo/dispatch/dispatch.rb', line 100

def session
  @request.session
end

#symbolize_keys(hash) ⇒ Object



36
37
38
# File 'lib/togo/dispatch/dispatch.rb', line 36

def symbolize_keys(hash)
  hash.inject({}){|m,v| m.merge!(v[0].to_sym => v[1])}
end