Class Maveric::Controller
In: maveric.rb
maveric/sessions.rb
Parent: Object

Controllers are the classes that do the actual handling and processing of requests. The number of normal methods is kept low to prevent clobbering by user defined methods.

Placing a Controller

They may be defined in any location, but if they are defined in a nested location within the Maveric class being used to serve at a particular location, on instantialization of the Maveric they will automatically be added at either the routes specified in their class definition or at the default route which is derived from their name and their nesting.

Working in Controller

Within an instance of Controller: @env contains the environment hash; @in contains the request body, and @cookies contains a hash of cookie values.

In addition @status, @header, and @body may be set to appropriate values for the response. Note that @headers should be a Hash, @status should be an Integer corresponding to a real HTTP status code, and @body should contain a String.

The instance variable @action contains a Symbol corresponding to the Controller method to be called. The result of this call is assigned to @body.

Those are the only instance variables you should be warned against playing with frivously. All instance variables are initially assigned before the before actions have been run, with the exception of @body which is set after @action is called.

Methods

Constants

REQUEST_METHODS = [:post, :get, :put, :delete, :head]

Attributes

body  [R] 
headers  [R] 
status  [R] 

Public Class methods

Add a route to the Controller.

[Source]

     # File maveric.rb, line 475
475:     def add_route r, o={}
476:       ::Maveric.type_check :r, r, String, ::Maveric::Route
477:       r = ::Maveric::Route.new r, o if r.is_a? String
478:       @routes << r
479:     end

If no argument is given, the array of actions is returned.

If a Symbol or String is given with no block, during Controller initialization after the action is called, the corresponding method is called with the Controller instance as an argument. If a block is given, the block is called with the controller instance as an argument instead.

If you are specifying other options, you must explicitly state :name => <chosen label> as an argument. Additional arguments include :only and :exclude, whose values should be a Symbol or an Array of such that correspond with actions that they should only run on or not run on.

NOTE: If you are referencing instance variables within the action, it is recommended that you create a method rather than a block.

[Source]

     # File maveric.rb, line 537
537:     def after act={}, &block
538:       ::Maveric.type_check :act, act, Hash, Symbol, String
539:       return @after if act.is_a? Hash and act.empty?
540:       act = {:name => act} unless act.is_a? Hash
541:       act[:do] = block
542:       act[:only]=[*act[:only]] if act.key? :only
543:       act[:exclude]=[*act[:exclude]] if act.key? :exclude
544:       @after << act
545:     end

If no argument is given, the array of actions is returned.

If a Symbol or String is given with no block, during Controller initialization before the action is called, the corresponding method is called with the Controller instance as an argument. If a block is given, the block is called with the controller instance as an argument instead.

If you are specifying other options, you must explicitly state :name => <chosen label> as an argument. Additional arguments include :only and :exclude, whose values should be a Symbol or an Array of such that correspond with actions that they should only run on or not run on.

NOTE: If you are referencing instance variables within the action, it is recommended that you create a method rather than a block.

[Source]

     # File maveric.rb, line 510
510:     def before act={}, &block
511:       ::Maveric.type_check :act, act, Hash, Symbol, String
512:       return @before if act.is_a? Hash and act.empty?
513:       act = {:name => act} unless act.is_a? Hash
514:       act[:do] = block
515:       act[:only]=[*act[:only]] if act.key? :only
516:       act[:exclude]=[*act[:exclude]] if act.key? :exclude
517:       @before << act
518:     end

Removes all currently set routes.

[Source]

     # File maveric.rb, line 482
482:     def clear_routes
483:       @routes.clear
484:     end

Family is important.

[Source]

     # File maveric.rb, line 457
457:     def inherited klass
458:       parent = self
459:       klass.class_eval do
460:         @routes = []
461:         @before = parent.before.dup
462:         @after = parent.after.dup
463:       end
464:     end

Main processing method of Controller.

The response body is set with the result of the specified action method if the result is a String and @body has not been set to a String. The action method is determined respectively by env[:route][:action], REQUEST_METHOD in downcased form, or ‘get’ by default.

By the time the Controller.new is done running, it should have @status, @headers, and @body set. @status should be an Integer matching the http status code, @headers a string keyed hash of http headers, and @body to a string of the http response body.

[Source]

     # File maveric.rb, line 560
