sinatra 2.2.0 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
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)