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

Default

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Templates

#builder, #erb, #haml, #sass

Methods included from Helpers

#attachment, #back, #body, #content_type, #error, #etag, #last_modified, #media_type, #not_found, #redirect, #send_file, #session, #status

Constructor Details

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

Returns a new instance of Base.

Yields:

  • (_self)

Yield Parameters:

  • _self (Sinatra::Base)

    the object that the method was called on



326
327
328
329
# File 'lib/sinatra/base.rb', line 326

def initialize(app=nil)
  @app = app
  yield self if block_given?
end

Class Attribute Details

.conditionsObject

Returns the value of attribute conditions.



552
553
554
# File 'lib/sinatra/base.rb', line 552

def conditions
  @conditions
end

.errorsObject

Returns the value of attribute errors.



552
553
554
# File 'lib/sinatra/base.rb', line 552

def errors
  @errors
end

.filtersObject

Returns the value of attribute filters.



552
553
554
# File 'lib/sinatra/base.rb', line 552

def filters
  @filters
end

.middlewareObject

Returns the value of attribute middleware.



552
553
554
# File 'lib/sinatra/base.rb', line 552

def middleware
  @middleware
end

.routesObject

Returns the value of attribute routes.



552
553
554
# File 'lib/sinatra/base.rb', line 552

def routes
  @routes
end

.templatesObject

Returns the value of attribute templates.



552
553
554
# File 'lib/sinatra/base.rb', line 552

def templates
  @templates
end

Instance Attribute Details

#appObject

Returns the value of attribute app.



324
325
326
# File 'lib/sinatra/base.rb', line 324

def app
  @app
end

#envObject

Returns the value of attribute env.



336
337
338
# File 'lib/sinatra/base.rb', line 336

def env
  @env
end

#paramsObject

Returns the value of attribute params.



336
337
338
# File 'lib/sinatra/base.rb', line 336

def params
  @params
end

#requestObject

Returns the value of attribute request.



336
337
338
# File 'lib/sinatra/base.rb', line 336

def request
  @request
end

#responseObject

Returns the value of attribute response.



336
337
338
# File 'lib/sinatra/base.rb', line 336

def response
  @response
end

Class Method Details

.before(&block) ⇒ Object



624
625
626
# File 'lib/sinatra/base.rb', line 624

def before(&block)
  @filters << block
end

.call(env) ⇒ Object



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

def call(env)
  synchronize do
    reload! if reload?
    prototype.call(env)
  end
end

.condition(&block) ⇒ Object



628
629
630
# File 'lib/sinatra/base.rb', line 628

def condition(&block)
  @conditions << block
end

.configure(*envs, &block) ⇒ Object



742
743
744
745
# File 'lib/sinatra/base.rb', line 742

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

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



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

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

.development?Boolean

Returns:

  • (Boolean)


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

def development? ; environment == :development ; end

.disable(*opts) ⇒ Object



575
576
577
# File 'lib/sinatra/base.rb', line 575

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

.enable(*opts) ⇒ Object



571
572
573
# File 'lib/sinatra/base.rb', line 571

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

.error(codes = Exception, &block) ⇒ Object



579
580
581
582
583
584
585
# File 'lib/sinatra/base.rb', line 579

def error(codes=Exception, &block)
  if codes.respond_to? :each
    codes.each { |err| error(err, &block) }
  else
    @errors[codes] = block
  end
end

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



664
665
666
667
668
669
670
# File 'lib/sinatra/base.rb', line 664

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

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

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



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

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

.helpers(*extensions, &block) ⇒ Object



725
726
727
728
# File 'lib/sinatra/base.rb', line 725

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

.layout(name = :layout, &block) ⇒ Object



595
596
597
# File 'lib/sinatra/base.rb', line 595

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

.media_type(type) ⇒ Object

Look up a media type by file extension in Rack’s mime registry.



618
619
620
621
622
# File 'lib/sinatra/base.rb', line 618

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

.new(*args, &bk) ⇒ Object

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.



777
778
779
780
781
782
783
784
785
# File 'lib/sinatra/base.rb', line 777

def new(*args, &bk)
  builder = Rack::Builder.new
  builder.use Rack::Session::Cookie if sessions? && !test?
  builder.use Rack::CommonLogger if logging?
  builder.use Rack::MethodOverride if methodoverride?
  @middleware.each { |c, args, bk| builder.use(c, *args, &bk) }
  builder.run super
  builder.to_app
end

.not_found(&block) ⇒ Object



587
588
589
# File 'lib/sinatra/base.rb', line 587

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

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



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

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

.production?Boolean

Returns:

  • (Boolean)


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

def production? ; environment == :production ; end

.prototypeObject

The prototype instance used to process requests.



770
771
772
# File 'lib/sinatra/base.rb', line 770

def prototype
  @prototype ||= new
end

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



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

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

.register(*extensions, &block) ⇒ Object



730
731
732
733
734
735
736
# File 'lib/sinatra/base.rb', line 730

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

