Class: Tap::Controller

Inherits:
Object
  • Object
show all
Includes:
Rack::Utils
Defined in:
lib/tap/controller.rb

Overview

Declaring Actions

By default all public methods in subclasses are declared as actions. You can declare a private or protected method as an action by:

  • manually adding it directly to actions

  • defining it as a public method and then call private(:method) or protected(:method)

Similarly, public method can be made non-action by actions by:

  • manually deleting it from actions

  • define it private or protected then call public(:method)

Defined Under Namespace

Modules: RestRoutes

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(server = nil, request = nil, response = nil) ⇒ Controller

Initializes a new instance of self. The input attributes are reset by call and are only provided for convenience during testing.



165
166
167
168
169
170
# File 'lib/tap/controller.rb', line 165

def initialize(server=nil, request=nil, response=nil)
  @server = server
  @request = request
  @response = response
  @action = nil
end

Class Attribute Details

.actionsObject (readonly)

An array of methods that can be called as actions. Actions must be stored as symbols. Actions are inherited.



82
83
84
# File 'lib/tap/controller.rb', line 82

def actions
  @actions
end

.default_layoutObject (readonly)

The default layout rendered when the render option :layout is true.



85
86
87
# File 'lib/tap/controller.rb', line 85

def default_layout
  @default_layout
end

Instance Attribute Details

#actionObject

The action currently being called by self.



161
162
163
# File 'lib/tap/controller.rb', line 161

def action
  @action
end

#requestObject

A Rack::Request wrapping env, set during call.



153
154
155
# File 'lib/tap/controller.rb', line 153

def request
  @request
end

#responseObject

A Rack::Response. If the action returns a string, it will be written to response and response will be returned by call. Otherwise, call returns the action result and response is ignored.



158
159
160
# File 'lib/tap/controller.rb', line 158

def response
  @response
end

#serverObject

Accesses the ‘tap.server’ specified in env, set during call.



150
151
152
# File 'lib/tap/controller.rb', line 150

def server
  @server
end

Class Method Details

.call(env) ⇒ Object

Instantiates self and performs call.



94
95
96
# File 'lib/tap/controller.rb', line 94

def call(env)
  new.call(env)
end

.inherited(child) ⇒ Object

Initialize instance variables on the child and inherit as necessary.



73
74
75
76
77
78
# File 'lib/tap/controller.rb', line 73

def inherited(child) # :nodoc:
  super
  child.set(:actions, actions.dup)
  child.set(:default_layout, default_layout)
  child.set(:define_action, true)
end

.nameObject

The base path prepended to render paths (ie render(<path>) renders <templates_dir/name/path>).



89
90
91
# File 'lib/tap/controller.rb', line 89

def name
  @name ||= to_s.underscore
end

.set(variable, input) ⇒ Object

Sets an instance variable for self, short for:

instance_variable_set(:@attribute, input)

Typically only these variables should be set:

actions:: sets actions
name:: the name of the controller
default_layout:: the default layout (used by render)


108
109
110
# File 'lib/tap/controller.rb', line 108

def set(variable, input)
  instance_variable_set("@#{variable}", input)
end

Instance Method Details

#appObject

Returns the app for the current session.



259
260
261
# File 'lib/tap/controller.rb', line 259

def app
  server.app(session[:id] ||= server.initialize_session)
end

#call(env) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# File 'lib/tap/controller.rb', line 172

def call(env)
  @server = env['tap.server'] || Tap::Server.new
  @request = Rack::Request.new(env)
  @response = Rack::Response.new
  
  # route to an action
  @action, args = route
  unless self.class.actions.include?(@action)
    raise ServerError.new("404 Error: page not found", 404)
  end
  
  result = send(@action, *args)
  if result.kind_of?(String) 
    response.write result
    response.finish
  else 
    result
  end
end

#empty_bindingObject

Generates an empty binding to self without any locals assigned.



279
280
281
# File 'lib/tap/controller.rb', line 279

def empty_binding # :nodoc:
  binding
end

#persistenceObject

Returns the file-based controller persistence.



269
270
271
# File 'lib/tap/controller.rb', line 269

def persistence
  @persistence ||= Support::Persistence.new(root)
end

#redirect(uri, status = 302, headers = {}, body = "") ⇒ Object

Redirects to the specified uri.



244
245
246
247
248
249
250
251
# File 'lib/tap/controller.rb', line 244

def redirect(uri, status=302, headers={}, body="")
  response.status = status
  response.headers.merge!(headers)
  response.body = body
  
  response['Location'] = uri
  response.finish
end

#render(path, options = {}) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
# File 'lib/tap/controller.rb', line 200

def render(path, options={})
  options, path = path, nil if path.kind_of?(Hash)
  
  # lookup template
  template_path = case
  when options.has_key?(:template)
    server.search(:views, options[:template])
  else
    server.search(:views, "#{self.class.name}/#{path}")
  end
  
  unless template_path
    raise "could not find template for: #{path}"
  end
  
  # render template
  template = File.read(template_path)
  content = render_erb(template, options)
  
  # render layout
  layout = options[:layout]
  layout = self.class.default_layout if layout == true
  if layout
    render(:template => layout, :locals => {:content => content})
  else
    content
  end
end

#render_erb(template, options = {}) ⇒ Object



229
230
231
232
233
234
235
236
237
238
239
240
241
# File 'lib/tap/controller.rb', line 229

def render_erb(template, options={})
  # assign locals to the render binding
  # this almost surely may be optimized...
  locals = options[:locals]
  binding = empty_binding
  
  locals.each_pair do |key, value|
    @assignment_value = value
    eval("#{key} = remove_instance_variable(:@assignment_value)", binding)
  end if locals
  
  ERB.new(template, nil, "<>").result(binding)
end

#rootObject

Returns the root for the current session.



264
265
266
# File 'lib/tap/controller.rb', line 264

def root
  server.root(session[:id] ||= server.initialize_session)
end

#routeObject



192
193
194
195
196
197
198
# File 'lib/tap/controller.rb', line 192

def route
  blank, action, *args = request.path_info.split("/").collect {|arg| unescape(arg) }
  action = "index" if action == nil || action.empty?
  action = action.chomp(File.extname(action)).to_sym
  
  [action, args]
end

#sessionObject

Returns a session hash.



254
255
256
# File 'lib/tap/controller.rb', line 254

def session
  request.env['rack.session'] ||= {}
end

#uri(action = nil, params = {}) ⇒ Object

Returns a controller uri.



274
275
276
# File 'lib/tap/controller.rb', line 274

def uri(action=nil, params={})
  server.uri(self.class.name, action, params)
end