sinatra 2.2.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  # Sinatra
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/sinatra.svg)](https://badge.fury.io/rb/sinatra)
4
- [![Build Status](https://secure.travis-ci.org/sinatra/sinatra.svg)](https://travis-ci.org/sinatra/sinatra)
5
- [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=sinatra&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=sinatra&package-manager=bundler&version-scheme=semver)
4
+ [![Testing](https://github.com/sinatra/sinatra/actions/workflows/test.yml/badge.svg)](https://github.com/sinatra/sinatra/actions/workflows/test.yml)
6
5
 
7
6
  Sinatra is a [DSL](https://en.wikipedia.org/wiki/Domain-specific_language) for
8
7
  quickly creating web applications in Ruby with minimal effort:
@@ -20,6 +19,7 @@ Install the gem:
20
19
 
21
20
  ```shell
22
21
  gem install sinatra
22
+ gem install puma # or any other server
23
23
  ```
24
24
 
25
25
  And run with:
@@ -31,101 +31,95 @@ ruby myapp.rb
31
31
  View at: [http://localhost:4567](http://localhost:4567)
32
32
 
33
33
  The code you changed will not take effect until you restart the server.
34
- Please restart the server every time you change or use
35
- [sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
34
+ Please restart the server every time you change or use a code reloader
35
+ like [rerun](https://github.com/alexch/rerun) or
36
+ [rack-unreloader](https://github.com/jeremyevans/rack-unreloader).
36
37
 
37
38
  It is recommended to also run `gem install puma`, which Sinatra will
38
39
  pick up if available.
39
40
 
40
41
  ## Table of Contents
41
42
 
42
- * [Sinatra](#sinatra)
43
- * [Table of Contents](#table-of-contents)
44
- * [Routes](#routes)
45
- * [Conditions](#conditions)
46
- * [Return Values](#return-values)
47
- * [Custom Route Matchers](#custom-route-matchers)
48
- * [Static Files](#static-files)
49
- * [Views / Templates](#views--templates)
50
- * [Literal Templates](#literal-templates)
51
- * [Available Template Languages](#available-template-languages)
52
- * [Haml Templates](#haml-templates)
53
- * [Erb Templates](#erb-templates)
54
- * [Builder Templates](#builder-templates)
55
- * [Nokogiri Templates](#nokogiri-templates)
56
- * [Sass Templates](#sass-templates)
57
- * [SCSS Templates](#scss-templates)
58
- * [Less Templates](#less-templates)
59
- * [Liquid Templates](#liquid-templates)
60
- * [Markdown Templates](#markdown-templates)
61
- * [Textile Templates](#textile-templates)
62
- * [RDoc Templates](#rdoc-templates)
63
- * [AsciiDoc Templates](#asciidoc-templates)
64
- * [Radius Templates](#radius-templates)
65
- * [Markaby Templates](#markaby-templates)
66
- * [RABL Templates](#rabl-templates)
67
- * [Slim Templates](#slim-templates)
68
- * [Creole Templates](#creole-templates)
69
- * [MediaWiki Templates](#mediawiki-templates)
70
- * [CoffeeScript Templates](#coffeescript-templates)
71
- * [Stylus Templates](#stylus-templates)
72
- * [Yajl Templates](#yajl-templates)
73
- * [WLang Templates](#wlang-templates)
74
- * [Accessing Variables in Templates](#accessing-variables-in-templates)
75
- * [Templates with `yield` and nested layouts](#templates-with-yield-and-nested-layouts)
76
- * [Inline Templates](#inline-templates)
77
- * [Named Templates](#named-templates)
78
- * [Associating File Extensions](#associating-file-extensions)
79
- * [Adding Your Own Template Engine](#adding-your-own-template-engine)
80
- * [Using Custom Logic for Template Lookup](#using-custom-logic-for-template-lookup)
81
- * [Filters](#filters)
82
- * [Helpers](#helpers)
83
- * [Using Sessions](#using-sessions)
84
- * [Session Secret Security](#session-secret-security)
85
- * [Session Config](#session-config)
86
- * [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
87
- * [Halting](#halting)
88
- * [Passing](#passing)
89
- * [Triggering Another Route](#triggering-another-route)
90
- * [Setting Body, Status Code and Headers](#setting-body-status-code-and-headers)
91
- * [Streaming Responses](#streaming-responses)
92
- * [Logging](#logging)
93
- * [Mime Types](#mime-types)
94
- * [Generating URLs](#generating-urls)
95
- * [Browser Redirect](#browser-redirect)
96
- * [Cache Control](#cache-control)
97
- * [Sending Files](#sending-files)
98
- * [Accessing the Request Object](#accessing-the-request-object)
99
- * [Attachments](#attachments)
100
- * [Dealing with Date and Time](#dealing-with-date-and-time)
101
- * [Looking Up Template Files](#looking-up-template-files)
102
- * [Configuration](#configuration)
103
- * [Configuring attack protection](#configuring-attack-protection)
104
- * [Available Settings](#available-settings)
105
- * [Environments](#environments)
106
- * [Error Handling](#error-handling)
107
- * [Not Found](#not-found)
108
- * [Error](#error)
109
- * [Rack Middleware](#rack-middleware)
110
- * [Testing](#testing)
111
- * [Sinatra::Base - Middleware, Libraries, and Modular Apps](#sinatrabase---middleware-libraries-and-modular-apps)
112
- * [Modular vs. Classic Style](#modular-vs-classic-style)
113
- * [Serving a Modular Application](#serving-a-modular-application)
114
- * [Using a Classic Style Application with a config.ru](#using-a-classic-style-application-with-a-configru)
115
- * [When to use a config.ru?](#when-to-use-a-configru)
116
- * [Using Sinatra as Middleware](#using-sinatra-as-middleware)
117
- * [Dynamic Application Creation](#dynamic-application-creation)
118
- * [Scopes and Binding](#scopes-and-binding)
119
- * [Application/Class Scope](#applicationclass-scope)
120
- * [Request/Instance Scope](#requestinstance-scope)
121
- * [Delegation Scope](#delegation-scope)
122
- * [Command Line](#command-line)
123
- * [Multi-threading](#multi-threading)
124
- * [Requirement](#requirement)
125
- * [The Bleeding Edge](#the-bleeding-edge)
126
- * [With Bundler](#with-bundler)
127
- * [Versioning](#versioning)
128
- * [Further Reading](#further-reading)
43
+ - [Sinatra](#sinatra)
44
+ - [Table of Contents](#table-of-contents)
45
+ - [Routes](#routes)
46
+ - [Conditions](#conditions)
47
+ - [Return Values](#return-values)
48
+ - [Custom Route Matchers](#custom-route-matchers)
49
+ - [Static Files](#static-files)
50
+ - [Views / Templates](#views--templates)
51
+ - [Literal Templates](#literal-templates)
52
+ - [Available Template Languages](#available-template-languages)
53
+ - [Haml Templates](#haml-templates)
54
+ - [Erb Templates](#erb-templates)
55
+ - [Builder Templates](#builder-templates)
56
+ - [Nokogiri Templates](#nokogiri-templates)
57
+ - [Sass Templates](#sass-templates)
58
+ - [Scss Templates](#scss-templates)
59
+ - [Liquid Templates](#liquid-templates)
60
+ - [Markdown Templates](#markdown-templates)
61
+ - [RDoc Templates](#rdoc-templates)
62
+ - [AsciiDoc Templates](#asciidoc-templates)
63
+ - [Markaby Templates](#markaby-templates)
64
+ - [RABL Templates](#rabl-templates)
65
+ - [Slim Templates](#slim-templates)
66
+ - [Yajl Templates](#yajl-templates)
67
+ - [Accessing Variables in Templates](#accessing-variables-in-templates)
68
+ - [Templates with `yield` and nested layouts](#templates-with-yield-and-nested-layouts)
69
+ - [Inline Templates](#inline-templates)
70
+ - [Named Templates](#named-templates)
71
+ - [Associating File Extensions](#associating-file-extensions)
72
+ - [Adding Your Own Template Engine](#adding-your-own-template-engine)
73
+ - [Using Custom Logic for Template Lookup](#using-custom-logic-for-template-lookup)
74
+ - [Filters](#filters)
75
+ - [Helpers](#helpers)
76
+ - [Using Sessions](#using-sessions)
77
+ - [Session Secret Security](#session-secret-security)
78
+ - [Session Config](#session-config)
79
+ - [Choosing Your Own Session Middleware](#choosing-your-own-session-middleware)
80
+ - [Halting](#halting)
81
+ - [Passing](#passing)
82
+ - [Triggering Another Route](#triggering-another-route)
83
+ - [Setting Body, Status Code, and Headers](#setting-body-status-code-and-headers)
84
+ - [Streaming Responses](#streaming-responses)
85
+ - [Logging](#logging)
86
+ - [Mime Types](#mime-types)
87
+ - [Generating URLs](#generating-urls)
88
+ - [Browser Redirect](#browser-redirect)
89
+ - [Cache Control](#cache-control)
90
+ - [Sending Files](#sending-files)
91
+ - [Accessing the Request Object](#accessing-the-request-object)
92
+ - [Attachments](#attachments)
93
+ - [Dealing with Date and Time](#dealing-with-date-and-time)
94
+ - [Looking Up Template Files](#looking-up-template-files)
95
+ - [Configuration](#configuration)
96
+ - [Configuring attack protection](#configuring-attack-protection)
97
+ - [Available Settings](#available-settings)
98
+ - [Lifecycle Events](#lifecycle-events)
99
+ - [Environments](#environments)
100
+ - [Error Handling](#error-handling)
101
+ - [Not Found](#not-found)
102
+ - [Error](#error)
103
+ - [Rack Middleware](#rack-middleware)
104
+ - [Testing](#testing)
105
+ - [Sinatra::Base - Middleware, Libraries, and Modular Apps](#sinatrabase---middleware-libraries-and-modular-apps)
106
+ - [Modular vs. Classic Style](#modular-vs-classic-style)
107
+ - [Serving a Modular Application](#serving-a-modular-application)
108
+ - [Using a Classic Style Application with a config.ru](#using-a-classic-style-application-with-a-configru)
109
+ - [When to use a config.ru?](#when-to-use-a-configru)
110
+ - [Using Sinatra as Middleware](#using-sinatra-as-middleware)
111
+ - [Dynamic Application Creation](#dynamic-application-creation)
112
+ - [Scopes and Binding](#scopes-and-binding)
113
+ - [Application/Class Scope](#applicationclass-scope)
114
+ - [Request/Instance Scope](#requestinstance-scope)
115
+ - [Delegation Scope](#delegation-scope)
116
+ - [Command Line](#command-line)
117
+ - [Multi-threading](#multi-threading)
118
+ - [Requirement](#requirement)
119
+ - [The Bleeding Edge](#the-bleeding-edge)
120
+ - [With Bundler](#with-bundler)
121
+ - [Versioning](#versioning)
122
+ - [Further Reading](#further-reading)
129
123
 
130
124
  ## Routes
131
125
 
@@ -382,15 +376,16 @@ stop there. You can easily define your own matchers:
382
376
 
383
377
  ```ruby
384
378
  class AllButPattern
385
- Match = Struct.new(:captures)
386
-
387
379
  def initialize(except)
388
- @except = except
389
- @captures = Match.new([])
380
+ @except = except
381
+ end
382
+
383
+ def to_pattern(options)
384
+ return self
390
385
  end
391
386
 
392
- def match(str)
393
- @captures unless @except === str
387
+ def params(route)
388
+ return {} unless @except === route
394
389
  end
395
390
  end
396
391
 
@@ -407,20 +402,12 @@ Note that the above example might be over-engineered, as it can also be
407
402
  expressed as:
408
403
 
409
404
  ```ruby
410
- get // do
405
+ get /.*/ do
411
406
  pass if request.path_info == "/index"
412
407
  # ...
413
408
  end
414
409
  ```
415
410
 
416
- Or, using negative look ahead:
417
-
418
- ```ruby
419
- get %r{(?!/index)} do
420
- # ...
421
- end
422
- ```
423
-
424
411
  ## Static Files
425
412
 
426
413
  Static files are served from the `./public` directory. You can specify
@@ -584,7 +571,7 @@ Some languages have multiple implementations. To specify what implementation
584
571
  to use (and to be thread-safe), you should simply require it first:
585
572
 
586
573
  ```ruby
587
- require 'rdiscount' # or require 'bluecloth'
574
+ require 'rdiscount'
588
575
  get('/') { markdown :index }
589
576
  ```
590
577
 
@@ -612,14 +599,12 @@ get('/') { markdown :index }
612
599
  <td>Dependency</td>
613
600
  <td>
614
601
  <a href="https://github.com/jeremyevans/erubi" title="erubi">erubi</a>
615
- or <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
616
602
  or erb (included in Ruby)
617
603
  </td>
618
604
  </tr>
619
605
  <tr>
620
606
  <td>File Extensions</td>
621
- <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubi</tt> (Erubi only)
622
- or <tt>.erubis</tt> (Erubis only)</td>
607
+ <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubi</tt> (Erubi only)</td>
623
608
  </tr>
624
609
  <tr>
625
610
  <td>Example</td>
@@ -672,7 +657,7 @@ It also takes a block for inline templates (see [example](#inline-templates)).
672
657
  <table>
673
658
  <tr>
674
659
  <td>Dependency</td>
675
- <td><a href="https://sass-lang.com/" title="sass">sass</a></td>
660
+ <td><a href="https://github.com/ntkme/sass-embedded-host-ruby" title="sass-embedded">sass-embedded</a></td>
676
661
  </tr>
677
662
  <tr>
678
663
  <td>File Extension</td>
@@ -684,12 +669,12 @@ It also takes a block for inline templates (see [example](#inline-templates)).
684
669
  </tr>
685
670
  </table>
686
671
 
687
- #### SCSS Templates
672
+ #### Scss Templates
688
673
 
689
674
  <table>
690
675
  <tr>
691
676
  <td>Dependency</td>
692
- <td><a href="https://sass-lang.com/" title="sass">sass</a></td>
677
+ <td><a href="https://github.com/ntkme/sass-embedded-host-ruby" title="sass-embedded">sass-embedded</a></td>
693
678
  </tr>
694
679
  <tr>
695
680
  <td>File Extension</td>
@@ -701,23 +686,6 @@ It also takes a block for inline templates (see [example](#inline-templates)).
701
686
  </tr>
702
687
  </table>
703
688
 
704
- #### Less Templates
705
-
706
- <table>
707
- <tr>
708
- <td>Dependency</td>
709
- <td><a href="http://lesscss.org/" title="less">less</a></td>
710
- </tr>
711
- <tr>
712
- <td>File Extension</td>
713
- <td><tt>.less</tt></td>
714
- </tr>
715
- <tr>
716
- <td>Example</td>
717
- <td><tt>less :stylesheet</tt></td>
718
- </tr>
719
- </table>
720
-
721
689
  #### Liquid Templates
722
690
 
723
691
  <table>
@@ -747,9 +715,7 @@ template, you almost always want to pass locals to it.
747
715
  Anyone of:
748
716
  <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
749
717
  <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
750
- <a href="https://github.com/ged/bluecloth" title="BlueCloth">BlueCloth</a>,
751
718
  <a href="https://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
752
- <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
753
719
  <a href="https://github.com/gjtorikian/commonmarker" title="commonmarker">commonmarker</a>
754
720
  <a href="https://github.com/alphabetum/pandoc-ruby" title="pandoc">pandoc</a>
755
721
  </td>
@@ -784,42 +750,6 @@ Since you cannot call Ruby from Markdown, you cannot use layouts written in
784
750
  Markdown. However, it is possible to use another rendering engine for the
785
751
  template than for the layout by passing the `:layout_engine` option.
786
752
 
787
- #### Textile Templates
788
-
789
- <table>
790
- <tr>
791
- <td>Dependency</td>
792
- <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
793
- </tr>
794
- <tr>
795
- <td>File Extension</td>
796
- <td><tt>.textile</tt></td>
797
- </tr>
798
- <tr>
799
- <td>Example</td>
800
- <td><tt>textile :index, :layout_engine => :erb</tt></td>
801
- </tr>
802
- </table>
803
-
804
- It is not possible to call methods from Textile, nor to pass locals to
805
- it. You therefore will usually use it in combination with another
806
- rendering engine:
807
-
808
- ```ruby
809
- erb :overview, :locals => { :text => textile(:introduction) }
810
- ```
811
-
812
- Note that you may also call the `textile` method from within other templates:
813
-
814
- ```ruby
815
- %h1 Hello From Haml!
816
- %p= textile(:greetings)
817
- ```
818
-
819
- Since you cannot call Ruby from Textile, you cannot use layouts written in
820
- Textile. However, it is possible to use another rendering engine for the
821
- template than for the layout by passing the `:layout_engine` option.
822
-
823
753
  #### RDoc Templates
824
754
 
825
755
  <table>
@@ -875,26 +805,6 @@ template than for the layout by passing the `:layout_engine` option.
875
805
  Since you cannot call Ruby methods directly from an AsciiDoc template, you
876
806
  almost always want to pass locals to it.
877
807
 
878
- #### Radius Templates
879
-
880
- <table>
881
- <tr>
882
- <td>Dependency</td>
883
- <td><a href="https://github.com/jlong/radius" title="Radius">Radius</a></td>
884
- </tr>
885
- <tr>
886
- <td>File Extension</td>
887
- <td><tt>.radius</tt></td>
888
- </tr>
889
- <tr>
890
- <td>Example</td>
891
- <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
892
- </tr>
893
- </table>
894
-
895
- Since you cannot call Ruby methods directly from a Radius template, you
896
- almost always want to pass locals to it.
897
-
898
808
  #### Markaby Templates
899
809
 
900
810
  <table>
@@ -948,139 +858,6 @@ It also takes a block for inline templates (see [example](#inline-templates)).
948
858
  </tr>
949
859
  </table>
950
860
 
951
- #### Creole Templates
952
-
953
- <table>
954
- <tr>
955
- <td>Dependency</td>
956
- <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
957
- </tr>
958
- <tr>
959
- <td>File Extension</td>
960
- <td><tt>.creole</tt></td>
961
- </tr>
962
- <tr>
963
- <td>Example</td>
964
- <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
965
- </tr>
966
- </table>
967
-
968
- It is not possible to call methods from Creole, nor to pass locals to it. You
969
- therefore will usually use it in combination with another rendering engine:
970
-
971
- ```ruby
972
- erb :overview, :locals => { :text => creole(:introduction) }
973
- ```
974
-
975
- Note that you may also call the `creole` method from within other templates:
976
-
977
- ```ruby
978
- %h1 Hello From Haml!
979
- %p= creole(:greetings)
980
- ```
981
-
982
- Since you cannot call Ruby from Creole, you cannot use layouts written in
983
- Creole. However, it is possible to use another rendering engine for the
984
- template than for the layout by passing the `:layout_engine` option.
985
-
986
- #### MediaWiki Templates
987
-
988
- <table>
989
- <tr>
990
- <td>Dependency</td>
991
- <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
992
- </tr>
993
- <tr>
994
- <td>File Extension</td>
995
- <td><tt>.mediawiki</tt> and <tt>.mw</tt></td>
996
- </tr>
997
- <tr>
998
- <td>Example</td>
999
- <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
1000
- </tr>
1001
- </table>
1002
-
1003
- It is not possible to call methods from MediaWiki markup, nor to pass
1004
- locals to it. You therefore will usually use it in combination with
1005
- another rendering engine:
1006
-
1007
- ```ruby
1008
- erb :overview, :locals => { :text => mediawiki(:introduction) }
1009
- ```
1010
-
1011
- Note that you may also call the `mediawiki` method from within other
1012
- templates:
1013
-
1014
- ```ruby
1015
- %h1 Hello From Haml!
1016
- %p= mediawiki(:greetings)
1017
- ```
1018
-
1019
- Since you cannot call Ruby from MediaWiki, you cannot use layouts written in
1020
- MediaWiki. However, it is possible to use another rendering engine for the
1021
- template than for the layout by passing the `:layout_engine` option.
1022
-
1023
- #### CoffeeScript Templates
1024
-
1025
- <table>
1026
- <tr>
1027
- <td>Dependency</td>
1028
- <td>
1029
- <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
1030
- CoffeeScript
1031
- </a> and a
1032
- <a href="https://github.com/sstephenson/execjs" title="ExecJS">
1033
- way to execute javascript
1034
- </a>
1035
- </td>
1036
- </tr>
1037
- <tr>
1038
- <td>File Extension</td>
1039
- <td><tt>.coffee</tt></td>
1040
- </tr>
1041
- <tr>
1042
- <td>Example</td>
1043
- <td><tt>coffee :index</tt></td>
1044
- </tr>
1045
- </table>
1046
-
1047
- #### Stylus Templates
1048
-
1049
- <table>
1050
- <tr>
1051
- <td>Dependency</td>
1052
- <td>
1053
- <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
1054
- Stylus
1055
- </a> and a
1056
- <a href="https://github.com/sstephenson/execjs" title="ExecJS">
1057
- way to execute javascript
1058
- </a>
1059
- </td>
1060
- </tr>
1061
- <tr>
1062
- <td>File Extension</td>
1063
- <td><tt>.styl</tt></td>
1064
- </tr>
1065
- <tr>
1066
- <td>Example</td>
1067
- <td><tt>stylus :index</tt></td>
1068
- </tr>
1069
- </table>
1070
-
1071
- Before being able to use Stylus templates, you need to load `stylus` and
1072
- `stylus/tilt` first:
1073
-
1074
- ```ruby
1075
- require 'sinatra'
1076
- require 'stylus'
1077
- require 'stylus/tilt'
1078
-
1079
- get '/' do
1080
- stylus :example
1081
- end
1082
- ```
1083
-
1084
861
  #### Yajl Templates
1085
862
 
1086
863
  <table>
@@ -1122,27 +899,6 @@ var resource = {"foo":"bar","baz":"qux"};
1122
899
  present(resource);
1123
900
  ```
1124
901
 
1125
- #### WLang Templates
1126
-
1127
- <table>
1128
- <tr>
1129
- <td>Dependency</td>
1130
- <td><a href="https://github.com/blambeau/wlang" title="WLang">WLang</a></td>
1131
- </tr>
1132
- <tr>
1133
- <td>File Extension</td>
1134
- <td><tt>.wlang</tt></td>
1135
- </tr>
1136
- <tr>
1137
- <td>Example</td>
1138
- <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1139
- </tr>
1140
- </table>
1141
-
1142
- Since calling ruby methods is not idiomatic in WLang, you almost always
1143
- want to pass locals to it. Layouts written in WLang and `yield` are
1144
- supported, though.
1145
-
1146
902
  ### Accessing Variables in Templates
1147
903
 
1148
904
  Templates are evaluated within the same context as route handlers. Instance
@@ -1201,7 +957,7 @@ end
1201
957
  ```
1202
958
 
1203
959
  Currently, the following rendering methods accept a block: `erb`, `haml`,
1204
- `liquid`, `slim `, `wlang`. Also, the general `render` method accepts a block.
960
+ `liquid`, `slim `. Also, the general `render` method accepts a block.
1205
961
 
1206
962
  ### Inline Templates
1207
963
 
@@ -1218,7 +974,7 @@ __END__
1218
974
 
1219
975
  @@ layout
1220
976
  %html
1221
- = yield
977
+ != yield
1222
978
 
1223
979
  @@ index
1224
980
  %div.title Hello world.
@@ -1261,10 +1017,10 @@ end
1261
1017
 
1262
1018
  To associate a file extension with a template engine, use
1263
1019
  `Tilt.register`. For instance, if you like to use the file extension
1264
- `tt` for Textile templates, you can do the following:
1020
+ `tt` for Haml templates, you can do the following:
1265
1021
 
1266
1022
  ```ruby
1267
- Tilt.register :tt, Tilt[:textile]
1023
+ Tilt.register Tilt[:haml], :tt
1268
1024
  ```
1269
1025
 
1270
1026
  ### Adding Your Own Template Engine
@@ -1272,7 +1028,7 @@ Tilt.register :tt, Tilt[:textile]
1272
1028
  First, register your engine with Tilt, then create a rendering method:
1273
1029
 
1274
1030
  ```ruby
1275
- Tilt.register :myat, MyAwesomeTemplateEngine
1031
+ Tilt.register MyAwesomeTemplateEngine, :myat
1276
1032
 
1277
1033
  helpers do
1278
1034
  def myat(*args) render(:myat, *args) end
@@ -2136,7 +1892,7 @@ end
2136
1892
  Another example would be using different directories for different engines:
2137
1893
 
2138
1894
  ```ruby
2139
- set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1895
+ set :views, :haml => 'templates', :default => 'views'
2140
1896
 
2141
1897
  helpers do
2142
1898
  def find_template(views, name, engine, &block)
@@ -2213,7 +1969,7 @@ end
2213
1969
  ### Configuring attack protection
2214
1970
 
2215
1971
  Sinatra is using
2216
- [Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme) to
1972
+ [Rack::Protection](https://github.com/sinatra/sinatra/tree/main/rack-protection#readme) to
2217
1973
  defend your application against common, opportunistic attacks. You can
2218
1974
  easily disable this behavior (which will open up your application to tons
2219
1975
  of common vulnerabilities):
@@ -2369,9 +2125,13 @@ set :protection, :session => true
2369
2125
 
2370
2126
  <dt>raise_errors</dt>
2371
2127
  <dd>
2372
- Raise exceptions (will stop application). Enabled by default when
2128
+ Raise unhandled errors (will stop application). Enabled by default when
2373
2129
  <tt>environment</tt> is set to <tt>"test"</tt>, disabled otherwise.
2374
2130
  </dd>
2131
+ <dd>
2132
+ Any explicitly defined error handlers always override this setting. See
2133
+ the "Error" section below.
2134
+ </dd>
2375
2135
 
2376
2136
  <dt>run</dt>
2377
2137
  <dd>
@@ -2464,6 +2224,24 @@ set :protection, :session => true
2464
2224
  </dd>
2465
2225
  </dl>
2466
2226
 
2227
+ ## Lifecycle Events
2228
+
2229
+ There are 2 lifecycle events currently exposed by Sinatra. One when the server starts and one when it stops.
2230
+
2231
+ They can be used like this:
2232
+
2233
+ ```ruby
2234
+ on_start do
2235
+ puts "===== Booting up ====="
2236
+ end
2237
+
2238
+ on_stop do
2239
+ puts "===== Shutting down ====="
2240
+ end
2241
+ ```
2242
+
2243
+ Note that these callbacks only work when using Sinatra to start the web server.
2244
+
2467
2245
  ## Environments
2468
2246
 
2469
2247
  There are three predefined `environments`: `"development"`,
@@ -2520,6 +2298,14 @@ show exceptions option to `:after_handler`:
2520
2298
  set :show_exceptions, :after_handler
2521
2299
  ```
2522
2300
 
2301
+ A catch-all error handler can be defined with `error` and a block:
2302
+
2303
+ ```ruby
2304
+ error do
2305
+ 'Sorry there was a nasty error'
2306
+ end
2307
+ ```
2308
+
2523
2309
  The exception object can be obtained from the `sinatra.error` Rack variable:
2524
2310
 
2525
2311
  ```ruby
@@ -2528,7 +2314,7 @@ error do
2528
2314
  end
2529
2315
  ```
2530
2316
 
2531
- Custom errors:
2317
+ Pass an error class as an argument to create handlers for custom errors:
2532
2318
 
2533
2319
  ```ruby
2534
2320
  error MyCustomError do
@@ -2574,6 +2360,51 @@ Sinatra installs special `not_found` and `error` handlers when
2574
2360
  running under the development environment to display nice stack traces
2575
2361
  and additional debugging information in your browser.
2576
2362
 
2363
+ ### Behavior with `raise_errors` option
2364
+
2365
+ When `raise_errors` option is `true`, errors that are unhandled are raised
2366
+ outside of the application. Additionally, any errors that would have been
2367
+ caught by the catch-all error handler are raised.
2368
+
2369
+ For example, consider the following configuration:
2370
+
2371
+ ```ruby
2372
+ # First handler
2373
+ error MyCustomError do
2374
+ 'A custom message'
2375
+ end
2376
+
2377
+ # Second handler
2378
+ error do
2379
+ 'A catch-all message'
2380
+ end
2381
+ ```
2382
+
2383
+ If `raise_errors` is `false`:
2384
+
2385
+ * When `MyCustomError` or descendant is raised, the first handler is invoked.
2386
+ The HTTP response body will contain `"A custom message"`.
2387
+ * When any other error is raised, the second handler is invoked. The HTTP
2388
+ response body will contain `"A catch-all message"`.
2389
+
2390
+ If `raise_errors` is `true`:
2391
+
2392
+ * When `MyCustomError` or descendant is raised, the behavior is identical to
2393
+ when `raise_errors` is `false`, described above.
2394
+ * When any other error is raised, the second handler is *not* invoked, and
2395
+ the error is raised outside of the application.
2396
+ * If the environment is `production`, the HTTP response body will contain
2397
+ a generic error message, e.g. `"An unhandled lowlevel error occurred. The
2398
+ application logs may have details."`
2399
+ * If the environment is not `production`, the HTTP response body will contain
2400
+ the verbose error backtrace.
2401
+ * Regardless of environment, if `show_exceptions` is set to `:after_handler`,
2402
+ the HTTP response body will contain the verbose error backtrace.
2403
+
2404
+ In the `test` environment, `raise_errors` is set to `true` by default. This
2405
+ means that in order to write a test for a catch-all error handler,
2406
+ `raise_errors` must temporarily be set to `false` for that particular test.
2407
+
2577
2408
  ## Rack Middleware
2578
2409
 
2579
2410
  Sinatra rides on [Rack](https://rack.github.io/), a minimal standard
@@ -2599,7 +2430,7 @@ end
2599
2430
  ```
2600
2431
 
2601
2432
  The semantics of `use` are identical to those defined for the
2602
- [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder) DSL
2433
+ [Rack::Builder](https://www.rubydoc.info/github/rack/rack/main/Rack/Builder) DSL
2603
2434
  (most frequently used from rackup files). For example, the `use` method
2604
2435
  accepts multiple/variable args as well as blocks:
2605
2436
 
@@ -2615,7 +2446,7 @@ many of these components automatically based on configuration so you
2615
2446
  typically don't have to `use` them explicitly.
2616
2447
 
2617
2448
  You can find useful middleware in
2618
- [rack](https://github.com/rack/rack/tree/master/lib/rack),
2449
+ [rack](https://github.com/rack/rack/tree/main/lib/rack),
2619
2450
  [rack-contrib](https://github.com/rack/rack-contrib#readme),
2620
2451
  or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2621
2452
 
@@ -2623,7 +2454,7 @@ or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2623
2454
 
2624
2455
  Sinatra tests can be written using any Rack-based testing library or
2625
2456
  framework.
2626
- [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)
2457
+ [Rack::Test](https://www.rubydoc.info/github/rack/rack-test/main/frames)
2627
2458
  is recommended:
2628
2459
 
2629
2460
  ```ruby
@@ -3085,9 +2916,9 @@ rainbows -c rainbows.conf
3085
2916
 
3086
2917
  The following Ruby versions are officially supported:
3087
2918
  <dl>
3088
- <dt>Ruby 2.3</dt>
2919
+ <dt>Ruby 2.6</dt>
3089
2920
  <dd>
3090
- 2.3 is fully supported and recommended. There are currently no plans to
2921
+ 2.6 is fully supported and recommended. There are currently no plans to
3091
2922
  drop official support for it.
3092
2923
  </dd>
3093
2924
 
@@ -3105,37 +2936,20 @@ The following Ruby versions are officially supported:
3105
2936
  </dd>
3106
2937
  </dl>
3107
2938
 
3108
- Versions of Ruby before 2.3 are no longer supported as of Sinatra 2.1.0.
3109
-
3110
- We also keep an eye on upcoming Ruby versions.
3111
-
3112
- The following Ruby implementations are not officially supported but still are
3113
- known to run Sinatra:
2939
+ Versions of Ruby before 2.6 are no longer supported as of Sinatra 3.0.0.
3114
2940
 
3115
- * Older versions of JRuby and Rubinius
3116
- * Ruby Enterprise Edition
3117
- * MacRuby, Maglev, IronRuby
3118
- * Ruby 1.9.0 and 1.9.1 (but we do recommend against using those)
3119
-
3120
- Not being officially supported means if things only break there and not on a
3121
- supported platform, we assume it's not our issue but theirs.
3122
-
3123
- We also run our CI against ruby-head (future releases of MRI), but we
3124
- can't guarantee anything, since it is constantly moving. Expect upcoming
3125
- 2.x releases to be fully supported.
2941
+ We also keep an eye on upcoming Ruby versions. Expect upcoming
2942
+ 3.x releases to be fully supported.
3126
2943
 
3127
2944
  Sinatra should work on any operating system supported by the chosen Ruby
3128
2945
  implementation.
3129
2946
 
3130
- If you run MacRuby, you should `gem install control_tower`.
3131
-
3132
- Sinatra currently doesn't run on Cardinal, SmallRuby, BlueRuby or any
3133
- Ruby version prior to 2.2.
2947
+ Running Sinatra on a not officially supported Ruby flavor means that if things only break there we assume it's not our issue but theirs.
3134
2948
 
3135
2949
  ## The Bleeding Edge
3136
2950
 
3137
2951
  If you would like to use Sinatra's latest bleeding-edge code, feel free
3138
- to run your application against the master branch, it should be rather
2952
+ to run your application against the main branch, it should be rather
3139
2953
  stable.
3140
2954
 
3141
2955
  We also push out prerelease gems from time to time, so you can do a
@@ -3184,20 +2998,19 @@ SemVerTag.
3184
2998
 
3185
2999
  ## Further Reading
3186
3000
 
3187
- * [Project Website](http://www.sinatrarb.com/) - Additional documentation,
3001
+ * [Project Website](https://sinatrarb.com/) - Additional documentation,
3188
3002
  news, and links to other resources.
3189
- * [Contributing](http://www.sinatrarb.com/contributing) - Find a bug? Need
3003
+ * [Contributing](https://sinatrarb.com/contributing) - Find a bug? Need
3190
3004
  help? Have a patch?
3191
3005
  * [Issue tracker](https://github.com/sinatra/sinatra/issues)
3192
3006
  * [Twitter](https://twitter.com/sinatra)
3193
3007
  * [Mailing List](https://groups.google.com/forum/#!forum/sinatrarb)
3194
3008
  * IRC: [#sinatra](irc://chat.freenode.net/#sinatra) on [Freenode](https://freenode.net)
3195
- * [Sinatra & Friends](https://sinatrarb.slack.com) on Slack
3196
- ([get an invite](https://sinatra-slack.herokuapp.com/))
3009
+ * [Sinatra & Friends](https://discord.gg/ncjsfsNHh7) on Discord
3197
3010
  * [Sinatra Book](https://github.com/sinatra/sinatra-book) - Cookbook Tutorial
3198
3011
  * [Sinatra Recipes](http://recipes.sinatrarb.com/) - Community contributed
3199
3012
  recipes
3200
- * API documentation for the [latest release](http://www.rubydoc.info/gems/sinatra)
3201
- or the [current HEAD](http://www.rubydoc.info/github/sinatra/sinatra) on
3202
- [RubyDoc](http://www.rubydoc.info/)
3203
- * [CI server](https://travis-ci.org/sinatra/sinatra)
3013
+ * API documentation for the [latest release](https://www.rubydoc.info/gems/sinatra)
3014
+ or the [current HEAD](https://www.rubydoc.info/github/sinatra/sinatra) on
3015
+ [RubyDoc](https://www.rubydoc.info/)
3016
+ * [CI Actions](https://github.com/sinatra/sinatra/actions)