class Racket::Controller

Base controller class. Your controllers should inherit this class.

Public Class Methods

after(*methods, &blk) click to toggle source

Adds a before hook to one or more actions. Actions should be given as a list of symbols. If no symbols are provided, all actions on the controller is affected.

@param [Array] methods @return [nil]

# File lib/racket/controller.rb, line 52
def self.after(*methods, &blk)
  __register_hook(:after, methods, blk) if block_given?
end
before(*methods, &blk) click to toggle source

Adds an after hook to one or more actions. Actions should be given as a list of symbols. If no symbols are provided, all actions on the controller is affected.

@param [Array] methods @return [nil]

# File lib/racket/controller.rb, line 61
def self.before(*methods, &blk)
  __register_hook(:before, methods, blk) if block_given?
end
context() click to toggle source

Returns the current context.

@return [Module]

# File lib/racket/controller.rb, line 68
def self.context
  Controller.instance_variable_get(:@context)
end
context=(context) click to toggle source

Injects context in Controller class. Context represents the current application state.

@param [Module] context

# File lib/racket/controller.rb, line 76
def self.context=(context)
  raise 'Context should only be set on Controller class' unless self == Controller
  @context = context
end
get_route(action = nil, *params) click to toggle source

Returns the route representing the parameters.

@param [Symbol|nil] action @param [Array] params

# File lib/racket/controller.rb, line 85
def self.get_route(action = nil, *params)
  context.get_route(self, action, params)
end
helper(*helpers) click to toggle source

Adds one or more helpers to the controller. All controllers get some default helpers (:routing and :view by default), but if you have your own helpers you want to load this is the preferred method.

By default Racket will look for your helpers in the helpers directory, but you can specify another location by changing the helper_dir setting.

@param [Array] helpers An array of symbols representing classes living in the Racket::Helpers

namespace.

@return [nil]

# File lib/racket/controller.rb, line 99
def self.helper(*helpers)
  helper_modules = {}
  unless settings.fetch(:helpers)
    # No helpers has been loaded yet. Load the default helpers first.
    helper_modules.merge!(
      context.helper_cache.load_helpers(settings.fetch(:default_controller_helpers))
    )
  end
  # Load new helpers
  __load_helpers(helpers.map(&:to_sym), helper_modules)
end
inherited(klass) click to toggle source

:@private

# File lib/racket/controller.rb, line 112
def self.inherited(klass)
  settings.fetch(:last_added_controller).push(klass)
end
layout_settings() click to toggle source

Returns the layout settings for the current controller.

@return [Hash]

# File lib/racket/controller.rb, line 119
def self.layout_settings
  template_settings = settings.fetch(:template_settings)
  template_settings[:common].merge(template_settings[:layout])
end
setting(key, val) click to toggle source

Add a setting for the current controller class

@param [Symbol] key @param [Object] val

# File lib/racket/controller.rb, line 128
def self.setting(key, val)
  settings.store(key, val)
end
settings() click to toggle source

Returns the settings for the current controller class

@return [Racket::Settings::Controller]

# File lib/racket/controller.rb, line 135
def self.settings
  @settings ||= Racket::Settings::Controller.new(self)
end
template_setting(key, value, type = :common) click to toggle source

Add a setting used by Tilt when rendering views/layouts.

@param [Symbol] key @param [Object] value @param [Symbol] type One of :common, :layout or :view

# File lib/racket/controller.rb, line 144
def self.template_setting(key, value, type = :common)
  # If controller has no template settings on its own, copy the template settings
  # from its "closest" parent (might even be application settings)
  # @todo - How about template options that are unmarshallable?
  settings.store(
    :template_settings, Marshal.load(Marshal.dump(settings.fetch(:template_settings)))
  ) unless settings.present?(:template_settings)

  # Fetch current settings (guaranteed to be in controller by now)
  template_settings = settings.fetch(:template_settings)

  # Update settings
  template_settings[type][key] = value
  settings.store(:template_settings, template_settings)
end
view_settings() click to toggle source

Returns the view settings for the current controller.

@return [Hash]

# File lib/racket/controller.rb, line 163
def self.view_settings
  template_settings = settings.fetch(:template_settings)
  template_settings[:common].merge(template_settings[:view])