.reload!Object



798
799
800
801
802
803
804
# File 'lib/sinatra/base.rb', line 798

def reload!
  @reloading = true
  reset!
  $LOADED_FEATURES.delete("sinatra.rb")
  ::Kernel.load app_file
  @reloading = false
end

.reloading?Boolean

Returns:

  • (Boolean)


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

def reloading?
  @reloading
end

.reset!(base = superclass) ⇒ Object



806
807
808
809
810
811
812
813
814
# File 'lib/sinatra/base.rb', line 806

def reset!(base=superclass)
  @routes     = base.dupe_routes
  @templates  = base.templates.dup
  @conditions = []
  @filters    = base.filters.dup
  @errors     = base.errors.dup
  @middleware = base.middleware.dup
  @prototype  = nil
end

.run!(options = {}) ⇒ Object



752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
# File 'lib/sinatra/base.rb', line 752

def run!(options={})
  set options
  handler      = detect_rack_handler
  handler_name = handler.name.gsub(/.*::/, '')
  puts "== Sinatra/#{Sinatra::VERSION} has taken the stage " +
    "on #{port} for #{environment} with backup from #{handler_name}" unless handler_name =~/cgi/i
  handler.run self, :Host => host, :Port => port do |server|
    trap(:INT) do
      ## Use thins' hard #stop! if available, otherwise just #stop
      server.respond_to?(:stop!) ? server.stop! : server.stop
      puts "\n== Sinatra has ended his set (crowd applauds)" unless handler_name =~/cgi/i
    end
  end
rescue Errno::EADDRINUSE => e
  puts "== Someone is already performing on port #{port}!"
end

.set(option, value = self) ⇒ Object



556
557
558
559
560
561
562
563
564
565
566
567
568
569
# File 'lib/sinatra/base.rb', line 556

def set(option, value=self)
  if value.kind_of?(Proc)
    metadef(option, &value)
    metadef("#{option}?") { !!__send__(option) }
    metadef("#{option}=") { |val| set(option, Proc.new{val}) }
  elsif value == self && option.respond_to?(:to_hash)
    option.to_hash.each { |k,v| set(k, v) }
  elsif respond_to?("#{option}=")
    __send__ "#{option}=", value
  else
    set option, Proc.new{value}
  end
  self
end

.template(name, &block) ⇒ Object



591
592
593
# File 'lib/sinatra/base.rb', line 591

def template(name, &block)
  templates[name] = block
end

.test?Boolean

Returns:

  • (Boolean)


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

def test? ; environment == :test ; end

.use(middleware, *args, &block) ⇒ Object



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

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

.use_in_file_templates!Object



599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
# File 'lib/sinatra/base.rb', line 599

def use_in_file_templates!
  ignore = [/lib\/sinatra.*\.rb/, /\(.*\)/, /rubygems\/custom_require\.rb/]
  file = caller.
    map  { |line| line.sub(/:\d+.*$/, '') }.
    find { |line| ignore.all? { |pattern| line !~ pattern } }
  if data = ::IO.read(file).split('__END__')[1]
    data.gsub!(/\r\n/, "\n")
    template = nil
    data.each_line do |line|
      if line =~ /^@@\s*(.*)/
        template = templates[$1.to_sym] = ''
      elsif template
        template << line
      end
    end
  end
end

Instance Method Details

#call(env) ⇒ Object

Rack call interface.



332
333
334
# File 'lib/sinatra/base.rb', line 332

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

#call!(env) ⇒ Object



338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
# File 'lib/sinatra/base.rb', line 338

def call!(env)
  @env      = env
  @request  = Request.new(env)
  @response = Response.new
  @params   = nil

  invoke { dispatch! }
  invoke { error_block!(response.status) }

  status, header, body = @response.finish

  # Never produce a body on HEAD requests. Do retain the Content-Length
  # unless it's "0", in which case we assume it was calculated erroneously
  # for a manual HEAD response and remove it entirely.
  if @env['REQUEST_METHOD'] == 'HEAD'
    body = []
    header.delete('Content-Length') if header['Content-Length'] == '0'
  end

  [status, header, body]
end

#forwardObject

Forward the request to the downstream app – middleware only.



377
378
379
380
381
382
383
384
# File 'lib/sinatra/base.rb', line 377

def forward
  fail "downstream app not set" unless @app.respond_to? :call
  status, headers, body = @app.call(@request.env)
  @response.status = status
  @response.body = body
  headers.each { |k, v| @response[k] = v }
  nil
end

#halt(*response) ⇒ Object

Exit the current block and halt the response.



366
367
368
369
# File 'lib/sinatra/base.rb', line 366

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

#optionsObject

Access options defined with Base.set.



361
362
363
# File 'lib/sinatra/base.rb', line 361

def options
  self.class
end

#passObject

Pass control to the next matching route.



372
373
374
# File 'lib/sinatra/base.rb', line 372

def pass
  throw :pass
end