sinatra 2.2.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
[![Gem Version](https://badge.fury.io/rb/sinatra.svg)](https://badge.fury.io/rb/sinatra)
|
4
|
-
[![
|
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
|
-
[
|
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)
|