560:   def initialize req_body=$stdin, env=ENV, opts={}
561:     ::Maveric.log.warn "Provided env has not been properly processed, results "+
562:       "may vary!" unless ([:maveric, :route, :params, :cookies]-env.keys).empty?
563:     ::Maveric.type_check :req_body, req_body, StringIO, IO
564:     ::Maveric.type_check :env, env, Hash
565:     ::Maveric.type_check :opts, opts, Hash
566: 
567:     @status, @headers = 200, {'Content-Type'=>'text/html'}
568:     @env, @in = env, req_body
569:     @cookies = @env[:cookies].dup
570: 
571:     action ||= @env[:route][:action] rescue nil
572:     action ||= @env['REQUEST_METHOD'].downcase rescue nil
573:     action ||= 'get'
574:     @action = action.to_sym
575: 
576:     ::Maveric.log.debug "#{self.class} action #{@action.inspect}"
577: 
578:     self.class.before.select do |act|
579:       (act[:only].nil? or act[:only].include? @action) and \
580:       (act[:exclude].nil? or not act[:exclude].include? @action)
581:     end.each do |act|
582:       ::Maveric.log.debug "#{self.class} before #{act[:name]}"
583:       if act[:do]
584:         act[:do].call env
585:       else
586:         __send__ act[:name], env
587:       end
588:     end
589: 
590:     raise NoMethodError, [503, "#{@action} not implemented.", nil, @env] if \
591:       REQUEST_METHODS.include? @action and not respond_to? @action
592:     @body = __send__ @action
593: 
594:     self.class.after.select do |act|
595:       (act[:only].nil? or act[:only].include? @action) and \
596:       (act[:exclude].nil? or not act[:exclude].include? @action)
597:     end.each do |act|
598:       ::Maveric.log.debug "#{self.class} after #{act[:name]}"
599:       if act[:do]
600:         act[:do].call env
601:       else
602:         __send__ act[:name], env
603:       end
604:     end
605: 
606:     ::Maveric.log.debug self # omg, masochistic.
607:   end

Returns a default Route based on the #nesting_path if no routes.

[Source]

     # File maveric.rb, line 487
487:     def routes
488:       @routes.empty? ?
489:         ::Maveric::Route.new(nesting_path) :
490:         @routes
491:     end

Removes currently set routes and adds the stated ones.

[Source]

     # File maveric.rb, line 467
467:     def set_routes r, o={}
468:       ::Maveric.type_check :r, r, String, Array
469:       clear_routes
470:       r = [r] unless r.is_a? Array
471:       r.flatten.map{|e| add_route e }
472:     end

Public Instance methods

Touches the session and includes it into the http headers.

[Source]

    # File maveric/sessions.rb, line 68
68:     def cleanup_1_sessions
69:       @env[:session].touch
70:       @headers['Set-Cookie'] = [@env[:session].to_s(@env)]
71:     end

For quick and raw response outputting!

[Source]

     # File maveric.rb, line 612
612:   def to_http
613:     response = "Status: #{@status}" + ::Maveric::EOL # Status message? :/
614:     response << @headers.map{|k,v| "#{k}: #{v}" }*::Maveric::EOL
615:     response << ::Maveric::EOL*2 + @body
616:   end

Private Instance methods

Standard Controller cleanup.

Folds the datasets of @cookie to @headers if they have been altered or are new.

[Source]

     # File maveric.rb, line 652
652:   def cleanup controller
653:     @cookies.each do |k,v|
654:       next unless v != @env[:cookies][k]
655:       @headers['Set-Cookie'] << "#{k}=#{::Maveric.escape(v)}"
656:     end
657:   end

TODO: Doc me. ehird is confused

This is a simple method, really. The only confusing part is the expressions just above the return. Controller#render calls itself. That is all.

[Source]

     # File maveric.rb, line 625
625:   def render view, s=''
626:     ::Maveric.log.debug "#{self.class}#render"+
627:       " #{view.inspect}, #{s.inspect}" # s is painful to logs.
628:     ::Maveric.type_check :view, view, Symbol, String
629:     ::Maveric.type_check :s, s, String
630:     s = yield s if block_given?
631:     s = __send__ view, s if respond_to? view
632:     s = render :layout, s unless view.to_s[/^(_|layout$)/] \
633:       or caller.any?{|l|l=~/`render'/} # i don't like this but it works
634:     return s
635:   end

Standard Controller setup.

Extends the Controller instance with the Views and Models modules of the pertinant Maveric instance.

[Source]

     # File maveric.rb, line 642
642:   def setup controller
643:     controller.extend @env[:maveric].class::Models
644:     controller.extend @env[:maveric].class::Views
645:   end

[Validate]