sinatra 2.2.0 → 3.1.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +133 -16
- data/CONTRIBUTING.md +11 -11
- data/Gemfile +48 -62
- data/MAINTENANCE.md +2 -2
- data/README.md +199 -386
- data/Rakefile +66 -75
- data/VERSION +1 -1
- data/examples/chat.rb +25 -12
- data/examples/lifecycle_events.rb +20 -0
- data/examples/rainbows.rb +3 -1
- data/examples/simple.rb +2 -0
- data/examples/stream.ru +2 -1
- data/lib/sinatra/base.rb +420 -338
- data/lib/sinatra/indifferent_hash.rb +25 -33
- data/lib/sinatra/main.rb +18 -16
- data/lib/sinatra/show_exceptions.rb +17 -15
- data/lib/sinatra/version.rb +3 -1
- data/lib/sinatra.rb +2 -0
- data/sinatra.gemspec +38 -33
- metadata +40 -30
- data/README.de.md +0 -3239
- data/README.es.md +0 -3231
- data/README.fr.md +0 -3111
- data/README.hu.md +0 -728
- data/README.ja.md +0 -2844
- data/README.ko.md +0 -2967
- data/README.malayalam.md +0 -3141
- data/README.pt-br.md +0 -3787
- data/README.pt-pt.md +0 -791
- data/README.ru.md +0 -3207
- data/README.zh.md +0 -2934
data/README.md
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
# Sinatra
|
2
2
|
|
3
3
|
[](https://badge.fury.io/rb/sinatra)
|
4
|
-
[](https://dependabot.com/compatibility-score.html?dependency-name=sinatra&package-manager=bundler&version-scheme=semver)
|
4
|
+
[](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
|
-
[
|
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
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
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
|
389
|
-
|
380
|
+
@except = except
|
381
|
+
end
|
382
|
+
|
383
|
+
def to_pattern(options)
|
384
|
+
return self
|
390
385
|
end
|
391
386
|
|
392
|
-
def
|
393
|
-
|
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
|
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'
|
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://
|
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
|
-
####
|
672
|
+
#### Scss Templates
|
688
673
|
|
689
674
|
<table>
|
690
675
|
<tr>
|
691
676
|
<td>Dependency</td>
|
692
|
-
<td><a href="https://
|
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
|
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
|
-
|
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
|
1020
|
+
`tt` for Haml templates, you can do the following:
|
1265
1021
|
|
1266
1022
|
```ruby
|
1267
|
-
Tilt.register :
|
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
|
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, :
|
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/
|
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
|
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
|
-
|
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](
|
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/
|
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](
|
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.
|
2919
|
+
<dt>Ruby 2.6</dt>
|
3089
2920
|
<dd>
|
3090
|
-
2.
|
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.
|
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
|
-
|
3116
|
-
|
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
|
-
|
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
|
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](
|
3001
|
+
* [Project Website](https://sinatrarb.com/) - Additional documentation,
|
3188
3002
|
news, and links to other resources.
|
3189
|
-
* [Contributing](
|
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://
|
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](
|
3201
|
-
or the [current HEAD](
|
3202
|
-
[RubyDoc](
|
3203
|
-
* [CI
|
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)
|