sinatra 2.0.7 → 2.0.8

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


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

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d4e8de01bf4c996539070ba126783554845768b3c92428813e36b572330b0105
4
- data.tar.gz: b5cea6545616d1296290fdbe88357619ff827ce16f6da7b0310a80bac86c657e
3
+ metadata.gz: 996ffb850e9fba979b72012a00ba18a9baf51dd8ecb4369330bd0a8f3057b599
4
+ data.tar.gz: cd3ccb02b5348188a5f644b5a208d94dad535703236d85e1402f53f32e13d054
5
5
  SHA512:
6
- metadata.gz: c197220fab61cfcfc1f4f2a5d4484a9ade9f3daac32f1baf29a0ce3e0104691b723d96149c792b4e5f14e2365cc1136b89b88e7eb0161383467d018349f55f59
7
- data.tar.gz: 24187702ce48a9f18566665a457646a163694685c41ac1a1e898525c9a2a38a139c5420eb56ab2cc28cef1baaf55eac2c1c3f8b30e74c0f5accd8a40f60d781c
6
+ metadata.gz: 6f1f6450b109378735e2018291f54d91be717942d04613df5db578c476c2ad70ec08fe589fb3a917007549957a8e45cc6abf70cee9bbd2fb09b59ff721a69837
7
+ data.tar.gz: 7aa231036ecad7c7ce280556d7cfbad1000572466c24c36bc47e5a32aa1594e4aac0393f598211c41b1c65e028125b7d45689a3442d824dcddd7a6a5adba23b8
@@ -1,3 +1,19 @@
1
+ ## 2.0.8 / 2020-01-01
2
+
3
+ * Lookup Tilt class for template engine without loading files [#1558](https://github.com/sinatra/sinatra/pull/1558). Fixes [#1172](https://github.com/sinatra/sinatra/issues/1172) by Jordan Owens
4
+
5
+ * Add request info in NotFound exception [#1566](https://github.com/sinatra/sinatra/pull/1566) by Stefan Sundin
6
+
7
+ * Add `.yaml` support in `Sinatra::Contrib::ConfigFile` [#1564](https://github.com/sinatra/sinatra/issues/1564). Fixes [#1563](https://github.com/sinatra/sinatra/issues/1563) by Emerson Manabu Araki
8
+
9
+ * Allow multiple hashes to be passed in `merge` and `merge!` for `Sinatra::IndifferentHash` [#1572](https://github.com/sinatra/sinatra/pull/1572) by Shota Iguchi
10
+
11
+ * Remove only routing parameters from @params hash [#1569](https://github.com/sinatra/sinatra/pull/1569). Fixes [#1567](https://github.com/sinatra/sinatra/issues/1567) by Jordan Owens, Horacio
12
+
13
+ * Support `capture` and `content_for` with Hamlit [#1580](https://github.com/sinatra/sinatra/pull/1580) by Takashi Kokubun
14
+
15
+ * Eliminate warnings of keyword parameter for Ruby 2.7.0 [#1581](https://github.com/sinatra/sinatra/pull/1581) by Osamtimizer
16
+
1
17
  ## 2.0.7 / 2019-08-22
2
18
 
3
19
  * Fix a regression [#1560](https://github.com/sinatra/sinatra/pull/1560) by Kunpei Sakai
data/Gemfile CHANGED
@@ -26,6 +26,10 @@ if RUBY_ENGINE == 'jruby'
26
26
  gem 'trinidad'
27
27
  end
28
28
 
29
+ if RUBY_ENGINE == 'jruby' || RUBY_ENGINE == 'ruby'
30
+ gem "activesupport", "~> 5.1.6"
31
+ end
32
+
29
33
  if RUBY_ENGINE == "ruby"
30
34
  gem 'less', '~> 2.0'
31
35
  gem 'therubyracer'
@@ -34,7 +38,6 @@ if RUBY_ENGINE == "ruby"
34
38
  gem 'bluecloth'
35
39
  gem 'rdiscount'
36
40
  gem 'RedCloth'
37
- gem "activesupport", "~> 5.1.6"
38
41
  gem 'puma'
39
42
  gem 'yajl-ruby'
40
43
  gem 'nokogiri'
@@ -3,13 +3,16 @@
3
3
  *Atenção: Este documento é apenas uma tradução da versão em inglês e
4
4
  pode estar desatualizado.*
5
5
 
6
- Alguns dos trechos de código a seguir utilizam caracteres UTF-8. Então, caso esteja utilizando uma versão de ruby inferior à `2.0.0`, adicione o encoding no início de seus arquivos:
6
+ Alguns dos trechos de código a seguir utilizam caracteres UTF-8. Então, caso
7
+ esteja utilizando uma versão de ruby inferior à `2.0.0`, adicione o encoding
8
+ no início de seus arquivos:
7
9
 
8
10
  ```ruby
9
11
  # encoding: utf-8
10
12
  ```
11
13
 
12
- Sinatra é uma [DSL](https://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para
14
+ Sinatra é uma
15
+ [DSL](https://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para
13
16
  criar aplicações web em Ruby com o mínimo de esforço e rapidez:
14
17
 
15
18
  ```ruby
@@ -33,10 +36,14 @@ Em seguida execute:
33
36
  ruby minha_app.rb
34
37
  ```
35
38
 
36
- Acesse: [http://localhost:4567](http://localhost:4567)
39
+ Acesse em: [http://localhost:4567](http://localhost:4567)
37
40
 
38
- É recomendado também executar `gem install thin`. Caso esta gem esteja disponível, o
39
- Sinatra irá utilizá-la.
41
+ Códigos alterados terão efeito após você reiniciar o servidor.
42
+ Por favor, reinicie o servidor após qualquer mudança ou use
43
+ [sinatra/reloader](http://www.sinatrarb.com/contrib/reloader).
44
+
45
+ É recomendado também executar `gem install thin`. Caso esta gem esteja
46
+ disponível, o Sinatra irá utilizá-la.
40
47
 
41
48
  ## Conteúdo
42
49
 
@@ -44,7 +51,7 @@ Sinatra irá utilizá-la.
44
51
  * [Conteúdo](#conteúdo)
45
52
  * [Rotas](#rotas)
46
53
  * [Condições](#condições)
47
- * [Retorno de valores](#retorno-de-valores)
54
+ * [Valores Retornados](#valores-retornados)
48
55
  * [Validadores de rota personalizados](#validadores-de-rota-personalizados)
49
56
  * [Arquivos estáticos](#arquivos-estáticos)
50
57
  * [Views / Templates](#views--templates)
@@ -82,19 +89,50 @@ Sinatra irá utilizá-la.
82
89
  * [Filtros](#filtros)
83
90
  * [Helpers](#helpers)
84
91
  * [Utilizando Sessões](#utilizando-sessões)
92
+ * [Segurança Secreta da Sessão](#segurança-secreta-da-sessão)
93
+ * [Configuração da Sessão](#configuração-da-sessão)
94
+ * [Escolhande Seu Próprio Middleware de Sessão](#escolhendo-middleware-de-sessão)
85
95
  * [Halting](#halting)
86
96
  * [Passing](#passing)
87
97
  * [Desencadeando Outra Rota](#desencadeando-outra-rota)
98
+ * [Definindo Corpo, Código de Status e Cabeçalhos](#definindo-corpo-codigo-de-status-cabeçalhos)
99
+ * [Transmitindo Respostas](#transmitindo-respostas)
100
+ * [Usando Logs](#usando-logs)
101
+ * [Tipos Mime](#tipos-mime)
102
+ * [Gerando URLS](#gerando-urls)
103
+ * [Redirecionamento do Navegador](#redirecionamento-do-navagador)
104
+ * [Controle de Cache](#controle-de-cache)
105
+ * [Enviando Arquivos](#enviando-arquivos)
106
+ * [Acessando o Objeto de Requisição](#acessando-o-objeto-de-requisição)
107
+ * [Anexos](#anexos)
108
+ * [Trabalhando com Data e Hora](#trabalhando-com-data-e-hora)
109
+ * [Procurando Arquivos de Modelo](#procurando-arquivos-de-modelo)
88
110
  * [Configuração](#configuração)
111
+ * [Configurando proteção a ataques](#configurando-proteção-a-ataques)
112
+ * [Configurações Disponíveis](#configurações-disponíveis)
113
+ * [Ambientes](#ambientes)
89
114
  * [Tratamento de Erros](#tratamento-de-erros)
115
+ * [Não Encontrado](#não-encontrado)
90
116
  * [Erro](#erro)
91
- * [Mime Types](#mime-types)
92
117
  * [Rack Middleware](#rack-middleware)
93
118
  * [Testando](#testando)
94
- * [Sinatra::Base - Middleware, Bibliotecas e aplicativos modulares](#sinatrabase---middleware-bibliotecas-e-aplicativos-modulares)
119
+ * [Sinatra::Base - Middleware, Bibliotecas e Aplicações Modulares](#sinatrabase-middleware-bibliotecas-e-aplicações-modulares)
120
+ * [Modular vs. Estilo Clássico](#modular-vs-estilo-clássico)
121
+ * [Servindo uma Aplicação Modular](#servindo-uma-aplicação-modular)
122
+ * [Usando uma Aplicação de Estilo Clássico com um config.ru](#usando-uma-aplicação-de-estilo-clássico-com-um-configru)
123
+ * [Quando usar um config.ru?](#quando-usar-um-configru)
124
+ * [Usando Sinatra como Middleware](#usando-sinatra-como-middleware)
125
+ * [Criação de Aplicações Dinâmicas](#criação-de-aplicações-dinamicas)
126
+ * [Escopos e Ligação](#escopos-e-ligação)
127
+ * [Escopo de Aplicação/Classe](#escopo-de-aplicação-classe)
128
+ * [Escopo de Instância/Requisição](#escopo-de-instância-requisição)
129
+ * [Escopo de Delegação](#escopo-de-delegação)
95
130
  * [Linha de comando](#linha-de-comando)
96
131
  * [Multi-threading](#multi-threading)
132
+ * [Requerimentos](#requerimentos)
97
133
  * [A última versão](#a-última-versão)
134
+ * [Com Bundler](#com-bundler)
135
+ * [Versionando](#versionando)
98
136
  * [Mais](#mais)
99
137
 
100
138
  ## Rotas
@@ -124,13 +162,29 @@ delete '/' do
124
162
  end
125
163
 
126
164
  options '/' do
127
- .. estabelecendo alguma coisa ..pe
165
+ .. estabelecendo alguma coisa ..
166
+ end
167
+
168
+ link '/' do
169
+ .. associando alguma coisa ..
170
+ end
171
+
172
+ unlink '/' do
173
+ .. separando alguma coisa ..
128
174
  end
129
175
  ```
130
176
 
131
177
  As rotas são interpretadas na ordem em que são definidas. A primeira
132
178
  rota encontrada responde a requisição.
133
179
 
180
+ Rotas com barras à direita são diferentes das que não contém as barras:
181
+
182
+ ```ruby
183
+ get '/foo' do
184
+ # Não é o mesmo que "GET /foo/"
185
+ end
186
+ ```
187
+
134
188
  Padrões de rota podem conter parâmetros nomeados, acessíveis por meio do
135
189
  hash `params`:
136
190
 
@@ -214,8 +268,23 @@ end
214
268
  ```
215
269
 
216
270
  A propósito, a menos que você desative a proteção contra ataques (veja
217
- abaixo), o caminho solicitado pode ser alterado antes de concluir a
218
- comparação com as suas rotas.
271
+ [abaixo](#configurando-proteção-a-ataques)), o caminho solicitado pode ser
272
+ alterado antes de concluir a comparação com as suas rotas.
273
+
274
+ Você pode customizar as opções usadas do
275
+ [Mustermann](https://github.com/sinatra/mustermann#readme) para uma
276
+ rota passando `:mustermann_opts` num hash:
277
+
278
+ ```ruby
279
+ get '\A/posts\z', :musterman_opts => { :type => regexp, :check_anchors => false } do
280
+ # corresponde a /posts exatamente, com ancoragem explícita
281
+ "Se você combinar um padrão ancorado bata palmas!"
282
+ end
283
+ ```
284
+
285
+ Parece com uma [condição](#condições) mas não é! Essas opções serão
286
+ misturadas no hash global `:mustermann_opts` descrito
287
+ [abaixo](#configurações-disponíveis)
219
288
 
220
289
  ## Condições
221
290
 
@@ -246,7 +315,7 @@ get '/', :provides => ['rss', 'atom', 'xml'] do
246
315
  builder :feed
247
316
  end
248
317
  ```
249
- `provides` procura pelos Accept header das requisições
318
+ `provides` procura o cabeçalho Accept das requisições
250
319
 
251
320
  Você pode facilmente definir suas próprias condições:
252
321
 
@@ -316,8 +385,9 @@ end
316
385
  get('/') { Stream.new }
317
386
  ```
318
387
 
319
- Você também pode usar o método auxiliar `stream` (descrito abaixo) para
320
- incorporar a lógica de streaming na rota.
388
+ Você também pode usar o método auxiliar `stream`
389
+ ([descrito abaixo](#respostas-de-streaming)) para reduzir códigos
390
+ boilerplate e para incorporar a lógica de streaming (transmissão) na rota.
321
391
 
322
392
  ## Validadores de Rota Personalizados
323
393
 
@@ -381,9 +451,13 @@ Note que o nome do diretório público não é incluido na URL. Um arquivo
381
451
  `./public/css/style.css` é disponibilizado como
382
452
  `http://exemplo.com/css/style.css`.
383
453
 
454
+ Use a configuração `:static_cache_control` (veja [abaixo](#controle-de-cache))
455
+ para adicionar a informação `Cache-Control` no cabeçalho.
456
+
384
457
  ## Views / Templates
385
458
 
386
- Cada linguagem de template é exposta através de seu próprio método de renderização. Estes metodos simplesmente retornam uma string:
459
+ Cada linguagem de template é exposta através de seu próprio método de
460
+ renderização. Estes métodos simplesmente retornam uma string:
387
461
 
388
462
  ```ruby
389
463
  get '/' do
@@ -393,7 +467,8 @@ end
393
467
 
394
468
  Isto renderiza `views/index.rb`
395
469
 
396
- Ao invés do nome do template, você também pode passar direto o conteúdo do template:
470
+ Ao invés do nome do template, você também pode passar direto o conteúdo do
471
+ template:
397
472
 
398
473
  ```ruby
399
474
  get '/' do
@@ -402,7 +477,7 @@ get '/' do
402
477
  end
403
478
  ```
404
479
 
405
- Templates também aceitam um segundo argumento, um hash de opções:
480
+ Templates também aceitam como um segundo argumento, um hash de opções:
406
481
 
407
482
  ```ruby
408
483
  get '/' do
@@ -410,9 +485,11 @@ get '/' do
410
485
  end
411
486
  ```
412
487
 
413
- Isto irá renderizar a `views/index.erb` inclusa dentro da `views/post.erb` (o padrão é a `views/layout.erb`, se existir).
488
+ Isto irá renderizar a `views/index.erb` inclusa dentro da `views/post.erb`
489
+ (o padrão é a `views/layout.erb`, se existir).
414
490
 
415
- Qualquer opção não reconhecida pelo Sinatra será passada adiante para o engine de template:
491
+ Qualquer opção não reconhecida pelo Sinatra será passada adiante para o engine
492
+ de template:
416
493
 
417
494
  ```ruby
418
495
  get '/' do
@@ -430,7 +507,8 @@ get '/' do
430
507
  end
431
508
  ```
432
509
 
433
- Opções passadas para o método de renderização sobrescreve as opções definitas através do método `set`.
510
+ Opções passadas para o método de renderização sobrescreve as opções definitas
511
+ através do método `set`.
434
512
 
435
513
  Opções disponíveis:
436
514
 
@@ -443,12 +521,14 @@ Opções disponíveis:
443
521
 
444
522
  <dt>default_encoding</dt>
445
523
  <dd>
446
- String encoding para ser utilizada em caso de incerteza. o padrão é <tt>settings.default_encoding</tt>.
524
+ String encoding para ser utilizada em caso de incerteza. o padrão é
525
+ <tt>settings.default_encoding</tt>.
447
526
  </dd>
448
527
 
449
528
  <dt>views</dt>
450
529
  <dd>
451
- Diretório de onde os templates são carregados. O padrão é <tt>settings.views</tt>.
530
+ Diretório de onde os templates são carregados. O padrão é
531
+ <tt>settings.views</tt>.
452
532
  </dd>
453
533
 
454
534
  <dt>layout</dt>
@@ -468,8 +548,8 @@ Opções disponíveis:
468
548
  <dt>scope</dt>
469
549
  <dd>
470
550
  Escopo em que o template será renderizado. Padrão é a
471
- instancia da aplicação. Se você mudar isto as variáveis
472
- de instânciae metodos auxiliares não serão
551
+ instância da aplicação. Se você mudar isto as variáveis
552
+ de instância métodos auxiliares não serão
473
553
  disponibilizados.
474
554
  </dd>
475
555
 
@@ -489,7 +569,8 @@ Opções disponíveis:
489
569
  </dd>
490
570
  </dl>
491
571
 
492
- É pressuposto que os templates estarão localizados direto sob o diretório `./views`. Para usar um diretório diferente:
572
+ É pressuposto que os templates estarão localizados diretamente sob o
573
+ diretório `./views`. Para usar um diretório diferente:
493
574
 
494
575
  ```ruby
495
576
  set :views, settings.root + '/templates'
@@ -511,11 +592,21 @@ get '/' do
511
592
  end
512
593
  ```
513
594
 
514
- Renderiza um template string.
595
+ Renderiza um template string. Você pode opcionalmente especificar `path`
596
+ e `:line` para um backtrace mais claro se existir um caminho do sistema de
597
+ arquivos ou linha associada com aquela string.
598
+
599
+ ```ruby
600
+ get '/' do
601
+ haml '%div.title Olá Mundo', :path => 'exemplos/arquivo.haml', :line => 3
602
+ end
603
+ ```
515
604
 
516
605
  ### Linguagens de template disponíveis
517
606
 
518
- Algumas linguagens possuem multiplas implementações. Para especificar qual implementação deverá ser utilizada (e para ser *thread-safe*), você deve simplesmente requere-la primeiro:
607
+ Algumas linguagens possuem multiplas implementações. Para especificar qual
608
+ implementação deverá ser utilizada (e para ser *thread-safe*), você deve
609
+ requere-la primeiro:
519
610
 
520
611
  ```ruby
521
612
  require 'rdiscount' # ou require 'bluecloth'
@@ -526,11 +617,11 @@ get('/') { markdown :index }
526
617
 
527
618
  <table>
528
619
  <tr>
529
- <td>Dependencia</td>
620
+ <td>Dependência</td>
530
621
  <td><a href="http://haml.info/" title="haml">haml</a></td>
531
622
  </tr>
532
623
  <tr>
533
- <td>Extencao do Arquivo</td>
624
+ <td>Extensão do Arquivo</td>
534
625
  <td><tt>.haml</tt></td>
535
626
  </tr>
536
627
  <tr>
@@ -543,14 +634,14 @@ get('/') { markdown :index }
543
634
 
544
635
  <table>
545
636
  <tr>
546
- <td>Dependencia</td>
637
+ <td>Dependência</td>
547
638
  <td>
548
639
  <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
549
640
  or erb (included in Ruby)
550
641
  </td>
551
642
  </tr>
552
643
  <tr>
553
- <td>Extencao do Arquivos</td>
644
+ <td>Extensão dos Arquivos</td>
554
645
  <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubis</tt> (Erubis only)</td>
555
646
  </tr>
556
647
  <tr>
@@ -563,13 +654,15 @@ get('/') { markdown :index }
563
654
 
564
655
  <table>
565
656
  <tr>
566
- <td>Dependencia</td>
657
+ <td>Dependêcia</td>
567
658
  <td>
568
- <a href="https://github.com/jimweirich/builder" title="builder">builder</a>
659
+ <a href="https://github.com/jimweirich/builder" title="builder">
660
+ builder
661
+ </a>
569
662
  </td>
570
663
  </tr>
571
664
  <tr>
572
- <td>Extencao do Arquivo</td>
665
+ <td>Extensão do Arquivo</td>
573
666
  <td><tt>.builder</tt></td>
574
667
  </tr>
575
668
  <tr>
@@ -584,11 +677,11 @@ It also takes a block for inline templates (see exemplo).
584
677
 
585
678
  <table>
586
679
  <tr>
587
- <td>Dependencia</td>
680
+ <td>Dependência</td>
588
681
  <td><a href="http://www.nokogiri.org/" title="nokogiri">nokogiri</a></td>
589
682
  </tr>
590
683
  <tr>
591
- <td>Extencao do Arquivo</td>
684
+ <td>Extensão do Arquivo</td>
592
685
  <td><tt>.nokogiri</tt></td>
593
686
  </tr>
594
687
  <tr>
@@ -603,11 +696,11 @@ It also takes a block for inline templates (see exemplo).
603
696
 
604
697
  <table>
605
698
  <tr>
606
- <td>Dependencia</td>
699
+ <td>Dependência</td>
607
700
  <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
608
701
  </tr>
609
702
  <tr>
610
- <td>Extencao do Arquivo</td>
703
+ <td>Extensão do Arquivo</td>
611
704
  <td><tt>.sass</tt></td>
612
705
  </tr>
613
706
  <tr>
@@ -620,11 +713,11 @@ It also takes a block for inline templates (see exemplo).
620
713
 
621
714
  <table>
622
715
  <tr>
623
- <td>Dependencia</td>
716
+ <td>Dependência</td>
624
717
  <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
625
718
  </tr>
626
719
  <tr>
627
- <td>Extencao do Arquivo</td>
720
+ <td>Extensão do Arquivo</td>
628
721
  <td><tt>.scss</tt></td>
629
722
  </tr>
630
723
  <tr>
@@ -637,11 +730,11 @@ It also takes a block for inline templates (see exemplo).
637
730
 
638
731
  <table>
639
732
  <tr>
640
- <td>Dependencia</td>
733
+ <td>Dependência</td>
641
734
  <td><a href="http://lesscss.org/" title="less">less</a></td>
642
735
  </tr>
643
736
  <tr>
644
- <td>Extencao do Arquivo</td>
737
+ <td>Extensão do Arquivo</td>
645
738
  <td><tt>.less</tt></td>
646
739
  </tr>
647
740
  <tr>
@@ -654,11 +747,13 @@ It also takes a block for inline templates (see exemplo).
654
747
 
655
748
  <table>
656
749
  <tr>
657
- <td>Dependencia</td>
658
- <td><a href="https://shopify.github.io/liquid/" title="liquid">liquid</a></td>
750
+ <td>Dependência</td>
751
+ <td>
752
+ <a href="https://shopify.github.io/liquid/" title="liquid">liquid</a>
753
+ </td>
659
754
  </tr>
660
755
  <tr>
661
- <td>Extencao do Arquivo</td>
756
+ <td>Extensão do Arquivo</td>
662
757
  <td><tt>.liquid</tt></td>
663
758
  </tr>
664
759
  <tr>
@@ -667,25 +762,35 @@ It also takes a block for inline templates (see exemplo).
667
762
  </tr>
668
763
  </table>
669
764
 
670
- Já que você não pode chamar o Ruby (exceto pelo método `yield`) pelo template Liquid,
671
- você quase sempre precisará passar o `locals` para ele.
765
+ Já que você não pode chamar o Ruby (exceto pelo método `yield`) pelo template
766
+ Liquid, você quase sempre precisará passar o `locals` para ele.
672
767
 
673
768
  #### Markdown Templates
674
769
 
675
770
  <table>
676
771
  <tr>
677
- <td>Dependencia</td>
772
+ <td>Dependência</td>
678
773
  <td>
679
774
  Anyone of:
680
- <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
681
- <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
682
- <a href="https://github.com/ged/bluecloth" title="bluecloth">BlueCloth</a>,
683
- <a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
684
- <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
775
+ <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">
776
+ RDiscount
777
+ </a>,
778
+ <a href="https://github.com/vmg/redcarpet" title="RedCarpet">
779
+ RedCarpet
780
+ </a>,
781
+ <a href="https://github.com/ged/bluecloth" title="bluecloth">
782
+ BlueCloth
783
+ </a>,
784
+ <a href="http://kramdown.gettalong.org/" title="kramdown">
785
+ kramdown
786
+ </a>,
787
+ <a href="https://github.com/bhollis/maruku" title="maruku">
788
+ maruku
789
+ </a>
685
790
  </td>
686
791
  </tr>
687
792
  <tr>
688
- <td>Extencao do Arquivos</td>
793
+ <td>Extensão do Arquivos</td>
689
794
  <td><tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt></td>
690
795
  </tr>
691
796
  <tr>
@@ -694,7 +799,8 @@ você quase sempre precisará passar o `locals` para ele.
694
799
  </tr>
695
800
  </table>
696
801
 
697
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
802
+ Não é possível chamar métodos por este template, nem passar *locals* para o
803
+ mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
698
804
 
699
805
  ```ruby
700
806
  erb :overview, :locals => { :text => markdown(:introducao) }
@@ -714,11 +820,11 @@ deve-se passar a `:layout_engine` como opção.
714
820
 
715
821
  <table>
716
822
  <tr>
717
- <td>Dependencia</td>
823
+ <td>Dependência</td>
718
824
  <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
719
825
  </tr>
720
826
  <tr>
721
- <td>Extencao do Arquivo</td>
827
+ <td>Extensão do Arquivo</td>
722
828
  <td><tt>.textile</tt></td>
723
829
  </tr>
724
830
  <tr>
@@ -727,7 +833,8 @@ deve-se passar a `:layout_engine` como opção.
727
833
  </tr>
728
834
  </table>
729
835
 
730
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
836
+ Não é possível chamar métodos por este template, nem passar *locals* para o
837
+ mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
731
838
 
732
839
  ```ruby
733
840
  erb :overview, :locals => { :text => textile(:introducao) }
@@ -749,11 +856,11 @@ deve-se passar a `:layout_engine` como opção.
749
856
 
750
857
  <table>
751
858
  <tr>
752
- <td>Dependencia</td>
859
+ <td>Dependência</td>
753
860
  <td><a href="http://rdoc.sourceforge.net/" title="RDoc">RDoc</a></td>
754
861
  </tr>
755
862
  <tr>
756
- <td>Extencao do Arquivo</td>
863
+ <td>Extensão do Arquivo</td>
757
864
  <td><tt>.rdoc</tt></td>
758
865
  </tr>
759
866
  <tr>
@@ -762,7 +869,8 @@ deve-se passar a `:layout_engine` como opção.
762
869
  </tr>
763
870
  </table>
764
871
 
765
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
872
+ Não é possível chamar métodos por este template, nem passar *locals* para o
873
+ mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
766
874
 
767
875
  ```ruby
768
876
  erb :overview, :locals => { :text => rdoc(:introducao) }
@@ -784,11 +892,13 @@ deve-se passar a `:layout_engine` como opção.
784
892
 
785
893
  <table>
786
894
  <tr>
787
- <td>Dependencia</td>
788
- <td><a href="http://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a></td>
895
+ <td>Dependência</td>
896
+ <td>
897
+ <a href="http://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a>
898
+ </td>
789
899
  </tr>
790
900
  <tr>
791
- <td>Extencao do Arquivo</td>
901
+ <td>Extensão do Arquivo</td>
792
902
  <td><tt>.asciidoc</tt>, <tt>.adoc</tt> and <tt>.ad</tt></td>
793
903
  </tr>
794
904
  <tr>
@@ -804,11 +914,11 @@ você quase sempre precisará passar o `locals` para ele.
804
914
 
805
915
  <table>
806
916
  <tr>
807
- <td>Dependencia</td>
917
+ <td>Dependência</td>
808
918
  <td><a href="https://github.com/jlong/radius" title="Radius">Radius</a></td>
809
919
  </tr>
810
920
  <tr>
811
- <td>Extencao do Arquivo</td>
921
+ <td>Extensão do Arquivo</td>
812
922
  <td><tt>.radius</tt></td>
813
923
  </tr>
814
924
  <tr>
@@ -824,11 +934,11 @@ você quase sempre precisará passar o `locals` para ele.
824
934
 
825
935
  <table>
826
936
  <tr>
827
- <td>Dependencia</td>
937
+ <td>Dependência</td>
828
938
  <td><a href="http://markaby.github.io/" title="Markaby">Markaby</a></td>
829
939
  </tr>
830
940
  <tr>
831
- <td>Extencao do Arquivo</td>
941
+ <td>Extensão do Arquivo</td>
832
942
  <td><tt>.mab</tt></td>
833
943
  </tr>
834
944
  <tr>
@@ -843,11 +953,11 @@ Este também recebe um bloco para templates (veja o exemplo).
843
953
 
844
954
  <table>
845
955
  <tr>
846
- <td>Dependencia</td>
956
+ <td>Dependência</td>
847
957
  <td><a href="https://github.com/nesquena/rabl" title="Rabl">Rabl</a></td>
848
958
  </tr>
849
959
  <tr>
850
- <td>Extencao do Arquivo</td>
960
+ <td>Extensão do Arquivo</td>
851
961
  <td><tt>.rabl</tt></td>
852
962
  </tr>
853
963
  <tr>
@@ -860,11 +970,11 @@ Este também recebe um bloco para templates (veja o exemplo).
860
970
 
861
971
  <table>
862
972
  <tr>
863
- <td>Dependencia</td>
973
+ <td>Dependência</td>
864
974
  <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
865
975
  </tr>
866
976
  <tr>
867
- <td>Extencao do Arquivo</td>
977
+ <td>Extensão do Arquivo</td>
868
978
  <td><tt>.slim</tt></td>
869
979
  </tr>
870
980
  <tr>
@@ -877,11 +987,11 @@ Este também recebe um bloco para templates (veja o exemplo).
877
987
 
878
988
  <table>
879
989
  <tr>
880
- <td>Dependencia</td>
990
+ <td>Dependência</td>
881
991
  <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
882
992
  </tr>
883
993
  <tr>
884
- <td>Extencao do Arquivo</td>
994
+ <td>Extensão do Arquivo</td>
885
995
  <td><tt>.creole</tt></td>
886
996
  </tr>
887
997
  <tr>
@@ -890,13 +1000,14 @@ Este também recebe um bloco para templates (veja o exemplo).
890
1000
  </tr>
891
1001
  </table>
892
1002
 
893
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
1003
+ Não é possível chamar métodos por este template, nem passar *locals* para o
1004
+ mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
894
1005
 
895
1006
  ```ruby
896
1007
  erb :overview, :locals => { :text => creole(:introduction) }
897
1008
  ```
898
1009
 
899
- Note que vcoê também pode chamar o método `creole` dentro de outros templates:
1010
+ Note que você também pode chamar o método `creole` dentro de outros templates:
900
1011
 
901
1012
  ```ruby
902
1013
  %h1 Olá do Haml!
@@ -912,11 +1023,15 @@ deve-se passar a `:layout_engine` como opção.
912
1023
 
913
1024
  <table>
914
1025
  <tr>
915
- <td>Dependencia</td>
916
- <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
1026
+ <td>Dependência</td>
1027
+ <td>
1028
+ <a href="https://github.com/nricciar/wikicloth" title="WikiCloth">
1029
+ WikiCloth
1030
+ </a>
1031
+ </td>
917
1032
  </tr>
918
1033
  <tr>
919
- <td>Extencao do Arquivo</td>
1034
+ <td>Extensão do Arquivo</td>
920
1035
  <td><tt>.mediawiki</tt> and <tt>.mw</tt></td>
921
1036
  </tr>
922
1037
  <tr>
@@ -949,7 +1064,7 @@ deve-se passar a `:layout_engine` como opção.
949
1064
 
950
1065
  <table>
951
1066
  <tr>
952
- <td>Dependencia</td>
1067
+ <td>Dependência</td>
953
1068
  <td>
954
1069
  <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
955
1070
  CoffeeScript
@@ -960,7 +1075,7 @@ deve-se passar a `:layout_engine` como opção.
960
1075
  </td>
961
1076
  </tr>
962
1077
  <tr>
963
- <td>Extencao do Arquivo</td>
1078
+ <td>Extensão do Arquivo</td>
964
1079
  <td><tt>.coffee</tt></td>
965
1080
  </tr>
966
1081
  <tr>
@@ -973,7 +1088,7 @@ deve-se passar a `:layout_engine` como opção.
973
1088
 
974
1089
  <table>
975
1090
  <tr>
976
- <td>Dependencia</td>
1091
+ <td>Dependência</td>
977
1092
  <td>
978
1093
  <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
979
1094
  Stylus
@@ -984,7 +1099,7 @@ deve-se passar a `:layout_engine` como opção.
984
1099
  </td>
985
1100
  </tr>
986
1101
  <tr>
987
- <td>Extencao do Arquivo</td>
1102
+ <td>Extensão do Arquivo</td>
988
1103
  <td><tt>.styl</tt></td>
989
1104
  </tr>
990
1105
  <tr>
@@ -993,7 +1108,8 @@ deve-se passar a `:layout_engine` como opção.
993
1108
  </tr>
994
1109
  </table>
995
1110
 
996
- Antes que vcoê possa utilizar o template Stylus primeiro você deve carregar `stylus` e `stylus/tilt`:
1111
+ Antes que vcoê possa utilizar o template Stylus primeiro você deve carregar
1112
+ `stylus` e `stylus/tilt`:
997
1113
 
998
1114
  ```ruby
999
1115
  require 'sinatra'
@@ -1009,11 +1125,15 @@ end
1009
1125
 
1010
1126
  <table>
1011
1127
  <tr>
1012
- <td>Dependencia</td>
1013
- <td><a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a></td>
1128
+ <td>Dependência</td>
1129
+ <td>
1130
+ <a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">
1131
+ yajl-ruby
1132
+ </a>
1133
+ </td>
1014
1134
  </tr>
1015
1135
  <tr>
1016
- <td>Extencao do Arquivo</td>
1136
+ <td>Extensão do Arquivo</td>
1017
1137
  <td><tt>.yajl</tt></td>
1018
1138
  </tr>
1019
1139
  <tr>
@@ -1029,14 +1149,16 @@ end
1029
1149
  </tr>
1030
1150
  </table>
1031
1151
 
1032
- O código-fonte do template é executado como uma string Ruby e a variável resultante em json é convertida utilizando `#to_json`:
1152
+ O código-fonte do template é executado como uma string Ruby e a variável
1153
+ resultante em json é convertida utilizando `#to_json`:
1033
1154
 
1034
1155
  ```ruby
1035
1156
  json = { :foo => 'bar' }
1036
1157
  json[:baz] = key
1037
1158
  ```
1038
1159
 
1039
- O `:callback` e `:variable` são opções que podem ser utilizadas para o objeto de renderização:
1160
+ O `:callback` e `:variable` são opções que podem ser utilizadas para o objeto
1161
+ de renderização:
1040
1162
 
1041
1163
  ```javascript
1042
1164
  var resource = {"foo":"bar","baz":"qux"};
@@ -1047,11 +1169,13 @@ present(resource);
1047
1169
 
1048
1170
  <table>
1049
1171
  <tr>
1050
- <td>Dependencia</td>
1051
- <td><a href="https://github.com/blambeau/wlang/" title="WLang">WLang</a></td>
1172
+ <td>Dependência</td>
1173
+ <td>
1174
+ <a href="https://github.com/blambeau/wlang/" title="WLang">WLang</a>
1175
+ </td>
1052
1176
  </tr>
1053
1177
  <tr>
1054
- <td>Extencao do Arquivo</td>
1178
+ <td>Extensão do Arquivo</td>
1055
1179
  <td><tt>.wlang</tt></td>
1056
1180
  </tr>
1057
1181
  <tr>
@@ -1067,7 +1191,7 @@ você quase sempre precisará passar o `locals` para ele.
1067
1191
  ## Acessando Variáveis nos Templates
1068
1192
 
1069
1193
  Templates são avaliados dentro do mesmo contexto como manipuladores de
1070
- rota. Variáveis de instância setadas em rotas manipuladas são
1194
+ rota. Variáveis de instância definidas em manipuladores de rota são
1071
1195
  diretamente acessadas por templates:
1072
1196
 
1073
1197
  ```ruby
@@ -1077,7 +1201,7 @@ get '/:id' do
1077
1201
  end
1078
1202
  ```
1079
1203
 
1080
- Ou, especifique um hash explícito para variáveis locais:
1204
+ Ou, especifique um hash explícito de variáveis locais:
1081
1205
 
1082
1206
  ```ruby
1083
1207
  get '/:id' do
@@ -1091,8 +1215,9 @@ partials dentro de outros templates.
1091
1215
 
1092
1216
  ### Templates com `yield` e layouts aninhados
1093
1217
 
1094
- O layout geralmente é apenas um template que executa `yield`.
1095
- Tal template pode ser utilizado pela opção `:template` descrita acima ou pode ser renderizado através de um bloco, como a seguir:
1218
+ Um layout geralmente é apenas um template que executa `yield`.
1219
+ Tal template pode ser utilizado pela opção `:template` descrita acima ou pode
1220
+ ser renderizado através de um bloco, como a seguir:
1096
1221
 
1097
1222
  ```ruby
1098
1223
  erb :post, :layout => false do
@@ -1102,7 +1227,8 @@ end
1102
1227
 
1103
1228
  Este código é quase equivalente a `erb :index, :layout => :post`
1104
1229
 
1105
- Passando blocos para os métodos de renderização é útil para criar layouts aninhados:
1230
+ Passando blocos para os métodos de renderização é útil para criar layouts
1231
+ aninhados:
1106
1232
 
1107
1233
  ```ruby
1108
1234
  erb :main_layout, :layout => false do
@@ -1121,11 +1247,11 @@ end
1121
1247
  ```
1122
1248
 
1123
1249
  Atualmente os métodos listados aceitam blocos: `erb`, `haml`,
1124
- `liquid`, `slim `, `wlang`. E também o método `render`.
1250
+ `liquid`, `slim `, `wlang`. E o método geral `render` também aceita blocos.
1125
1251
 
1126
1252
  ### Templates Inline
1127
1253
 
1128
- Templates podem ser definidos no final do arquivo fonte(.rb):
1254
+ Templates podem ser definidos no final do arquivo fonte:
1129
1255
 
1130
1256
  ```ruby
1131
1257
  require 'sinatra'
@@ -1145,10 +1271,10 @@ __END__
1145
1271
  ```
1146
1272
 
1147
1273
  NOTA: Templates inline definidos no arquivo fonte são automaticamente
1148
- carregados pelo sinatra. Digite \`enable :inline\_templates\` se você
1149
- tem templates inline no outro arquivo fonte.
1274
+ carregados pelo Sinatra. Digite `enable :inline_templates` explicitamente se
1275
+ você tem templates inline em outros arquivos fonte.
1150
1276
 
1151
- ### Templates nomeados
1277
+ ### Templates Nomeados
1152
1278
 
1153
1279
  Templates também podem ser definidos utilizando o método top-level
1154
1280
  `template`:
@@ -1169,7 +1295,8 @@ end
1169
1295
 
1170
1296
  Se existir um template com nome “layout”, ele será utilizado toda vez
1171
1297
  que um template for renderizado. Você pode desabilitar layouts passando
1172
- `:layout => false`.
1298
+ `:layout => false` ou desabilita-los por padrão
1299
+ via `set :haml, :layout => false`
1173
1300
 
1174
1301
  ```ruby
1175
1302
  get '/' do
@@ -1177,9 +1304,11 @@ get '/' do
1177
1304
  end
1178
1305
  ```
1179
1306
 
1180
- ### Associando extensões de arquivos
1307
+ ### Associando Extensões de Arquivos
1181
1308
 
1182
- Para associar uma extensão de arquivo com um engine de template use o método `Tilt.register`. Por exemplo, se você quiser usar a extensão `tt` para os templates Textile você pode fazer o seguinte:
1309
+ Para associar uma extensão de arquivo com um engine de template use o método
1310
+ `Tilt.register`. Por exemplo, se você quiser usar a extensão `tt` para os
1311
+ templates Textile você pode fazer o seguinte:
1183
1312
 
1184
1313
  ```ruby
1185
1314
  Tilt.register :tt, Tilt[:textile]
@@ -1187,7 +1316,8 @@ Tilt.register :tt, Tilt[:textile]
1187
1316
 
1188
1317
  ### Adicionando seu Próprio Engine de Template
1189
1318
 
1190
- Primeiro registre seu engine utilizando o Tilt, e então crie um método de renderização:
1319
+ Primeiro registre seu engine utilizando o Tilt, e então crie um método de
1320
+ renderização:
1191
1321
 
1192
1322
  ```ruby
1193
1323
  Tilt.register :myat, MyAwesomeTemplateEngine
@@ -1201,12 +1331,13 @@ get '/' do
1201
1331
  end
1202
1332
  ```
1203
1333
 
1204
- Renderize `./views/index.myat`. Veja
1205
- https://github.com/rtomayko/tilt para saber mais sobre Tilt.
1334
+ Renderize `./views/index.myat`. Aprenda mais sobre o
1335
+ Tilt [aqui](https://github.com/rtomayko/tilt#readme).
1206
1336
 
1207
- ### Customizando lógica para encontrar templates
1337
+ ### Customizando Lógica para Encontrar Templates
1208
1338
 
1209
- Para implementar sua própria lógica para busca de templates você pode escrever seu próprio método `#find_template`
1339
+ Para implementar sua própria lógica para busca de templates você pode escrever
1340
+ seu próprio método `#find_template`
1210
1341
 
1211
1342
  ```ruby
1212
1343
  configure do
@@ -1224,7 +1355,7 @@ end
1224
1355
 
1225
1356
  Filtros Before são avaliados antes de cada requisição dentro do contexto
1226
1357
  da requisição e podem modificar a requisição e a reposta. Variáveis de
1227
- instância setadas nos filtros são acessadas através de rotas e
1358
+ instância definidas nos filtros são acessadas através de rotas e
1228
1359
  templates:
1229
1360
 
1230
1361
  ```ruby
@@ -1239,9 +1370,9 @@ get '/foo/*' do
1239
1370
  end
1240
1371
  ```
1241
1372
 
1242
- Filtros After são avaliados após cada requisição dentro do contexto da
1373
+ Filtros After são avaliados após cada requisição dentro do mesmo contexto da
1243
1374
  requisição e também podem modificar a requisição e a resposta. Variáveis de
1244
- instância e rotas definidas nos filtros before são acessadas através dos
1375
+ instância definidas nos filtros before e rotas são acessadas através dos
1245
1376
  filtros after:
1246
1377
 
1247
1378
  ```ruby
@@ -1250,6 +1381,10 @@ after do
1250
1381
  end
1251
1382
  ```
1252
1383
 
1384
+ Nota: A não ser que você use o metódo `body` ao invés de apenas retornar uma
1385
+ String das rotas, o corpo ainda não estará disponível no filtro after, uma vez
1386
+ que é gerado depois.
1387
+
1253
1388
  Filtros opcionalmente têm um padrão, fazendo com que sejam avaliados
1254
1389
  somente se o caminho do pedido coincidir com esse padrão:
1255
1390
 
@@ -1263,6 +1398,18 @@ after '/create/:slug' do |slug|
1263
1398
  end
1264
1399
  ```
1265
1400
 
1401
+ Como rotas, filtros também aceitam condições:
1402
+
1403
+ ```ruby
1404
+ before :agent => /Songbird/ do
1405
+ #...
1406
+ end
1407
+
1408
+ after '/blog/*', :host_name => 'exemplo.com' do
1409
+ #...
1410
+ end
1411
+ ```
1412
+
1266
1413
  ## Helpers
1267
1414
 
1268
1415
  Use o método de alto nível `helpers` para definir métodos auxiliares
@@ -1280,9 +1427,27 @@ get '/:nome' do
1280
1427
  end
1281
1428
  ```
1282
1429
 
1430
+ Alternativamente, métodos auxiliares podem ser definidos separadamente em
1431
+ módulos:
1432
+
1433
+ ```ruby
1434
+ module FooUtils
1435
+ def foo(nome) "#{nome}foo" end
1436
+ end
1437
+
1438
+ module BarUtils
1439
+ def bar(nome) "#{nome}bar" end
1440
+ end
1441
+
1442
+ helpers FooUtils, BarUtils
1443
+ ```
1444
+
1445
+ O efeito é o mesmo que incluir os módulos na classe da aplicação.
1446
+
1283
1447
  ### Utilizando Sessões
1284
1448
 
1285
- Sessões são usadas para manter um estado durante uma requisição. Se ativa, você terá disponível um hash de sessão para cada sessão de usuário:
1449
+ Uma sessão é usada para manter o estado durante requisições. Se ativada, você
1450
+ terá disponível um hash de sessão para cada sessão de usuário:
1286
1451
 
1287
1452
  ```ruby
1288
1453
  enable :sessions
@@ -1295,40 +1460,134 @@ get '/:value' do
1295
1460
  session['value'] = params['value']
1296
1461
  end
1297
1462
  ```
1463
+ #### Segredo Seguro da Sessão
1298
1464
 
1299
- Note que `enable :sessions` utilizará um cookie para guardar todos os dados da sessão. Isso nem sempre pode ser o que você quer (guardar muitos dados irá aumentar o seu tráfego, por exemplo). Você pode utilizar qualquer Rack middleware de sessão: para fazer isso **não** utilize o método `enable :sessions`, ao invés disso utilize seu middleware de sessão como utilizaria qualquer outro:
1465
+ Para melhorar a segurança, os dados da sessão no cookie são assinado com uma
1466
+ segredo de sessão usando `HMAC-SHA1`. Esse segredo de sessão deve ser, de
1467
+ preferência, um valor criptograficamente randômico, seguro, de um comprimento
1468
+ apropriado no qual `HMAC-SHA1` é maior ou igual a 64 bytes (512 bits, 128
1469
+ carecteres hexadecimais). Você será avisado para não usar uma chave secreta
1470
+ menor que 32 bytes de randomicidade (256 bits, 64 caracteres hexadecimais).
1471
+ Portanto, é **muito importante** que você não invente o segredo, mas use um
1472
+ gerador de números aleatórios seguro para cria-lo. Humanos são extremamente
1473
+ ruins em gerar números aleatórios.
1300
1474
 
1301
- ```ruby
1302
- use Rack::Session::Pool, :expire_after => 2592000
1475
+ Por padrão, um segredo de sessão aleatório seguro de 32 bytes é gerada para
1476
+ você pelo Sinatra, mas ele mudará toda vez que você reiniciar sua aplicação. Se
1477
+ você tiver múltiplas instâncias da sua aplicação e você deixar que o Sinatra
1478
+ gere a chave, cada instância teria uma chave de sessão diferente, o que
1479
+ certamente não é o que você quer.
1303
1480
 
1304
- get '/' do
1305
- "value = " << session[:value].inspect
1306
- end
1481
+ Para melhor segurança e usabilidade é
1482
+ [recomendado](https://12factor.net/config) que você gere um segredo randômico
1483
+ secreto e salve-o em uma variável de ambiente em cada host rodando sua
1484
+ aplicação, assim todas as instâncias da sua aplicação irão compartilhar o mesmo
1485
+ segredo. Você deve, periodicamente, mudar esse segredo de sessão para um novo
1486
+ valor. Abaixo, são mostrados alguns exemplos de como você pode criar um segredo
1487
+ de 64 bytes e usa-lo:
1307
1488
 
1308
- get '/:value' do
1309
- session['value'] = params['value']
1310
- end
1489
+ **Gerando Segredo de Sessão**
1490
+
1491
+ ```text
1492
+ $ ruby -e "require 'securerandom'; puts SecureRandom.hex(64)"
1493
+ 99ae8af...snip...ec0f262ac
1494
+ ```
1495
+
1496
+ **Gerando Segredo de Sessão (Pontos adicionais)**
1497
+
1498
+ Use preferencialmente a
1499
+ [gem sysrandom](https://github.com/cryptosphere/sysrandom#readme) para utilizar
1500
+ as facilidades do sistema RNG para gerar valores aleatórios ao invés
1501
+ do `OpenSSL` no qual o MRI Ruby padroniza para:
1502
+
1503
+ ```text
1504
+ $ gem install sysrandom
1505
+ Building native extensions. This could take a while...
1506
+ Sucessfully installed sysrandom-1.x
1507
+ 1 gem installed
1508
+
1509
+ $ ruby -e "require 'sysrandom/securerandom'; puts SecureRandom.hex(64)"
1510
+ 99ae8af...snip...ec0f262ac
1511
+ ```
1512
+
1513
+ **Segredo de Sessão numa Variável de Ambiente**
1514
+
1515
+ Defina uma variável de ambiente `SESSION_SECRET` para o Sinatra com o valor que
1516
+ você gerou. Salve esse valor entre as reinicializações do seu host. Já que a
1517
+ forma de fazer isso irá variar entre os sistemas operacionais, o exemplo abaixo
1518
+ serve apenas para fins ilustrativos:
1519
+
1520
+ ```bash
1521
+ # echo "export SESSION_SECRET = 99ae8af...snip...ec0f262ac" >> ~/.bashrc
1311
1522
  ```
1312
1523
 
1313
- Para melhorar a segurança, os dados da sessão guardados no cookie é assinado com uma chave secreta da sessão. Uma chave aleatória é gerada para você pelo Sinatra. Contudo, já que a chave mudará cada vez que você inicia sua aplicação, você talvez queira defini-la você mesmo para que todas as instâncias da aplicação compartilhe-a:
1524
+ **Configurando o Segredo de Sessão na Aplicação**
1525
+
1526
+ Configure sua aplicação para uma falha de segredo seguro aleatório se a
1527
+ variável de ambiente `SESSION_SECRET` não estiver disponível.
1528
+
1529
+ Como ponto adicional use a
1530
+ [gem sysrandom](https://github.com/cryptosphere/sysrandom#readme) da seguinte
1531
+ forma:
1314
1532
 
1315
1533
  ```ruby
1316
- set :session_secret, 'super secret'
1534
+ require 'securerandom'
1535
+ # -or- require 'sysrandom/securearandom'
1536
+ set :session_secret, ENV.fecth(`SESSION_SECRET`) { SecureRandom.hex(64) }
1317
1537
  ```
1318
1538
 
1319
- Se você quiser fazer outras configurações, você também pode guardar um hash com as opções nas configurações da `session`:
1539
+ #### Configuração de Sessão
1540
+
1541
+ Se você deseja configurar isso adicionalmente, você pode salvar um hash com
1542
+ opções na definição de `sessions`:
1320
1543
 
1321
1544
  ```ruby
1322
1545
  set :sessions, :domain => 'foo.com'
1323
1546
  ```
1324
1547
 
1325
- Para compartilhar sua sessão entre outros aplicativos em um subdomínio de foo.com, utilize o prefixo *.*:
1548
+ Para compartilhar sua sessão com outras aplicações no subdomínio de foo.com,
1549
+ adicione um *.* antes do domínio como no exemplo abaixo:
1326
1550
 
1327
1551
  ```ruby
1328
1552
  set :sessions, :domain => '.foo.com'
1329
1553
  ```
1330
1554
 
1331
- ### Halting
1555
+ #### Escolhendo Seu Próprio Middleware de Sessão
1556
+
1557
+ Perceba que `enable :sessions` na verdade guarda todos seus dados num cookie.
1558
+ Isto pode não ser o que você deseja sempre (armazenar muitos dados irá aumentar
1559
+ seu tráfego, por exemplo). Você pode usar qualquer middleware de sessão Rack
1560
+ para fazer isso, um dos seguintes métodos pode ser usado:
1561
+
1562
+ ```ruby
1563
+ enable :sessions
1564
+ set :session_store, Rack::Session::Pool
1565
+ ```
1566
+
1567
+ Ou definir as sessões com um hash de opções:
1568
+
1569
+ ```ruby
1570
+ set :sessions, :expire_after => 2592000
1571
+ set :session_store, Rack::Session::Pool
1572
+ ```
1573
+
1574
+ Outra opção é **não** usar `enable :sessions`, mas ao invés disso trazer seu
1575
+ middleware escolhido como você faria com qualquer outro middleware.
1576
+
1577
+ É importante lembrar que usando esse método, a proteção baseada na sessão
1578
+ **não estará habilitada por padrão**.
1579
+
1580
+ Para o middleware Rack fazer isso, será preciso que isso também seja adicionado:
1581
+
1582
+ ```ruby
1583
+ use Rack::Session::Pool, :expire_after => 2592000
1584
+ use Rack::Protection::RemoteToken
1585
+ use Rack::Protection::SessionHijacking
1586
+ ```
1587
+ Veja '[Configurando proteção a ataques](#configurando-proteção-a-ataques)' para
1588
+ mais informações.
1589
+
1590
+ ### Parando
1332
1591
 
1333
1592
  Para parar imediatamente uma requisição com um filtro ou rota utilize:
1334
1593
 
@@ -1336,31 +1595,31 @@ Para parar imediatamente uma requisição com um filtro ou rota utilize:
1336
1595
  halt
1337
1596
  ```
1338
1597
 
1339
- Você também pode especificar o status quando parar
1598
+ Você também pode especificar o status quando parar:
1340
1599
 
1341
1600
  ```ruby
1342
1601
  halt 410
1343
1602
  ```
1344
1603
 
1345
- Ou com corpo de texto…
1604
+ Ou o corpo:
1346
1605
 
1347
1606
  ```ruby
1348
- halt 'isso será o corpo do texto'
1607
+ halt 'isso será o corpo'
1349
1608
  ```
1350
1609
 
1351
- Ou também…
1610
+ Ou ambos:
1352
1611
 
1353
1612
  ```ruby
1354
- halt 401, 'vamos embora!'
1613
+ halt 401, ' embora!'
1355
1614
  ```
1356
1615
 
1357
- Com cabeçalhos
1616
+ Com cabeçalhos:
1358
1617
 
1359
1618
  ```ruby
1360
1619
  halt 402, {'Content-Type' => 'text/plain'}, 'revanche'
1361
1620
  ```
1362
1621
 
1363
- É obviamente possivel combinar um template com o `halt`:
1622
+ Também é obviamente possível combinar um template com o `halt`:
1364
1623
 
1365
1624
  ```ruby
1366
1625
  halt erb(:error)
@@ -1383,12 +1642,14 @@ end
1383
1642
  ```
1384
1643
 
1385
1644
  O bloqueio da rota é imediatamente encerrado e o controle continua com a
1386
- próxima rota de parâmetro. Se o parâmetro da rota não for encontrado, um
1645
+ próxima rota compatível. Se nenhuma rota compatível for encontrada, um
1387
1646
  404 é retornado.
1388
1647
 
1389
1648
  ### Desencadeando Outra Rota
1390
1649
 
1391
- As vezes o `pass` não é o que você quer, ao invés dele talvez você queira obter o resultado chamando outra rota. Utilize o método `call` neste caso:
1650
+ As vezes o `pass` não é o que você quer, ao invés dele talvez você queira obter
1651
+ o resultado chamando outra rota. Simplesmente utilize o método `call` neste
1652
+ caso:
1392
1653
 
1393
1654
  ```ruby
1394
1655
  get '/foo' do
@@ -1401,271 +1662,1963 @@ get '/bar' do
1401
1662
  end
1402
1663
  ```
1403
1664
 
1404
- Note que no exemplo acima você ganharia performance ao simplemente mover o `"bar"` em um helper usado por ambos `/foo` e `/bar`.
1665
+ Note que no exemplo acima você ganharia performance e facilitaria os testes ao
1666
+ simplesmente mover `"bar"` para um método auxiliar usado por ambos `/foo`
1667
+ e `/bar`.
1405
1668
 
1406
- Se você quer que a requisição seja enviada para a mesma instancia da aplicação ao invês de uma duplicada, use `call!` no lugar de `call`.
1669
+ Se você quer que a requisição seja enviada para a mesma instância da aplicação
1670
+ no lugar de uma duplicada, use `call!` no lugar de `call`.
1407
1671
 
1408
1672
  Veja a especificação do Rack se você quer aprender mais sobre o `call`.
1409
1673
 
1410
- ## Configuração
1674
+ ### Definindo Corpo, Código de Status e Cabeçalhos
1411
1675
 
1412
- Rodando uma vez, na inicialização, em qualquer ambiente:
1676
+ É possível e recomendado definir o código de status e o corpo da resposta com o
1677
+ valor retornado do bloco da rota. Entretanto, em alguns cenários você pode
1678
+ querer definir o corpo em um ponto arbitrário do fluxo de execução. Você pode
1679
+ fazer isso com o metódo auxiliar `body`. Se você fizer isso, poderá usar esse
1680
+ metódo de agora em diante para acessar o body:
1413
1681
 
1414
1682
  ```ruby
1415
- configure do
1416
- ...
1683
+ get '/foo' do
1684
+ body "bar"
1685
+ end
1686
+
1687
+ after do
1688
+ puts body
1417
1689
  end
1418
1690
  ```
1419
1691
 
1420
- Rodando somente quando o ambiente (`APP_ENV` environment variável) é
1421
- setado para `:production`:
1692
+ Também é possivel passar um bloco para `body`, que será executado pelo
1693
+ manipulador Rack (isso pode ser usado para implementar transmissão,
1694
+ [veja "Retorno de Valores"](#retorno-de-valores)).
1695
+
1696
+ Similar ao corpo, você pode também definir o código de status e cabeçalhos:
1422
1697
 
1423
1698
  ```ruby
1424
- configure :production do
1425
- ...
1699
+ get '/foo' do
1700
+ status 418
1701
+ headers \
1702
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN"
1703
+ "Refresh" => "Refresh: 20; https://ietf.org/rfc/rfc2324.txt"
1704
+ body "Eu sou um bule de chá!"
1426
1705
  end
1427
1706
  ```
1428
1707
 
1429
- Rodando quando o ambiente é setado para `:production` ou `:test`:
1708
+ Assim como `body`, `headers` e `status` sem argumentos podem ser usados para
1709
+ acessar seus valores atuais.
1710
+
1711
+ ### Transmitindo Respostas
1712
+
1713
+ As vezes você quer começar a mandar dados enquanto está gerando partes do corpo
1714
+ da resposta. Em exemplos extremos, você quer continuar enviando dados até o
1715
+ cliente encerrar a conexão. Você pode usar o método auxiliar `stream` para
1716
+ evitar criar seu próprio empacotador:
1430
1717
 
1431
1718
  ```ruby
1432
- configure :production, :test do
1433
- ...
1719
+ get '/' do
1720
+ stream do |out|
1721
+ out << "Isso será len -\n"
1722
+ sleep 0.5
1723
+ out << " Aguarde \n"
1724
+ sleep 1
1725
+ out << " dário!\n"
1726
+ end
1434
1727
  end
1435
1728
  ```
1436
1729
 
1437
- ## Tratamento de Erros
1438
-
1439
- Tratamento de erros rodam dentro do mesmo contexto como rotas e filtros
1440
- before, o que significa que você pega todos os presentes que tem para
1441
- oferecer, como `haml`, `erb`, `halt`, etc.
1730
+ Isso permite você implementar APIs de Transmissão,
1731
+ [Eventos Enviados pelo Servidor](https://w3c.github.io/eventsource/), e pode
1732
+ ser usado como a base para
1733
+ [WebSockets](https://en.wikipedia.org/wiki/WebSocket). Pode ser usado também
1734
+ para aumentar a taxa de transferência se algum, mas não todo, conteúdo depender
1735
+ de um recurso lento.
1442
1736
 
1443
- ### Não Encontrado
1737
+ Perceba que o comportamento da transmissão, especialmente o número de
1738
+ requisições concorrentes, depende altamente do servidor web usado para servir a
1739
+ aplicação. Alguns servidores podem até mesmo não suportar transmissão de
1740
+ maneira alguma. Se o servidor não suportar transmissão, o corpo será enviado
1741
+ completamente após que o bloco passado para `stream` terminar de executar.
1742
+ Transmissão não funciona de nenhuma maneira com Shotun.
1444
1743
 
1445
- Quando um `Sinatra::NotFound` exception é levantado, ou o código de
1446
- status da reposta é 404, o manipulador `not_found` é invocado:
1744
+ Se o parâmetro opcional é definido como `keep_open`, ele não chamará `close` no
1745
+ objeto transmitido, permitindo você a fecha-lo em algum outro ponto futuro no
1746
+ fluxo de execução. Isso funciona apenas em servidores orientados a eventos,
1747
+ como Thin e Rainbows. Outros servidores irão continuar fechando a transmissão:
1447
1748
 
1448
1749
  ```ruby
1449
- not_found do
1450
- 'Isto está longe de ser encontrado'
1750
+ # long polling
1751
+
1752
+ set :server, :thin
1753
+ conexoes = []
1754
+
1755
+ get '/assinar' do
1756
+ # registra o interesse de um cliente em servidores de eventos
1757
+ stream(:keep_open) do |saida|
1758
+ conexoes << saida
1759
+ # retire conexões mortas
1760
+ conexoes.reject!(&:closed?)
1761
+ end
1451
1762
  end
1452
- ```
1453
1763
 
1454
- ### Erro
1764
+ post '/:messagem' do
1765
+ conexoes.each do |saida|
1766
+ # notifica o cliente que uma nova mensagem chegou
1767
+ saida << params['messagem'] << "\n"
1455
1768
 
1456
- O manipulador `error` é invocado toda a vez que uma exceção é lançada a
1457
- partir de um bloco de rota ou um filtro. O objeto da exceção pode ser
1458
- obtido a partir da variável Rack `sinatra.error`:
1769
+ # indica ao cliente para se conectar novamente
1770
+ saida.close
1771
+ end
1459
1772
 
1460
- ```ruby
1461
- error do
1462
- 'Desculpe, houve um erro desagradável - ' + env['sinatra.error'].message
1773
+ # confirma
1774
+ "messagem recebida"
1463
1775
  end
1464
1776
  ```
1465
1777
 
1466
- Erros customizados:
1778
+ Também é possivel para o cliente fechar a conexão quando está tentando escrever
1779
+ para o socket. Devido a isso, é recomendado checar `out.closed?` antes de
1780
+ tentar escrever.
1781
+
1782
+ ### Usando Logs
1783
+
1784
+ No escopo da requisição, o método auxiliar `logger` expõe uma instância
1785
+ `Logger`:
1467
1786
 
1468
1787
  ```ruby
1469
- error MeuErroCustomizado do
1470
- 'Então que aconteceu foi...' + env['sinatra.error'].message
1788
+ get '/' do
1789
+ logger.info "loading data"
1790
+ # ...
1471
1791
  end
1472
1792
  ```
1473
1793
 
1474
- Então, se isso acontecer:
1794
+ Esse logger irá automaticamente botar as configurações de log do manipulador
1795
+ Rack na sua conta. Se a produção de logs estiver desabilitads, esse método
1796
+ retornará um objeto dummy, então você não terá que se preocupar com suas rotas
1797
+ e filtros.
1798
+
1799
+ Perceba que a produção de logs está habilitada apenas para
1800
+ `Sinatra::Application` por padrão, então se você herdar de `Sinatra::Base`,
1801
+ você provavelmente irá querer habilitar:
1475
1802
 
1476
1803
  ```ruby
1477
- get '/' do
1478
- raise MeuErroCustomizado, 'alguma coisa ruim'
1479
- end
1804
+ class MyApp < Sinatra::Base
1805
+ configure :production, :development do
1806
+ enable :logging
1807
+ end
1808
+ end
1480
1809
  ```
1481
1810
 
1482
- Você receberá isso:
1811
+ Para evitar que qualquer middleware de logs seja configurado, defina a
1812
+ configuração `logging` como `nil`. Entretanto, tenha em mente que `logger`
1813
+ retornará, nesse caso, `nil`. Um caso de uso comum é quando você quer definir
1814
+ seu próprio logger. Sinatra irá usar qualquer um que ele achar
1815
+ em `env['rack.logger']`
1483
1816
 
1484
- Então que aconteceu foi... alguma coisa ruim
1817
+ ### Tipos Mime
1485
1818
 
1486
- Alternativamente, você pode instalar manipulador de erro para um código
1487
- de status:
1819
+ Quando se está usando `send_file` ou arquivos estáticos, você pode ter tipos
1820
+ mime que o Sinatra não entende. Use `mime_type` para registrá-los pela extensão
1821
+ do arquivo:
1488
1822
 
1489
1823
  ```ruby
1490
- error 403 do
1491
- 'Accesso negado'
1492
- end
1493
-
1494
- get '/secreto' do
1495
- 403
1824
+ configure do
1825
+ mime_type :foo, 'text/foo'
1496
1826
  end
1497
1827
  ```
1498
1828
 
1499
- Ou um range:
1829
+ Você pode utilizar também com o método auxiliar `content_type`:
1500
1830
 
1501
1831
  ```ruby
1502
- error 400..510 do
1503
- 'Boom'
1832
+ get '/' do
1833
+ content-type :foo
1834
+ "foo foo foo"
1504
1835
  end
1505
1836
  ```
1506
1837
 
1507
- O Sinatra instala os manipuladores especiais `not_found` e `error`
1508
- quando roda sobre o ambiente de desenvolvimento.
1509
-
1510
- ## Mime Types
1838
+ ### Gerando URLs
1511
1839
 
1512
- Quando utilizamos `send_file` ou arquivos estáticos você pode ter mime
1513
- types Sinatra não entendidos. Use `mime_type` para registrar eles por
1514
- extensão de arquivos:
1840
+ Para gerar URLs você deve usar o metódo auxiliar `url` no Haml:
1515
1841
 
1516
1842
  ```ruby
1517
- mime_type :foo, 'text/foo'
1843
+ %a{:href => url('/foo')} foo
1518
1844
  ```
1519
1845
 
1520
- Você também pode utilizar isto com o helper `content_type`:
1521
-
1522
- ```ruby
1523
- content_type :foo
1524
- ```
1846
+ Isso inclui proxies reversos e rotas Rack, se presentes.
1525
1847
 
1526
- ## Rack Middleware
1848
+ Esse método é também apelidado para `to` (veja
1849
+ [abaixo](#redirecionamento-do-browser) para um exemplo).
1527
1850
 
1528
- O Sinatra roda no [Rack](http://rack.github.io/), uma interface
1529
- padrão mínima para frameworks web em Ruby. Um das capacidades mais
1530
- interessantes do Rack para desenvolver aplicativos é suporte a
1531
- “middleware” – componentes que ficam entre o servidor e sua aplicação
1532
- monitorando e/ou manipulando o request/response do HTTP para prover
1533
- vários tipos de funcionalidades comuns.
1851
+ ### Redirecionamento do Browser
1534
1852
 
1535
- O Sinatra faz construtores pipelines do middleware Rack facilmente em um
1536
- nível superior utilizando o método `use`:
1853
+ Você pode lançar um redirecionamento no browser com o metódo auxiliar
1854
+ `redirect`:
1537
1855
 
1538
1856
  ```ruby
1539
- require 'sinatra'
1540
- require 'meu_middleware_customizado'
1857
+ get '/foo' do
1858
+ redirect to('/bar')
1859
+ end
1860
+ ```
1541
1861
 
1542
- use Rack::Lint
1543
- use MeuMiddlewareCustomizado
1862
+ Quaisquer paramêtros adicionais são interpretados como argumentos passados
1863
+ ao `halt`:
1544
1864
 
1545
- get '/ola' do
1546
- 'Olá mundo'
1547
- end
1865
+ ```ruby
1866
+ redirect to('/bar'), 303
1867
+ redirect 'http://www.google.com/', 'lugar errado, amigo'
1548
1868
  ```
1549
1869
 
1550
- A semântica de `use` é idêntica aquela definida para a DSL
1551
- [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)
1552
- (mais frequentemente utilizada para arquivos rackup). Por exemplo, o
1553
- método `use` aceita múltiplos argumentos/variáveis bem como blocos:
1870
+ Você pode também facilmente redirecionar para a página da qual o usuário veio
1871
+ com `redirect back`:
1554
1872
 
1555
1873
  ```ruby
1556
- use Rack::Auth::Basic do |usuario, senha|
1557
- usuario == 'admin' && senha == 'secreto'
1874
+ get '/foo' do
1875
+ "<a href='/bar'>do something</a>"
1876
+ end
1877
+
1878
+ get '/bar' do
1879
+ do_something
1880
+ redirect back
1558
1881
  end
1559
1882
  ```
1560
1883
 
1561
- O Rack é distribuido com uma variedade de middleware padrões para logs,
1562
- debugs, rotas de URL, autenticação, e manipuladores de sessão. Sinatra
1563
- utilizada muitos desses componentes automaticamente baseando sobre
1564
- configuração, então, tipicamente você não tem `use` explicitamente.
1884
+ Para passar argumentos com um redirecionamento, adicione-os a query:
1565
1885
 
1566
- ## Testando
1886
+ ```ruby
1887
+ redirect to('/bar?sum=42')
1888
+ ```
1567
1889
 
1568
- Testes no Sinatra podem ser escritos utilizando qualquer biblioteca ou
1569
- framework de teste baseados no Rack.
1570
- [Rack::Test](http://gitrdoc.com/brynary/rack-test) é recomendado:
1890
+ Ou use uma sessão:
1571
1891
 
1572
1892
  ```ruby
1573
- require 'minha_aplicacao_sinatra'
1574
- require 'rack/test'
1893
+ enable :sessions
1575
1894
 
1576
- class MinhaAplicacaoTeste < Minitest::Test
1577
- include Rack::Test::Methods
1895
+ get '/foo' do
1896
+ session[:secret] = 'foo'
1897
+ redirect to('/bar')
1898
+ end
1578
1899
 
1579
- def app
1580
- Sinatra::Application
1581
- end
1900
+ get '/bar' do
1901
+ session[:secret]
1902
+ end
1903
+ ```
1582
1904
 
1583
- def meu_test_default
1584
- get '/'
1585
- assert_equal 'Ola Mundo!', last_response.body
1586
- end
1905
+ ### Controle de Cache
1587
1906
 
1588
- def teste_com_parametros
1589
- get '/atender', :name => 'Frank'
1590
- assert_equal 'Olá Frank!', last_response.bodymeet
1591
- end
1907
+ Definir sues cabeçalhos corretamente é o principal passo para uma correta cache
1908
+ HTTP.
1592
1909
 
1593
- def test_com_ambiente_rack
1594
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
1595
- assert_equal "Você está utilizando o Songbird!", last_response.body
1596
- end
1910
+ Você pode facilmente definir o cabeçalho de Cache-Control como:
1911
+
1912
+ ```ruby
1913
+ get '/' do
1914
+ cache_control :public
1915
+ "guarde isso!"
1597
1916
  end
1598
1917
  ```
1599
1918
 
1600
- NOTA: Os módulos de classe embutidos `Sinatra::Test` e
1601
- `Sinatra::TestHarness` são depreciados na versão 0.9.2.
1919
+ Dica profissional: Configure a cache em um filtro anterior:
1602
1920
 
1603
- ## Sinatra::Base - Middleware, Bibliotecas e aplicativos modulares
1921
+ ```ruby
1922
+ before do
1923
+ cache_control :public, :must_revalidate, :max_age => 60
1924
+ end
1925
+ ```
1604
1926
 
1605
- Definir sua aplicação em um nível superior de trabalho funciona bem para
1606
- micro aplicativos, mas tem consideráveis incovenientes na construção de
1607
- componentes reutilizáveis como um middleware Rack, metal Rails,
1608
- bibliotecas simples como um componente de servidor, ou mesmo extensões
1609
- Sinatra. A DSL de nível superior polui o espaço do objeto e assume um
1610
- estilo de configuração de micro aplicativos (exemplo: uma simples
1611
- arquivo de aplicação, diretórios `./public` e `./views`, logs, página de
1612
- detalhes de exceção, etc.). É onde o `Sinatra::Base` entra em jogo:
1927
+ Se você está usando o método auxiliar `expires` para definir seu cabeçalho
1928
+ correspondente, `Cache-Control` irá ser definida automaticamente para você:
1613
1929
 
1614
1930
  ```ruby
1615
- require 'sinatra/base'
1931
+ before do
1932
+ expires 500, :public, :must_revalidate
1933
+ end
1934
+ ```
1616
1935
 
1617
- class MinhaApp < Sinatra::Base
1618
- set :sessions, true
1619
- set :foo, 'bar'
1936
+ Para usar propriciamente caches, você deve considerar usar `etag` ou
1937
+ `last_modified`. É recomendado chamar esses métodos auxiliares *antes* de fazer
1938
+ qualquer tipo de processamento pesado, já que eles irão imediatamente retornar
1939
+ uma resposta se o cliente já possui a versão atual na sua cache:
1620
1940
 
1621
- get '/' do
1622
- 'Ola mundo!'
1623
- end
1941
+ ```ruby
1942
+ get "/artigo/:id" do
1943
+ @artigo = Artigo.find params['id']
1944
+ last_modified @artigo.updated_at
1945
+ etag @artigo.sha1
1946
+ erb :artigo
1624
1947
  end
1625
1948
  ```
1626
1949
 
1627
- A classe `MinhaApp` é um componente Rack independente que pode agir como
1628
- um middleware Rack, uma aplicação Rack, ou metal Rails. Você pode
1629
- utilizar ou executar esta classe com um arquivo rackup `config.ru`;
1630
- ou, controlar um componente de servidor fornecendo como biblioteca:
1950
+ Também é possível usar uma
1951
+ [ETag fraca](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation):
1631
1952
 
1632
1953
  ```ruby
1633
- MinhaApp.run! :host => 'localhost', :port => 9090
1954
+ etag @article.sha1, :weak
1634
1955
  ```
1956
+ Esses métodos auxiliares não irão fazer nenhum processo de cache para você, mas
1957
+ irão alimentar as informações necessárias para sua cache. Se você está
1958
+ pesquisando por uma solução rápida de fazer cache com proxy-reverso, tente
1959
+ [rack-cache](https://github.com/rtomayko/rack-cache#readme):
1635
1960
 
1636
- Os métodos disponíveis para subclasses `Sinatra::Base` são exatamente como
1637
- aqueles disponíveis via a DSL de nível superior. Aplicações de nível
1638
- mais alto podem ser convertidas para componentes `Sinatra::Base` com duas
1639
- modificações:
1640
-
1641
- - Seu arquivo deve requerer `sinatra/base` ao invés de `sinatra`;
1642
- outra coisa, todos os métodos DSL do Sinatra são importados para o
1643
- espaço principal.
1961
+ ```ruby
1962
+ require "rack/cache"
1963
+ require "sinatra"
1644
1964
 
1645
- - Coloque as rotas da sua aplicação, manipuladores de erro, filtros e
1646
- opções na subclasse de um `Sinatra::Base`.
1965
+ use Rack::Cache
1647
1966
 
1648
- `Sinatra::Base` é um quadro branco. Muitas opções são desabilitadas por
1967
+ get '/' do
1968
+ cache_control :public, :max_age => 36000
1969
+ sleep 5
1970
+ "olá"
1971
+ end
1972
+ ```
1973
+
1974
+ Use a configuração `:static_cache_control` (veja [acima]#(controle-de-cache))
1975
+ para adicionar o cabeçalho de informação `Cache-Control` para arquivos
1976
+ estáticos.
1977
+
1978
+ De acordo com a RFC 2616, sua aplicação deve se comportar diferentemente se o
1979
+ cabeçalho If-Match ou If-None-Match é definido para `*`, dependendo se o
1980
+ recurso requisitado já existe. Sinatra assume que recursos para requisições
1981
+ seguras (como get) e idempotentes (como put) já existem, enquanto que para
1982
+ outros recursos (por exemplo requisições post) são tratados como novos
1983
+ recursos. Você pode mudar esse comportamento passando em uma opção
1984
+ `:new_resource`:
1985
+
1986
+ ```ruby
1987
+ get '/create' do
1988
+ etag '', :new_resource => true
1989
+ Artigo.create
1990
+ erb :novo_artigo
1991
+ end
1992
+ ```
1993
+
1994
+ Se você quer continuar usando um ETag fraco, passe em uma opção `:kind`:
1995
+
1996
+ ```ruby
1997
+ etag '', :new_resource => true, :kind => :weak
1998
+ ```
1999
+
2000
+ ### Enviando Arquivos
2001
+
2002
+ Para retornar os conteúdos de um arquivo como as resposta, você pode usar o
2003
+ metódo auxiliar `send_file`:
2004
+
2005
+ ```ruby
2006
+ get '/' do
2007
+ send_file 'foo.png'
2008
+ end
2009
+ ```
2010
+
2011
+ Também aceita opções:
2012
+
2013
+ ```ruby
2014
+ send_file 'foo.png', :type => :jpg
2015
+ ```
2016
+
2017
+ As opções são:
2018
+
2019
+ <dl>
2020
+ <dt>filename</dt>
2021
+ <dd>Nome do arquivo a ser usado na respota,
2022
+ o padrão é o nome do arquivo reak</dd>
2023
+ <dt>last_modified</dt>
2024
+ <dd>Valor do cabeçalho Last-Modified, o padrão corresponde ao mtime do
2025
+ arquivo.</dd>
2026
+
2027
+ <dt>type</dt>
2028
+ <dd>Valor do cabeçalho Content-Type, extraído da extensão do arquivo se
2029
+ inexistente.</dd>
2030
+
2031
+ <dt>disposition</dt>
2032
+ <dd>
2033
+ Valor do cabeçalho Content-Disposition, valores possíveis: <tt>nil</tt>
2034
+ (default), <tt>:attachment</tt> and <tt>:inline</tt>
2035
+ </dd>
2036
+
2037
+ <dt>length</dt>
2038
+ <dd>Valor do cabeçalho Content-Length, o padrão corresponde ao tamanho do
2039
+ arquivo.</dd>
2040
+
2041
+ <dt>status</dt>
2042
+ <dd>
2043
+ Código de status a ser enviado. Útil quando está se enviando um arquivo
2044
+ estático como uma página de erro. Se suportado pelo handler do Rack,
2045
+ outros meios além de transmissão do processo do Ruby serão usados.
2046
+ So você usar esse metódo auxiliar, o Sinatra irá automaticamente lidar com
2047
+ requisições de alcance.
2048
+ </dd>
2049
+ </dl>
2050
+
2051
+ ### Acessando o Objeto da Requisção
2052
+
2053
+ O objeto vindo da requisição pode ser acessado do nível de requsição (filtros,
2054
+ rotas, manipuladores de erro) através do método `request`:
2055
+
2056
+ ```ruby
2057
+ # app rodando em http://exemplo.com/exemplo
2058
+ get '/foo' do
2059
+ t = %w[text/css text/html application/javascript]
2060
+ request.accept # ['text/html', '*/*']
2061
+ request.accept? 'text/xml' # true
2062
+ request.preferred_type(t) # 'text/html'
2063
+ request.body # corpo da requisição enviado pelo cliente (veja abaixo)
2064
+ request.scheme # "http"
2065
+ request.script_name # "/exemplo"
2066
+ request.path_info # "/foo"
2067
+ request.port # 80
2068
+ request.request_method # "GET"
2069
+ request.query_string # ""
2070
+ request.content_length # tamanho do request.body
2071
+ request.media_type # tipo de mídia of request.body
2072
+ request.host # "exemplo.com"
2073
+ request.get? # true (metodo similar para outros tipos de requisição)
2074
+ request.form_data? # false
2075
+ request["algum_ param"] # valor do paramêtro 'algum_param'. [] é um atalho para o hash de parametros
2076
+ request.referrer # a referência do cliente ou '/'
2077
+ request.user_agent # agente de usuário (usado por :agent condition)
2078
+ request.cookies # hash dos cookies do browser
2079
+ request.xhr? # isto é uma requisição ajax?
2080
+ request.url # "http://exemplo.com/exemplo/foo"
2081
+ request.path # "/exemplo/foo"
2082
+ request.ip # endereço de IP do cliente
2083
+ request.secure? # false (seria true se a conexão fosse ssl)
2084
+ request.forwarded? # true (se está rodando por um proxy reverso)
2085
+ request.env # raw env hash handed in by Rack
2086
+ end
2087
+ ```
2088
+
2089
+ Algumas opções, como `script_name` ou `path_info, podem ser escritas como:
2090
+
2091
+ ```ruby
2092
+ before { request.path_info = "/" }
2093
+
2094
+ get "/" do
2095
+ "todas requisições acabam aqui"
2096
+ end
2097
+ ```
2098
+ `request.body` é uma ES ou um objeo StringIO:
2099
+
2100
+ ```ruby
2101
+ post "/api" do
2102
+ request.body.rewind # em caso de algo já ter lido
2103
+ data = JSON.parse request.body.read
2104
+ "Oi #{data['nome']}!"
2105
+ end
2106
+ ```
2107
+
2108
+ ### Anexos
2109
+
2110
+ Você pode usar o método auxiliar `attachment` para dizer ao navegador que a
2111
+ reposta deve ser armazenada no disco no lugar de ser exibida no browser:
2112
+
2113
+ ```ruby
2114
+ get '/' do
2115
+ attachment "info.txt"
2116
+ "salve isso!"
2117
+ end
2118
+ ```
2119
+
2120
+ ### Trabalhando com Data e Hora
2121
+
2122
+ O Sinatra oferece um método auxiliar `time_for` que gera um objeto Time do
2123
+ valor dado. É também possível converter `DateTime`, `Date` e classes similares:
2124
+
2125
+
2126
+ ```ruby
2127
+ get '/' do
2128
+ pass if Time.now > time_for('Dec 23, 2016')
2129
+ "continua no tempo"
2130
+ end
2131
+ ```
2132
+
2133
+ Esse método é usado internamente por `expires`, `last_modified` e akin. Você
2134
+ pode portanto facilmente estender o comportamento desses métodos sobrescrevendo
2135
+ `time_for` na sua aplicação:
2136
+
2137
+ ```ruby
2138
+ helpers do
2139
+ def time_for(valor)
2140
+ case valor
2141
+ when :ontem then Time.now - 24*60*60
2142
+ when :amanha then Time.now + 24*60*60
2143
+ else super
2144
+ end
2145
+ end
2146
+ end
2147
+
2148
+ get '/' do
2149
+ last_modified :ontem
2150
+ expires :amanha
2151
+ "oi"
2152
+ end
2153
+ ```
2154
+
2155
+ ### Pesquisando por Arquivos de Template
2156
+
2157
+ O método auxiliar `find_template` é usado para encontrar arquivos de template
2158
+ para renderizar:
2159
+
2160
+ ```ruby
2161
+ find_template settings.views, 'foo', Tilt[:haml] do |arquivo|
2162
+ puts "pode ser #{arquivo}"
2163
+ end
2164
+ ```
2165
+
2166
+ Isso não é realmente útil. Mas é útil que você possa na verdade sobrescrever
2167
+ esse método para conectar no seu próprio mecanismo de pesquisa. Por exemplo, se
2168
+ você quer ser capaz de usar mais de um diretório de view:
2169
+
2170
+ ```ruby
2171
+ set :views, ['views', 'templates']
2172
+
2173
+ helpers do
2174
+ def find_template(views, name, engine, &block)
2175
+ Array(views).each { |v| super(v, name, engine, &block) }
2176
+ end
2177
+ end
2178
+ ```
2179
+
2180
+ Outro exemplo seria utilizando diretórios diferentes para motores (engines)
2181
+ diferentes:
2182
+
2183
+ ```ruby
2184
+ set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
2185
+
2186
+ helpers do
2187
+ def find_template(views, name, engine, &block)
2188
+ _, folder = views.detect { |k,v| engine == Tilt[k] }
2189
+ folder ||= views[:default]
2190
+ super(folder, name, engine, &block)
2191
+ end
2192
+ end
2193
+ ```
2194
+
2195
+ Você pode facilmente embrulhar isso é uma extensão e compartilhar com outras
2196
+ pessoas!
2197
+
2198
+ Perceba que `find_template` não verifica se o arquivo realmente existe. Ao
2199
+ invés disso, ele chama o bloco dado para todos os caminhos possíveis. Isso não
2200
+ significa um problema de perfomance, já que `render` irá usar `break` assim que
2201
+ o arquivo é encontrado. Além disso, as localizações (e conteúdo) de templates
2202
+ serão guardados na cache se você não estiver rodando no modo de
2203
+ desenvolvimento. Você deve se lembrar disso se você escrever um método
2204
+ realmente maluco.
2205
+
2206
+ ## Configuração
2207
+
2208
+ É possível e recomendado definir o código de status e o corpo da resposta com o
2209
+ valor retornado do bloco da rota. Entretanto, em alguns cenários você pode
2210
+ querer definir o corpo em um ponto arbitrário do fluxo de execução. Você pode
2211
+ fazer isso com o metódo auxiliar `body`. Se você fizer isso, poderá usar esse
2212
+ metódo de agora em diante para acessar o body:
2213
+
2214
+ ```ruby
2215
+ get '/foo' do
2216
+ body "bar"
2217
+ end
2218
+
2219
+ after do
2220
+ puts body
2221
+ end
2222
+ ```
2223
+
2224
+ Também é possivel passar um bloco para `body`, que será executado pelo
2225
+ manipulador Rack (isso pode ser usado para implementar transmissão,
2226
+ [veja "Retorno de Valores"](#retorno-de-valores)).
2227
+
2228
+ Similar ao corpo, você pode também definir o código de status e cabeçalhos:
2229
+
2230
+ ```ruby
2231
+ get '/foo' do
2232
+ status 418
2233
+ headers \
2234
+ "Allow" => "BREW, POST, GET, PROPFIND, WHEN"
2235
+ "Refresh" => "Refresh: 20; https://ietf.org/rfc/rfc2324.txt"
2236
+ body "Eu sou um bule de chá!"
2237
+ end
2238
+ ```
2239
+
2240
+ Assim como `body`, `headers` e `status` sem argumentos podem ser usados para
2241
+ acessar seus valores atuais.
2242
+
2243
+ ### Transmitindo Respostas
2244
+
2245
+ As vezes você quer começar a mandar dados enquanto está gerando partes do corpo
2246
+ da resposta. Em exemplos extremos, você quer continuar enviando dados até o
2247
+ cliente encerrar a conexão. Você pode usar o método auxiliar `stream` para
2248
+ evitar criar seu próprio empacotador:
2249
+
2250
+ ```ruby
2251
+ get '/' do
2252
+ stream do |out|
2253
+ out << "Isso será len -\n"
2254
+ sleep 0.5
2255
+ out << " Aguarde \n"
2256
+ sleep 1
2257
+ out << " dário!\n"
2258
+ end
2259
+ end
2260
+ ```
2261
+
2262
+ Isso permite você implementar APIs de Transmissão,
2263
+ [Eventos Enviados pelo Servidor](https://w3c.github.io/eventsource/), e pode
2264
+ ser usado como a base para
2265
+ [WebSockets](https://en.wikipedia.org/wiki/WebSocket). Pode ser usado também
2266
+ para aumentar a taxa de transferência se algum, mas não todo, conteúdo depender
2267
+ de um recurso lento.
2268
+
2269
+ Perceba que o comportamento da transmissão, especialmente o número de
2270
+ requisições concorrentes, depende altamente do servidor web usado para servir a
2271
+ aplicação. Alguns servidores podem até mesmo não suportar transmissão de
2272
+ maneira alguma. Se o servidor não suportar transmissão, o corpo será enviado
2273
+ completamente após que o bloco passado para `stream` terminar de executar.
2274
+ Transmissão não funciona de nenhuma maneira com Shotun.
2275
+
2276
+ Se o parâmetro opcional é definido como `keep_open`, ele não chamará `close` no
2277
+ objeto transmitido, permitindo você a fecha-lo em algum outro ponto futuro no
2278
+ fluxo de execução. Isso funciona apenas em servidores orientados a eventos,
2279
+ como Thin e Rainbows. Outros servidores irão continuar fechando a transmissão:
2280
+
2281
+ ```ruby
2282
+ # long polling
2283
+
2284
+ set :server, :thin
2285
+ conexoes = []
2286
+
2287
+ get '/assinar' do
2288
+ # registra o interesse de um cliente em servidores de eventos
2289
+ stream(:keep_open) do |saida|
2290
+ conexoes << saida
2291
+ # retire conexões mortas
2292
+ conexoes.reject!(&:closed?)
2293
+ end
2294
+ end
2295
+
2296
+ post '/:messagem' do
2297
+ conexoes.each do |saida|
2298
+ # notifica o cliente que uma nova mensagem chegou
2299
+ saida << params['messagem'] << "\n"
2300
+
2301
+ # indica ao cliente para se conectar novamente
2302
+ saida.close
2303
+ end
2304
+
2305
+ # confirma
2306
+ "messagem recebida"
2307
+ end
2308
+ ```
2309
+
2310
+ Também é possivel para o cliente fechar a conexão quando está tentando escrever
2311
+ para o socket. Devido a isso, é recomendado checar `out.closed?` antes de
2312
+ tentar escrever.
2313
+
2314
+ ### Usando Logs
2315
+
2316
+ No escopo da requisição, o método auxiliar `logger` expõe uma instância
2317
+ `Logger`:
2318
+
2319
+ ```ruby
2320
+ get '/' do
2321
+ logger.info "loading data"
2322
+ # ...
2323
+ end
2324
+ ```
2325
+
2326
+ Esse logger irá automaticamente botar as configurações de log do manipulador
2327
+ Rack na sua conta. Se a produção de logs estiver desabilitads, esse método
2328
+ retornará um objeto dummy, então você não terá que se preocupar com suas rotas
2329
+ e filtros.
2330
+
2331
+ Perceba que a produção de logs está habilitada apenas para
2332
+ `Sinatra::Application` por padrão, então se você herdar de `Sinatra::Base`,
2333
+ você provavelmente irá querer habilitar:
2334
+
2335
+ ```ruby
2336
+ class MyApp < Sinatra::Base
2337
+ configure :production, :development do
2338
+ enable :logging
2339
+ end
2340
+ end
2341
+ ```
2342
+
2343
+ Para evitar que qualquer middleware de logs seja configurado, defina a
2344
+ configuração `logging` como `nil`. Entretanto, tenha em mente que `logger`
2345
+ retornará, nesse caso, `nil`. Um caso de uso comum é quando você quer definir
2346
+ seu próprio logger. Sinatra irá usar qualquer um que ele achar em
2347
+ `env['rack.logger']`
2348
+
2349
+ ### Tipos Mime
2350
+
2351
+ Quando se está usando `send_file` ou arquivos estáticos, você pode ter tipos
2352
+ Mime que o Sinatra não entende. Use `mime_type` para registrá-los pela extensão
2353
+ do arquivo:
2354
+
2355
+ ```ruby
2356
+ configure do
2357
+ mime_type :foo, 'text/foo'
2358
+ end
2359
+ ```
2360
+
2361
+ Você pode utilizar também com o método auxiliar `content_type`:
2362
+
2363
+ ```ruby
2364
+ get '/' do
2365
+ content-type :foo
2366
+ "foo foo foo"
2367
+ end
2368
+ ```
2369
+
2370
+ ### Gerando URLs
2371
+
2372
+ Para gerar URLs você deve usar o metódo auxiliar `url` no Haml:
2373
+
2374
+ ```ruby
2375
+ %a{:href => url('/foo')} foo
2376
+ ```
2377
+
2378
+ Isso inclui proxies reversos e rotas Rack, se presentes.
2379
+
2380
+ Esse método é também apelidado para `to` (veja
2381
+ [abaixo](#redirecionamento-do-browser) para um exemplo).
2382
+
2383
+ ### Redirecionamento do Browser
2384
+
2385
+ Você pode lançar um redirecionamento no browser com o metódo auxiliar
2386
+ `redirect`:
2387
+
2388
+ ```ruby
2389
+ get '/foo' do
2390
+ redirect to('/bar')
2391
+ end
2392
+ ```
2393
+
2394
+ Quaisquer paramêtros adicionais são interpretados como argumentos passados ao
2395
+ `halt`:
2396
+
2397
+ ```ruby
2398
+ redirect to('/bar'), 303
2399
+ redirect 'http://www.google.com/', 'lugar errado, amigo'
2400
+ ```
2401
+
2402
+ Você pode também facilmente redirecionar para a página da qual o usuário veio
2403
+ com `redirect back`:
2404
+
2405
+ ```ruby
2406
+ get '/foo' do
2407
+ "<a href='/bar'>do something</a>"
2408
+ end
2409
+
2410
+ get '/bar' do
2411
+ do_something
2412
+ redirect back
2413
+ end
2414
+ ```
2415
+
2416
+ Para passar argumentos com um redirecionamento, adicione-os a query:
2417
+
2418
+ ```ruby
2419
+ redirect to('/bar?sum=42')
2420
+ ```
2421
+
2422
+ Ou use uma sessão:
2423
+
2424
+ ```ruby
2425
+ enable :sessions
2426
+
2427
+ get '/foo' do
2428
+ session[:secret] = 'foo'
2429
+ redirect to('/bar')
2430
+ end
2431
+
2432
+ get '/bar' do
2433
+ session[:secret]
2434
+ end
2435
+ ```
2436
+
2437
+ ### Controle de Cache
2438
+
2439
+ Definir sues cabeçalhos corretamente é o principal passo para uma correta cache
2440
+ HTTP.
2441
+
2442
+ Você pode facilmente definir o cabeçalho de Cache-Control como:
2443
+
2444
+ ```ruby
2445
+ get '/' do
2446
+ cache_control :public
2447
+ "guarde isso!"
2448
+ end
2449
+ ```
2450
+
2451
+ Dica profissional: Configure a cache em um filtro anterior:
2452
+
2453
+ ```ruby
2454
+ before do
2455
+ cache_control :public, :must_revalidate, :max_age => 60
2456
+ end
2457
+ ```
2458
+
2459
+ Se você está usando o método auxiliar `expires` para definir seu cabeçalho
2460
+ correspondente, `Cache-Control` irá ser definida automaticamente para você:
2461
+
2462
+ ```ruby
2463
+ before do
2464
+ expires 500, :public, :must_revalidate
2465
+ end
2466
+ ```
2467
+
2468
+ Para usar propriciamente caches, você deve considerar usar `etag` ou
2469
+ `last_modified`. É recomendado chamar esses métodos auxiliares *antes* de fazer
2470
+ qualquer tipo de processamento pesado, já que eles irão imediatamente retornar
2471
+ uma resposta se o cliente já possui a versão atual na sua cache:
2472
+
2473
+ ```ruby
2474
+ get "/artigo/:id" do
2475
+ @artigo = Artigo.find params['id']
2476
+ last_modified @artigo.updated_at
2477
+ etag @artigo.sha1
2478
+ erb :artigo
2479
+ end
2480
+ ```
2481
+
2482
+ Também é possível usar uma
2483
+ [ETag fraca](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation):
2484
+
2485
+ ```ruby
2486
+ etag @article.sha1, :weak
2487
+ ```
2488
+ Esses métodos auxiliares não irão fazer nenhum processo de cache para você, mas
2489
+ irão alimentar as informações necessárias para sua cache. Se você está
2490
+ pesquisando por uma solução rápida de fazer cache com proxy-reverso, tente
2491
+ [rack-cache](https://github.com/rtomayko/rack-cache#readme):
2492
+
2493
+ ```ruby
2494
+ require "rack/cache"
2495
+ require "sinatra"
2496
+
2497
+ use Rack::Cache
2498
+
2499
+ get '/' do
2500
+ cache_control :public, :max_age => 36000
2501
+ sleep 5
2502
+ "olá"
2503
+ end
2504
+ ```
2505
+
2506
+ Use a configuração `:static_cache_control` (veja [acima]#(controle-de-cache))
2507
+ para adicionar o cabeçalho de informação `Cache-Control` para arquivos
2508
+ estáticos.
2509
+
2510
+ De acordo com a RFC 2616, sua aplicação deve se comportar diferentemente se o
2511
+ cabeçalho If-Match ou If-None-Match é definido para `*`, dependendo se o
2512
+ recurso requisitado já existe. Sinatra assume que recursos para requisições
2513
+ seguras (como get) e idempotentes (como put) já existem, enquanto que para
2514
+ outros recursos (por exemplo requisições post) são tratados como novos
2515
+ recursos. Você pode mudar esse comportamento passando em uma opção
2516
+ `:new_resource`:
2517
+
2518
+ ```ruby
2519
+ get '/create' do
2520
+ etag '', :new_resource => true
2521
+ Artigo.create
2522
+ erb :novo_artigo
2523
+ end
2524
+ ```
2525
+
2526
+ Se você quer continuar usando um ETag fraco, passe em uma opção `:kind`:
2527
+
2528
+ ```ruby
2529
+ etag '', :new_resource => true, :kind => :weak
2530
+ ```
2531
+
2532
+ ### Enviando Arquivos
2533
+
2534
+ Para retornar os conteúdos de um arquivo como as resposta, você pode usar o
2535
+ metódo auxiliar `send_file`:
2536
+
2537
+ ```ruby
2538
+ get '/' do
2539
+ send_file 'foo.png'
2540
+ end
2541
+ ```
2542
+
2543
+ Também aceita opções:
2544
+
2545
+ ```ruby
2546
+ send_file 'foo.png', :type => :jpg
2547
+ ```
2548
+
2549
+ As opções são:
2550
+
2551
+ <dl>
2552
+ <dt>filename</dt>
2553
+ <dd>Nome do arquivo a ser usado na respota,
2554
+ o padrão é o nome do arquivo reak</dd>
2555
+ <dt>last_modified</dt>
2556
+ <dd>Valor do cabeçalho Last-Modified, o padrão corresponde ao mtime do
2557
+ arquivo.</dd>
2558
+
2559
+ <dt>type</dt>
2560
+ <dd>Valor do cabeçalho Content-Type, extraído da extensão do arquivo se
2561
+ inexistente.</dd>
2562
+
2563
+ <dt>disposition</dt>
2564
+ <dd>
2565
+ Valor do cabeçalho Content-Disposition, valores possíveis: <tt>nil</tt>
2566
+ (default), <tt>:attachment</tt> and <tt>:inline</tt>
2567
+ </dd>
2568
+
2569
+ <dt>length</dt>
2570
+ <dd>Valor do cabeçalho Content-Length, o padrão corresponde ao tamanho do
2571
+ arquivo.</dd>
2572
+
2573
+ <dt>status</dt>
2574
+ <dd>
2575
+ Código de status a ser enviado. Útil quando está se enviando um arquivo
2576
+ estático como uma página de erro. Se suportado pelo handler do Rack,
2577
+ outros meios além de transmissão do processo do Ruby serão usados.
2578
+ So você usar esse metódo auxiliar, o Sinatra irá automaticamente lidar
2579
+ com requisições de alcance.
2580
+ </dd>
2581
+ </dl>
2582
+
2583
+ ### Acessando o Objeto da Requisção
2584
+
2585
+ O objeto vindo da requisição pode ser acessado do nível de requsição (filtros,
2586
+ rotas, manipuladores de erro) através do método `request`:
2587
+
2588
+ ```ruby
2589
+ # app rodando em http://exemplo.com/exemplo
2590
+ get '/foo' do
2591
+ t = %w[text/css text/html application/javascript]
2592
+ request.accept # ['text/html', '*/*']
2593
+ request.accept? 'text/xml' # true
2594
+ request.preferred_type(t) # 'text/html'
2595
+ request.body # corpo da requisição enviado pelo cliente (veja abaixo)
2596
+ request.scheme # "http"
2597
+ request.script_name # "/exemplo"
2598
+ request.path_info # "/foo"
2599
+ request.port # 80
2600
+ request.request_method # "GET"
2601
+ request.query_string # ""
2602
+ request.content_length # tamanho do request.body
2603
+ request.media_type # tipo de mídia of request.body
2604
+ request.host # "exemplo.com"
2605
+ request.get? # true (metodo similar para outros tipos de requisição)
2606
+ request.form_data? # false
2607
+ request["algum_ param"] # valor do paramêtro 'algum_param'. [] é um atalho para o hash de parametros
2608
+ request.referrer # a referência do cliente ou '/'
2609
+ request.user_agent # agente de usuário (usado por :agent condition)
2610
+ request.cookies # hash dos cookies do browser
2611
+ request.xhr? # isto é uma requisição ajax?
2612
+ request.url # "http://exemplo.com/exemplo/foo"
2613
+ request.path # "/exemplo/foo"
2614
+ request.ip # endereço de IP do cliente
2615
+ request.secure? # false (seria true se a conexão fosse ssl)
2616
+ request.forwarded? # true (se está rodando por um proxy reverso)
2617
+ request.env # raw env hash handed in by Rack
2618
+ end
2619
+ ```
2620
+
2621
+ Algumas opções, como `script_name` ou `path_info, podem ser escritas como:
2622
+
2623
+ ```ruby
2624
+ before { request.path_info = "/" }
2625
+
2626
+ get "/" do
2627
+ "todas requisições acabam aqui"
2628
+ end
2629
+ ```
2630
+ `request.body` é uma ES ou um objeo StringIO:
2631
+
2632
+ ```ruby
2633
+ post "/api" do
2634
+ request.body.rewind # em caso de algo já ter lido
2635
+ data = JSON.parse request.body.read
2636
+ "Oi #{data['nome']}!"
2637
+ end
2638
+ ```
2639
+
2640
+ ### Anexos
2641
+
2642
+ Você pode usar o método auxiliar `attachment` para dizer ao navegador que a
2643
+ reposta deve ser armazenada no disco no lugar de ser exibida no browser:
2644
+
2645
+ ```ruby
2646
+ get '/' do
2647
+ attachment "info.txt"
2648
+ "salve isso!"
2649
+ end
2650
+ ```
2651
+
2652
+ ### Trabalhando com Data e Hora
2653
+
2654
+ O Sinatra oferece um método auxiliar `time_for` que gera um objeto Time do
2655
+ valor dado. É também possível converter `DateTime`, `Date` e classes similares:
2656
+
2657
+
2658
+ ```ruby
2659
+ get '/' do
2660
+ pass if Time.now > time_for('Dec 23, 2016')
2661
+ "continua no tempo"
2662
+ end
2663
+ ```
2664
+
2665
+ Esse método é usado internamente por `expires`, `last_modified` e akin. Você
2666
+ pode portanto facilmente estender o comportamento desses métodos sobrescrevendo
2667
+ `time_for` na sua aplicação:
2668
+
2669
+ ```ruby
2670
+ helpers do
2671
+ def time_for(valor)
2672
+ case valor
2673
+ when :ontem then Time.now - 24*60*60
2674
+ when :amanha then Time.now + 24*60*60
2675
+ else super
2676
+ end
2677
+ end
2678
+ end
2679
+
2680
+ get '/' do
2681
+ last_modified :ontem
2682
+ expires :amanha
2683
+ "oi"
2684
+ end
2685
+ ```
2686
+
2687
+ ### Pesquisando por Arquivos de Template
2688
+
2689
+ O método auxiliar `find_template` é usado para encontrar arquivos de template
2690
+ para renderizar:
2691
+
2692
+ ```ruby
2693
+ find_template settings.views, 'foo', Tilt[:haml] do |arquivo|
2694
+ puts "pode ser #{arquivo}"
2695
+ end
2696
+ ```
2697
+
2698
+ Isso não é realmente útil. Mas é útil que você possa na verdade sobrescrever
2699
+ esse método para conectar no seu próprio mecanismo de pesquisa. Por exemplo, se
2700
+ você quer ser capaz de usar mais de um diretório de view:
2701
+
2702
+ ```ruby
2703
+ set :views, ['views', 'templates']
2704
+
2705
+ helpers do
2706
+ def find_template(views, name, engine, &block)
2707
+ Array(views).each { |v| super(v, name, engine, &block) }
2708
+ end
2709
+ end
2710
+ ```
2711
+
2712
+ Outro exemplo seria utilizando diretórios diferentes para motores (engines)
2713
+ diferentes:
2714
+
2715
+ ```ruby
2716
+ set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
2717
+
2718
+ helpers do
2719
+ def find_template(views, name, engine, &block)
2720
+ _, folder = views.detect { |k,v| engine == Tilt[k] }
2721
+ folder ||= views[:default]
2722
+ super(folder, name, engine, &block)
2723
+ end
2724
+ end
2725
+ ```
2726
+
2727
+ Você pode facilmente embrulhar isso é uma extensão e compartilhar com outras
2728
+ pessoas!
2729
+
2730
+ Perceba que `find_template` não verifica se o arquivo realmente existe. Ao
2731
+ invés disso, ele chama o bloco dado para todos os caminhos possíveis. Isso não
2732
+ significa um problema de perfomance, já que `render` irá usar `break` assim que
2733
+ o arquivo é encontrado. Além disso, as localizações (e conteúdo) de templates
2734
+ serão guardados na cache se você não estiver rodando no modo de
2735
+ desenvolvimento. Você deve se lembrar disso se você escrever um método
2736
+ realmente maluco.
2737
+
2738
+ ## Configuração
2739
+
2740
+ Rode uma vez, na inicialização, em qualquer ambiente:
2741
+
2742
+ ```ruby
2743
+ configure do
2744
+ ...
2745
+ end
2746
+ ```
2747
+
2748
+ ```ruby
2749
+ configure do
2750
+ # configurando uma opção
2751
+ set :option, 'value'
2752
+
2753
+ # configurando múltiplas opções
2754
+ set :a => 1, :b => 2
2755
+
2756
+ # o mesmo que `set :option, true`
2757
+ enable :option
2758
+
2759
+ # o mesmo que `set :option, false`
2760
+ disable :option
2761
+
2762
+ # você pode também ter configurações dinâmicas com blocos
2763
+ set(:css_dir) { File.join(views, 'css') }
2764
+ end
2765
+ ```
2766
+
2767
+ Rode somente quando o ambiente (`APP_ENV` variável de ambiente) é definida para
2768
+ `:production`:
2769
+
2770
+ ```ruby
2771
+ configure :production do
2772
+ ...
2773
+ end
2774
+ ```
2775
+
2776
+ Rode quando o ambiente é definido para `:production` ou `:test`:
2777
+
2778
+ ```ruby
2779
+ configure :production, :test do
2780
+ ...
2781
+ end
2782
+ ```
2783
+
2784
+ Você pode acessar essas opções por meio de `settings`:
2785
+
2786
+ ```ruby
2787
+ configure do
2788
+ set :foo, 'bar'
2789
+ end
2790
+
2791
+ get '/' do
2792
+ settings.foo? # => true
2793
+ settings.foo # => 'bar'
2794
+ ...
2795
+ end
2796
+ ```
2797
+
2798
+ ### Configurando proteção a ataques
2799
+
2800
+ O Sinatra está usando
2801
+ [Rack::Protection](https://github.com/sinatra/sinatra/tree/master/rack-protection#readme)
2802
+ para defender sua aplicação contra ataques oportunistas comuns. Você pode
2803
+ facilmente desabilitar esse comportamento (o que irá abrir sua aplicação à
2804
+ toneladas de vulnerabilidades comuns):
2805
+
2806
+ ```ruby
2807
+ disable :protection
2808
+ ```
2809
+
2810
+ Para pular uma única camada de defesa, defina `protection` como um hash de
2811
+ opções:
2812
+
2813
+ ```ruby
2814
+ set :protection, :except => :path_traversal
2815
+ ```
2816
+
2817
+ Você também pode definir em um array, visando desabilitar uma lista de
2818
+ proteções:
2819
+
2820
+ ```ruby
2821
+ set :protection, :except => [:path_traversal, :session_hijacking]
2822
+ ```
2823
+
2824
+ Por padrão, o Sinatra irá configurar apenas sessões com proteção se `:sessions`
2825
+ tiver sido habilitado. Veja '[Utilizando Sessões](#utilizando-sessões)'. As
2826
+ vezes você pode querer configurar sessões "fora" da aplicação do Sinatra, como
2827
+ em config.ru ou com uma instância de `Rack::Builder` separada. Nesse caso, você
2828
+ pode continuar configurando uma sessão com proteção passando a opção `:session`:
2829
+
2830
+ ```ruby
2831
+ set :protection, :session => true
2832
+ ```
2833
+
2834
+ ### Configurações Disponíveis
2835
+
2836
+ <dl>
2837
+ <dt>absolute_redirects</dt>
2838
+ <dd>
2839
+ Se desabilitada, o Sinatra irá permitir redirecionamentos relativos,
2840
+ entretanto, isso não estará conforme a RFC 2616 (HTTP 1.1), que permite
2841
+ apenas redirecionamentos absolutos.
2842
+ </dd>
2843
+ <dd>
2844
+ Habilite se sua aplicação estiver rodando antes de um proxy reverso que
2845
+ não foi configurado corretamente. Note que o método auxiliar <tt>url</tt>
2846
+ irá continuar produzindo URLs absolutas, a não ser que você passe
2847
+ <tt>false</tt> como segundo parâmetro.
2848
+ </dd>
2849
+ <dd>Desabilitado por padrão.</dd>
2850
+
2851
+ <dt>add_charset</dt>
2852
+ <dd>
2853
+ Para tipos Mime o método auxiliar <tt>content_type</tt> irá
2854
+ automaticamente adicionar a informção de codificação. Você deve adcionar
2855
+ isto no lugar de sobrescrever essa opção:
2856
+ <tt>settings.add_charset << "application/foobar"</tt>
2857
+ </dd>
2858
+
2859
+ <dt>app_file</dt>
2860
+ <dd>
2861
+ Caminho para o arquivo principal da aplicação, usado para detectar a raíz
2862
+ do projeto, views e pastas públicas e templates inline.
2863
+ </dd>
2864
+
2865
+ <dt>bind</dt>
2866
+ <dd>
2867
+ Endereço IP a ser ligado (padrão: <tt>0.0.0.0</tt> ou <tt>localhost</tt>
2868
+ se seu ambiente está definido como desenvolvimento). Usado apenas para
2869
+ servidor embutido.
2870
+ </dd>
2871
+
2872
+ <dt>default_encoding</dt>
2873
+ <dd>Codificação assumida caso a mesma seja desconhecida (padrão corresponde
2874
+ a <tt>"utf-8"</tt>).</dd>
2875
+
2876
+ <dt>dump_errors</dt>
2877
+ <dd>Exibe erros no log.</dd>
2878
+
2879
+ <dt>environment</dt>
2880
+ <dd>
2881
+ Ambiente atual. O padrão é <tt>ENV['APP_ENV']</tt>, ou
2882
+ <tt>"development"</tt> se o primeiro não estiver disponível.
2883
+ </dd>
2884
+
2885
+ <dt>logging</dt>
2886
+ <dd>Usa o logger.</dd>
2887
+
2888
+ <dt>lock</dt>
2889
+ <dd>
2890
+ Coloca um bloqueio em torno de cada requisição, executando apenas
2891
+ processamento sob requisição por processo Ruby simultaneamente.
2892
+ </dd>
2893
+ <dd>Habilitado se sua aplicação não for 'thread-safe'. Desabilitado por
2894
+ padrão.</dd>
2895
+
2896
+ <dt>method_override</dt>
2897
+ <dd>
2898
+ Use a mágica <tt>_method</tt> para permitir formulários put/delete em
2899
+ navegadores que não oferecem suporte à essas operações.
2900
+ </dd>
2901
+
2902
+ <dt>mustermann_opts</dt>
2903
+ <dd>
2904
+ Um hash de opções padrão para passar a Mustermann.new quando se está
2905
+ compilado os caminho de roteamento.
2906
+ </dd>
2907
+
2908
+ <dt>port</dt>
2909
+ <dd>Porta a ser escutada. Usado apenas para servidores embutidos.</dd>
2910
+
2911
+ <dt>prefixed_redirects</dt>
2912
+ <dd>
2913
+ Inserir ou não inserir <tt>request.script_name</tt> nos redirecionamentos
2914
+ se nenhum caminho absoluto for dado. Dessa forma <tt>redirect '/foo'</tt>
2915
+ irá se comportar como <tt>redirect to('/foo').</tt>
2916
+ </dd>
2917
+ <dd>Desabilitado por padrão.</dd>
2918
+
2919
+ <dt>protection</dt>
2920
+ <dd>
2921
+ Habilitar ou não proteções a ataques web. Veja a sessão de proteção acima.
2922
+ </dd>
2923
+
2924
+ <dt>public_dir</dt>
2925
+ <dd>Apelido para <tt>public_folder</tt>. Veja abaixo.</dd>
2926
+
2927
+ <dt>public_folder</dt>
2928
+ <dd>
2929
+ Caminho para o diretório de arquivos públicos. Usado apenas se a exibição
2930
+ de arquivos estáticos estiver habilitada (veja a configuração
2931
+ <tt>static</tt> abaixo). Deduzido da configuração <tt>app_file</tt> se
2932
+ não for definido.
2933
+ </dd>
2934
+
2935
+ <dt>quiet</dt>
2936
+ <dd>
2937
+ Desabilita logs gerados pelos comandos de inicio e parada do Sinatra.
2938
+ <tt>false</tt> por padrão.
2939
+ </dd>
2940
+
2941
+ <dt>reload_templates</dt>
2942
+ <dd>
2943
+ Se deve ou não recarregar templates entre as requisições. Habilitado no
2944
+ modo de desenvolvimento.
2945
+ </dd>
2946
+
2947
+ <dt>root</dt>
2948
+ <dd>
2949
+ Caminho para o diretório raíz do projeto. Deduzido da configuração
2950
+ <tt>app_file</tt> se não for definido.
2951
+ </dd>
2952
+
2953
+ <dt>raise_errors</dt>
2954
+ <dd>
2955
+ Lança exceções (irá para a aplicação). Habilitado por padrão quando o
2956
+ ambiente está definido para <tt>"test</tt>, desabilitado em caso
2957
+ contrário.
2958
+ </dd>
2959
+
2960
+ <dt>run</dt>
2961
+ <dd>
2962
+ Se habilitado, o Sinatra irá lidar com o início do servidor web. Não
2963
+ habilite se estiver usando rackup ou outros meios.
2964
+ </dd>
2965
+
2966
+ <dt>running</dt>
2967
+ <dd>É o servidor embutido que está rodando agora? Não mude essa
2968
+ configuração!</dd>
2969
+
2970
+ <dt>server</dt>
2971
+ <dd>
2972
+ Servidor ou listas de servidores para usar o servidor embutido. A ordem
2973
+ indica prioridade, por padrão depende da implementação do Ruby
2974
+ </dd>
2975
+
2976
+ <dt>server_settings</dt>
2977
+ <dd>
2978
+ Se você estiver usando um servidor web WEBrick, presumidamente para seu
2979
+ ambiente de desenvolvimento, você pode passar um hash de opções para
2980
+ <tt>server_settings</tt>, tais como <tt>SSLEnable</tt> ou
2981
+ <tt>SSLVerifyClient</tt>. Entretanto, servidores web como Puma e Thin não
2982
+ suportam isso, então você pode definir <tt>server_settings</tt> como um
2983
+ metódo quando chamar <tt>configure</tt>.
2984
+ </dd>
2985
+
2986
+ <dt>sessions</dt>
2987
+ <dd>
2988
+ Habilita o suporte a sessões baseadas em cookie usando
2989
+ <tt>Rack::Session::Cookie</tt>. Veja a seção 'Usando Sessões' para mais
2990
+ informações.
2991
+ </dd>
2992
+
2993
+ <dt>session_store</dt>
2994
+ <dd>
2995
+ O middleware de sessão Rack usado. O padrão é
2996
+ <tt>Rack::Session::Cookie</tt>. Veja a sessão 'Usando Sessões' para mais
2997
+ informações.
2998
+ </dd>
2999
+
3000
+ <dt>show_exceptions</dt>
3001
+ <dd>
3002
+ Mostra um relatório de erros no navegador quando uma exceção ocorrer.
3003
+ Habilitado por padrão quando o <tt>ambiente</tt> é definido como
3004
+ <tt>"development"</tt>, desabilitado caso contrário.
3005
+ </dd>
3006
+ <dd>
3007
+ Pode também ser definido para <tt>:after_handler</tt> para disparar um
3008
+ manipulador de erro específico da aplicação antes de mostrar um relatório
3009
+ de erros no navagador.
3010
+ </dd>
3011
+
3012
+ <dt>static</dt>
3013
+ <dd>
3014
+ Define se o Sinatra deve lidar com o oferecimento de arquivos
3015
+ estáticos.
3016
+ </dd>
3017
+ <dd>
3018
+ Desabilitado quando está utilizando um servidor capaz de fazer isso
3019
+ sozinho.
3020
+ </dd>
3021
+ <dd>Desabilitar irá aumentar a perfomance</dd>
3022
+ <dd>
3023
+ Habilitado por padrão no estilo clássico, desabilitado para aplicações
3024
+ modulares.
3025
+ </dd>
3026
+
3027
+ <dt>static_cache_control</dt>
3028
+ <dd>
3029
+ Quando o Sinatra está oferecendo arquivos estáticos, definir isso irá
3030
+ adicionar cabeçalhos <tt>Cache-Control</tt> nas respostas. Usa o método
3031
+ auxiliar <tt>cache-control</tt>. Desabilitado por padrão.
3032
+ </dd>
3033
+ <dd>
3034
+ Use um array explícito quando estiver definindo múltiplos valores:
3035
+ <tt>set :static_cache_control, [:public, :max_age => 300]</tt>
3036
+ </dd>
3037
+
3038
+ <dt>threaded</dt>
3039
+ <dd>
3040
+ Se estiver definido como <tt>true</tt>, irá definir que o Thin use
3041
+ <tt>EventMachine.defer</tt> para processar a requisição.
3042
+ </dd>
3043
+
3044
+ <dt>traps</dt>
3045
+ <dd>Define se o Sinatra deve lidar com sinais do sistema.</dd>
3046
+
3047
+ <dt>views</dt>
3048
+ <dd>
3049
+ Caminho para o diretório de views. Deduzido da configuração
3050
+ <tt>app_file</tt> se não estiver definido.
3051
+ </dd>
3052
+
3053
+ <dt>x_cascade</dt>
3054
+ <dd>
3055
+ Se deve ou não definir o cabeçalho X-Cascade se nenhuma rota combinar.
3056
+ Definido como padrão <tt>true</tt>
3057
+ </dd>
3058
+ </dl>
3059
+
3060
+ ## Ambientes
3061
+
3062
+ Existem três `environments` (ambientes) pré-definidos: `"development"`
3063
+ (desenvolvimento), `"production"` (produção) e `"test"` (teste). Ambientes
3064
+ podem ser definidos através da variável de ambiente `APP_ENV`. O valor padrão é
3065
+ `"development"`. No ambiente `"development"` todos os templates são
3066
+ recarregados entre as requisições e manipuladores especiais como `not_found` e
3067
+ `error` exibem relatórios de erros no seu navegador. Nos ambientes de
3068
+ `"production"` e `"test"`, os templates são guardos em cache por padrão.
3069
+
3070
+ Para rodar diferentes ambientes, defina a variável de ambiente `APP_ENV`:
3071
+
3072
+ ```shell
3073
+ APP_ENV=production ruby minha_app.rb
3074
+ ```
3075
+
3076
+ Você pode usar métodos pré-definidos: `development?`, `test?` e `production?`
3077
+ para checar a configuração atual de ambiente:
3078
+
3079
+ ```ruby
3080
+ get '/' do
3081
+ if settings.development?
3082
+ "desenvolvimento!"
3083
+ else
3084
+ "não está em desenvolvimento!"
3085
+ end
3086
+ end
3087
+ ```
3088
+
3089
+ ## Tratamento de Erros
3090
+
3091
+ Manipuladores de erros rodam dentro do mesmo contexto como rotas e filtros
3092
+ before, o que significa que você pega todos os "presentes" que eles têm para
3093
+ oferecer, como `haml`, `erb`, `halt`, etc.
3094
+
3095
+ ### Não Encontrado
3096
+
3097
+ Quando uma exceção `Sinatra::NotFound` é lançada, ou o código de
3098
+ status da reposta é 404, o manipulador `not_found` é invocado:
3099
+
3100
+ ```ruby
3101
+ not_found do
3102
+ 'Isto está longe de ser encontrado'
3103
+ end
3104
+ ```
3105
+
3106
+ ### Erro
3107
+
3108
+ O manipulador `error` é invocado toda a vez que uma exceção é lançada a
3109
+ partir de um bloco de rota ou um filtro. Note que em desenvolvimento, ele irá
3110
+ rodar apenas se você tiver definido a opção para exibir exceções em
3111
+ `:after_handler`:
3112
+
3113
+ ```ruby
3114
+ set :show_exceptions, :after_handler
3115
+ ```
3116
+
3117
+ O objeto da exceção pode ser
3118
+ obtido a partir da variável Rack `sinatra.error`:
3119
+
3120
+ ```ruby
3121
+ error do
3122
+ 'Desculpe, houve um erro desagradável - ' + env['sinatra.error'].message
3123
+ end
3124
+ ```
3125
+
3126
+ Erros customizados:
3127
+
3128
+ ```ruby
3129
+ error MeuErroCustomizado do
3130
+ 'Então que aconteceu foi...' + env['sinatra.error'].message
3131
+ end
3132
+ ```
3133
+
3134
+ Então, se isso acontecer:
3135
+
3136
+ ```ruby
3137
+ get '/' do
3138
+ raise MeuErroCustomizado, 'alguma coisa ruim'
3139
+ end
3140
+ ```
3141
+
3142
+ Você receberá isso:
3143
+
3144
+ ```
3145
+ Então que aconteceu foi... alguma coisa ruim
3146
+ ````
3147
+
3148
+ Alternativamente, você pode instalar um manipulador de erro para um código
3149
+ de status:
3150
+
3151
+ ```ruby
3152
+ error 403 do
3153
+ 'Accesso negado'
3154
+ end
3155
+
3156
+ get '/secreto' do
3157
+ 403
3158
+ end
3159
+ ```
3160
+
3161
+ Ou um alcance:
3162
+
3163
+ ```ruby
3164
+ error 400..510 do
3165
+ 'Boom'
3166
+ end
3167
+ ```
3168
+
3169
+ O Sinatra instala os manipuladores especiais `not_found` e `error`
3170
+ quando roda sobre o ambiente de desenvolvimento para exibir relatórios de erros
3171
+ bonitos e informações adicionais de "debug" no seu navegador.
3172
+
3173
+ ## Rack Middleware
3174
+
3175
+ O Sinatra roda no [Rack](http://rack.github.io/), uma interface
3176
+ padrão mínima para frameworks web em Ruby. Um das capacidades mais
3177
+ interessantes do Rack para desenvolver aplicativos é suporte a
3178
+ “middleware” – componentes que ficam entre o servidor e sua aplicação
3179
+ monitorando e/ou manipulando o request/response do HTTP para prover
3180
+ vários tipos de funcionalidades comuns.
3181
+
3182
+ O Sinatra faz construtores pipelines do middleware Rack facilmente em um
3183
+ nível superior utilizando o método `use`:
3184
+
3185
+ ```ruby
3186
+ require 'sinatra'
3187
+ require 'meu_middleware_customizado'
3188
+
3189
+ use Rack::Lint
3190
+ use MeuMiddlewareCustomizado
3191
+
3192
+ get '/ola' do
3193
+ 'Olá mundo'
3194
+ end
3195
+ ```
3196
+
3197
+ A semântica de `use` é idêntica aquela definida para a DSL
3198
+ [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)
3199
+ (mais frequentemente utilizada para arquivos rackup). Por exemplo, o
3200
+ método `use` aceita múltiplos argumentos/variáveis bem como blocos:
3201
+
3202
+ ```ruby
3203
+ use Rack::Auth::Basic do |usuario, senha|
3204
+ usuario == 'admin' && senha == 'secreto'
3205
+ end
3206
+ ```
3207
+
3208
+ O Rack é distribuido com uma variedade de middleware padrões para logs,
3209
+ debugs, rotas de URL, autenticação, e manipuladores de sessão. Sinatra
3210
+ utilizada muitos desses componentes automaticamente baseando sobre
3211
+ configuração, então, tipicamente você não tem `use` explicitamente.
3212
+
3213
+ Você pode achar middlwares utéis em
3214
+ [rack](https://github.com/rack/rack/tree/master/lib/rack),
3215
+ [rack-contrib](https://github.com/rack/rack-contrib#readme),
3216
+ ou em [Rack wiki](https://github.com/rack/rack/wiki/List-of-Middleware).
3217
+
3218
+ ## Testando
3219
+
3220
+ Testes no Sinatra podem ser escritos utilizando qualquer biblioteca ou
3221
+ framework de teste baseados no Rack.
3222
+ [Rack::Test](http://gitrdoc.com/brynary/rack-test) é recomendado:
3223
+
3224
+ ```ruby
3225
+ require 'minha_aplicacao_sinatra'
3226
+ require 'minitest/autorun'
3227
+ require 'rack/test'
3228
+
3229
+ class MinhaAplicacaoTeste < Minitest::Test
3230
+ include Rack::Test::Methods
3231
+
3232
+ def app
3233
+ Sinatra::Application
3234
+ end
3235
+
3236
+ def meu_test_default
3237
+ get '/'
3238
+ assert_equal 'Ola Mundo!', last_response.body
3239
+ end
3240
+
3241
+ def teste_com_parametros
3242
+ get '/atender', :name => 'Frank'
3243
+ assert_equal 'Olá Frank!', last_response.bodymeet
3244
+ end
3245
+
3246
+ def test_com_ambiente_rack
3247
+ get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
3248
+ assert_equal "Você está utilizando o Songbird!", last_response.body
3249
+ end
3250
+ end
3251
+ ```
3252
+
3253
+ NOTA: Se você está usando o Sinatra no estilo modular, substitua
3254
+ `Sinatra::Application' acima com o nome da classe da sua aplicação
3255
+
3256
+ ## Sinatra::Base - Middleware, Bibliotecas e aplicativos modulares
3257
+
3258
+ Definir sua aplicação em um nível superior de trabalho funciona bem para
3259
+ micro aplicativos, mas tem consideráveis incovenientes na construção de
3260
+ componentes reutilizáveis como um middleware Rack, metal Rails,
3261
+ bibliotecas simples como um componente de servidor, ou mesmo extensões
3262
+ Sinatra. A DSL de nível superior polui o espaço do objeto e assume um
3263
+ estilo de configuração de micro aplicativos (exemplo: uma simples
3264
+ arquivo de aplicação, diretórios `./public` e `./views`, logs, página de
3265
+ detalhes de exceção, etc.). É onde o `Sinatra::Base` entra em jogo:
3266
+
3267
+ ```ruby
3268
+ require 'sinatra/base'
3269
+
3270
+ class MinhaApp < Sinatra::Base
3271
+ set :sessions, true
3272
+ set :foo, 'bar'
3273
+
3274
+ get '/' do
3275
+ 'Ola mundo!'
3276
+ end
3277
+ end
3278
+ ```
3279
+
3280
+ Os métodos disponíveis para subclasses `Sinatra::Base` são exatamente como
3281
+ aqueles disponíveis via a DSL de nível superior. Aplicações de nível
3282
+ mais alto podem ser convertidas para componentes `Sinatra::Base` com duas
3283
+ modificações:
3284
+
3285
+ * Seu arquivo deve requerer `sinatra/base` ao invés de `sinatra`; caso
3286
+ contrário, todos os métodos DSL do Sinatra são importados para o espaço de
3287
+ nomes principal.
3288
+
3289
+ * Coloque as rotas da sua aplicação, manipuladores de erro, filtros e opções
3290
+ numa subclasse de `Sinatra::Base`.
3291
+
3292
+ `Sinatra::Base` é um quadro branco. Muitas opções são desabilitadas por
1649
3293
  padrão, incluindo o servidor embutido. Veja [Opções e
1650
3294
  Configurações](http://www.sinatrarb.com/configuration.html) para
1651
- detalhes de opções disponíveis e seus comportamentos.
1652
-
1653
- SIDEBAR: A DSL de alto nível do Sinatra é implementada utilizando um simples
1654
- sistema de delegação. A classe `Sinatra::Application` – uma subclasse especial
1655
- da `Sinatra::Base` – recebe todos os `:get`, `:put`, `:post`, `:delete`,
1656
- `:before`, `:error`, `:not_found`, `:configure`, e `:set messages` enviados
1657
- para o alto nível. Dê uma olhada no código você mesmo: aqui está o
1658
- [Sinatra::Delegator
1659
- mixin](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128)
1660
- sendo [incluido dentro de um espaço
1661
- principal](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28)
3295
+ detalhes de opções disponíveis e seus comportamentos. Se você quer
3296
+ comportamento mais similiar à quando você definiu sua aplicação em nível mais
3297
+ alto (também conhecido como estilo Clássico), você pode usar subclasses de
3298
+ `Sinatra::Application`:
3299
+
3300
+ ```ruby
3301
+ require 'sinatra/base'
3302
+
3303
+ class MinhaApp < Sinatra::Application
3304
+ get '/' do
3305
+ 'Olá mundo!'
3306
+ end
3307
+ end
3308
+ ```
3309
+
3310
+ ### Estilo Clássico vs. Modular
3311
+
3312
+ Ao contrário da crença comum, não há nada de errado com o estilo clássico. Se
3313
+ encaixa com sua aplicação, você não tem que mudar para uma aplicação modular.
3314
+
3315
+ As desvantagens principais de usar o estilo clássico no lugar do estilo modular
3316
+ é que você ira ter apenas uma aplicação Sinatra por processo Ruby. Se seu plano
3317
+ é usar mais de uma, mude para o estilo modular. Não há nenhum impedimento para
3318
+ você misturar os estilos clássico e modular.
3319
+
3320
+ Se vai mudar de um estilo para outro, você deve tomar cuidado com algumas
3321
+ configurações diferentes:
3322
+
3323
+ <table>
3324
+ <tr>
3325
+ <th>Configuração</th>
3326
+ <th>Clássico</th>
3327
+ <th>Modular</th>
3328
+ <th>Modular</th>
3329
+ </tr>
3330
+
3331
+ <tr>
3332
+ <td>app_file</td>
3333
+ <td>arquivo carregando sinatra</td>
3334
+ <td>arquivo usando subclasse Sinatra::Base</td>
3335
+ <td>arquivo usando subclasse Sinatra::Application</td>
3336
+ </tr>
3337
+
3338
+ <tr>
3339
+ <td>run</td>
3340
+ <td>$0 == app_file</td>
3341
+ <td>false</td>
3342
+ <td>false</td>
3343
+ </tr>
3344
+
3345
+ <tr>
3346
+ <td>logging</td>
3347
+ <td>true</td>
3348
+ <td>false</td>
3349
+ <td>true</td>
3350
+ </tr>
3351
+
3352
+ <tr>
3353
+ <td>method_override</td>
3354
+ <td>true</td>
3355
+ <td>false</td>
3356
+ <td>true</td>
3357
+ </tr>
3358
+
3359
+ <tr>
3360
+ <td>inline_templates</td>
3361
+ <td>true</td>
3362
+ <td>false</td>
3363
+ <td>true</td>
3364
+ </tr>
3365
+
3366
+ <tr>
3367
+ <td>static</td>
3368
+ <td>true</td>
3369
+ <td>File.exist?(public_folder)</td>
3370
+ <td>true</td>
3371
+ </tr>
3372
+ </table>
3373
+
3374
+ ### Servindo uma Aplicação Modular:
3375
+
3376
+ Existem duas opções comuns para começar uma aplicação modular, ativamente
3377
+ começando com `run!`:
3378
+
3379
+ ```ruby
3380
+ # minha_app.rb
3381
+ require 'sinatra/base'
3382
+
3383
+ class MinhaApp < Sinatra::Base
3384
+ # ... código da aplicação aqui ...
3385
+
3386
+ # inicie o servidor se o arquivo ruby foi executado diretamente
3387
+ run! if app_file == $0
3388
+ end
3389
+ ```
3390
+
3391
+ Inicie com with:
3392
+
3393
+ ```shell
3394
+ ruby minha_app.rb
3395
+ ```
3396
+
3397
+ Ou com um arquivo `config.ru`, que permite você usar qualquer manipulador Rack:
3398
+
3399
+ ```ruby
3400
+ # config.ru (roda com rackup)
3401
+ require './minha_app'
3402
+ run MinhaApp
3403
+ ```
3404
+
3405
+ Rode:
3406
+
3407
+ ```shell
3408
+ rackup -p 4567
3409
+ ```
3410
+
3411
+ ### Usando uma Aplicação de Estilo Clássico com um config.ru:
3412
+
3413
+ Escreva o arquivo da sua aplicação:
3414
+
3415
+ ```ruby
3416
+ # app.rb
3417
+ require 'sinatra'
3418
+
3419
+ get '/' do
3420
+ 'Olá mundo!'
3421
+ end
3422
+ ```
3423
+
3424
+ E um `config.ru` correspondente:
3425
+
3426
+ ```ruby
3427
+ require './app'
3428
+ run Sinatra::Application
3429
+ ```
3430
+
3431
+ ### Quando usar um config.ru?
3432
+
3433
+ Um arquivo `config.ru` é recomendado se:
3434
+
3435
+ * Você quer lançar com um manipulador Rack diferente (Passenger, Unicorn,
3436
+ Heroku, ...).
3437
+
3438
+ * Você quer usar mais de uma subclasse de `Sinatra::Base`.
3439
+ * Você quer usar Sinatra apenas como middleware, mas não como um "endpoint".
3440
+
3441
+ **Não há necessidade de mudar para um `config.ru` simplesmente porque você mudou para o estilo modular, e você não tem que usar o estilo modular para rodar com um `config.ru`.**
3442
+
3443
+ ### Usando Sinatra como Middleware
3444
+
3445
+ O Sinatra não é capaz apenas de usar outro middleware Rack, qualquer aplicação
3446
+ Sinatra pode ser adicionada na frente de qualquer "endpoint" Rack como
3447
+ middleware. Esse endpoint pode ser outra aplicação Sinatra, ou qualquer outra
3448
+ aplicação baseada em Rack (Rails/Hanami/Roda/...):
3449
+
3450
+ ```ruby
3451
+ require 'sinatra/base'
3452
+
3453
+ class TelaLogin < Sinatra::Base
3454
+ enable :sessions
3455
+
3456
+ get('/login') { haml :login }
3457
+
3458
+ post('/login') do
3459
+ if params['nome'] == 'admin' && params['senha'] == 'admin'
3460
+ session['nome_usuario'] = params['nome']
3461
+ else
3462
+ redirect '/login'
3463
+ end
3464
+ end
3465
+ end
3466
+
3467
+ class MinhaApp < Sinatra::Base
3468
+ # middleware irá rodar filtros before
3469
+ use TelaLogin
3470
+
3471
+ before do
3472
+ unless session['nome_usuario']
3473
+ halt "Acesso negado, por favor <a href='/login'>login</a>."
3474
+ end
3475
+ end
3476
+
3477
+ get('/') { "Olá #{session['nome_usuario']}." }
3478
+ end
3479
+ ```
3480
+
3481
+ ### Criação de Aplicações Dinâmicas
3482
+
3483
+ Às vezes, você quer criar novas aplicações em tempo de execução sem ter que
3484
+ associa-las a uma constante. Você pode fazer isso com `Sinatra.new`:
3485
+
3486
+ ```ruby
3487
+ require 'sinatra/base'
3488
+ minha_app = Sinatra.new { get('/') { "oi" } }
3489
+ minha_app.run!
3490
+ ```
3491
+
3492
+ Isso leva a aplicação à herdar como um argumento opcional:
3493
+
3494
+ ```ruby
3495
+ # config.ru (roda com rackup)
3496
+ require 'sinatra/base'
3497
+
3498
+ controller = Sinatra.new do
3499
+ enable :logging
3500
+ helpers MeusHelpers
3501
+ end
3502
+
3503
+ map('/a') do
3504
+ run Sinatra.new(controller) { get('/') { 'a' } }
3505
+ end
3506
+
3507
+ map('/b') do
3508
+ run Sinatra.new(controller) { get('/') { 'b' } }
3509
+ end
3510
+ ```
3511
+
3512
+ Isso é especialmente útil para testar extensões do Sinatra ou usar Sinatra na
3513
+ sua própria biblioteca.
3514
+
3515
+ Isso também faz o uso do Sinatra como middleware extremamente fácil:
3516
+
3517
+ ```ruby
3518
+ require 'sinatra/base'
3519
+
3520
+ use Sinatra do
3521
+ get('/') { ... }
3522
+ end
3523
+
3524
+ run RailsProject::Application
3525
+ ```
3526
+
3527
+ # Escopos e Ligação
3528
+
3529
+ O escopo que você está atualmente determina quais métodos e varáveis está
3530
+ disponíveis.
3531
+
3532
+ ### Escopo de Aplicação/Classe
3533
+
3534
+ Toda aplicação Sinatra corresponde à um subclasse de `Sinatra::Base`. Se você
3535
+ está utilizando a DSL de nível mais alto (`require 'sinatra`), então esta
3536
+ classe é `Sinatra::Application`, caso contrário é a subclasse que você criou
3537
+ explicitamente. No nível de classe você tem métodos como `get` ou `before`, mas
3538
+ você não pode acessar os objetos `request` ou `session`, como existe apenas uma
3539
+ única classe de aplicativo para todas as solicitações.
3540
+
3541
+ Opções criadas via `set` são métodos a nível de classe:
3542
+
3543
+ ```ruby
3544
+ class MinhaApp < Sinatra::Base
3545
+ # Hey, eu estou no escopo da aplicação!
3546
+ set :foo, 42
3547
+ foo # => 42
3548
+
3549
+ get '/foo' do
3550
+ # Hey, eu não estou mais no escopo da aplicação!
3551
+ end
3552
+ end
3553
+ ```
3554
+
3555
+ Você tem a ligação ao escopo da aplicação dentro:
3556
+
3557
+ * Do corpo da classe da sua aplicação
3558
+ * De métodos definidos por extensões
3559
+ * Do bloco passado a `helpers`
3560
+ * De Procs/Blocos usados como valor para `set``
3561
+ * Do bloco passado a `Sinatra.new``
3562
+
3563
+ Você pode atingir o escopo do objeto (a classe) de duas maneiras:
3564
+
3565
+ * Por meio do objeto passado aos blocos "configure" (`configure { |c| ...}`)
3566
+ * `settings` de dentro do escopo da requisição
3567
+
3568
+ ### Escopo de Instância/Requisição
3569
+
3570
+ Para toda requsição que chega, uma nova instância da classe da sua aplicação é
3571
+ criada e todos blocos de manipulação rodam nesse escopo. Dentro desse escopo
3572
+ você pode acessar os objetos `request` e `session` ou chamar métodos de
3573
+ renderização como `erb` ou `haml`. Você pode acessar o escopo da aplicação de
3574
+ dentro do escopo da requisição através do método auxiliar `settings`:
3575
+
3576
+ ```ruby
3577
+ class MinhaApp < Sinatra::Base
3578
+ # Hey, eu estou no escopo da aplicação!
3579
+ get '/define_rota/:nome' do
3580
+ # Escopo da requisição para '/define_rota/:nome'
3581
+ @valor = 42
3582
+
3583
+ settings.get("/#{params['nome']}") do
3584
+ # Escopo da requisição para "/#{params['nome']}"
3585
+ @valor # => nil (não é a mesma requisição)
3586
+ end
3587
+
3588
+ "Rota definida!"
3589
+ end
3590
+ end
3591
+ ```
3592
+
3593
+ Você tem a ligação ao escopo da requisição dentro dos:
3594
+
3595
+ * blocos get, head, post, put, delete, options, patch, link e unlink
3596
+ * filtros after e before
3597
+ * métodos "helper" (auxiliares)
3598
+ * templates/views
3599
+
3600
+ ### Escopo de Delegação
3601
+
3602
+ O escopo de delegação apenas encaminha métodos ao escopo da classe. Entretando,
3603
+ ele não se comporta exatamente como o escopo da classse já que você não tem a
3604
+ ligação da classe. Apenas métodos marcados explicitamente para delegação
3605
+ estarão disponíveis e você não compartilha variáveis/estado com o escopo da
3606
+ classe (leia: você tem um `self` diferente). Você pode explicitamente adicionar
3607
+ delegações de métodos chamando `Sinatra::Delegator.delegate :method_name`.
3608
+
3609
+ Você tem a ligação com o escopo delegado dentro:
3610
+
3611
+ * Da ligação de maior nível, se você digitou `require "sinatra"`
3612
+ * De um objeto estendido com o mixin `Sinatra::Delegator`
3613
+
3614
+ Dê uma olhada no código você mesmo: aqui está [Sinatra::Delegator mixin](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/base.rb#L1609-1633) em [estendendo o objeto principal](https://github.com/sinatra/sinatra/blob/ca06364/lib/sinatra/main.rb#L28-30).
1662
3615
 
1663
3616
  ## Linha de Comando
1664
3617
 
1665
3618
  Aplicações Sinatra podem ser executadas diretamente:
1666
3619
 
1667
3620
  ```shell
1668
- ruby minhaapp.rb [-h] [-x] [-e AMBIENTE] [-p PORTA] [-o HOST] [-s SERVIDOR]
3621
+ ruby minhaapp.rb [-h] [-x] [-q] [-e AMBIENTE] [-p PORTA] [-o HOST] [-s MANIPULADOR]
1669
3622
  ```
1670
3623
 
1671
3624
  As opções são:
@@ -1676,19 +3629,20 @@ As opções são:
1676
3629
  -o # define o host (padrão é 0.0.0.0)
1677
3630
  -e # define o ambiente (padrão é development)
1678
3631
  -s # especifica o servidor/manipulador rack (padrão é thin)
1679
- -x # ativa o bloqueio (padrão é desligado)
3632
+ -x # ativa o bloqueio mutex (padrão é desligado)
1680
3633
  ```
1681
3634
 
1682
3635
  ### Multi-threading
1683
3636
 
1684
3637
  _Parafraseando [esta resposta no StackOverflow](resposta-so) por Konstantin_
1685
3638
 
1686
- Sinatra não impõe nenhum modelo de concorrencia, mas deixa isso como responsabilidade
1687
- do Rack (servidor) subjacente como o Thin, Puma ou WEBrick. Sinatra por si só é thread-safe,
1688
- então não há nenhum problema se um Rack handler usar um modelo de thread de concorrência. Isso
1689
- significaria que ao iniciar o servidor, você teria que espeficiar o método de invocação correto
1690
- para o Rack handler específico. Os seguintes exemplos é uma demonstração de como iniciar um
1691
- servidor Thin multi-thread:
3639
+ Sinatra não impõe nenhum modelo de concorrencia, mas deixa isso como
3640
+ responsabilidade do Rack (servidor) subjacente como o Thin, Puma ou WEBrick.
3641
+ Sinatra por si só é thread-safe, então não há nenhum problema se um Rack
3642
+ handler usar um modelo de thread de concorrência. Isso significaria que ao
3643
+ iniciar o servidor, você teria que espeficiar o método de invocação correto
3644
+ para o Rack handler específico. Os seguintes exemplos é uma demonstração de
3645
+ como iniciar um servidor Thin multi-thread:
1692
3646
 
1693
3647
  ```ruby
1694
3648
  # app.rb
@@ -1710,51 +3664,124 @@ Para iniciar o servidor seria:
1710
3664
  thin --threaded start
1711
3665
  ```
1712
3666
 
1713
- [resposrta-so]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
3667
+ ## Requerimentos
3668
+
3669
+ As seguintes versões do Ruby são oficialmente suportadas:
3670
+ <dl>
3671
+ <dt>Ruby 2.2</dt>
3672
+ <dd>
3673
+ 2.2 é totalmente suportada e recomendada. Atualmente não existem planos
3674
+ para para o suporte oficial para ela.
3675
+ </dd>
3676
+
3677
+ <dt>Rubinius</dt>
3678
+ <dd>
3679
+ Rubinius é oficialmente suportado (Rubinius >= 2.x). É recomendado rodar
3680
+ <tt>gem install puma</tt>.
3681
+ </dd>
3682
+
3683
+ <dt>JRuby</dt>
3684
+ <dd>
3685
+ A útlima versão estável lançada do JRuby é oficialmente suportada. Não é
3686
+ recomendado usar extensões em C com o JRuby. É recomendado rodar
3687
+ <tt>gem install trinidad</tt>.
3688
+ </dd>
3689
+ </dl>
3690
+
3691
+ Versões do Ruby antes da 2.2.2 não são mais suportadas pelo Sinatra 2.0.
3692
+
3693
+ Nós também estamos de olhos em versões futuras do Ruby.
3694
+
3695
+ As seguintes implementações do Ruby não são oficialmente suportadas mas sabemos
3696
+ que rodam o Sinatra:
3697
+
3698
+ * Versões antigas do JRuby e Rubinius
3699
+ * Ruby Enterprise Edition
3700
+ * MacRuby, Maglev, IronRuby
3701
+ * Ruby 1.9.0 e 1.9.1 (mas nós não recomendamos o uso dessas)
3702
+
3703
+ Não ser oficialmente suportada significa que se algo quebrar e não estiver nas
3704
+ plataformas suporta, iremos assumir que não é um problema nosso e sim das
3705
+ plataformas.
3706
+
3707
+ Nós também rodas nossa IC sobre ruby-head (lançamentos futuros do MRI), mas nós
3708
+ não podemos garantir nada, já que está em constante mudança. Espera-se que
3709
+ lançamentos futuros da versão 2.x sejam totalmente suportadas.
3710
+
3711
+ Sinatra deve funcionar em qualquer sistema operacional suportado pela
3712
+ implementação Ruby escolhida.
3713
+
3714
+ Se você rodar MacRuby, você deve rodar `gem install control_tower`.
3715
+
3716
+ O Sinatra atualmente não roda em Cardinal, SmallRuby, BlueRuby ou qualquer
3717
+ versão do Ruby anterior ao 2.2.
1714
3718
 
1715
3719
  ## A última versão
1716
3720
 
1717
- Se você gostaria de utilizar o código da última versão do Sinatra, crie
1718
- um clone local e execute sua aplicação com o diretório `sinatra/lib` no
1719
- `LOAD_PATH`:
3721
+ Se você gostaria de utilizar o código da última versão do Sinatra, sinta-se
3722
+ livre para rodar a aplicação com o ramo master, ele deve ser estável.
3723
+
3724
+ Nós também lançamos pré-lançamentos de gems de tempos em tempos, então você
3725
+ pode fazer:
3726
+
3727
+ ```shell
3728
+ gem install sinatra --pre
3729
+ ```
3730
+
3731
+ para obter alguma das últimas funcionalidades.
3732
+
3733
+ ### Com Bundler
3734
+
3735
+ Se você quer rodar sua aplicação com a última versão do Sinatra usando
3736
+ [Bundler](https://bundler.io) é recomendado fazer dessa forma.
3737
+
3738
+ Primeiramente, instale o Bundler, se você ainda não tiver:
1720
3739
 
1721
3740
  ```shell
1722
- cd minhaapp
1723
- git clone git://github.com/sinatra/sinatra.git
1724
- ruby -I sinatra/lib minhaapp.rb
3741
+ gem install bundler
1725
3742
  ```
1726
3743
 
1727
- Alternativamente, você pode adicionar o diretório do `sinatra/lib` no
1728
- `LOAD_PATH` do seu aplicativo:
3744
+ Então, no diretório do seu projeto, crie uma `Gemfile`:
1729
3745
 
1730
3746
  ```ruby
1731
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
1732
- require 'rubygems'
1733
- require 'sinatra'
3747
+ source 'https://rubygems.org'
3748
+ gem 'sinatra', :github => 'sinatra/sinatra'
1734
3749
 
1735
- get '/sobre' do
1736
- "Estou rodando a versão" + Sinatra::VERSION
1737
- end
3750
+ # outras dependências
3751
+ gem 'haml' # por exemplo, se você usar haml
1738
3752
  ```
1739
3753
 
1740
- Para atualizar o código do Sinatra no futuro:
3754
+ Perceba que você terá que listar todas suas dependências de aplicação no
3755
+ `Gemfile`. As dependências diretas do Sinatra (Rack e Tilt) irão, entretanto,
3756
+ ser automaticamente recuperadas e adicionadas pelo Bundler.
3757
+
3758
+ Então você pode rodar sua aplicação assim:
1741
3759
 
1742
3760
  ```shell
1743
- cd meuprojeto/sinatra
1744
- git pull
3761
+ bundle exec ruby myapp.rb
1745
3762
  ```
1746
3763
 
3764
+ ## Versionando
3765
+
3766
+ O Sinatras segue [Versionamento Semântico](https://semver.org/), tanto SemVer
3767
+ como SemVerTag.
3768
+
1747
3769
  ## Mais
1748
3770
 
1749
3771
  * [Website do Projeto](http://www.sinatrarb.com/) - Documentação
1750
- adicional, novidades e links para outros recursos.
1751
- * [Contribuir](http://www.sinatrarb.com/contributing) - Encontrar um
1752
- bug? Precisa de ajuda? Tem um patch?
1753
- * [Acompanhar Questões](https://github.com/sinatra/sinatra/issues)
3772
+ adicional, novidades e links para outros recursos.
3773
+ * [Contribuir](http://www.sinatrarb.com/contributing) - Encontrou um
3774
+ bug? Precisa de ajuda? Tem um patch?
3775
+ * [Acompanhar Problemas](https://github.com/sinatra/sinatra/issues)
1754
3776
  * [Twitter](https://twitter.com/sinatra)
1755
3777
  * [Lista de Email](http://groups.google.com/group/sinatrarb/topics)
1756
- * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Livro de Receitas
1757
- * Documentação da API para a [última release](http://www.rubydoc.info/gems/sinatra)
1758
- * [IRC: \#sinatra](irc://chat.freenode.net/#sinatra) em
1759
- [freenode.net](http://freenode.net)
3778
+ * [Sinatra & Amigos](https://sinatrarb.slack.com) no Slack
3779
+ ([consiga um convite](https://sinatra-slack.herokuapp.com/))
3780
+ * [Sinatra Book](https://github.com/sinatra/sinatra-book/) - Livro de "Receitas"
3781
+ * [Sinatra Recipes](http://recipes.sinatrarb.com/) - "Receitas" de
3782
+ contribuições da comunidade
3783
+ * Documentação da API para a
3784
+ [última release](http://www.rubydoc.info/gems/sinatra)
3785
+ ou para o [HEAD atual](http://www.rubydoc.info/github/sinatra/sinatra)
3786
+ no [Ruby Doc](http://www.rubydoc.info/)
1760
3787
  * [Servidor de CI](https://travis-ci.org/sinatra/sinatra)