Class: Trellis::Application

Inherits:
Object show all
Includes:
Logging, Rack::Utils
Defined in:
lib/trellis/trellis.rb

Overview

– Application – Represents a Trellis Web Application. An application can define one or more pages and it must define a home page or entry point into the application

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, logger

Class Method Details

.home(sym) ⇒ Object

class method that defines the homepage or entry point of the application the entry point is the URL pattern / where the application is mounted



64
65
66
# File 'lib/trellis/trellis.rb', line 64

def self.home(sym)
  @homepage = sym   
end

.inherited(child) ⇒ Object

descendant application classes get a singleton class level instances for holding homepage, dependent pages, static resource routing paths



55
56
57
58
59
60
# File 'lib/trellis/trellis.rb', line 55

def self.inherited(child) #:nodoc:
  child.class_attr_reader(:homepage)
  child.attr_array(:static_routes)
  child.meta_def(:logger) { Application.logger }
  super
end

.map_static(urls = [], root = File.expand_path("#{File.dirname($0)}/../html/")) ⇒ Object

define url paths for static resources



69
70
71
# File 'lib/trellis/trellis.rb', line 69

def self.map_static(urls = [], root = File.expand_path("#{File.dirname($0)}/../html/"))
  @static_routes << {:urls => urls, :root => root}
end

Instance Method Details

#call(env) ⇒ Object

implements the rack specification



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/trellis/trellis.rb', line 113

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

  Application.logger.debug "request received with url_root of #{request.script_name}" if request.script_name

  session = env["rack.session"]

  router = find_router_for(request)
  route = router.route(request)
  
  page = route.destination.new if route.destination
  if page
    page.class.url_root = request.script_name
    page.path = request.path_info.sub(/^\//, '')
    page.inject_dependent_pages
    page.call_if_provided(:before_load)
    page.load_page_session_information(session)
    page.call_if_provided(:after_load)
    page.params = request.params.keys_to_symbols
    router.inject_parameters_into_page_instance(page, request)
    result = route.event ? page.process_event(route.event, route.value, route.source, session) : page

    Application.logger.debug "response is #{result} an instance of #{result.class}"

    # prepare the http response
    if (request.post? || route.event) && result.kind_of?(Trellis::Page)
      # for action events of posts then use redirect after post pattern
      # remove the events path and just return to the page
      path = result.path ? result.path.gsub(/\/events\/.*/, '') : result.class.class_to_sym
      response.status = 302
      response.headers["Location"] = "#{request.script_name}/#{path}"
      Application.logger.debug "redirecting to ==> #{request.script_name}/#{path}"
    else
      # for render requests simply render the page
      response.body = result.kind_of?(Trellis::Page) ? result.render : result
      response.status = 200
    end
  else
    response.status = 404
  end
  response.finish
end

#configured_instanceObject



91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/trellis/trellis.rb', line 91

def configured_instance
  # configure rack middleware
  application = Rack::ShowStatus.new(self)
  application = Rack::ShowExceptions.new(application)
  application = Rack::Reloader.new(application)
  application = Rack::CommonLogger.new(application, Application.logger)
  application = Rack::Session::Cookie.new(application)

  # set all static resource paths
  self.class.static_routes.each do |path|
    application = Rack::Static.new(application, path)
  end
  application
end

#find_router_for(request) ⇒ Object

find the first page with a suitable router, if none is found use the default router



107
108
109
110
# File 'lib/trellis/trellis.rb', line 107

def find_router_for(request)
  match = Page.subclasses.values.find { |page| page.router && page.router.matches?(request) }
  match ? match.router : DefaultRouter.new(:application => self)
end

#start(port = 3000) ⇒ Object

bootstrap the application



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/trellis/trellis.rb', line 74

def start(port = 3000)
  Application.logger.info "Starting Trellis Application #{self.class} on port #{port}"

  directory_watcher = configure_directory_watcher
  directory_watcher.start

  Rack::Handler::Mongrel.run configured_instance, :Port => port do |server|
    trap(:INT) do
      Application.logger.info "Exiting Trellis Application #{self.class}"
      directory_watcher.stop
      server.stop
    end
  end
rescue Exception => e
  Application.logger.warn "#{ e } (#{ e.class })!"
end