sinatra 2.2.4 → 3.0.0

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.

data/README.pt-br.md DELETED
@@ -1,3787 +0,0 @@
1
- # Sinatra
2
-
3
- *Atenção: Este documento é apenas uma tradução da versão em inglês e
4
- pode estar desatualizado.*
5
-
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:
9
-
10
- ```ruby
11
- # encoding: utf-8
12
- ```
13
-
14
- Sinatra é uma
15
- [DSL](https://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para
16
- criar aplicações web em Ruby com o mínimo de esforço e rapidez:
17
-
18
- ```ruby
19
- # minha_app.rb
20
- require 'sinatra'
21
-
22
- get '/' do
23
- 'Olá Mundo!'
24
- end
25
- ```
26
-
27
- Instale a gem:
28
-
29
- ```shell
30
- gem install sinatra
31
- ```
32
-
33
- Em seguida execute:
34
-
35
- ```shell
36
- ruby minha_app.rb
37
- ```
38
-
39
- Acesse em: [http://localhost:4567](http://localhost:4567)
40
-
41
- Códigos alterados só 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.
47
-
48
- ## Conteúdo
49
-
50
- * [Sinatra](#sinatra)
51
- * [Conteúdo](#conteúdo)
52
- * [Rotas](#rotas)
53
- * [Condições](#condições)
54
- * [Valores Retornados](#valores-retornados)
55
- * [Validadores de rota personalizados](#validadores-de-rota-personalizados)
56
- * [Arquivos estáticos](#arquivos-estáticos)
57
- * [Views / Templates](#views--templates)
58
- * [Literal Templates](#literal-templates)
59
- * [Linguagens de template disponíveis](#linguagens-de-template-disponíveis)
60
- * [Haml Templates](#haml-templates)
61
- * [Erb Templates](#erb-templates)
62
- * [Builder Templates](#builder-templates)
63
- * [Nokogiri Templates](#nokogiri-templates)
64
- * [Sass Templates](#sass-templates)
65
- * [SCSS Templates](#scss-templates)
66
- * [Less Templates](#less-templates)
67
- * [Liquid Templates](#liquid-templates)
68
- * [Markdown Templates](#markdown-templates)
69
- * [Textile Templates](#textile-templates)
70
- * [RDoc Templates](#rdoc-templates)
71
- * [AsciiDoc Templates](#asciidoc-templates)
72
- * [Radius Templates](#radius-templates)
73
- * [Markaby Templates](#markaby-templates)
74
- * [RABL Templates](#rabl-templates)
75
- * [Slim Templates](#slim-templates)
76
- * [Creole Templates](#creole-templates)
77
- * [MediaWiki Templates](#mediawiki-templates)
78
- * [CoffeeScript Templates](#coffeescript-templates)
79
- * [Stylus Templates](#stylus-templates)
80
- * [Yajl Templates](#yajl-templates)
81
- * [WLang Templates](#wlang-templates)
82
- * [Acessando Variáveis nos Templates](#acessando-variáveis-nos-templates)
83
- * [Templates com `yield` e layouts aninhados](#templates-com-yield-e-layouts-aninhados)
84
- * [Templates Inline](#templates-inline)
85
- * [Templates Nomeados](#templates-nomeados)
86
- * [Associando extensões de arquivos](#associando-extensões-de-arquivos)
87
- * [Adicionando seu Próprio Engine de Template](#adicionando-seu-próprio-engine-de-template)
88
- * [Customizando lógica para encontrar templates](#customizando-lógica-para-encontrar-templates)
89
- * [Filtros](#filtros)
90
- * [Helpers](#helpers)
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)
95
- * [Halting](#halting)
96
- * [Passing](#passing)
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)
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)
114
- * [Tratamento de Erros](#tratamento-de-erros)
115
- * [Não Encontrado](#não-encontrado)
116
- * [Erro](#erro)
117
- * [Rack Middleware](#rack-middleware)
118
- * [Testando](#testando)
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)
130
- * [Linha de comando](#linha-de-comando)
131
- * [Multi-threading](#multi-threading)
132
- * [Requerimentos](#requerimentos)
133
- * [A última versão](#a-última-versão)
134
- * [Com Bundler](#com-bundler)
135
- * [Versionando](#versionando)
136
- * [Mais](#mais)
137
-
138
- ## Rotas
139
-
140
- No Sinatra, uma rota é um método HTTP emparelhado com um padrão de URL.
141
- Cada rota possui um bloco de execução:
142
-
143
- ```ruby
144
- get '/' do
145
- .. mostrando alguma coisa ..
146
- end
147
-
148
- post '/' do
149
- .. criando alguma coisa ..
150
- end
151
-
152
- put '/' do
153
- .. atualizando alguma coisa ..
154
- end
155
-
156
- patch '/' do
157
- .. modificando alguma coisa ..
158
- end
159
-
160
- delete '/' do
161
- .. removendo alguma coisa ..
162
- end
163
-
164
- options '/' do
165
- .. estabelecendo alguma coisa ..
166
- end
167
-
168
- link '/' do
169
- .. associando alguma coisa ..
170
- end
171
-
172
- unlink '/' do
173
- .. separando alguma coisa ..
174
- end
175
- ```
176
-
177
- As rotas são interpretadas na ordem em que são definidas. A primeira
178
- rota encontrada responde a requisição.
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
-
188
- Padrões de rota podem conter parâmetros nomeados, acessíveis por meio do
189
- hash `params`:
190
-
191
- ```ruby
192
- get '/ola/:nome' do
193
- # corresponde a "GET /ola/foo" e "GET /ola/bar"
194
- # params['nome'] é 'foo' ou 'bar'
195
- "Olá #{params['nome']}!"
196
- end
197
- ```
198
-
199
- Você também pode acessar parâmetros nomeados por meio dos parâmetros de
200
- um bloco:
201
-
202
- ```ruby
203
- get '/ola/:nome' do |n|
204
- # corresponde a "GET /ola/foo" e "GET /ola/bar"
205
- # params['nome'] é 'foo' ou 'bar'
206
- # n guarda o valor de params['nome']
207
- "Olá #{n}!"
208
- end
209
- ```
210
-
211
- Padrões de rota também podem conter parâmetros splat (curinga),
212
- acessível por meio do array `params['splat']`:
213
-
214
- ```ruby
215
- get '/diga/*/para/*' do
216
- # corresponde a /diga/ola/para/mundo
217
- params['splat'] # => ["ola", "mundo"]
218
- end
219
-
220
- get '/download/*.*' do
221
- # corresponde a /download/caminho/do/arquivo.xml
222
- params['splat'] # => ["caminho/do/arquivo", "xml"]
223
- end
224
- ```
225
-
226
- Ou com parâmetros de um bloco:
227
-
228
- ```ruby
229
- get '/download/*.*' do |caminho, ext|
230
- [caminho, ext] # => ["caminho/do/arquivo", "xml"]
231
- end
232
- ```
233
-
234
- Rotas podem casar com expressões regulares:
235
-
236
- ```ruby
237
- get /\/ola\/([\w]+)/ do
238
- "Olá, #{params['captures'].first}!"
239
- end
240
- ```
241
-
242
- Ou com parâmetros de um bloco:
243
-
244
- ```ruby
245
- get %r{/ola/([\w]+)} do |c|
246
- # corresponde a "GET /meta/ola/mundo", "GET /ola/mundo/1234" etc.
247
- "Olá, #{c}!"
248
- end
249
- ```
250
-
251
- Padrões de rota podem contar com parâmetros opcionais:
252
-
253
- ```ruby
254
- get '/posts/:formato?' do
255
- # corresponde a "GET /posts/" e qualquer extensão "GET /posts/json", "GET /posts/xml", etc.
256
- end
257
- ```
258
-
259
- Rotas também podem utilizar query strings:
260
-
261
- ```ruby
262
- get '/posts' do
263
- # corresponde a "GET /posts?titulo=foo&autor=bar"
264
- titulo = params['titulo']
265
- autor = params['autor']
266
- # utiliza as variáveis titulo e autor; a query é opcional para a rota /posts
267
- end
268
- ```
269
-
270
- A propósito, a menos que você desative a proteção contra ataques (veja
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)
288
-
289
- ## Condições
290
-
291
- Rotas podem incluir uma variedade de condições, tal como o `user agent`:
292
-
293
- ```ruby
294
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
295
- "Você está usando o Songbird versão #{params['agent'][0]}"
296
- end
297
-
298
- get '/foo' do
299
- # Correspondente a navegadores que não sejam Songbird
300
- end
301
- ```
302
-
303
- Outras condições disponíveis são `host_name` e `provides`:
304
-
305
- ```ruby
306
- get '/', :host_name => /^admin\./ do
307
- "Área administrativa. Acesso negado!"
308
- end
309
-
310
- get '/', :provides => 'html' do
311
- haml :index
312
- end
313
-
314
- get '/', :provides => ['rss', 'atom', 'xml'] do
315
- builder :feed
316
- end
317
- ```
318
- `provides` procura o cabeçalho Accept das requisições
319
-
320
- Você pode facilmente definir suas próprias condições:
321
-
322
- ```ruby
323
- set(:probabilidade) { |valor| condition { rand <= valor } }
324
-
325
- get '/ganha_um_carro', :probabilidade => 0.1 do
326
- "Você ganhou!"
327
- end
328
-
329
- get '/ganha_um_carro' do
330
- "Sinto muito, você perdeu."
331
- end
332
- ```
333
-
334
- Use splat, para uma condição que leva vários valores:
335
-
336
- ```ruby
337
- set(:auth) do |*roles| # <- observe o splat aqui
338
- condition do
339
- unless logged_in? && roles.any? {|role| current_user.in_role? role }
340
- redirect "/login/", 303
341
- end
342
- end
343
- end
344
-
345
- get "/minha/conta/", :auth => [:usuario, :administrador] do
346
- "Detalhes da sua conta"
347
- end
348
-
349
- get "/apenas/administrador/", :auth => :administrador do
350
- "Apenas administradores são permitidos aqui!"
351
- end
352
- ```
353
-
354
- ## Retorno de valores
355
-
356
- O valor de retorno do bloco de uma rota determina pelo menos o corpo da
357
- resposta passado para o cliente HTTP, ou pelo menos o próximo middleware
358
- na pilha Rack. Frequentemente, isto é uma `string`, tal como nos
359
- exemplos acima. Entretanto, outros valores também são aceitos.
360
-
361
- Você pode retornar uma resposta válida ou um objeto para o Rack, sendo
362
- eles de qualquer tipo de objeto que queira. Além disso, é possível
363
- retornar um código de status HTTP.
364
-
365
- * Um array com três elementos: `[status (Integer), cabeçalho (Hash),
366
- corpo da resposta (responde à #each)]`
367
-
368
- * Um array com dois elementos: `[status (Integer), corpo da resposta
369
- (responde à #each)]`
370
-
371
- * Um objeto que responda à `#each` sem passar nada, mas, sim, `strings`
372
- para um dado bloco
373
-
374
- * Um objeto `Integer` representando o código de status
375
-
376
- Dessa forma, podemos implementar facilmente um exemplo de streaming:
377
-
378
- ```ruby
379
- class Stream
380
- def each
381
- 100.times { |i| yield "#{i}\n" }
382
- end
383
- end
384
-
385
- get('/') { Stream.new }
386
- ```
387
-
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.
391
-
392
- ## Validadores de Rota Personalizados
393
-
394
- Como apresentado acima, a estrutura do Sinatra conta com suporte
395
- embutido para uso de padrões de String e expressões regulares como
396
- validadores de rota. No entanto, ele não pára por aí. Você pode
397
- facilmente definir os seus próprios validadores:
398
-
399
- ```ruby
400
- class AllButPattern
401
- Match = Struct.new(:captures)
402
-
403
- def initialize(except)
404
- @except = except
405
- @captures = Match.new([])
406
- end
407
-
408
- def match(str)
409
- @captures unless @except === str
410
- end
411
- end
412
-
413
- def all_but(pattern)
414
- AllButPattern.new(pattern)
415
- end
416
-
417
- get all_but("/index") do
418
- # ...
419
- end
420
- ```
421
-
422
- Note que o exemplo acima pode ser robusto e complicado em excesso. Pode
423
- também ser implementado como:
424
-
425
- ```ruby
426
- get // do
427
- pass if request.path_info == "/index"
428
- # ...
429
- end
430
- ```
431
-
432
- Ou, usando algo mais denso à frente:
433
-
434
- ```ruby
435
- get %r{(?!/index)} do
436
- # ...
437
- end
438
- ```
439
-
440
- ## Arquivos estáticos
441
-
442
- Arquivos estáticos são disponibilizados a partir do diretório
443
- `./public`. Você pode especificar um local diferente pela opção
444
- `:public_folder`
445
-
446
- ```ruby
447
- set :public_folder, __dir__ + '/estatico'
448
- ```
449
-
450
- Note que o nome do diretório público não é incluído na URL. Um arquivo
451
- `./public/css/style.css` é disponibilizado como
452
- `http://exemplo.com/css/style.css`.
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
-
457
- ## Views / Templates
458
-
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:
461
-
462
- ```ruby
463
- get '/' do
464
- erb :index
465
- end
466
- ```
467
-
468
- Isto renderiza `views/index.rb`
469
-
470
- Ao invés do nome do template, você também pode passar direto o conteúdo do
471
- template:
472
-
473
- ```ruby
474
- get '/' do
475
- code = "<%= Time.now %>"
476
- erb code
477
- end
478
- ```
479
-
480
- Templates também aceitam como um segundo argumento, um hash de opções:
481
-
482
- ```ruby
483
- get '/' do
484
- erb :index, :layout => :post
485
- end
486
- ```
487
-
488
- Isto irá renderizar a `views/index.erb` inclusa dentro da `views/post.erb`
489
- (o padrão é a `views/layout.erb`, se existir).
490
-
491
- Qualquer opção não reconhecida pelo Sinatra será passada adiante para o engine
492
- de template:
493
-
494
- ```ruby
495
- get '/' do
496
- haml :index, :format => :html5
497
- end
498
- ```
499
-
500
- Você também pode definir opções padrões para um tipo de template:
501
-
502
- ```ruby
503
- set :haml, :format => :html5
504
-
505
- get '/' do
506
- haml :index
507
- end
508
- ```
509
-
510
- Opções passadas para o método de renderização sobrescreve as opções definitas
511
- através do método `set`.
512
-
513
- Opções disponíveis:
514
-
515
- <dl>
516
- <dt>locals</dt>
517
- <dd>
518
- Lista de locais passado para o documento. Conveniente para *partials*
519
- Exemplo: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
520
- </dd>
521
-
522
- <dt>default_encoding</dt>
523
- <dd>
524
- String encoding para ser utilizada em caso de incerteza. o padrão é
525
- <tt>settings.default_encoding</tt>.
526
- </dd>
527
-
528
- <dt>views</dt>
529
- <dd>
530
- Diretório de onde os templates são carregados. O padrão é
531
- <tt>settings.views</tt>.
532
- </dd>
533
-
534
- <dt>layout</dt>
535
- <dd>
536
- Para definir quando utilizar ou não um
537
- layout (<tt>true</tt> ou <tt>false</tt>). E se for um
538
- Symbol, especifica qual template usar. Exemplo:
539
- <tt>erb :index, :layout => !request.xhr?</tt>
540
- </dd>
541
-
542
- <dt>content_type</dt>
543
- <dd>
544
- O *Content-Type* que o template produz. O padrão depende
545
- da linguagem de template utilizada.
546
- </dd>
547
-
548
- <dt>scope</dt>
549
- <dd>
550
- Escopo em que o template será renderizado. Padrão é a
551
- instância da aplicação. Se você mudar isto as variáveis
552
- de instância métodos auxiliares não serão
553
- disponibilizados.
554
- </dd>
555
-
556
- <dt>layout_engine</dt>
557
- <dd>
558
- A engine de template utilizada para renderizar seu layout.
559
- Útil para linguagens que não suportam templates de outra
560
- forma. O padrão é a engine do template utilizado. Exemplo:
561
- <tt>set :rdoc, :layout_engine => :erb</tt>
562
- </dd>
563
-
564
- <dt>layout_options</dt>
565
- <dd>
566
- Opções especiais utilizadas apenas para renderizar o
567
- layout. Exemplo:
568
- <tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt>
569
- </dd>
570
- </dl>
571
-
572
- É pressuposto que os templates estarão localizados diretamente sob o
573
- diretório `./views`. Para usar um diretório diferente:
574
-
575
- ```ruby
576
- set :views, settings.root + '/templates'
577
- ```
578
-
579
- Uma coisa importante para se lembrar é que você sempre deve
580
- referenciar os templates utilizando *symbols*, mesmo que
581
- eles estejam em um subdiretório (neste caso use:
582
- `:'subdir/template'` or `'subdir/template'.to_sym`). Você deve
583
- utilizar um *symbol* porque senão o método de renderização irá
584
- renderizar qualquer outra string que você passe diretamente
585
- para ele
586
-
587
- ### Literal Templates
588
-
589
- ```ruby
590
- get '/' do
591
- haml '%div.title Olá Mundo'
592
- end
593
- ```
594
-
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
- ```
604
-
605
- ### Linguagens de template disponíveis
606
-
607
- Algumas linguagens possuem múltiplas implementações. Para especificar qual
608
- implementação deverá ser utilizada (e para ser *thread-safe*), você deve
609
- requerê-la primeiro:
610
-
611
- ```ruby
612
- require 'rdiscount' # ou require 'bluecloth'
613
- get('/') { markdown :index }
614
- ```
615
-
616
- #### Haml Templates
617
-
618
- <table>
619
- <tr>
620
- <td>Dependência</td>
621
- <td><a href="http://haml.info/" title="haml">haml</a></td>
622
- </tr>
623
- <tr>
624
- <td>Extensão do Arquivo</td>
625
- <td><tt>.haml</tt></td>
626
- </tr>
627
- <tr>
628
- <td>Exemplo</td>
629
- <td><tt>haml :index, :format => :html5</tt></td>
630
- </tr>
631
- </table>
632
-
633
- #### Erb Templates
634
-
635
- <table>
636
- <tr>
637
- <td>Dependência</td>
638
- <td>
639
- <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
640
- or erb (included in Ruby)
641
- </td>
642
- </tr>
643
- <tr>
644
- <td>Extensão dos Arquivos</td>
645
- <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubis</tt> (Erubis only)</td>
646
- </tr>
647
- <tr>
648
- <td>Exemplo</td>
649
- <td><tt>erb :index</tt></td>
650
- </tr>
651
- </table>
652
-
653
- #### Builder Templates
654
-
655
- <table>
656
- <tr>
657
- <td>Dependência</td>
658
- <td>
659
- <a href="https://github.com/jimweirich/builder" title="builder">
660
- builder
661
- </a>
662
- </td>
663
- </tr>
664
- <tr>
665
- <td>Extensão do Arquivo</td>
666
- <td><tt>.builder</tt></td>
667
- </tr>
668
- <tr>
669
- <td>Exemplo</td>
670
- <td><tt>builder { |xml| xml.em "hi" }</tt></td>
671
- </tr>
672
- </table>
673
-
674
- It also takes a block for inline templates (see exemplo).
675
-
676
- #### Nokogiri Templates
677
-
678
- <table>
679
- <tr>
680
- <td>Dependência</td>
681
- <td><a href="http://www.nokogiri.org/" title="nokogiri">nokogiri</a></td>
682
- </tr>
683
- <tr>
684
- <td>Extensão do Arquivo</td>
685
- <td><tt>.nokogiri</tt></td>
686
- </tr>
687
- <tr>
688
- <td>Exemplo</td>
689
- <td><tt>nokogiri { |xml| xml.em "hi" }</tt></td>
690
- </tr>
691
- </table>
692
-
693
- It also takes a block for inline templates (see exemplo).
694
-
695
- #### Sass Templates
696
-
697
- <table>
698
- <tr>
699
- <td>Dependência</td>
700
- <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
701
- </tr>
702
- <tr>
703
- <td>Extensão do Arquivo</td>
704
- <td><tt>.sass</tt></td>
705
- </tr>
706
- <tr>
707
- <td>Exemplo</td>
708
- <td><tt>sass :stylesheet, :style => :expanded</tt></td>
709
- </tr>
710
- </table>
711
-
712
- #### SCSS Templates
713
-
714
- <table>
715
- <tr>
716
- <td>Dependência</td>
717
- <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
718
- </tr>
719
- <tr>
720
- <td>Extensão do Arquivo</td>
721
- <td><tt>.scss</tt></td>
722
- </tr>
723
- <tr>
724
- <td>Exemplo</td>
725
- <td><tt>scss :stylesheet, :style => :expanded</tt></td>
726
- </tr>
727
- </table>
728
-
729
- #### Less Templates
730
-
731
- <table>
732
- <tr>
733
- <td>Dependência</td>
734
- <td><a href="http://lesscss.org/" title="less">less</a></td>
735
- </tr>
736
- <tr>
737
- <td>Extensão do Arquivo</td>
738
- <td><tt>.less</tt></td>
739
- </tr>
740
- <tr>
741
- <td>Exemplo</td>
742
- <td><tt>less :stylesheet</tt></td>
743
- </tr>
744
- </table>
745
-
746
- #### Liquid Templates
747
-
748
- <table>
749
- <tr>
750
- <td>Dependência</td>
751
- <td>
752
- <a href="https://shopify.github.io/liquid/" title="liquid">liquid</a>
753
- </td>
754
- </tr>
755
- <tr>
756
- <td>Extensão do Arquivo</td>
757
- <td><tt>.liquid</tt></td>
758
- </tr>
759
- <tr>
760
- <td>Exemplo</td>
761
- <td><tt>liquid :index, :locals => { :key => 'value' }</tt></td>
762
- </tr>
763
- </table>
764
-
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.
767
-
768
- #### Markdown Templates
769
-
770
- <table>
771
- <tr>
772
- <td>Dependência</td>
773
- <td>
774
- Anyone of:
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>
790
- </td>
791
- </tr>
792
- <tr>
793
- <td>Extensão do Arquivos</td>
794
- <td><tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt></td>
795
- </tr>
796
- <tr>
797
- <td>Exemplo</td>
798
- <td><tt>markdown :index, :layout_engine => :erb</tt></td>
799
- </tr>
800
- </table>
801
-
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:
804
-
805
- ```ruby
806
- erb :overview, :locals => { :text => markdown(:introducao) }
807
- ```
808
-
809
- Note que você também pode chamar o método `markdown` dentro de outros templates:
810
-
811
- ```ruby
812
- %h1 Olá do Haml!
813
- %p= markdown(:saudacoes)
814
- ```
815
-
816
- Já que você não pode chamar o Ruby pelo Markdown, você não
817
- pode utilizar um layout escrito em Markdown. Contudo é
818
- possível utilizar outra engine de renderização como template,
819
- deve-se passar a `:layout_engine` como opção.
820
-
821
- <table>
822
- <tr>
823
- <td>Dependência</td>
824
- <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
825
- </tr>
826
- <tr>
827
- <td>Extensão do Arquivo</td>
828
- <td><tt>.textile</tt></td>
829
- </tr>
830
- <tr>
831
- <td>Exemplo</td>
832
- <td><tt>textile :index, :layout_engine => :erb</tt></td>
833
- </tr>
834
- </table>
835
-
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:
838
-
839
- ```ruby
840
- erb :overview, :locals => { :text => textile(:introducao) }
841
- ```
842
-
843
- Note que você também pode chamar o método `textile` dentro de outros templates:
844
-
845
- ```ruby
846
- %h1 Olá do Haml!
847
- %p= textile(:saudacoes)
848
- ```
849
-
850
- Já que você não pode chamar o Ruby pelo Textile, você não
851
- pode utilizar um layout escrito em Textile. Contudo é
852
- possível utilizar outra engine de renderização como template,
853
- deve-se passar a `:layout_engine` como opção.
854
-
855
- #### RDoc Templates
856
-
857
- <table>
858
- <tr>
859
- <td>Dependência</td>
860
- <td><a href="http://rdoc.sourceforge.net/" title="RDoc">RDoc</a></td>
861
- </tr>
862
- <tr>
863
- <td>Extensão do Arquivo</td>
864
- <td><tt>.rdoc</tt></td>
865
- </tr>
866
- <tr>
867
- <td>Exemplo</td>
868
- <td><tt>rdoc :README, :layout_engine => :erb</tt></td>
869
- </tr>
870
- </table>
871
-
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:
874
-
875
- ```ruby
876
- erb :overview, :locals => { :text => rdoc(:introducao) }
877
- ```
878
-
879
- Note que você também pode chamar o método `rdoc` dentro de outros templates:
880
-
881
- ```ruby
882
- %h1 Olá do Haml!
883
- %p= rdoc(:saudacoes)
884
- ```
885
-
886
- Já que você não pode chamar o Ruby pelo RDoc, você não
887
- pode utilizar um layout escrito em RDoc. Contudo é
888
- possível utilizar outra engine de renderização como template,
889
- deve-se passar a `:layout_engine` como opção.
890
-
891
- #### AsciiDoc Templates
892
-
893
- <table>
894
- <tr>
895
- <td>Dependência</td>
896
- <td>
897
- <a href="http://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a>
898
- </td>
899
- </tr>
900
- <tr>
901
- <td>Extensão do Arquivo</td>
902
- <td><tt>.asciidoc</tt>, <tt>.adoc</tt> and <tt>.ad</tt></td>
903
- </tr>
904
- <tr>
905
- <td>Exemplo</td>
906
- <td><tt>asciidoc :README, :layout_engine => :erb</tt></td>
907
- </tr>
908
- </table>
909
-
910
- Já que você não pode chamar o Ruby pelo template AsciiDoc,
911
- você quase sempre precisará passar o `locals` para ele.
912
-
913
- #### Radius Templates
914
-
915
- <table>
916
- <tr>
917
- <td>Dependência</td>
918
- <td><a href="https://github.com/jlong/radius" title="Radius">Radius</a></td>
919
- </tr>
920
- <tr>
921
- <td>Extensão do Arquivo</td>
922
- <td><tt>.radius</tt></td>
923
- </tr>
924
- <tr>
925
- <td>Exemplo</td>
926
- <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
927
- </tr>
928
- </table>
929
-
930
- Já que você não pode chamar o Ruby pelo template Radius,
931
- você quase sempre precisará passar o `locals` para ele.
932
-
933
- #### Markaby Templates
934
-
935
- <table>
936
- <tr>
937
- <td>Dependência</td>
938
- <td><a href="http://markaby.github.io/" title="Markaby">Markaby</a></td>
939
- </tr>
940
- <tr>
941
- <td>Extensão do Arquivo</td>
942
- <td><tt>.mab</tt></td>
943
- </tr>
944
- <tr>
945
- <td>Exemplo</td>
946
- <td><tt>markaby { h1 "Welcome!" }</tt></td>
947
- </tr>
948
- </table>
949
-
950
- Este também recebe um bloco para templates (veja o exemplo).
951
-
952
- #### RABL Templates
953
-
954
- <table>
955
- <tr>
956
- <td>Dependência</td>
957
- <td><a href="https://github.com/nesquena/rabl" title="Rabl">Rabl</a></td>
958
- </tr>
959
- <tr>
960
- <td>Extensão do Arquivo</td>
961
- <td><tt>.rabl</tt></td>
962
- </tr>
963
- <tr>
964
- <td>Exemplo</td>
965
- <td><tt>rabl :index</tt></td>
966
- </tr>
967
- </table>
968
-
969
- #### Slim Templates
970
-
971
- <table>
972
- <tr>
973
- <td>Dependência</td>
974
- <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
975
- </tr>
976
- <tr>
977
- <td>Extensão do Arquivo</td>
978
- <td><tt>.slim</tt></td>
979
- </tr>
980
- <tr>
981
- <td>Exemplo</td>
982
- <td><tt>slim :index</tt></td>
983
- </tr>
984
- </table>
985
-
986
- #### Creole Templates
987
-
988
- <table>
989
- <tr>
990
- <td>Dependência</td>
991
- <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
992
- </tr>
993
- <tr>
994
- <td>Extensão do Arquivo</td>
995
- <td><tt>.creole</tt></td>
996
- </tr>
997
- <tr>
998
- <td>Exemplo</td>
999
- <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
1000
- </tr>
1001
- </table>
1002
-
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:
1005
-
1006
- ```ruby
1007
- erb :overview, :locals => { :text => creole(:introduction) }
1008
- ```
1009
-
1010
- Note que você também pode chamar o método `creole` dentro de outros templates:
1011
-
1012
- ```ruby
1013
- %h1 Olá do Haml!
1014
- %p= creole(:saudacoes)
1015
- ```
1016
-
1017
- Já que você não pode chamar o Ruby pelo Creole, você não
1018
- pode utilizar um layout escrito em Creole. Contudo é
1019
- possível utilizar outra engine de renderização como template,
1020
- deve-se passar a `:layout_engine` como opção.
1021
-
1022
- #### MediaWiki Templates
1023
-
1024
- <table>
1025
- <tr>
1026
- <td>Dependência</td>
1027
- <td>
1028
- <a href="https://github.com/nricciar/wikicloth" title="WikiCloth">
1029
- WikiCloth
1030
- </a>
1031
- </td>
1032
- </tr>
1033
- <tr>
1034
- <td>Extensão do Arquivo</td>
1035
- <td><tt>.mediawiki</tt> and <tt>.mw</tt></td>
1036
- </tr>
1037
- <tr>
1038
- <td>Exemplo</td>
1039
- <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
1040
- </tr>
1041
- </table>
1042
-
1043
- It is not possible to call methods from MediaWiki markup, nor to pass locals to
1044
- it. You therefore will usually use it in combination with another rendering
1045
- engine:
1046
-
1047
- ```ruby
1048
- erb :overview, :locals => { :text => mediawiki(:introduction) }
1049
- ```
1050
-
1051
- Note that you may also call the `mediawiki` method from within other templates:
1052
-
1053
- ```ruby
1054
- %h1 Hello From Haml!
1055
- %p= mediawiki(:greetings)
1056
- ```
1057
-
1058
- Já que você não pode chamar o Ruby pelo MediaWiki, você não
1059
- pode utilizar um layout escrito em MediaWiki. Contudo é
1060
- possível utilizar outra engine de renderização como template,
1061
- deve-se passar a `:layout_engine` como opção.
1062
-
1063
- #### CoffeeScript Templates
1064
-
1065
- <table>
1066
- <tr>
1067
- <td>Dependência</td>
1068
- <td>
1069
- <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
1070
- CoffeeScript
1071
- </a> and a
1072
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
1073
- way to execute javascript
1074
- </a>
1075
- </td>
1076
- </tr>
1077
- <tr>
1078
- <td>Extensão do Arquivo</td>
1079
- <td><tt>.coffee</tt></td>
1080
- </tr>
1081
- <tr>
1082
- <td>Exemplo</td>
1083
- <td><tt>coffee :index</tt></td>
1084
- </tr>
1085
- </table>
1086
-
1087
- #### Stylus Templates
1088
-
1089
- <table>
1090
- <tr>
1091
- <td>Dependência</td>
1092
- <td>
1093
- <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
1094
- Stylus
1095
- </a> and a
1096
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
1097
- way to execute javascript
1098
- </a>
1099
- </td>
1100
- </tr>
1101
- <tr>
1102
- <td>Extensão do Arquivo</td>
1103
- <td><tt>.styl</tt></td>
1104
- </tr>
1105
- <tr>
1106
- <td>Exemplo</td>
1107
- <td><tt>stylus :index</tt></td>
1108
- </tr>
1109
- </table>
1110
-
1111
- Antes que você possa utilizar o template Stylus primeiro você deve carregar
1112
- `stylus` e `stylus/tilt`:
1113
-
1114
- ```ruby
1115
- require 'sinatra'
1116
- require 'stylus'
1117
- require 'stylus/tilt'
1118
-
1119
- get '/' do
1120
- stylus :exemplo
1121
- end
1122
- ```
1123
-
1124
- #### Yajl Templates
1125
-
1126
- <table>
1127
- <tr>
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>
1134
- </tr>
1135
- <tr>
1136
- <td>Extensão do Arquivo</td>
1137
- <td><tt>.yajl</tt></td>
1138
- </tr>
1139
- <tr>
1140
- <td>Exemplo</td>
1141
- <td>
1142
- <tt>
1143
- yajl :index,
1144
- :locals => { :key => 'qux' },
1145
- :callback => 'present',
1146
- :variable => 'resource'
1147
- </tt>
1148
- </td>
1149
- </tr>
1150
- </table>
1151
-
1152
- O código-fonte do template é executado como uma string Ruby e a variável
1153
- resultante em json é convertida utilizando `#to_json`:
1154
-
1155
- ```ruby
1156
- json = { :foo => 'bar' }
1157
- json[:baz] = key
1158
- ```
1159
-
1160
- O `:callback` e `:variable` são opções que podem ser utilizadas para o objeto
1161
- de renderização:
1162
-
1163
- ```javascript
1164
- var resource = {"foo":"bar","baz":"qux"};
1165
- present(resource);
1166
- ```
1167
-
1168
- #### WLang Templates
1169
-
1170
- <table>
1171
- <tr>
1172
- <td>Dependência</td>
1173
- <td>
1174
- <a href="https://github.com/blambeau/wlang/" title="WLang">WLang</a>
1175
- </td>
1176
- </tr>
1177
- <tr>
1178
- <td>Extensão do Arquivo</td>
1179
- <td><tt>.wlang</tt></td>
1180
- </tr>
1181
- <tr>
1182
- <td>Exemplo</td>
1183
- <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1184
- </tr>
1185
- </table>
1186
-
1187
- Já que você não pode chamar o Ruby (exceto pelo método
1188
- `yield`) pelo template WLang,
1189
- você quase sempre precisará passar o `locals` para ele.
1190
-
1191
- ## Acessando Variáveis nos Templates
1192
-
1193
- Templates são avaliados dentro do mesmo contexto como manipuladores de
1194
- rota. Variáveis de instância definidas em manipuladores de rota são
1195
- diretamente acessadas por templates:
1196
-
1197
- ```ruby
1198
- get '/:id' do
1199
- @foo = Foo.find(params['id'])
1200
- haml '%h1= @foo.nome'
1201
- end
1202
- ```
1203
-
1204
- Ou, especifique um hash explícito de variáveis locais:
1205
-
1206
- ```ruby
1207
- get '/:id' do
1208
- foo = Foo.find(params['id'])
1209
- haml '%h1= foo.nome', :locals => { :foo => foo }
1210
- end
1211
- ```
1212
-
1213
- Isso é tipicamente utilizando quando renderizamos templates como
1214
- partials dentro de outros templates.
1215
-
1216
- ### Templates com `yield` e layouts aninhados
1217
-
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:
1221
-
1222
- ```ruby
1223
- erb :post, :layout => false do
1224
- erb :index
1225
- end
1226
- ```
1227
-
1228
- Este código é quase equivalente a `erb :index, :layout => :post`
1229
-
1230
- Passando blocos para os métodos de renderização é útil para criar layouts
1231
- aninhados:
1232
-
1233
- ```ruby
1234
- erb :main_layout, :layout => false do
1235
- erb :admin_layout do
1236
- erb :user
1237
- end
1238
- end
1239
- ```
1240
-
1241
- Também pode ser feito com menos linhas de código:
1242
-
1243
- ```ruby
1244
- erb :admin_layout, :layout => :main_layout do
1245
- erb :user
1246
- end
1247
- ```
1248
-
1249
- Atualmente os métodos listados aceitam blocos: `erb`, `haml`,
1250
- `liquid`, `slim `, `wlang`. E o método geral `render` também aceita blocos.
1251
-
1252
- ### Templates Inline
1253
-
1254
- Templates podem ser definidos no final do arquivo fonte:
1255
-
1256
- ```ruby
1257
- require 'sinatra'
1258
-
1259
- get '/' do
1260
- haml :index
1261
- end
1262
-
1263
- __END__
1264
-
1265
- @@ layout
1266
- %html
1267
- = yield
1268
-
1269
- @@ index
1270
- %div.title Olá Mundo.
1271
- ```
1272
-
1273
- NOTA: Templates inline definidos no arquivo fonte são automaticamente
1274
- carregados pelo Sinatra. Digite `enable :inline_templates` explicitamente se
1275
- você tem templates inline em outros arquivos fonte.
1276
-
1277
- ### Templates Nomeados
1278
-
1279
- Templates também podem ser definidos utilizando o método top-level
1280
- `template`:
1281
-
1282
- ```ruby
1283
- template :layout do
1284
- "%html\n =yield\n"
1285
- end
1286
-
1287
- template :index do
1288
- '%div.title Olá Mundo!'
1289
- end
1290
-
1291
- get '/' do
1292
- haml :index
1293
- end
1294
- ```
1295
-
1296
- Se existir um template com nome “layout”, ele será utilizado toda vez
1297
- que um template for renderizado. Você pode desabilitar layouts passando
1298
- `:layout => false` ou desabilita-los por padrão
1299
- via `set :haml, :layout => false`
1300
-
1301
- ```ruby
1302
- get '/' do
1303
- haml :index, :layout => !request.xhr?
1304
- end
1305
- ```
1306
-
1307
- ### Associando Extensões de Arquivos
1308
-
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:
1312
-
1313
- ```ruby
1314
- Tilt.register :tt, Tilt[:textile]
1315
- ```
1316
-
1317
- ### Adicionando seu Próprio Engine de Template
1318
-
1319
- Primeiro registre seu engine utilizando o Tilt, e então crie um método de
1320
- renderização:
1321
-
1322
- ```ruby
1323
- Tilt.register :myat, MyAwesomeTemplateEngine
1324
-
1325
- helpers do
1326
- def myat(*args) render(:myat, *args) end
1327
- end
1328
-
1329
- get '/' do
1330
- myat :index
1331
- end
1332
- ```
1333
-
1334
- Renderize `./views/index.myat`. Aprenda mais sobre o
1335
- Tilt [aqui](https://github.com/rtomayko/tilt#readme).
1336
-
1337
- ### Customizando Lógica para Encontrar Templates
1338
-
1339
- Para implementar sua própria lógica para busca de templates você pode escrever
1340
- seu próprio método `#find_template`
1341
-
1342
- ```ruby
1343
- configure do
1344
- set :views [ './views/a', './views/b' ]
1345
- end
1346
-
1347
- def find_template(views, name, engine, &block)
1348
- Array(views).each do |v|
1349
- super(v, name, engine, &block)
1350
- end
1351
- end
1352
- ```
1353
-
1354
- ## Filtros
1355
-
1356
- Filtros Before são avaliados antes de cada requisição dentro do contexto
1357
- da requisição e podem modificar a requisição e a reposta. Variáveis de
1358
- instância definidas nos filtros são acessadas através de rotas e
1359
- templates:
1360
-
1361
- ```ruby
1362
- before do
1363
- @nota = 'Oi!'
1364
- request.path_info = '/foo/bar/baz'
1365
- end
1366
-
1367
- get '/foo/*' do
1368
- @nota #=> 'Oi!'
1369
- params['splat'] #=> 'bar/baz'
1370
- end
1371
- ```
1372
-
1373
- Filtros After são avaliados após cada requisição dentro do mesmo contexto da
1374
- requisição e também podem modificar a requisição e a resposta. Variáveis de
1375
- instância definidas nos filtros before e rotas são acessadas através dos
1376
- filtros after:
1377
-
1378
- ```ruby
1379
- after do
1380
- puts response.status
1381
- end
1382
- ```
1383
-
1384
- Nota: A não ser que você use o método `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
-
1388
- Filtros opcionalmente têm um padrão, fazendo com que sejam avaliados
1389
- somente se o caminho do pedido coincidir com esse padrão:
1390
-
1391
- ```ruby
1392
- before '/protected/*' do
1393
- authenticate!
1394
- end
1395
-
1396
- after '/create/:slug' do |slug|
1397
- session[:last_slug] = slug
1398
- end
1399
- ```
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
-
1413
- ## Helpers
1414
-
1415
- Use o método de alto nível `helpers` para definir métodos auxiliares
1416
- para utilizar em manipuladores de rotas e modelos:
1417
-
1418
- ```ruby
1419
- helpers do
1420
- def bar(nome)
1421
- "#{nome}bar"
1422
- end
1423
- end
1424
-
1425
- get '/:nome' do
1426
- bar(params['nome'])
1427
- end
1428
- ```
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
-
1447
- ### Utilizando Sessões
1448
-
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:
1451
-
1452
- ```ruby
1453
- enable :sessions
1454
-
1455
- get '/' do
1456
- "value = " << session[:value].inspect
1457
- end
1458
-
1459
- get '/:value' do
1460
- session['value'] = params['value']
1461
- end
1462
- ```
1463
- #### Segredo Seguro da Sessão
1464
-
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
- caracteres 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.
1474
-
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.
1480
-
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:
1488
-
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
1522
- ```
1523
-
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:
1532
-
1533
- ```ruby
1534
- require 'securerandom'
1535
- # -or- require 'sysrandom/securearandom'
1536
- set :session_secret, ENV.fecth(`SESSION_SECRET`) { SecureRandom.hex(64) }
1537
- ```
1538
-
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`:
1543
-
1544
- ```ruby
1545
- set :sessions, :domain => 'foo.com'
1546
- ```
1547
-
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:
1550
-
1551
- ```ruby
1552
- set :sessions, :domain => '.foo.com'
1553
- ```
1554
-
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
1591
-
1592
- Para parar imediatamente uma requisição com um filtro ou rota utilize:
1593
-
1594
- ```ruby
1595
- halt
1596
- ```
1597
-
1598
- Você também pode especificar o status quando parar:
1599
-
1600
- ```ruby
1601
- halt 410
1602
- ```
1603
-
1604
- Ou o corpo:
1605
-
1606
- ```ruby
1607
- halt 'isso será o corpo'
1608
- ```
1609
-
1610
- Ou ambos:
1611
-
1612
- ```ruby
1613
- halt 401, 'vá embora!'
1614
- ```
1615
-
1616
- Com cabeçalhos:
1617
-
1618
- ```ruby
1619
- halt 402, {'Content-Type' => 'text/plain'}, 'revanche'
1620
- ```
1621
-
1622
- Também é obviamente possível combinar um template com o `halt`:
1623
-
1624
- ```ruby
1625
- halt erb(:error)
1626
- ```
1627
-
1628
- ### Passing
1629
-
1630
- Uma rota pode processar aposta para a próxima rota correspondente usando
1631
- `pass`:
1632
-
1633
- ```ruby
1634
- get '/adivinhar/:quem' do
1635
- pass unless params['quem'] == 'Frank'
1636
- 'Você me pegou!'
1637
- end
1638
-
1639
- get '/adivinhar/*' do
1640
- 'Você falhou!'
1641
- end
1642
- ```
1643
-
1644
- O bloqueio da rota é imediatamente encerrado e o controle continua com a
1645
- próxima rota compatível. Se nenhuma rota compatível for encontrada, um
1646
- 404 é retornado.
1647
-
1648
- ### Desencadeando Outra Rota
1649
-
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:
1653
-
1654
- ```ruby
1655
- get '/foo' do
1656
- status, headers, body = call env.merge("PATH_INFO" => '/bar')
1657
- [status, headers, body.map(&:upcase)]
1658
- end
1659
-
1660
- get '/bar' do
1661
- "bar"
1662
- end
1663
- ```
1664
-
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`.
1668
-
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`.
1671
-
1672
- Veja a especificação do Rack se você quer aprender mais sobre o `call`.
1673
-
1674
- ### Definindo Corpo, Código de Status e Cabeçalhos
1675
-
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 método auxiliar `body`. Se você fizer isso, poderá usar esse
1680
- método de agora em diante para acessar o body:
1681
-
1682
- ```ruby
1683
- get '/foo' do
1684
- body "bar"
1685
- end
1686
-
1687
- after do
1688
- puts body
1689
- end
1690
- ```
1691
-
1692
- Também é possível 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:
1697
-
1698
- ```ruby
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á!"
1705
- end
1706
- ```
1707
-
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:
1717
-
1718
- ```ruby
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
1727
- end
1728
- ```
1729
-
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.
1736
-
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.
1743
-
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:
1748
-
1749
- ```ruby
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
1762
- end
1763
-
1764
- post '/:mensagem' do
1765
- conexoes.each do |saida|
1766
- # notifica o cliente que uma nova mensagem chegou
1767
- saida << params['mensagem'] << "\n"
1768
-
1769
- # indica ao cliente para se conectar novamente
1770
- saida.close
1771
- end
1772
-
1773
- # confirma
1774
- "mensagem recebida"
1775
- end
1776
- ```
1777
-
1778
- Também é possível 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`:
1786
-
1787
- ```ruby
1788
- get '/' do
1789
- logger.info "loading data"
1790
- # ...
1791
- end
1792
- ```
1793
-
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 desabilitada, 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:
1802
-
1803
- ```ruby
1804
- class MyApp < Sinatra::Base
1805
- configure :production, :development do
1806
- enable :logging
1807
- end
1808
- end
1809
- ```
1810
-
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']`
1816
-
1817
- ### Tipos Mime
1818
-
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:
1822
-
1823
- ```ruby
1824
- configure do
1825
- mime_type :foo, 'text/foo'
1826
- end
1827
- ```
1828
-
1829
- Você pode utilizar também com o método auxiliar `content_type`:
1830
-
1831
- ```ruby
1832
- get '/' do
1833
- content-type :foo
1834
- "foo foo foo"
1835
- end
1836
- ```
1837
-
1838
- ### Gerando URLs
1839
-
1840
- Para gerar URLs você deve usar o método auxiliar `url` no Haml:
1841
-
1842
- ```ruby
1843
- %a{:href => url('/foo')} foo
1844
- ```
1845
-
1846
- Isso inclui proxies reversos e rotas Rack, se presentes.
1847
-
1848
- Esse método é também apelidado para `to` (veja
1849
- [abaixo](#redirecionamento-do-browser) para um exemplo).
1850
-
1851
- ### Redirecionamento do Browser
1852
-
1853
- Você pode lançar um redirecionamento no browser com o método auxiliar
1854
- `redirect`:
1855
-
1856
- ```ruby
1857
- get '/foo' do
1858
- redirect to('/bar')
1859
- end
1860
- ```
1861
-
1862
- Quaisquer parâmetros adicionais são interpretados como argumentos passados
1863
- ao `halt`:
1864
-
1865
- ```ruby
1866
- redirect to('/bar'), 303
1867
- redirect 'http://www.google.com/', 'lugar errado, amigo'
1868
- ```
1869
-
1870
- Você pode também facilmente redirecionar para a página da qual o usuário veio
1871
- com `redirect back`:
1872
-
1873
- ```ruby
1874
- get '/foo' do
1875
- "<a href='/bar'>do something</a>"
1876
- end
1877
-
1878
- get '/bar' do
1879
- do_something
1880
- redirect back
1881
- end
1882
- ```
1883
-
1884
- Para passar argumentos com um redirecionamento, adicione-os a query:
1885
-
1886
- ```ruby
1887
- redirect to('/bar?sum=42')
1888
- ```
1889
-
1890
- Ou use uma sessão:
1891
-
1892
- ```ruby
1893
- enable :sessions
1894
-
1895
- get '/foo' do
1896
- session[:secret] = 'foo'
1897
- redirect to('/bar')
1898
- end
1899
-
1900
- get '/bar' do
1901
- session[:secret]
1902
- end
1903
- ```
1904
-
1905
- ### Controle de Cache
1906
-
1907
- Definir sues cabeçalhos corretamente é o principal passo para uma correta cache
1908
- HTTP.
1909
-
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!"
1916
- end
1917
- ```
1918
-
1919
- Dica profissional: Configure a cache em um filtro anterior:
1920
-
1921
- ```ruby
1922
- before do
1923
- cache_control :public, :must_revalidate, :max_age => 60
1924
- end
1925
- ```
1926
-
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ê:
1929
-
1930
- ```ruby
1931
- before do
1932
- expires 500, :public, :must_revalidate
1933
- end
1934
- ```
1935
-
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:
1940
-
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
1947
- end
1948
- ```
1949
-
1950
- Também é possível usar uma
1951
- [ETag fraca](https://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation):
1952
-
1953
- ```ruby
1954
- etag @article.sha1, :weak
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):
1960
-
1961
- ```ruby
1962
- require "rack/cache"
1963
- require "sinatra"
1964
-
1965
- use Rack::Cache
1966
-
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
- método 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 método auxiliar, o Sinatra irá automaticamente lidar com
2047
- requisições de alcance.
2048
- </dd>
2049
- </dl>
2050
-
2051
- ### Acessando o Objeto da Requisição
2052
-
2053
- O objeto vindo da requisição pode ser acessado do nível de requisiçã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 (método similar para outros tipos de requisição)
2074
- request.form_data? # false
2075
- request["algum_ param"] # valor do parâmetro 'algum_param'. [] é um atalho para o hash de parâmetros
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 objeto 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
- resposta 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 método auxiliar `body`. Se você fizer isso, poderá usar esse
2212
- método 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 é possível 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 é possível 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 desabilitada, 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 método 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 método auxiliar
2386
- `redirect`:
2387
-
2388
- ```ruby
2389
- get '/foo' do
2390
- redirect to('/bar')
2391
- end
2392
- ```
2393
-
2394
- Quaisquer parâmetros 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
- método 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 método 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 requisiçã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 parâmetro 'algum_param'. [] é um atalho para o hash de parâmetros
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 objeto 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 informação de codificação. Você deve adicionar
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
- método 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 guardados 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 é distribuído 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 middlewares 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_parâmetros
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 inconvenientes 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
3293
- padrão, incluindo o servidor embutido. Veja [Opções e
3294
- Configurações](http://www.sinatrarb.com/configuration.html) para
3295
- detalhes de opções disponíveis e seus comportamentos. Se você quer
3296
- comportamento mais similar à 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 requisiçã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. Entretanto,
3603
- ele não se comporta exatamente como o escopo da classe 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).
3615
-
3616
- ## Linha de Comando
3617
-
3618
- Aplicações Sinatra podem ser executadas diretamente:
3619
-
3620
- ```shell
3621
- ruby minhaapp.rb [-h] [-x] [-q] [-e AMBIENTE] [-p PORTA] [-o HOST] [-s MANIPULADOR]
3622
- ```
3623
-
3624
- As opções são:
3625
-
3626
- ```
3627
- -h # ajuda
3628
- -p # define a porta (padrão é 4567)
3629
- -o # define o host (padrão é 0.0.0.0)
3630
- -e # define o ambiente (padrão é development)
3631
- -s # especifica o servidor/manipulador rack (padrão é thin)
3632
- -x # ativa o bloqueio mutex (padrão é desligado)
3633
- ```
3634
-
3635
- ### Multi-threading
3636
-
3637
- _Parafraseando [esta resposta no StackOverflow](resposta-so) por Konstantin_
3638
-
3639
- Sinatra não impõe nenhum modelo de concorrência, 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 especificar 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:
3646
-
3647
- ```ruby
3648
- # app.rb
3649
-
3650
- require 'sinatra/base'
3651
-
3652
- class App < Sinatra::Base
3653
- get '/' do
3654
- 'Olá mundo'
3655
- end
3656
- end
3657
-
3658
- App.run!
3659
- ```
3660
-
3661
- Para iniciar o servidor seria:
3662
-
3663
- ```shell
3664
- thin --threaded start
3665
- ```
3666
-
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 última 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.
3718
-
3719
- ## A última versão
3720
-
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:
3739
-
3740
- ```shell
3741
- gem install bundler
3742
- ```
3743
-
3744
- Então, no diretório do seu projeto, crie uma `Gemfile`:
3745
-
3746
- ```ruby
3747
- source 'https://rubygems.org'
3748
- gem 'sinatra', :github => 'sinatra/sinatra'
3749
-
3750
- # outras dependências
3751
- gem 'haml' # por exemplo, se você usar haml
3752
- ```
3753
-
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:
3759
-
3760
- ```shell
3761
- bundle exec ruby myapp.rb
3762
- ```
3763
-
3764
- ## Versionando
3765
-
3766
- O Sinatras segue [Versionamento Semântico](https://semver.org/), tanto SemVer
3767
- como SemVerTag.
3768
-
3769
- ## Mais
3770
-
3771
- * [Website do Projeto](http://www.sinatrarb.com/) - Documentação
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)
3776
- * [Twitter](https://twitter.com/sinatra)
3777
- * [Lista de Email](http://groups.google.com/group/sinatrarb/topics)
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/)
3787
- * [Servidor de CI](https://travis-ci.org/sinatra/sinatra)