Class: Sinatra::Base

Inherits:
Object
  • Object
show all
Includes:
Rack::Utils, Helpers, Templates
Defined in:
lib/sinatra/base.rb

Overview

Base class for all Sinatra applications and middleware.

Direct Known Subclasses

Application

Constant Summary

CALLERS_TO_IGNORE =

:nodoc:

[ # :nodoc:
  /\/sinatra(\/(base|main|showexceptions))?\.rb$/, # all sinatra code
  /lib\/tilt.*\.rb$/,                              # all tilt code
  /^\(.*\)$/,                                      # generated code
  /rubygems\/custom_require\.rb$/,                 # rubygems require hacks
  /active_support/,                                # active_support require hacks
  /bundler(\/runtime)?\.rb/,                       # bundler require hacks
  /<internal:/,                                    # internal in ruby >= 1.9.2
  /src\/kernel\/bootstrap\/[A-Z]/                  # maglev kernel files
]

Class Attribute Summary (collapse)

Instance Attribute Summary (collapse)

Class Method Summary (collapse)

Instance Method Summary (collapse)

Methods included from Templates

#builder, #coffee, #creole, #erb, #erubis, #find_template, #haml, #less, #liquid, #markaby, #markdown, #nokogiri, #radius, #rdoc, #sass, #scss, #slim, #textile, #yajl

Methods included from Helpers

#attachment, #back, #body, #cache_control, #client_error?, #content_type, #error, #etag, #expires, #headers, #informational?, #last_modified, #logger, #mime_type, #not_found, #not_found?, #redirect, #redirect?, #send_file, #server_error?, #session, #status, #stream, #success?, #time_for, #uri

Constructor Details

- (Base) initialize(app = nil) {|_self| ... }

A new instance of Base

Yields:

  • (_self)

Yield Parameters:

  • _self (Sinatra::Base)

    the object that the method was called on



750
751
752
753
754
755
# File 'lib/sinatra/base.rb', line 750

def initialize(app=nil)
  super()
  @app = app
  @template_cache = Tilt::Cache.new
  yield self if block_given?
end

Class Attribute Details

+ (Object) errors (readonly)

Returns the value of attribute errors



1007
1008
1009
# File 'lib/sinatra/base.rb', line 1007

def errors
  @errors
end

+ (Object) filters (readonly)

Returns the value of attribute filters



1007
1008
1009
# File 'lib/sinatra/base.rb', line 1007

def filters
  @filters
end

+ (Object) routes (readonly)

Returns the value of attribute routes



1007
1008
1009
# File 'lib/sinatra/base.rb', line 1007

def routes
  @routes
end

+ (Object) templates (readonly)

Returns the value of attribute templates



1007
1008
1009
# File 'lib/sinatra/base.rb', line 1007

def templates
  @templates
end

Instance Attribute Details

- (Object) app

Returns the value of attribute app



747
748
749
# File 'lib/sinatra/base.rb', line 747

def app
  @app
end

- (Object) env

Returns the value of attribute env



762
763
764
# File 'lib/sinatra/base.rb', line 762

def env
  @env
end

- (Object) params

Returns the value of attribute params



762
763
764
# File 'lib/sinatra/base.rb', line 762

def params
  @params
end

- (Object) request

Returns the value of attribute request



762
763
764
# File 'lib/sinatra/base.rb', line 762

def request
  @request
end

- (Object) response

Returns the value of attribute response



762
763
764
# File 'lib/sinatra/base.rb', line 762

def response
  @response
end

- (Object) template_cache (readonly)

Returns the value of attribute template_cache



748
749
750
# File 'lib/sinatra/base.rb', line 748

def template_cache
  @template_cache
end

Class Method Details

+ (Object) add_filter(type, path = nil, options = {}, &block)

add a filter



1182
1183
1184
1185
# File 'lib/sinatra/base.rb', line 1182