end

Private Class Methods

__load_helpers(helpers, helper_modules) click to toggle source

Loads new helpers and stores the list of helpers associated with the currenct controller in the settings.

@param [Array] helpers Requested helpers @param [Array] helper_modules Helper modules already loaded @return nil

# File lib/racket/controller.rb, line 174
def self.__load_helpers(helpers, helper_modules)
  helpers.reject! { |helper| helper_modules.key?(helper) }
  helper_modules.merge!(context.helper_cache.load_helpers(helpers))
  setting(:helpers, helper_modules) && nil
end
__register_hook(type, methods, blk) click to toggle source

Adds a hook to one or more actions.

@param [Symbol] type @param [Array] methods @param [Proc] blk @return [nil]

# File lib/racket/controller.rb, line 28
def self.__register_hook(type, methods, blk)
  meths = public_instance_methods(false)
  meths &= methods.map(&:to_sym) unless methods.empty?
  __update_hooks("#{type}_hooks".to_sym, meths, blk)
  context.logger.inform_dev("Adding #{type} hook #{blk} for actions #{meths} for #{self}.")
end
__update_hooks(hook_key, meths, blk) click to toggle source

Updates hooks in settings object.

@param [Symbol] hook_key @param [Array] meths @param [Proc] blk @return [nil]

# File lib/racket/controller.rb, line 41
def self.__update_hooks(hook_key, meths, blk)
  hooks = settings.fetch(hook_key, {})
  meths.each { |meth| hooks[meth] = blk }
  setting(hook_key, hooks) && nil
end

Public Instance Methods

__run() click to toggle source

Calls hooks, action and renderer.

@return [String]

# File lib/racket/controller.rb, line 241
def __run
  __run_hook(:before)
  __run_action
  __run_hook(:after)
  self.class.context.view_manager.render(self)
end
layout_settings() click to toggle source

Returns layout settings associated with the current controller

# File lib/racket/controller.rb, line 183
def layout_settings
  self.class.layout_settings
end
redirect(target, status = 302) click to toggle source

Redirects the client. After hooks are run.

@param [String] target URL to redirect to @param [Fixnum] status HTTP status to send @return [Object]

# File lib/racket/controller.rb, line 192
def redirect(target, status = 302)
  response.redirect(target, status)
  respond(response.status, response.headers, '')
end
redirect!(target, status = 302) click to toggle source

Redirects the client. After hooks are NOT run.

@param [String] target URL to redirect to @param [Fixnum] status HTTP status to send @return [Object]

# File lib/racket/controller.rb, line 202
def redirect!(target, status = 302)
  response.redirect(target, status)
  respond!(response.status, response.headers, '')
end
respond(status = 200, headers = {}, body = '') click to toggle source

Stop processing request and send a custom response. After calling this method, after hooks (but no rendering) will be run.

@param [Fixnum] status @param [Hash] headers @param [String] body

# File lib/racket/controller.rb, line 213
def respond(status = 200, headers = {}, body = '')
  __run_hook(:after)
  respond!(status, headers, body)
end
respond!(status = 200, headers = {}, body = '') click to toggle source

Stop processing request and send a custom response. After calling this method, no further processing of the request is done.

@param [Fixnum] status @param [Hash] headers @param [String] body

# File lib/racket/controller.rb, line 224
def respond!(status = 200, headers = {}, body = '')
  throw :response, [status, headers, body]
end
settings() click to toggle source

Returns settings associated with the current controller

# File lib/racket/controller.rb, line 229
def settings
  self.class.settings
end
view_settings() click to toggle source

Returns view settings associated with the current controller

# File lib/racket/controller.rb, line 234
def view_settings
  self.class.view_settings
end

Private Instance Methods

__run_action() click to toggle source
# File lib/racket/controller.rb, line 250
def __run_action
  meth = method(racket.action)
  params = racket.params[0...meth.parameters.length]
  (racket.action_result = meth.call(*params)) && nil
end
__run_hook(type) click to toggle source
# File lib/racket/controller.rb, line 256
def __run_hook(type)
  hooks = settings.fetch("#{type}_hooks".to_sym, {})
  blk = hooks.fetch(racket.action, nil)
  (instance_eval(&blk) if blk) && nil
end