sinatra 2.2.4 → 3.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sinatra might be problematic. Click here for more details.

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>
@@ -936,7 +846,7 @@ It also takes a block for inline templates (see [example](#inline-templates)).
936
846
  <table>
937
847
  <tr>
938
848
  <td>Dependency</td>
939
- <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
849
+ <td><a href="https://slim-template.github.io/" title="Slim Lang">Slim Lang</a></td>
940
850
  </tr>
941
851
  <tr>
942
852
  <td>File Extension</td>
@@ -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
@@ -1443,22 +1199,6 @@ $ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
1443
1199
  99ae8af...snip...ec0f262ac
1444
1200
  ```
1445
1201
 
1446
- **Session Secret Generation (Bonus Points)**
1447
-
1448
- Use the [sysrandom gem](https://github.com/cryptosphere/sysrandom#readme) to
1449
- use the system RNG facilities to generate random values instead of
1450
- userspace `OpenSSL` which MRI Ruby currently defaults to:
1451
-
1452
- ```text
1453
- $ gem install sysrandom
1454
- Building native extensions. This could take a while...
1455
- Successfully installed sysrandom-1.x
1456
- 1 gem installed
1457
-
1458
- $ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
1459
- 99ae8af...snip...ec0f262ac
1460
- ```
1461
-
1462
1202
  **Session Secret Environment Variable**
1463
1203
 
1464
1204
  Set a `SESSION_SECRET` environment variable for Sinatra to the value you
@@ -1473,14 +1213,10 @@ purposes only:
1473
1213
  **Session Secret App Config**
1474
1214
 
1475
1215
  Set up your app config to fail-safe to a secure random secret
1476
- if the `SESSION_SECRET` environment variable is not available.
1477
-
1478
- For bonus points use the [sysrandom
1479
- gem](https://github.com/cryptosphere/sysrandom#readme) here as well:
1216
+ if the `SESSION_SECRET` environment variable is not available:
1480
1217
 
1481
1218
  ```ruby
1482
1219
  require 'securerandom'
1483
- # -or- require 'sysrandom/securerandom'
1484
1220
  set :session_secret, ENV.fetch('SESSION_SECRET') { SecureRandom.hex(64) }
1485
1221
  ```
1486
1222
 
@@ -1685,53 +1421,9 @@ to `stream` finishes executing. Streaming does not work at all with Shotgun.
1685
1421
 
1686
1422
  If the optional parameter is set to `keep_open`, it will not call `close` on
1687
1423
  the stream object, allowing you to close it at any later point in the
1688
- execution flow. This only works on evented servers, like Rainbows.
1689
- Other servers will still close the stream:
1690
-
1691
- ```ruby
1692
- # config.ru
1693
- require 'sinatra/base'
1424
+ execution flow.
1694
1425
 
1695
- class App < Sinatra::Base
1696
- connections = []
1697
-
1698
- get '/subscribe', provides: 'text/event-stream' do
1699
- # register a client's interest in server events
1700
- stream(:keep_open) do |out|
1701
- connections << out
1702
- # purge dead connections
1703
- connections.reject!(&:closed?)
1704
- end
1705
- end
1706
-
1707
- post '/' do
1708
- connections.each do |out|
1709
- # notify client that a new message has arrived
1710
- out << "data: #{params[:msg]}\n\n"
1711
-
1712
- # indicate client to connect again
1713
- out.close
1714
- end
1715
-
1716
- 204 # response without entity body
1717
- end
1718
- end
1719
-
1720
- run App
1721
- ```
1722
-
1723
- ```ruby
1724
- # rainbows.conf
1725
- Rainbows! do
1726
- use :EventMachine
1727
- end
1728
- ````
1729
-
1730
- Run:
1731
-
1732
- ```shell
1733
- rainbows -c rainbows.conf
1734
- ```
1426
+ You can have a look at the [chat example](https://github.com/sinatra/sinatra/blob/main/examples/chat.rb)
1735
1427
 
1736
1428
  It's also possible for the client to close the connection when trying to
1737
1429
  write to the socket. Because of this, it's recommended to check
@@ -2136,7 +1828,7 @@ end
2136
1828
  Another example would be using different directories for different engines:
2137
1829
 
2138
1830
  ```ruby
2139
- set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
1831
+ set :views, :haml => 'templates', :default => 'views'
2140
1832
 
2141
1833
  helpers do
2142
1834
  def find_template(views, name, engine, &block)
@@ -2213,7 +1905,7 @@ end
2213
1905
  ### Configuring attack protection
2214
1906
 
2215
1907
  Sinatra is using
2216
- [Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme) to
1908
+ [Rack::Protection](https://github.com/sinatra/sinatra/tree/main/rack-protection#readme) to
2217
1909
  defend your application against common, opportunistic attacks. You can
2218
1910
  easily disable this behavior (which will open up your application to tons
2219
1911
  of common vulnerabilities):
@@ -2369,9 +2061,13 @@ set :protection, :session => true
2369
2061
 
2370
2062
  <dt>raise_errors</dt>
2371
2063
  <dd>
2372
- Raise exceptions (will stop application). Enabled by default when
2064
+ Raise unhandled errors (will stop application). Enabled by default when
2373
2065
  <tt>environment</tt> is set to <tt>"test"</tt>, disabled otherwise.
2374
2066
  </dd>
2067
+ <dd>
2068
+ Any explicitly defined error handlers always override this setting. See
2069
+ the "Error" section below.
2070
+ </dd>
2375
2071
 
2376
2072
  <dt>run</dt>
2377
2073
  <dd>
@@ -2464,6 +2160,24 @@ set :protection, :session => true
2464
2160
  </dd>
2465
2161
  </dl>
2466
2162
 
2163
+ ## Lifecycle Events
2164
+
2165
+ There are 2 lifecycle events currently exposed by Sinatra. One when the server starts and one when it stops.
2166
+
2167
+ They can be used like this:
2168
+
2169
+ ```ruby
2170
+ on_start do
2171
+ puts "===== Booting up ====="
2172
+ end
2173
+
2174
+ on_stop do
2175
+ puts "===== Shutting down ====="
2176
+ end
2177
+ ```
2178
+
2179
+ Note that these callbacks only work when using Sinatra to start the web server.
2180
+
2467
2181
  ## Environments
2468
2182
 
2469
2183
  There are three predefined `environments`: `"development"`,
@@ -2520,6 +2234,14 @@ show exceptions option to `:after_handler`:
2520
2234
  set :show_exceptions, :after_handler
2521
2235
  ```
2522
2236
 
2237
+ A catch-all error handler can be defined with `error` and a block:
2238
+
2239
+ ```ruby
2240
+ error do
2241
+ 'Sorry there was a nasty error'
2242
+ end
2243
+ ```
2244
+
2523
2245
  The exception object can be obtained from the `sinatra.error` Rack variable:
2524
2246
 
2525
2247
  ```ruby
@@ -2528,7 +2250,7 @@ error do
2528
2250
  end
2529
2251
  ```
2530
2252
 
2531
- Custom errors:
2253
+ Pass an error class as an argument to create handlers for custom errors:
2532
2254
 
2533
2255
  ```ruby
2534
2256
  error MyCustomError do
@@ -2574,6 +2296,51 @@ Sinatra installs special `not_found` and `error` handlers when
2574
2296
  running under the development environment to display nice stack traces
2575
2297
  and additional debugging information in your browser.
2576
2298
 
2299
+ ### Behavior with `raise_errors` option
2300
+
2301
+ When `raise_errors` option is `true`, errors that are unhandled are raised
2302
+ outside of the application. Additionally, any errors that would have been
2303
+ caught by the catch-all error handler are raised.
2304
+
2305
+ For example, consider the following configuration:
2306
+
2307
+ ```ruby
2308
+ # First handler
2309
+ error MyCustomError do
2310
+ 'A custom message'
2311
+ end
2312
+
2313
+ # Second handler
2314
+ error do
2315
+ 'A catch-all message'
2316
+ end
2317
+ ```
2318
+
2319
+ If `raise_errors` is `false`:
2320
+
2321
+ * When `MyCustomError` or descendant is raised, the first handler is invoked.
2322
+ The HTTP response body will contain `"A custom message"`.
2323
+ * When any other error is raised, the second handler is invoked. The HTTP
2324
+ response body will contain `"A catch-all message"`.
2325
+
2326
+ If `raise_errors` is `true`:
2327
+
2328
+ * When `MyCustomError` or descendant is raised, the behavior is identical to
2329
+ when `raise_errors` is `false`, described above.
2330
+ * When any other error is raised, the second handler is *not* invoked, and
2331
+ the error is raised outside of the application.
2332
+ * If the environment is `production`, the HTTP response body will contain
2333
+ a generic error message, e.g. `"An unhandled lowlevel error occurred. The
2334
+ application logs may have details."`
2335
+ * If the environment is not `production`, the HTTP response body will contain
2336
+ the verbose error backtrace.
2337
+ * Regardless of environment, if `show_exceptions` is set to `:after_handler`,
2338
+ the HTTP response body will contain the verbose error backtrace.
2339
+
2340
+ In the `test` environment, `raise_errors` is set to `true` by default. This
2341
+ means that in order to write a test for a catch-all error handler,
2342
+ `raise_errors` must temporarily be set to `false` for that particular test.
2343
+
2577
2344
  ## Rack Middleware
2578
2345
 
2579
2346
  Sinatra rides on [Rack](https://rack.github.io/), a minimal standard
@@ -2599,7 +2366,7 @@ end
2599
2366
  ```
2600
2367
 
2601
2368
  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
2369
+ [Rack::Builder](https://www.rubydoc.info/github/rack/rack/main/Rack/Builder) DSL
2603
2370
  (most frequently used from rackup files). For example, the `use` method
2604
2371
  accepts multiple/variable args as well as blocks:
2605
2372
 
@@ -2615,7 +2382,7 @@ many of these components automatically based on configuration so you
2615
2382
  typically don't have to `use` them explicitly.
2616
2383
 
2617
2384
  You can find useful middleware in
2618
- [rack](https://github.com/rack/rack/tree/master/lib/rack),
2385
+ [rack](https://github.com/rack/rack/tree/main/lib/rack),
2619
2386
  [rack-contrib](https://github.com/rack/rack-contrib#readme),
2620
2387
  or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2621
2388
 
@@ -2623,7 +2390,7 @@ or in the [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
2623
2390
 
2624
2391
  Sinatra tests can be written using any Rack-based testing library or
2625
2392
  framework.
2626
- [Rack::Test](http://www.rubydoc.info/github/brynary/rack-test/master/frames)
2393
+ [Rack::Test](https://www.rubydoc.info/github/rack/rack-test/main/frames)
2627
2394
  is recommended:
2628
2395
 
2629
2396
  ```ruby
@@ -3047,47 +2814,15 @@ by Konstantin_
3047
2814
  Sinatra doesn't impose any concurrency model but leaves that to the
3048
2815
  underlying Rack handler (server) like Puma or WEBrick. Sinatra
3049
2816
  itself is thread-safe, so there won't be any problem if the Rack handler
3050
- uses a threaded model of concurrency. This would mean that when starting
3051
- the server, you'd have to specify the correct invocation method for the
3052
- specific Rack handler. The following example is a demonstration of how
3053
- to start a multi-threaded Rainbows server:
3054
-
3055
- ```ruby
3056
- # config.ru
3057
-
3058
- require 'sinatra/base'
3059
-
3060
- class App < Sinatra::Base
3061
- get '/' do
3062
- "Hello, World"
3063
- end
3064
- end
3065
-
3066
- run App
3067
- ```
3068
-
3069
- ```ruby
3070
- # rainbows.conf
3071
-
3072
- # Rainbows configurator is based on Unicorn.
3073
- Rainbows! do
3074
- use :ThreadSpawn
3075
- end
3076
- ```
3077
-
3078
- To start the server, the command would be:
3079
-
3080
- ```shell
3081
- rainbows -c rainbows.conf
3082
- ```
2817
+ uses a threaded model of concurrency.
3083
2818
 
3084
2819
  ## Requirement
3085
2820
 
3086
2821
  The following Ruby versions are officially supported:
3087
2822
  <dl>
3088
- <dt>Ruby 2.3</dt>
2823
+ <dt>Ruby 2.6</dt>
3089
2824
  <dd>
3090
- 2.3 is fully supported and recommended. There are currently no plans to
2825
+ 2.6 is fully supported and recommended. There are currently no plans to
3091
2826
  drop official support for it.
3092
2827
  </dd>
3093
2828
 
@@ -3105,37 +2840,20 @@ The following Ruby versions are officially supported:
3105
2840
  </dd>
3106
2841
  </dl>
3107
2842
 
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:
2843
+ Versions of Ruby before 2.6 are no longer supported as of Sinatra 3.0.0.
3114
2844
 
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.
2845
+ We also keep an eye on upcoming Ruby versions. Expect upcoming
2846
+ 3.x releases to be fully supported.
3126
2847
 
3127
2848
  Sinatra should work on any operating system supported by the chosen Ruby
3128
2849
  implementation.
3129
2850
 
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.
2851
+ 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
2852
 
3135
2853
  ## The Bleeding Edge
3136
2854
 
3137
2855
  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
2856
+ to run your application against the main branch, it should be rather
3139
2857
  stable.
3140
2858
 
3141
2859
  We also push out prerelease gems from time to time, so you can do a
@@ -3184,20 +2902,19 @@ SemVerTag.
3184
2902
 
3185
2903
  ## Further Reading
3186
2904
 
3187
- * [Project Website](http://www.sinatrarb.com/) - Additional documentation,
2905
+ * [Project Website](https://sinatrarb.com/) - Additional documentation,
3188
2906
  news, and links to other resources.
3189
- * [Contributing](http://www.sinatrarb.com/contributing) - Find a bug? Need
2907
+ * [Contributing](https://sinatrarb.com/contributing) - Find a bug? Need
3190
2908
  help? Have a patch?
3191
2909
  * [Issue tracker](https://github.com/sinatra/sinatra/issues)
3192
2910
  * [Twitter](https://twitter.com/sinatra)
3193
2911
  * [Mailing List](https://groups.google.com/forum/#!forum/sinatrarb)
3194
2912
  * 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/))
2913
+ * [Sinatra & Friends](https://discord.gg/ncjsfsNHh7) on Discord
3197
2914
  * [Sinatra Book](https://github.com/sinatra/sinatra-book) - Cookbook Tutorial
3198
2915
  * [Sinatra Recipes](http://recipes.sinatrarb.com/) - Community contributed
3199
2916
  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)
2917
+ * API documentation for the [latest release](https://www.rubydoc.info/gems/sinatra)
2918
+ or the [current HEAD](https://www.rubydoc.info/github/sinatra/sinatra) on
2919
+ [RubyDoc](https://www.rubydoc.info/)
2920
+ * [CI Actions](https://github.com/sinatra/sinatra/actions)