def add_filter(type, path = nil, options = {}, &block)
  path, options = //, path if path.respond_to?(:each_pair)
  filters[type] << compile!(type, path || //, block, options)
end

+ (Object) after(path = nil, options = {}, &block)

Define an after filter; runs after all requests within the same context as route handlers and may access/modify the request and response.



1177
1178
1179
# File 'lib/sinatra/base.rb', line 1177

def after(path = nil, options = {}, &block)
  add_filter(:after, path, options, &block)
end

+ (Object) before(path = nil, options = {}, &block)

Define a before filter; runs before all requests within the same context as route handlers and may access/modify the request and response.



1170
1171
1172
# File 'lib/sinatra/base.rb', line 1170

def before(path = nil, options = {}, &block)
  add_filter(:before, path, options, &block)
end

+ (Object) build(app)

Creates a Rack::Builder instance with all the middleware set up and the given app as end point.



1418
1419
1420
1421
1422
1423
1424
# File 'lib/sinatra/base.rb', line 1418

def build(app)
  builder = Rack::Builder.new
  setup_default_middleware builder
  setup_middleware builder
  builder.run app
  builder
end

+ (Object) call(env)



1426
1427
1428
# File 'lib/sinatra/base.rb', line 1426

def call(env)
  synchronize { prototype.call(env) }
end

+ (Object) caller_files

Like Kernel#caller but excluding certain magic entries and without line / method information; the resulting array contains filenames only.



1532
1533
1534
# File 'lib/sinatra/base.rb', line 1532

def caller_files
  cleaned_caller(1).flatten
end

+ (Object) caller_locations

Like caller_files, but containing Arrays rather than strings with the first element being the file, and the second being the line.



1538
1539
1540
# File 'lib/sinatra/base.rb', line 1538

def caller_locations
  cleaned_caller 2
end

+ (Object) condition(name = "#{caller.first[/`.*'/]} condition", &block)

Add a route condition. The route is considered non-matching when the block returns false.



1189
1190
1191
# File 'lib/sinatra/base.rb', line 1189

def condition(name = "#{caller.first[/`.*'/]} condition", &block)
  @conditions << generate_method(name, &block)
end

+ (Object) configure(*envs) {|_self| ... }

Set configuration options for Sinatra and/or the app. Allows scoping of settings for certain environments.

Yields:

  • (_self)

Yield Parameters:

  • _self (Sinatra::Base)

    the object that the method was called on



1362
1363
1364
# File 'lib/sinatra/base.rb', line 1362

def configure(*envs, &block)
  yield self if envs.empty? || envs.include?(environment.to_sym)
end

+ (Object) delete(path, opts = {}, &bk)



1264
# File 'lib/sinatra/base.rb', line 1264

def delete(path, opts={}, &bk)  route 'DELETE',  path, opts, &bk end

+ (Boolean) development?

Returns:

  • (Boolean)


1356
# File 'lib/sinatra/base.rb', line 1356

def development?; environment == :development end

+ (Object) disable(*opts)

Same as calling `set :option, false` for each of the given options.



1088
1089
1090
# File 'lib/sinatra/base.rb', line 1088

def disable(*opts)
  opts.each { |key| set(key, false) }
end

+ (Object) enable(*opts)

Same as calling `set :option, true` for each of the given options.



1083
1084
1085
# File 'lib/sinatra/base.rb', line 1083

def enable(*opts)
  opts.each { |key| set(key, true) }
end

+ (Object) error(*codes, &block)

Define a custom error handler. Optionally takes either an Exception class, or an HTTP status code to specify which errors should be handled.



1095
1096
1097
1098
1099
1100
# File 'lib/sinatra/base.rb', line 1095

def error(*codes, &block) 
  args  = compile! "ERROR", //, block
  codes = codes.map { |c| Array(c) }.flatten
  codes << Exception if codes.empty?
  codes.each { |c| (@errors[c] ||= []) << args }
end

+ (Object) extensions

Extension modules registered on this class and all superclasses.



1028
1029
1030
1031
1032
1033
1034
# File 'lib/sinatra/base.rb', line 1028

def extensions
  if superclass.respond_to?(:extensions)
    (@extensions + superclass.extensions).uniq
  else
    @extensions
  end
end

+ (Object) force_encoding(data, encoding = default_encoding)



1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
# File 'lib/sinatra/base.rb', line 1564

def self.force_encoding(data, encoding = default_encoding)
  return if data == settings || data.is_a?(Tempfile)
  if data.respond_to? :force_encoding
    data.force_encoding(encoding).encode!
  elsif data.respond_to? :each_value
    data.each_value { |v| force_encoding(v, encoding) }
  elsif data.respond_to? :each
    data.each { |v| force_encoding(v, encoding) }
  end
  data
end

+ (Object) get(path, opts = {}, &block)

Defining a `GET` handler also automatically defines a `HEAD` handler.



1254
1255
1256
1257
1258
1259
1260
# File 'lib/sinatra/base.rb', line 1254

def get(path, opts={}, &block)
  conditions = @conditions.dup
  route('GET', path, opts, &block)

  @conditions = conditions
  route('HEAD', path, opts, &block)
end

+ (Object) head(path, opts = {}, &bk)



1265
# File 'lib/sinatra/base.rb', line 1265

def head(path, opts={}, &bk)    route 'HEAD',    path, opts, &bk end

+ (Object) helpers(*extensions, &block)

Makes the methods defined in the block and in the Modules given in `extensions` available to the handlers and templates



1340
1341
1342
1343
# File 'lib/sinatra/base.rb', line 1340

def helpers(*extensions, &block)
  class_eval(&block)   if block_given?
  include(*extensions) if extensions.any?
end

+ (Object) inline_templates=(file = nil)

Load embeded templates from the file; uses the caller's __FILE__ when no file is specified.



1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
# File 'lib/sinatra/base.rb', line 1120

def inline_templates=(file=nil)
  file = (file.nil? || file == true) ? (caller_files.first || File.expand_path($0)) : file

  begin
    io = ::IO.respond_to?(:binread) ? ::IO.binread(file) : ::IO.read(file)
    app, data = io.gsub("\r\n", "\n").split(/^__END__$/, 2)
  rescue Errno::ENOENT
    app, data = nil
  end

  if data
    if app and app =~ /([^\n]*\n)?#[^\n]*coding: *(\S+)/m
      encoding = $2
    else
      encoding = settings.default_encoding
    end
    lines = app.count("\n") + 1
    template = nil
    force_encoding data, encoding
    data.each_line do |line|
      lines += 1
      if line =~ /^@@\s*(.*\S)\s*$/
        template = force_encoding('', encoding)
        templates[$1.to_sym] = [template, file, lines]
      elsif template
        template << line
      end
    end
  end
end

+ (Object) layout(name = :layout, &block)

Define the layout template. The block must return the template source.



1114
1115
1116
# File 'lib/sinatra/base.rb', line 1114

def layout(name=:layout, &block)
  template name, &block
end

+ (Object) middleware

Middleware used in this class and all superclasses.



1037
1038
1039
1040
1041
1042
1043
# File 'lib/sinatra/base.rb', line 1037

def middleware
  if superclass.respond_to?(:middleware)
    superclass.middleware + @middleware
  else
    @middleware
  end
end

+ (Object) mime_type(type, value = nil)

Lookup or register a mime type in Rack's mime registry.



1152
1153
1154
1155
1156
1157
# File 'lib/sinatra/base.rb', line 1152

def mime_type(type, value=nil)
  return type if type.nil? || type.to_s.include?('/')
  type = ".#{type}" unless type.to_s[0] == ?.
  return Rack::Mime.mime_type(type, nil) unless value
  Rack::Mime::MIME_TYPES[type] = value
end

+ (Object) mime_types(type)

provides all mime types matching type, including deprecated types:

mime_types :html # => ['text/html']
mime_types :js   # => ['application/javascript', 'text/javascript']


1162
1163
1164
1165
# File 'lib/sinatra/base.rb', line 1162

def mime_types(type)
  type = mime_type type
  type =~ /^application\/(xml|javascript)$/ ? [type, "text/#$1"] : [type]
end

+ (Object) new(*args, &bk)

Create a new instance of the class fronted by its middleware pipeline. The object is guaranteed to respond to #call but may not be an instance of the class new was called on.



1411
1412
1413
1414
# File 'lib/sinatra/base.rb', line 1411

def new(*args, &bk)
  instance = new!(*args, &bk)
  Wrapper.new(build(instance).to_app, instance)
end

+ (Object) not_found(&block)

Sugar for `error(404) { ... }`



1103
1104
1105
# File 'lib/sinatra/base.rb', line 1103

def not_found(&block)
  error 404, &block
end

+ (Object) options(path, opts = {}, &bk)



1266
# File 'lib/sinatra/base.rb', line 1266

def options(path, opts={}, &bk) route 'OPTIONS', path, opts, &bk end

+ (Object) patch(path, opts = {}, &bk)



1267
# File 'lib/sinatra/base.rb', line 1267

def patch(path, opts={}, &bk)   route 'PATCH',   path, opts, &bk end

+ (Object) post(path, opts = {}, &bk)



1263
# File 'lib/sinatra/base.rb', line 1263

def post(path, opts={}, &bk)    route 'POST',    path, opts, &bk end

+ (Boolean) production?

Returns:

  • (Boolean)


1357
# File 'lib/sinatra/base.rb', line 1357

def production?;  environment == :production  end

+ (Object) prototype

The prototype instance used to process requests.



1401
1402
1403
# File 'lib/sinatra/base.rb', line 1401

def prototype
  @prototype ||= new
end

+ (Object) public=(value)



1193
1194
1195
1196
# File 'lib/sinatra/base.rb', line 1193

def public=(value)
  warn ":public is no longer used to avoid overloading Module#public, use :public_dir instead"
  set(:public_folder, value)
end

+ (Object) public_dir



1202
1203
1204
# File 'lib/sinatra/base.rb', line 1202

def public_dir
  public_folder
end

+ (Object) public_dir=(value)



1198
1199
1200
# File 'lib/sinatra/base.rb', line 1198

def public_dir=(value)
  self.public_folder = value
end

+ (Object) put(path, opts = {}, &bk)



1262
# File 'lib/sinatra/base.rb', line 1262

def put(path, opts={}, &bk)     route 'PUT',     path, opts, &bk end

+ (Object) quit!(server, handler_name)



1372
1373
1374
1375
1376
# File 'lib/sinatra/base.rb', line 1372

def quit!(server, handler_name)
  # Use Thin's hard #stop! if available, otherwise just #stop.
  server.respond_to?(:stop!) ? server.stop! : server.stop
  $stderr.puts "\n== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/i
end

+ (Object) register(*extensions, &block)

Register an extension. Alternatively take a block from which an extension will be created and registered on the fly.



1347
1348
1349
1350
1351
1352
1353
1354
# File 'lib/sinatra/base.rb', line 1347

def register(*extensions, &block)
  extensions << Module.new(&block) if block_given?
  @extensions += extensions
  extensions.each do |extension|
    extend extension
    extension.registered(self) if extension.respond_to?(:registered)
  end
end

+ (Object) reset!

Removes all routes, filters, middleware and extension hooks from the current class (not routes/filters/... defined by its superclass).



1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
# File 'lib/sinatra/base.rb', line 1011

def reset!
  @conditions     = []
  @routes         = {}
  @filters        = {:before => [], :after => []}
  @errors         = {}
  @middleware     = []
  @prototype      = nil
  @extensions     = []

  if superclass.respond_to?(:templates)
    @templates = Hash.new { |hash,key| superclass.templates[key] }
  else
    @templates = {}
  end
end

+ (Object) run!(options = {})

Run the Sinatra app as a self-hosted server using Thin, Puma, Mongrel, or WEBrick (in that order). If given a block, will call with the constructed handler once we have taken the stage.



1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
# File 'lib/sinatra/base.rb', line 1381

def run!(options={})
  set options
  handler         = detect_rack_handler
  handler_name    = handler.name.gsub(/.*::/, '')
  server_settings = settings.respond_to?(:server_settings) ? settings.server_settings : {}
  handler.run self, server_settings.merge(:Port => port, :Host => bind) do |server|
    unless handler_name =~ /cgi/i
      $stderr.puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
      "on #{port} for #{environment} with backup from #{handler_name}"
    end
    [:INT, :TERM].each { |sig| trap(sig) { quit!(server, handler_name) } }
    server.threaded = settings.threaded if server.respond_to? :threaded=
    set :running, true
    yield server if block_given?
  end
rescue Errno::EADDRINUSE
  $stderr.puts "== Someone is already performing on port #{port}!"
end

+ (Object) set(option, value = (not_set = true), ignore_setter = false, &block)

Sets an option to the given value. If the value is a proc, the proc will be called every time the option is accessed.

Raises:

  • (ArgumentError)


1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
# File 'lib/sinatra/base.rb', line 1047

def set(option, value = (not_set = true), ignore_setter = false, &block)
  raise ArgumentError if block and !not_set
  value, not_set = block, false if block

  if not_set
    raise ArgumentError unless option.respond_to?(:each)
    option.each { |k,v| set(k, v) }
    return self
  end

  if respond_to?("#{option}=") and not ignore_setter
    return __send__("#{option}=", value)
  end

  setter = proc { |val| set option, val, true }
  getter = proc { value }

  case value
  when Proc
    getter = value
  when Symbol, Fixnum, FalseClass, TrueClass, NilClass
    getter = value.inspect
  when Hash
    setter = proc do |val|
      val = value.merge val if Hash === val
      set option, val, true
    end
  end

  define_singleton_method("#{option}=", setter) if setter
  define_singleton_method(option, getter) if getter
  define_singleton_method("#{option}?", "!!#{option}") unless method_defined? "#{option}?"
  self
end

+ (Object) settings

Access settings defined with Base.set.



788
789
790
# File 'lib/sinatra/base.rb', line 788

def self.settings
  self
end

+ (Object) template(name, &block)

Define a named template. The block must return the template source.



1108
1109
1110
1111
# File 'lib/sinatra/base.rb', line 1108

def template(name, &block)
  filename, line = caller_locations.first
  templates[name] = [block, filename, line.to_i]
end

+ (Boolean) test?

Returns:

  • (Boolean)


1358
# File 'lib/sinatra/base.rb', line 1358

def test?;        environment == :test        end

+ (Object) use(middleware, *args, &block)

Use the specified Rack middleware



1367
1368
1369
1370
# File 'lib/sinatra/base.rb', line 1367

def use(middleware, *args, &block)
  @prototype = nil
  @middleware << [middleware, args, block]
end

Instance Method Details

- (Object) call(env)

Rack call interface.



758
759
760
# File 'lib/sinatra/base.rb', line 758

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

- (Object) call!(env)

:nodoc:



764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
# File 'lib/sinatra/base.rb', line 764

def call!(env) # :nodoc:
  @env      = env
  @request  = Request.new(env)
  @response = Response.new
  @params   = indifferent_params(@request.params)
  template_cache.clear if settings.reload_templates
  force_encoding(@params)

  @response['Content-Type'] = nil
  invoke { dispatch! }
  invoke { error_block!(response.status) }

  unless @response['Content-Type']
    if Array === body and body[0].respond_to? :content_type
      content_type body[0].content_type
    else
      content_type :html
    end
  end

  @response.finish
end

- (Object) forward

Forward the request to the downstream app -- middleware only.



818
819
820
821
822
823
824
825
# File 'lib/sinatra/base.rb', line 818

def forward
  fail "downstream app not set" unless @app.respond_to? :call
  status, headers, body = @app.call env
  @response.status = status
  @response.body = body
  @response.headers.merge! headers
  nil
end

- (Object) halt(*response)

Exit the current block, halts any further processing of the request, and returns the specified response.



805
806
807
808
# File 'lib/sinatra/base.rb', line 805

def halt(*response)
  response = response.first if response.length == 1
  throw :halt, response
end

- (Object) new!



1406
# File 'lib/sinatra/base.rb', line 1406

alias new! new

- (Object) options



797
798
799
800
801
# File 'lib/sinatra/base.rb', line 797

def options
  warn "Sinatra::Base#options is deprecated and will be removed, " \
    "use #settings instead."
  settings
end

- (Object) pass(&block)

Pass control to the next matching route. If there are no more matching routes, Sinatra will return a 404 response.



813
814
815
# File 'lib/sinatra/base.rb', line 813

def pass(&block)
  throw :pass, block
end

- (Object) settings

Access settings defined with Base.set.



793
794
795
# File 'lib/sinatra/base.rb', line 793

def settings
  self.class.settings
end