sinatra 2.0.7 → 3.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/README.pt-br.md DELETED
@@ -1,1760 +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 esteja utilizando uma versão de ruby inferior à `2.0.0`, adicione o encoding no início de seus arquivos:
7
-
8
- ```ruby
9
- # encoding: utf-8
10
- ```
11
-
12
- Sinatra é uma [DSL](https://pt.wikipedia.org/wiki/Linguagem_de_domínio_específico) para
13
- criar aplicações web em Ruby com o mínimo de esforço e rapidez:
14
-
15
- ```ruby
16
- # minha_app.rb
17
- require 'sinatra'
18
-
19
- get '/' do
20
- 'Olá Mundo!'
21
- end
22
- ```
23
-
24
- Instale a gem:
25
-
26
- ```shell
27
- gem install sinatra
28
- ```
29
-
30
- Em seguida execute:
31
-
32
- ```shell
33
- ruby minha_app.rb
34
- ```
35
-
36
- Acesse: [http://localhost:4567](http://localhost:4567)
37
-
38
- É recomendado também executar `gem install thin`. Caso esta gem esteja disponível, o
39
- Sinatra irá utilizá-la.
40
-
41
- ## Conteúdo
42
-
43
- * [Sinatra](#sinatra)
44
- * [Conteúdo](#conteúdo)
45
- * [Rotas](#rotas)
46
- * [Condições](#condições)
47
- * [Retorno de valores](#retorno-de-valores)
48
- * [Validadores de rota personalizados](#validadores-de-rota-personalizados)
49
- * [Arquivos estáticos](#arquivos-estáticos)
50
- * [Views / Templates](#views--templates)
51
- * [Literal Templates](#literal-templates)
52
- * [Linguagens de template disponíveis](#linguagens-de-template-disponíveis)
53
- * [Haml Templates](#haml-templates)
54
- * [Erb Templates](#erb-templates)
55
- * [Builder Templates](#builder-templates)
56
- * [Nokogiri Templates](#nokogiri-templates)
57
- * [Sass Templates](#sass-templates)
58
- * [SCSS Templates](#scss-templates)
59
- * [Less Templates](#less-templates)
60
- * [Liquid Templates](#liquid-templates)
61
- * [Markdown Templates](#markdown-templates)
62
- * [Textile Templates](#textile-templates)
63
- * [RDoc Templates](#rdoc-templates)
64
- * [AsciiDoc Templates](#asciidoc-templates)
65
- * [Radius Templates](#radius-templates)
66
- * [Markaby Templates](#markaby-templates)
67
- * [RABL Templates](#rabl-templates)
68
- * [Slim Templates](#slim-templates)
69
- * [Creole Templates](#creole-templates)
70
- * [MediaWiki Templates](#mediawiki-templates)
71
- * [CoffeeScript Templates](#coffeescript-templates)
72
- * [Stylus Templates](#stylus-templates)
73
- * [Yajl Templates](#yajl-templates)
74
- * [WLang Templates](#wlang-templates)
75
- * [Acessando Variáveis nos Templates](#acessando-variáveis-nos-templates)
76
- * [Templates com `yield` e layouts aninhados](#templates-com-yield-e-layouts-aninhados)
77
- * [Templates Inline](#templates-inline)
78
- * [Templates Nomeados](#templates-nomeados)
79
- * [Associando extensões de arquivos](#associando-extensões-de-arquivos)
80
- * [Adicionando seu Próprio Engine de Template](#adicionando-seu-próprio-engine-de-template)
81
- * [Customizando lógica para encontrar templates](#customizando-lógica-para-encontrar-templates)
82
- * [Filtros](#filtros)
83
- * [Helpers](#helpers)
84
- * [Utilizando Sessões](#utilizando-sessões)
85
- * [Halting](#halting)
86
- * [Passing](#passing)
87
- * [Desencadeando Outra Rota](#desencadeando-outra-rota)
88
- * [Configuração](#configuração)
89
- * [Tratamento de Erros](#tratamento-de-erros)
90
- * [Erro](#erro)
91
- * [Mime Types](#mime-types)
92
- * [Rack Middleware](#rack-middleware)
93
- * [Testando](#testando)
94
- * [Sinatra::Base - Middleware, Bibliotecas e aplicativos modulares](#sinatrabase---middleware-bibliotecas-e-aplicativos-modulares)
95
- * [Linha de comando](#linha-de-comando)
96
- * [Multi-threading](#multi-threading)
97
- * [A última versão](#a-última-versão)
98
- * [Mais](#mais)
99
-
100
- ## Rotas
101
-
102
- No Sinatra, uma rota é um método HTTP emparelhado com um padrão de URL.
103
- Cada rota possui um bloco de execução:
104
-
105
- ```ruby
106
- get '/' do
107
- .. mostrando alguma coisa ..
108
- end
109
-
110
- post '/' do
111
- .. criando alguma coisa ..
112
- end
113
-
114
- put '/' do
115
- .. atualizando alguma coisa ..
116
- end
117
-
118
- patch '/' do
119
- .. modificando alguma coisa ..
120
- end
121
-
122
- delete '/' do
123
- .. removendo alguma coisa ..
124
- end
125
-
126
- options '/' do
127
- .. estabelecendo alguma coisa ..pe
128
- end
129
- ```
130
-
131
- As rotas são interpretadas na ordem em que são definidas. A primeira
132
- rota encontrada responde a requisição.
133
-
134
- Padrões de rota podem conter parâmetros nomeados, acessíveis por meio do
135
- hash `params`:
136
-
137
- ```ruby
138
- get '/ola/:nome' do
139
- # corresponde a "GET /ola/foo" e "GET /ola/bar"
140
- # params['nome'] é 'foo' ou 'bar'
141
- "Olá #{params['nome']}!"
142
- end
143
- ```
144
-
145
- Você também pode acessar parâmetros nomeados por meio dos parâmetros de
146
- um bloco:
147
-
148
- ```ruby
149
- get '/ola/:nome' do |n|
150
- # corresponde a "GET /ola/foo" e "GET /ola/bar"
151
- # params['nome'] é 'foo' ou 'bar'
152
- # n guarda o valor de params['nome']
153
- "Olá #{n}!"
154
- end
155
- ```
156
-
157
- Padrões de rota também podem conter parâmetros splat (curinga),
158
- acessível por meio do array `params['splat']`:
159
-
160
- ```ruby
161
- get '/diga/*/para/*' do
162
- # corresponde a /diga/ola/para/mundo
163
- params['splat'] # => ["ola", "mundo"]
164
- end
165
-
166
- get '/download/*.*' do
167
- # corresponde a /download/caminho/do/arquivo.xml
168
- params['splat'] # => ["caminho/do/arquivo", "xml"]
169
- end
170
- ```
171
-
172
- Ou com parâmetros de um bloco:
173
-
174
- ```ruby
175
- get '/download/*.*' do |caminho, ext|
176
- [caminho, ext] # => ["caminho/do/arquivo", "xml"]
177
- end
178
- ```
179
-
180
- Rotas podem casar com expressões regulares:
181
-
182
- ```ruby
183
- get /\/ola\/([\w]+)/ do
184
- "Olá, #{params['captures'].first}!"
185
- end
186
- ```
187
-
188
- Ou com parâmetros de um bloco:
189
-
190
- ```ruby
191
- get %r{/ola/([\w]+)} do |c|
192
- # corresponde a "GET /meta/ola/mundo", "GET /ola/mundo/1234" etc.
193
- "Olá, #{c}!"
194
- end
195
- ```
196
-
197
- Padrões de rota podem contar com parâmetros opcionais:
198
-
199
- ```ruby
200
- get '/posts/:formato?' do
201
- # corresponde a "GET /posts/" e qualquer extensão "GET /posts/json", "GET /posts/xml", etc.
202
- end
203
- ```
204
-
205
- Rotas também podem utilizar query strings:
206
-
207
- ```ruby
208
- get '/posts' do
209
- # corresponde a "GET /posts?titulo=foo&autor=bar"
210
- titulo = params['titulo']
211
- autor = params['autor']
212
- # utiliza as variaveis titulo e autor; a query é opicional para a rota /posts
213
- end
214
- ```
215
-
216
- A propósito, a menos que você desative a proteção contra ataques (veja
217
- abaixo), o caminho solicitado pode ser alterado antes de concluir a
218
- comparação com as suas rotas.
219
-
220
- ## Condições
221
-
222
- Rotas podem incluir uma variedade de condições, tal como o `user agent`:
223
-
224
- ```ruby
225
- get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
226
- "Você está usando o Songbird versão #{params['agent'][0]}"
227
- end
228
-
229
- get '/foo' do
230
- # Correspondente a navegadores que não sejam Songbird
231
- end
232
- ```
233
-
234
- Outras condições disponíveis são `host_name` e `provides`:
235
-
236
- ```ruby
237
- get '/', :host_name => /^admin\./ do
238
- "Área administrativa. Acesso negado!"
239
- end
240
-
241
- get '/', :provides => 'html' do
242
- haml :index
243
- end
244
-
245
- get '/', :provides => ['rss', 'atom', 'xml'] do
246
- builder :feed
247
- end
248
- ```
249
- `provides` procura pelos Accept header das requisições
250
-
251
- Você pode facilmente definir suas próprias condições:
252
-
253
- ```ruby
254
- set(:probabilidade) { |valor| condition { rand <= valor } }
255
-
256
- get '/ganha_um_carro', :probabilidade => 0.1 do
257
- "Você ganhou!"
258
- end
259
-
260
- get '/ganha_um_carro' do
261
- "Sinto muito, você perdeu."
262
- end
263
- ```
264
-
265
- Use splat, para uma condição que leva vários valores:
266
-
267
- ```ruby
268
- set(:auth) do |*roles| # <- observe o splat aqui
269
- condition do
270
- unless logged_in? && roles.any? {|role| current_user.in_role? role }
271
- redirect "/login/", 303
272
- end
273
- end
274
- end
275
-
276
- get "/minha/conta/", :auth => [:usuario, :administrador] do
277
- "Detalhes da sua conta"
278
- end
279
-
280
- get "/apenas/administrador/", :auth => :administrador do
281
- "Apenas administradores são permitidos aqui!"
282
- end
283
- ```
284
-
285
- ## Retorno de valores
286
-
287
- O valor de retorno do bloco de uma rota determina pelo menos o corpo da
288
- resposta passado para o cliente HTTP, ou pelo menos o próximo middleware
289
- na pilha Rack. Frequentemente, isto é uma `string`, tal como nos
290
- exemplos acima. Entretanto, outros valores também são aceitos.
291
-
292
- Você pode retornar uma resposta válida ou um objeto para o Rack, sendo
293
- eles de qualquer tipo de objeto que queira. Além disso, é possível
294
- retornar um código de status HTTP.
295
-
296
- * Um array com três elementros: `[status (Integer), cabecalho (Hash),
297
- corpo da resposta (responde à #each)]`
298
-
299
- * Um array com dois elementros: `[status (Integer), corpo da resposta
300
- (responde à #each)]`
301
-
302
- * Um objeto que responda à `#each` sem passar nada, mas, sim, `strings`
303
- para um dado bloco
304
-
305
- * Um objeto `Integer` representando o código de status
306
-
307
- Dessa forma, podemos implementar facilmente um exemplo de streaming:
308
-
309
- ```ruby
310
- class Stream
311
- def each
312
- 100.times { |i| yield "#{i}\n" }
313
- end
314
- end
315
-
316
- get('/') { Stream.new }
317
- ```
318
-
319
- Você também pode usar o método auxiliar `stream` (descrito abaixo) para
320
- incorporar a lógica de streaming na rota.
321
-
322
- ## Validadores de Rota Personalizados
323
-
324
- Como apresentado acima, a estrutura do Sinatra conta com suporte
325
- embutido para uso de padrões de String e expressões regulares como
326
- validadores de rota. No entanto, ele não pára por aí. Você pode
327
- facilmente definir os seus próprios validadores:
328
-
329
- ```ruby
330
- class AllButPattern
331
- Match = Struct.new(:captures)
332
-
333
- def initialize(except)
334
- @except = except
335
- @captures = Match.new([])
336
- end
337
-
338
- def match(str)
339
- @captures unless @except === str
340
- end
341
- end
342
-
343
- def all_but(pattern)
344
- AllButPattern.new(pattern)
345
- end
346
-
347
- get all_but("/index") do
348
- # ...
349
- end
350
- ```
351
-
352
- Note que o exemplo acima pode ser robusto e complicado em excesso. Pode
353
- também ser implementado como:
354
-
355
- ```ruby
356
- get // do
357
- pass if request.path_info == "/index"
358
- # ...
359
- end
360
- ```
361
-
362
- Ou, usando algo mais denso à frente:
363
-
364
- ```ruby
365
- get %r{(?!/index)} do
366
- # ...
367
- end
368
- ```
369
-
370
- ## Arquivos estáticos
371
-
372
- Arquivos estáticos são disponibilizados a partir do diretório
373
- `./public`. Você pode especificar um local diferente pela opção
374
- `:public_folder`
375
-
376
- ```ruby
377
- set :public_folder, File.dirname(__FILE__) + '/estatico'
378
- ```
379
-
380
- Note que o nome do diretório público não é incluido na URL. Um arquivo
381
- `./public/css/style.css` é disponibilizado como
382
- `http://exemplo.com/css/style.css`.
383
-
384
- ## Views / Templates
385
-
386
- Cada linguagem de template é exposta através de seu próprio método de renderização. Estes metodos simplesmente retornam uma string:
387
-
388
- ```ruby
389
- get '/' do
390
- erb :index
391
- end
392
- ```
393
-
394
- Isto renderiza `views/index.rb`
395
-
396
- Ao invés do nome do template, você também pode passar direto o conteúdo do template:
397
-
398
- ```ruby
399
- get '/' do
400
- code = "<%= Time.now %>"
401
- erb code
402
- end
403
- ```
404
-
405
- Templates também aceitam um segundo argumento, um hash de opções:
406
-
407
- ```ruby
408
- get '/' do
409
- erb :index, :layout => :post
410
- end
411
- ```
412
-
413
- Isto irá renderizar a `views/index.erb` inclusa dentro da `views/post.erb` (o padrão é a `views/layout.erb`, se existir).
414
-
415
- Qualquer opção não reconhecida pelo Sinatra será passada adiante para o engine de template:
416
-
417
- ```ruby
418
- get '/' do
419
- haml :index, :format => :html5
420
- end
421
- ```
422
-
423
- Você também pode definir opções padrões para um tipo de template:
424
-
425
- ```ruby
426
- set :haml, :format => :html5
427
-
428
- get '/' do
429
- haml :index
430
- end
431
- ```
432
-
433
- Opções passadas para o método de renderização sobrescreve as opções definitas através do método `set`.
434
-
435
- Opções disponíveis:
436
-
437
- <dl>
438
- <dt>locals</dt>
439
- <dd>
440
- Lista de locais passado para o documento. Conveniente para *partials*
441
- Exemplo: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
442
- </dd>
443
-
444
- <dt>default_encoding</dt>
445
- <dd>
446
- String encoding para ser utilizada em caso de incerteza. o padrão é <tt>settings.default_encoding</tt>.
447
- </dd>
448
-
449
- <dt>views</dt>
450
- <dd>
451
- Diretório de onde os templates são carregados. O padrão é <tt>settings.views</tt>.
452
- </dd>
453
-
454
- <dt>layout</dt>
455
- <dd>
456
- Para definir quando utilizar ou não um
457
- layout (<tt>true</tt> ou <tt>false</tt>). E se for um
458
- Symbol, especifica qual template usar. Exemplo:
459
- <tt>erb :index, :layout => !request.xhr?</tt>
460
- </dd>
461
-
462
- <dt>content_type</dt>
463
- <dd>
464
- O *Content-Type* que o template produz. O padrão depente
465
- da linguagem de template utilizada.
466
- </dd>
467
-
468
- <dt>scope</dt>
469
- <dd>
470
- Escopo em que o template será renderizado. Padrão é a
471
- instancia da aplicação. Se você mudar isto as variáveis
472
- de instânciae metodos auxiliares não serão
473
- disponibilizados.
474
- </dd>
475
-
476
- <dt>layout_engine</dt>
477
- <dd>
478
- A engine de template utilizada para renderizar seu layout.
479
- Útil para linguagens que não suportam templates de outra
480
- forma. O padrão é a engine do template utilizado. Exemplo:
481
- <tt>set :rdoc, :layout_engine => :erb</tt>
482
- </dd>
483
-
484
- <dt>layout_options</dt>
485
- <dd>
486
- Opções especiais utilizadas apenas para renderizar o
487
- layout. Exemplo:
488
- <tt>set :rdoc, :layout_options => { :views => 'views/layouts' }</tt>
489
- </dd>
490
- </dl>
491
-
492
- É pressuposto que os templates estarão localizados direto sob o diretório `./views`. Para usar um diretório diferente:
493
-
494
- ```ruby
495
- set :views, settings.root + '/templates'
496
- ```
497
-
498
- Uma coisa importante para se lembrar é que você sempre deve
499
- referenciar os templates utilizando *symbols*, mesmo que
500
- eles estejam em um subdiretório (neste caso use:
501
- `:'subdir/template'` or `'subdir/template'.to_sym`). Você deve
502
- utilizar um *symbol* porque senão o método de renderização irá
503
- renderizar qualquer outra string que você passe diretamente
504
- para ele
505
-
506
- ### Literal Templates
507
-
508
- ```ruby
509
- get '/' do
510
- haml '%div.title Olá Mundo'
511
- end
512
- ```
513
-
514
- Renderiza um template string.
515
-
516
- ### Linguagens de template disponíveis
517
-
518
- Algumas linguagens possuem multiplas implementações. Para especificar qual implementação deverá ser utilizada (e para ser *thread-safe*), você deve simplesmente requere-la primeiro:
519
-
520
- ```ruby
521
- require 'rdiscount' # ou require 'bluecloth'
522
- get('/') { markdown :index }
523
- ```
524
-
525
- #### Haml Templates
526
-
527
- <table>
528
- <tr>
529
- <td>Dependencia</td>
530
- <td><a href="http://haml.info/" title="haml">haml</a></td>
531
- </tr>
532
- <tr>
533
- <td>Extencao do Arquivo</td>
534
- <td><tt>.haml</tt></td>
535
- </tr>
536
- <tr>
537
- <td>Exemplo</td>
538
- <td><tt>haml :index, :format => :html5</tt></td>
539
- </tr>
540
- </table>
541
-
542
- #### Erb Templates
543
-
544
- <table>
545
- <tr>
546
- <td>Dependencia</td>
547
- <td>
548
- <a href="http://www.kuwata-lab.com/erubis/" title="erubis">erubis</a>
549
- or erb (included in Ruby)
550
- </td>
551
- </tr>
552
- <tr>
553
- <td>Extencao do Arquivos</td>
554
- <td><tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubis</tt> (Erubis only)</td>
555
- </tr>
556
- <tr>
557
- <td>Exemplo</td>
558
- <td><tt>erb :index</tt></td>
559
- </tr>
560
- </table>
561
-
562
- #### Builder Templates
563
-
564
- <table>
565
- <tr>
566
- <td>Dependencia</td>
567
- <td>
568
- <a href="https://github.com/jimweirich/builder" title="builder">builder</a>
569
- </td>
570
- </tr>
571
- <tr>
572
- <td>Extencao do Arquivo</td>
573
- <td><tt>.builder</tt></td>
574
- </tr>
575
- <tr>
576
- <td>Exemplo</td>
577
- <td><tt>builder { |xml| xml.em "hi" }</tt></td>
578
- </tr>
579
- </table>
580
-
581
- It also takes a block for inline templates (see exemplo).
582
-
583
- #### Nokogiri Templates
584
-
585
- <table>
586
- <tr>
587
- <td>Dependencia</td>
588
- <td><a href="http://www.nokogiri.org/" title="nokogiri">nokogiri</a></td>
589
- </tr>
590
- <tr>
591
- <td>Extencao do Arquivo</td>
592
- <td><tt>.nokogiri</tt></td>
593
- </tr>
594
- <tr>
595
- <td>Exemplo</td>
596
- <td><tt>nokogiri { |xml| xml.em "hi" }</tt></td>
597
- </tr>
598
- </table>
599
-
600
- It also takes a block for inline templates (see exemplo).
601
-
602
- #### Sass Templates
603
-
604
- <table>
605
- <tr>
606
- <td>Dependencia</td>
607
- <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
608
- </tr>
609
- <tr>
610
- <td>Extencao do Arquivo</td>
611
- <td><tt>.sass</tt></td>
612
- </tr>
613
- <tr>
614
- <td>Exemplo</td>
615
- <td><tt>sass :stylesheet, :style => :expanded</tt></td>
616
- </tr>
617
- </table>
618
-
619
- #### SCSS Templates
620
-
621
- <table>
622
- <tr>
623
- <td>Dependencia</td>
624
- <td><a href="http://sass-lang.com/" title="sass">sass</a></td>
625
- </tr>
626
- <tr>
627
- <td>Extencao do Arquivo</td>
628
- <td><tt>.scss</tt></td>
629
- </tr>
630
- <tr>
631
- <td>Exemplo</td>
632
- <td><tt>scss :stylesheet, :style => :expanded</tt></td>
633
- </tr>
634
- </table>
635
-
636
- #### Less Templates
637
-
638
- <table>
639
- <tr>
640
- <td>Dependencia</td>
641
- <td><a href="http://lesscss.org/" title="less">less</a></td>
642
- </tr>
643
- <tr>
644
- <td>Extencao do Arquivo</td>
645
- <td><tt>.less</tt></td>
646
- </tr>
647
- <tr>
648
- <td>Exemplo</td>
649
- <td><tt>less :stylesheet</tt></td>
650
- </tr>
651
- </table>
652
-
653
- #### Liquid Templates
654
-
655
- <table>
656
- <tr>
657
- <td>Dependencia</td>
658
- <td><a href="https://shopify.github.io/liquid/" title="liquid">liquid</a></td>
659
- </tr>
660
- <tr>
661
- <td>Extencao do Arquivo</td>
662
- <td><tt>.liquid</tt></td>
663
- </tr>
664
- <tr>
665
- <td>Exemplo</td>
666
- <td><tt>liquid :index, :locals => { :key => 'value' }</tt></td>
667
- </tr>
668
- </table>
669
-
670
- Já que você não pode chamar o Ruby (exceto pelo método `yield`) pelo template Liquid,
671
- você quase sempre precisará passar o `locals` para ele.
672
-
673
- #### Markdown Templates
674
-
675
- <table>
676
- <tr>
677
- <td>Dependencia</td>
678
- <td>
679
- Anyone of:
680
- <a href="https://github.com/davidfstr/rdiscount" title="RDiscount">RDiscount</a>,
681
- <a href="https://github.com/vmg/redcarpet" title="RedCarpet">RedCarpet</a>,
682
- <a href="https://github.com/ged/bluecloth" title="bluecloth">BlueCloth</a>,
683
- <a href="http://kramdown.gettalong.org/" title="kramdown">kramdown</a>,
684
- <a href="https://github.com/bhollis/maruku" title="maruku">maruku</a>
685
- </td>
686
- </tr>
687
- <tr>
688
- <td>Extencao do Arquivos</td>
689
- <td><tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt></td>
690
- </tr>
691
- <tr>
692
- <td>Exemplo</td>
693
- <td><tt>markdown :index, :layout_engine => :erb</tt></td>
694
- </tr>
695
- </table>
696
-
697
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
698
-
699
- ```ruby
700
- erb :overview, :locals => { :text => markdown(:introducao) }
701
- ```
702
-
703
- Note que vcoê também pode chamar o método `markdown` dentro de outros templates:
704
-
705
- ```ruby
706
- %h1 Olá do Haml!
707
- %p= markdown(:saudacoes)
708
- ```
709
-
710
- Já que você não pode chamar o Ruby pelo Markdown, você não
711
- pode utilizar um layout escrito em Markdown. Contudo é
712
- possível utilizar outra engine de renderização como template,
713
- deve-se passar a `:layout_engine` como opção.
714
-
715
- <table>
716
- <tr>
717
- <td>Dependencia</td>
718
- <td><a href="http://redcloth.org/" title="RedCloth">RedCloth</a></td>
719
- </tr>
720
- <tr>
721
- <td>Extencao do Arquivo</td>
722
- <td><tt>.textile</tt></td>
723
- </tr>
724
- <tr>
725
- <td>Exemplo</td>
726
- <td><tt>textile :index, :layout_engine => :erb</tt></td>
727
- </tr>
728
- </table>
729
-
730
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
731
-
732
- ```ruby
733
- erb :overview, :locals => { :text => textile(:introducao) }
734
- ```
735
-
736
- Note que vcoê também pode chamar o método `textile` dentro de outros templates:
737
-
738
- ```ruby
739
- %h1 Olá do Haml!
740
- %p= textile(:saudacoes)
741
- ```
742
-
743
- Já que você não pode chamar o Ruby pelo Textile, você não
744
- pode utilizar um layout escrito em Textile. Contudo é
745
- possível utilizar outra engine de renderização como template,
746
- deve-se passar a `:layout_engine` como opção.
747
-
748
- #### RDoc Templates
749
-
750
- <table>
751
- <tr>
752
- <td>Dependencia</td>
753
- <td><a href="http://rdoc.sourceforge.net/" title="RDoc">RDoc</a></td>
754
- </tr>
755
- <tr>
756
- <td>Extencao do Arquivo</td>
757
- <td><tt>.rdoc</tt></td>
758
- </tr>
759
- <tr>
760
- <td>Exemplo</td>
761
- <td><tt>rdoc :README, :layout_engine => :erb</tt></td>
762
- </tr>
763
- </table>
764
-
765
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
766
-
767
- ```ruby
768
- erb :overview, :locals => { :text => rdoc(:introducao) }
769
- ```
770
-
771
- Note que vcoê também pode chamar o método `rdoc` dentro de outros templates:
772
-
773
- ```ruby
774
- %h1 Olá do Haml!
775
- %p= rdoc(:saudacoes)
776
- ```
777
-
778
- Já que você não pode chamar o Ruby pelo RDoc, você não
779
- pode utilizar um layout escrito em RDoc. Contudo é
780
- possível utilizar outra engine de renderização como template,
781
- deve-se passar a `:layout_engine` como opção.
782
-
783
- #### AsciiDoc Templates
784
-
785
- <table>
786
- <tr>
787
- <td>Dependencia</td>
788
- <td><a href="http://asciidoctor.org/" title="Asciidoctor">Asciidoctor</a></td>
789
- </tr>
790
- <tr>
791
- <td>Extencao do Arquivo</td>
792
- <td><tt>.asciidoc</tt>, <tt>.adoc</tt> and <tt>.ad</tt></td>
793
- </tr>
794
- <tr>
795
- <td>Exemplo</td>
796
- <td><tt>asciidoc :README, :layout_engine => :erb</tt></td>
797
- </tr>
798
- </table>
799
-
800
- Já que você não pode chamar o Ruby pelo template AsciiDoc,
801
- você quase sempre precisará passar o `locals` para ele.
802
-
803
- #### Radius Templates
804
-
805
- <table>
806
- <tr>
807
- <td>Dependencia</td>
808
- <td><a href="https://github.com/jlong/radius" title="Radius">Radius</a></td>
809
- </tr>
810
- <tr>
811
- <td>Extencao do Arquivo</td>
812
- <td><tt>.radius</tt></td>
813
- </tr>
814
- <tr>
815
- <td>Exemplo</td>
816
- <td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
817
- </tr>
818
- </table>
819
-
820
- Já que você não pode chamar o Ruby pelo template Radius,
821
- você quase sempre precisará passar o `locals` para ele.
822
-
823
- #### Markaby Templates
824
-
825
- <table>
826
- <tr>
827
- <td>Dependencia</td>
828
- <td><a href="http://markaby.github.io/" title="Markaby">Markaby</a></td>
829
- </tr>
830
- <tr>
831
- <td>Extencao do Arquivo</td>
832
- <td><tt>.mab</tt></td>
833
- </tr>
834
- <tr>
835
- <td>Exemplo</td>
836
- <td><tt>markaby { h1 "Welcome!" }</tt></td>
837
- </tr>
838
- </table>
839
-
840
- Este também recebe um bloco para templates (veja o exemplo).
841
-
842
- #### RABL Templates
843
-
844
- <table>
845
- <tr>
846
- <td>Dependencia</td>
847
- <td><a href="https://github.com/nesquena/rabl" title="Rabl">Rabl</a></td>
848
- </tr>
849
- <tr>
850
- <td>Extencao do Arquivo</td>
851
- <td><tt>.rabl</tt></td>
852
- </tr>
853
- <tr>
854
- <td>Exemplo</td>
855
- <td><tt>rabl :index</tt></td>
856
- </tr>
857
- </table>
858
-
859
- #### Slim Templates
860
-
861
- <table>
862
- <tr>
863
- <td>Dependencia</td>
864
- <td><a href="http://slim-lang.com/" title="Slim Lang">Slim Lang</a></td>
865
- </tr>
866
- <tr>
867
- <td>Extencao do Arquivo</td>
868
- <td><tt>.slim</tt></td>
869
- </tr>
870
- <tr>
871
- <td>Exemplo</td>
872
- <td><tt>slim :index</tt></td>
873
- </tr>
874
- </table>
875
-
876
- #### Creole Templates
877
-
878
- <table>
879
- <tr>
880
- <td>Dependencia</td>
881
- <td><a href="https://github.com/minad/creole" title="Creole">Creole</a></td>
882
- </tr>
883
- <tr>
884
- <td>Extencao do Arquivo</td>
885
- <td><tt>.creole</tt></td>
886
- </tr>
887
- <tr>
888
- <td>Exemplo</td>
889
- <td><tt>creole :wiki, :layout_engine => :erb</tt></td>
890
- </tr>
891
- </table>
892
-
893
- Não é possível chamar métodos por este template, nem passar *locals* para o mesmo. Portanto normalmente é utilizado junto a outra engine de renderização:
894
-
895
- ```ruby
896
- erb :overview, :locals => { :text => creole(:introduction) }
897
- ```
898
-
899
- Note que vcoê também pode chamar o método `creole` dentro de outros templates:
900
-
901
- ```ruby
902
- %h1 Olá do Haml!
903
- %p= creole(:saudacoes)
904
- ```
905
-
906
- Já que você não pode chamar o Ruby pelo Creole, você não
907
- pode utilizar um layout escrito em Creole. Contudo é
908
- possível utilizar outra engine de renderização como template,
909
- deve-se passar a `:layout_engine` como opção.
910
-
911
- #### MediaWiki Templates
912
-
913
- <table>
914
- <tr>
915
- <td>Dependencia</td>
916
- <td><a href="https://github.com/nricciar/wikicloth" title="WikiCloth">WikiCloth</a></td>
917
- </tr>
918
- <tr>
919
- <td>Extencao do Arquivo</td>
920
- <td><tt>.mediawiki</tt> and <tt>.mw</tt></td>
921
- </tr>
922
- <tr>
923
- <td>Exemplo</td>
924
- <td><tt>mediawiki :wiki, :layout_engine => :erb</tt></td>
925
- </tr>
926
- </table>
927
-
928
- It is not possible to call methods from MediaWiki markup, nor to pass locals to
929
- it. You therefore will usually use it in combination with another rendering
930
- engine:
931
-
932
- ```ruby
933
- erb :overview, :locals => { :text => mediawiki(:introduction) }
934
- ```
935
-
936
- Note that you may also call the `mediawiki` method from within other templates:
937
-
938
- ```ruby
939
- %h1 Hello From Haml!
940
- %p= mediawiki(:greetings)
941
- ```
942
-
943
- Já que você não pode chamar o Ruby pelo MediaWiki, você não
944
- pode utilizar um layout escrito em MediaWiki. Contudo é
945
- possível utilizar outra engine de renderização como template,
946
- deve-se passar a `:layout_engine` como opção.
947
-
948
- #### CoffeeScript Templates
949
-
950
- <table>
951
- <tr>
952
- <td>Dependencia</td>
953
- <td>
954
- <a href="https://github.com/josh/ruby-coffee-script" title="Ruby CoffeeScript">
955
- CoffeeScript
956
- </a> and a
957
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
958
- way to execute javascript
959
- </a>
960
- </td>
961
- </tr>
962
- <tr>
963
- <td>Extencao do Arquivo</td>
964
- <td><tt>.coffee</tt></td>
965
- </tr>
966
- <tr>
967
- <td>Exemplo</td>
968
- <td><tt>coffee :index</tt></td>
969
- </tr>
970
- </table>
971
-
972
- #### Stylus Templates
973
-
974
- <table>
975
- <tr>
976
- <td>Dependencia</td>
977
- <td>
978
- <a href="https://github.com/forgecrafted/ruby-stylus" title="Ruby Stylus">
979
- Stylus
980
- </a> and a
981
- <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme" title="ExecJS">
982
- way to execute javascript
983
- </a>
984
- </td>
985
- </tr>
986
- <tr>
987
- <td>Extencao do Arquivo</td>
988
- <td><tt>.styl</tt></td>
989
- </tr>
990
- <tr>
991
- <td>Exemplo</td>
992
- <td><tt>stylus :index</tt></td>
993
- </tr>
994
- </table>
995
-
996
- Antes que vcoê possa utilizar o template Stylus primeiro você deve carregar `stylus` e `stylus/tilt`:
997
-
998
- ```ruby
999
- require 'sinatra'
1000
- require 'stylus'
1001
- require 'stylus/tilt'
1002
-
1003
- get '/' do
1004
- stylus :exemplo
1005
- end
1006
- ```
1007
-
1008
- #### Yajl Templates
1009
-
1010
- <table>
1011
- <tr>
1012
- <td>Dependencia</td>
1013
- <td><a href="https://github.com/brianmario/yajl-ruby" title="yajl-ruby">yajl-ruby</a></td>
1014
- </tr>
1015
- <tr>
1016
- <td>Extencao do Arquivo</td>
1017
- <td><tt>.yajl</tt></td>
1018
- </tr>
1019
- <tr>
1020
- <td>Exemplo</td>
1021
- <td>
1022
- <tt>
1023
- yajl :index,
1024
- :locals => { :key => 'qux' },
1025
- :callback => 'present',
1026
- :variable => 'resource'
1027
- </tt>
1028
- </td>
1029
- </tr>
1030
- </table>
1031
-
1032
- O código-fonte do template é executado como uma string Ruby e a variável resultante em json é convertida utilizando `#to_json`:
1033
-
1034
- ```ruby
1035
- json = { :foo => 'bar' }
1036
- json[:baz] = key
1037
- ```
1038
-
1039
- O `:callback` e `:variable` são opções que podem ser utilizadas para o objeto de renderização:
1040
-
1041
- ```javascript
1042
- var resource = {"foo":"bar","baz":"qux"};
1043
- present(resource);
1044
- ```
1045
-
1046
- #### WLang Templates
1047
-
1048
- <table>
1049
- <tr>
1050
- <td>Dependencia</td>
1051
- <td><a href="https://github.com/blambeau/wlang/" title="WLang">WLang</a></td>
1052
- </tr>
1053
- <tr>
1054
- <td>Extencao do Arquivo</td>
1055
- <td><tt>.wlang</tt></td>
1056
- </tr>
1057
- <tr>
1058
- <td>Exemplo</td>
1059
- <td><tt>wlang :index, :locals => { :key => 'value' }</tt></td>
1060
- </tr>
1061
- </table>
1062
-
1063
- Já que você não pode chamar o Ruby (exceto pelo método
1064
- `yield`) pelo template WLang,
1065
- você quase sempre precisará passar o `locals` para ele.
1066
-
1067
- ## Acessando Variáveis nos Templates
1068
-
1069
- Templates são avaliados dentro do mesmo contexto como manipuladores de
1070
- rota. Variáveis de instância setadas em rotas manipuladas são
1071
- diretamente acessadas por templates:
1072
-
1073
- ```ruby
1074
- get '/:id' do
1075
- @foo = Foo.find(params['id'])
1076
- haml '%h1= @foo.nome'
1077
- end
1078
- ```
1079
-
1080
- Ou, especifique um hash explícito para variáveis locais:
1081
-
1082
- ```ruby
1083
- get '/:id' do
1084
- foo = Foo.find(params['id'])
1085
- haml '%h1= foo.nome', :locals => { :foo => foo }
1086
- end
1087
- ```
1088
-
1089
- Isso é tipicamente utilizando quando renderizamos templates como
1090
- partials dentro de outros templates.
1091
-
1092
- ### Templates com `yield` e layouts aninhados
1093
-
1094
- O layout geralmente é apenas um template que executa `yield`.
1095
- Tal template pode ser utilizado pela opção `:template` descrita acima ou pode ser renderizado através de um bloco, como a seguir:
1096
-
1097
- ```ruby
1098
- erb :post, :layout => false do
1099
- erb :index
1100
- end
1101
- ```
1102
-
1103
- Este código é quase equivalente a `erb :index, :layout => :post`
1104
-
1105
- Passando blocos para os métodos de renderização é útil para criar layouts aninhados:
1106
-
1107
- ```ruby
1108
- erb :main_layout, :layout => false do
1109
- erb :admin_layout do
1110
- erb :user
1111
- end
1112
- end
1113
- ```
1114
-
1115
- Também pode ser feito com menos linhas de código:
1116
-
1117
- ```ruby
1118
- erb :admin_layout, :layout => :main_layout do
1119
- erb :user
1120
- end
1121
- ```
1122
-
1123
- Atualmente os métodos listados aceitam blocos: `erb`, `haml`,
1124
- `liquid`, `slim `, `wlang`. E também o método `render`.
1125
-
1126
- ### Templates Inline
1127
-
1128
- Templates podem ser definidos no final do arquivo fonte(.rb):
1129
-
1130
- ```ruby
1131
- require 'sinatra'
1132
-
1133
- get '/' do
1134
- haml :index
1135
- end
1136
-
1137
- __END__
1138
-
1139
- @@ layout
1140
- %html
1141
- = yield
1142
-
1143
- @@ index
1144
- %div.title Olá Mundo.
1145
- ```
1146
-
1147
- NOTA: Templates inline definidos no arquivo fonte são automaticamente
1148
- carregados pelo sinatra. Digite \`enable :inline\_templates\` se você
1149
- tem templates inline no outro arquivo fonte.
1150
-
1151
- ### Templates nomeados
1152
-
1153
- Templates também podem ser definidos utilizando o método top-level
1154
- `template`:
1155
-
1156
- ```ruby
1157
- template :layout do
1158
- "%html\n =yield\n"
1159
- end
1160
-
1161
- template :index do
1162
- '%div.title Olá Mundo!'
1163
- end
1164
-
1165
- get '/' do
1166
- haml :index
1167
- end
1168
- ```
1169
-
1170
- Se existir um template com nome “layout”, ele será utilizado toda vez
1171
- que um template for renderizado. Você pode desabilitar layouts passando
1172
- `:layout => false`.
1173
-
1174
- ```ruby
1175
- get '/' do
1176
- haml :index, :layout => !request.xhr?
1177
- end
1178
- ```
1179
-
1180
- ### Associando extensões de arquivos
1181
-
1182
- Para associar uma extensão de arquivo com um engine de template use o método `Tilt.register`. Por exemplo, se você quiser usar a extensão `tt` para os templates Textile você pode fazer o seguinte:
1183
-
1184
- ```ruby
1185
- Tilt.register :tt, Tilt[:textile]
1186
- ```
1187
-
1188
- ### Adicionando seu Próprio Engine de Template
1189
-
1190
- Primeiro registre seu engine utilizando o Tilt, e então crie um método de renderização:
1191
-
1192
- ```ruby
1193
- Tilt.register :myat, MyAwesomeTemplateEngine
1194
-
1195
- helpers do
1196
- def myat(*args) render(:myat, *args) end
1197
- end
1198
-
1199
- get '/' do
1200
- myat :index
1201
- end
1202
- ```
1203
-
1204
- Renderize `./views/index.myat`. Veja
1205
- https://github.com/rtomayko/tilt para saber mais sobre Tilt.
1206
-
1207
- ### Customizando lógica para encontrar templates
1208
-
1209
- Para implementar sua própria lógica para busca de templates você pode escrever seu próprio método `#find_template`
1210
-
1211
- ```ruby
1212
- configure do
1213
- set :views [ './views/a', './views/b' ]
1214
- end
1215
-
1216
- def find_template(views, name, engine, &block)
1217
- Array(views).each do |v|
1218
- super(v, name, engine, &block)
1219
- end
1220
- end
1221
- ```
1222
-
1223
- ## Filtros
1224
-
1225
- Filtros Before são avaliados antes de cada requisição dentro do contexto
1226
- da requisição e podem modificar a requisição e a reposta. Variáveis de
1227
- instância setadas nos filtros são acessadas através de rotas e
1228
- templates:
1229
-
1230
- ```ruby
1231
- before do
1232
- @nota = 'Oi!'
1233
- request.path_info = '/foo/bar/baz'
1234
- end
1235
-
1236
- get '/foo/*' do
1237
- @nota #=> 'Oi!'
1238
- params['splat'] #=> 'bar/baz'
1239
- end
1240
- ```
1241
-
1242
- Filtros After são avaliados após cada requisição dentro do contexto da
1243
- requisição e também podem modificar a requisição e a resposta. Variáveis de
1244
- instância e rotas definidas nos filtros before são acessadas através dos
1245
- filtros after:
1246
-
1247
- ```ruby
1248
- after do
1249
- puts response.status
1250
- end
1251
- ```
1252
-
1253
- Filtros opcionalmente têm um padrão, fazendo com que sejam avaliados
1254
- somente se o caminho do pedido coincidir com esse padrão:
1255
-
1256
- ```ruby
1257
- before '/protected/*' do
1258
- authenticate!
1259
- end
1260
-
1261
- after '/create/:slug' do |slug|
1262
- session[:last_slug] = slug
1263
- end
1264
- ```
1265
-
1266
- ## Helpers
1267
-
1268
- Use o método de alto nível `helpers` para definir métodos auxiliares
1269
- para utilizar em manipuladores de rotas e modelos:
1270
-
1271
- ```ruby
1272
- helpers do
1273
- def bar(nome)
1274
- "#{nome}bar"
1275
- end
1276
- end
1277
-
1278
- get '/:nome' do
1279
- bar(params['nome'])
1280
- end
1281
- ```
1282
-
1283
- ### Utilizando Sessões
1284
-
1285
- Sessões são usadas para manter um estado durante uma requisição. Se ativa, você terá disponível um hash de sessão para cada sessão de usuário:
1286
-
1287
- ```ruby
1288
- enable :sessions
1289
-
1290
- get '/' do
1291
- "value = " << session[:value].inspect
1292
- end
1293
-
1294
- get '/:value' do
1295
- session['value'] = params['value']
1296
- end
1297
- ```
1298
-
1299
- Note que `enable :sessions` utilizará um cookie para guardar todos os dados da sessão. Isso nem sempre pode ser o que você quer (guardar muitos dados irá aumentar o seu tráfego, por exemplo). Você pode utilizar qualquer Rack middleware de sessão: para fazer isso **não** utilize o método `enable :sessions`, ao invés disso utilize seu middleware de sessão como utilizaria qualquer outro:
1300
-
1301
- ```ruby
1302
- use Rack::Session::Pool, :expire_after => 2592000
1303
-
1304
- get '/' do
1305
- "value = " << session[:value].inspect
1306
- end
1307
-
1308
- get '/:value' do
1309
- session['value'] = params['value']
1310
- end
1311
- ```
1312
-
1313
- Para melhorar a segurança, os dados da sessão guardados no cookie é assinado com uma chave secreta da sessão. Uma chave aleatória é gerada para você pelo Sinatra. Contudo, já que a chave mudará cada vez que você inicia sua aplicação, você talvez queira defini-la você mesmo para que todas as instâncias da aplicação compartilhe-a:
1314
-
1315
- ```ruby
1316
- set :session_secret, 'super secret'
1317
- ```
1318
-
1319
- Se você quiser fazer outras configurações, você também pode guardar um hash com as opções nas configurações da `session`:
1320
-
1321
- ```ruby
1322
- set :sessions, :domain => 'foo.com'
1323
- ```
1324
-
1325
- Para compartilhar sua sessão entre outros aplicativos em um subdomínio de foo.com, utilize o prefixo *.*:
1326
-
1327
- ```ruby
1328
- set :sessions, :domain => '.foo.com'
1329
- ```
1330
-
1331
- ### Halting
1332
-
1333
- Para parar imediatamente uma requisição com um filtro ou rota utilize:
1334
-
1335
- ```ruby
1336
- halt
1337
- ```
1338
-
1339
- Você também pode especificar o status quando parar…
1340
-
1341
- ```ruby
1342
- halt 410
1343
- ```
1344
-
1345
- Ou com corpo de texto…
1346
-
1347
- ```ruby
1348
- halt 'isso será o corpo do texto'
1349
- ```
1350
-
1351
- Ou também…
1352
-
1353
- ```ruby
1354
- halt 401, 'vamos embora!'
1355
- ```
1356
-
1357
- Com cabeçalhos…
1358
-
1359
- ```ruby
1360
- halt 402, {'Content-Type' => 'text/plain'}, 'revanche'
1361
- ```
1362
-
1363
- É obviamente possivel combinar um template com o `halt`:
1364
-
1365
- ```ruby
1366
- halt erb(:error)
1367
- ```
1368
-
1369
- ### Passing
1370
-
1371
- Uma rota pode processar aposta para a próxima rota correspondente usando
1372
- `pass`:
1373
-
1374
- ```ruby
1375
- get '/adivinhar/:quem' do
1376
- pass unless params['quem'] == 'Frank'
1377
- 'Você me pegou!'
1378
- end
1379
-
1380
- get '/adivinhar/*' do
1381
- 'Você falhou!'
1382
- end
1383
- ```
1384
-
1385
- O bloqueio da rota é imediatamente encerrado e o controle continua com a
1386
- próxima rota de parâmetro. Se o parâmetro da rota não for encontrado, um
1387
- 404 é retornado.
1388
-
1389
- ### Desencadeando Outra Rota
1390
-
1391
- As vezes o `pass` não é o que você quer, ao invés dele talvez você queira obter o resultado chamando outra rota. Utilize o método `call` neste caso:
1392
-
1393
- ```ruby
1394
- get '/foo' do
1395
- status, headers, body = call env.merge("PATH_INFO" => '/bar')
1396
- [status, headers, body.map(&:upcase)]
1397
- end
1398
-
1399
- get '/bar' do
1400
- "bar"
1401
- end
1402
- ```
1403
-
1404
- Note que no exemplo acima você ganharia performance ao simplemente mover o `"bar"` em um helper usado por ambos `/foo` e `/bar`.
1405
-
1406
- Se você quer que a requisição seja enviada para a mesma instancia da aplicação ao invês de uma duplicada, use `call!` no lugar de `call`.
1407
-
1408
- Veja a especificação do Rack se você quer aprender mais sobre o `call`.
1409
-
1410
- ## Configuração
1411
-
1412
- Rodando uma vez, na inicialização, em qualquer ambiente:
1413
-
1414
- ```ruby
1415
- configure do
1416
- ...
1417
- end
1418
- ```
1419
-
1420
- Rodando somente quando o ambiente (`APP_ENV` environment variável) é
1421
- setado para `:production`:
1422
-
1423
- ```ruby
1424
- configure :production do
1425
- ...
1426
- end
1427
- ```
1428
-
1429
- Rodando quando o ambiente é setado para `:production` ou `:test`:
1430
-
1431
- ```ruby
1432
- configure :production, :test do
1433
- ...
1434
- end
1435
- ```
1436
-
1437
- ## Tratamento de Erros
1438
-
1439
- Tratamento de erros rodam dentro do mesmo contexto como rotas e filtros
1440
- before, o que significa que você pega todos os presentes que tem para
1441
- oferecer, como `haml`, `erb`, `halt`, etc.
1442
-
1443
- ### Não Encontrado
1444
-
1445
- Quando um `Sinatra::NotFound` exception é levantado, ou o código de
1446
- status da reposta é 404, o manipulador `not_found` é invocado:
1447
-
1448
- ```ruby
1449
- not_found do
1450
- 'Isto está longe de ser encontrado'
1451
- end
1452
- ```
1453
-
1454
- ### Erro
1455
-
1456
- O manipulador `error` é invocado toda a vez que uma exceção é lançada a
1457
- partir de um bloco de rota ou um filtro. O objeto da exceção pode ser
1458
- obtido a partir da variável Rack `sinatra.error`:
1459
-
1460
- ```ruby
1461
- error do
1462
- 'Desculpe, houve um erro desagradável - ' + env['sinatra.error'].message
1463
- end
1464
- ```
1465
-
1466
- Erros customizados:
1467
-
1468
- ```ruby
1469
- error MeuErroCustomizado do
1470
- 'Então que aconteceu foi...' + env['sinatra.error'].message
1471
- end
1472
- ```
1473
-
1474
- Então, se isso acontecer:
1475
-
1476
- ```ruby
1477
- get '/' do
1478
- raise MeuErroCustomizado, 'alguma coisa ruim'
1479
- end
1480
- ```
1481
-
1482
- Você receberá isso:
1483
-
1484
- Então que aconteceu foi... alguma coisa ruim
1485
-
1486
- Alternativamente, você pode instalar manipulador de erro para um código
1487
- de status:
1488
-
1489
- ```ruby
1490
- error 403 do
1491
- 'Accesso negado'
1492
- end
1493
-
1494
- get '/secreto' do
1495
- 403
1496
- end
1497
- ```
1498
-
1499
- Ou um range:
1500
-
1501
- ```ruby
1502
- error 400..510 do
1503
- 'Boom'
1504
- end
1505
- ```
1506
-
1507
- O Sinatra instala os manipuladores especiais `not_found` e `error`
1508
- quando roda sobre o ambiente de desenvolvimento.
1509
-
1510
- ## Mime Types
1511
-
1512
- Quando utilizamos `send_file` ou arquivos estáticos você pode ter mime
1513
- types Sinatra não entendidos. Use `mime_type` para registrar eles por
1514
- extensão de arquivos:
1515
-
1516
- ```ruby
1517
- mime_type :foo, 'text/foo'
1518
- ```
1519
-
1520
- Você também pode utilizar isto com o helper `content_type`:
1521
-
1522
- ```ruby
1523
- content_type :foo
1524
- ```
1525
-
1526
- ## Rack Middleware
1527
-
1528
- O Sinatra roda no [Rack](http://rack.github.io/), uma interface
1529
- padrão mínima para frameworks web em Ruby. Um das capacidades mais
1530
- interessantes do Rack para desenvolver aplicativos é suporte a
1531
- “middleware” – componentes que ficam entre o servidor e sua aplicação
1532
- monitorando e/ou manipulando o request/response do HTTP para prover
1533
- vários tipos de funcionalidades comuns.
1534
-
1535
- O Sinatra faz construtores pipelines do middleware Rack facilmente em um
1536
- nível superior utilizando o método `use`:
1537
-
1538
- ```ruby
1539
- require 'sinatra'
1540
- require 'meu_middleware_customizado'
1541
-
1542
- use Rack::Lint
1543
- use MeuMiddlewareCustomizado
1544
-
1545
- get '/ola' do
1546
- 'Olá mundo'
1547
- end
1548
- ```
1549
-
1550
- A semântica de `use` é idêntica aquela definida para a DSL
1551
- [Rack::Builder](http://www.rubydoc.info/github/rack/rack/master/Rack/Builder)
1552
- (mais frequentemente utilizada para arquivos rackup). Por exemplo, o
1553
- método `use` aceita múltiplos argumentos/variáveis bem como blocos:
1554
-
1555
- ```ruby
1556
- use Rack::Auth::Basic do |usuario, senha|
1557
- usuario == 'admin' && senha == 'secreto'
1558
- end
1559
- ```
1560
-
1561
- O Rack é distribuido com uma variedade de middleware padrões para logs,
1562
- debugs, rotas de URL, autenticação, e manipuladores de sessão. Sinatra
1563
- utilizada muitos desses componentes automaticamente baseando sobre
1564
- configuração, então, tipicamente você não tem `use` explicitamente.
1565
-
1566
- ## Testando
1567
-
1568
- Testes no Sinatra podem ser escritos utilizando qualquer biblioteca ou
1569
- framework de teste baseados no Rack.
1570
- [Rack::Test](http://gitrdoc.com/brynary/rack-test) é recomendado:
1571
-
1572
- ```ruby
1573
- require 'minha_aplicacao_sinatra'
1574
- require 'rack/test'
1575
-
1576
- class MinhaAplicacaoTeste < Minitest::Test
1577
- include Rack::Test::Methods
1578
-
1579
- def app
1580
- Sinatra::Application
1581
- end
1582
-
1583
- def meu_test_default
1584
- get '/'
1585
- assert_equal 'Ola Mundo!', last_response.body
1586
- end
1587
-
1588
- def teste_com_parametros
1589
- get '/atender', :name => 'Frank'
1590
- assert_equal 'Olá Frank!', last_response.bodymeet
1591
- end
1592
-
1593
- def test_com_ambiente_rack
1594
- get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
1595
- assert_equal "Você está utilizando o Songbird!", last_response.body
1596
- end
1597
- end
1598
- ```
1599
-
1600
- NOTA: Os módulos de classe embutidos `Sinatra::Test` e
1601
- `Sinatra::TestHarness` são depreciados na versão 0.9.2.
1602
-
1603
- ## Sinatra::Base - Middleware, Bibliotecas e aplicativos modulares
1604
-
1605
- Definir sua aplicação em um nível superior de trabalho funciona bem para
1606
- micro aplicativos, mas tem consideráveis incovenientes na construção de
1607
- componentes reutilizáveis como um middleware Rack, metal Rails,
1608
- bibliotecas simples como um componente de servidor, ou mesmo extensões
1609
- Sinatra. A DSL de nível superior polui o espaço do objeto e assume um
1610
- estilo de configuração de micro aplicativos (exemplo: uma simples
1611
- arquivo de aplicação, diretórios `./public` e `./views`, logs, página de
1612
- detalhes de exceção, etc.). É onde o `Sinatra::Base` entra em jogo:
1613
-
1614
- ```ruby
1615
- require 'sinatra/base'
1616
-
1617
- class MinhaApp < Sinatra::Base
1618
- set :sessions, true
1619
- set :foo, 'bar'
1620
-
1621
- get '/' do
1622
- 'Ola mundo!'
1623
- end
1624
- end
1625
- ```
1626
-
1627
- A classe `MinhaApp` é um componente Rack independente que pode agir como
1628
- um middleware Rack, uma aplicação Rack, ou metal Rails. Você pode
1629
- utilizar ou executar esta classe com um arquivo rackup `config.ru`;
1630
- ou, controlar um componente de servidor fornecendo como biblioteca:
1631
-
1632
- ```ruby
1633
- MinhaApp.run! :host => 'localhost', :port => 9090
1634
- ```
1635
-
1636
- Os métodos disponíveis para subclasses `Sinatra::Base` são exatamente como
1637
- aqueles disponíveis via a DSL de nível superior. Aplicações de nível
1638
- mais alto podem ser convertidas para componentes `Sinatra::Base` com duas
1639
- modificações:
1640
-
1641
- - Seu arquivo deve requerer `sinatra/base` ao invés de `sinatra`;
1642
- outra coisa, todos os métodos DSL do Sinatra são importados para o
1643
- espaço principal.
1644
-
1645
- - Coloque as rotas da sua aplicação, manipuladores de erro, filtros e
1646
- opções na subclasse de um `Sinatra::Base`.
1647
-
1648
- `Sinatra::Base` é um quadro branco. Muitas opções são desabilitadas por
1649
- padrão, incluindo o servidor embutido. Veja [Opções e
1650
- Configurações](http://www.sinatrarb.com/configuration.html) para
1651
- detalhes de opções disponíveis e seus comportamentos.
1652
-
1653
- SIDEBAR: A DSL de alto nível do Sinatra é implementada utilizando um simples
1654
- sistema de delegação. A classe `Sinatra::Application` – uma subclasse especial
1655
- da `Sinatra::Base` – recebe todos os `:get`, `:put`, `:post`, `:delete`,
1656
- `:before`, `:error`, `:not_found`, `:configure`, e `:set messages` enviados
1657
- para o alto nível. Dê uma olhada no código você mesmo: aqui está o
1658
- [Sinatra::Delegator
1659
- mixin](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128)
1660
- sendo [incluido dentro de um espaço
1661
- principal](http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28)
1662
-
1663
- ## Linha de Comando
1664
-
1665
- Aplicações Sinatra podem ser executadas diretamente:
1666
-
1667
- ```shell
1668
- ruby minhaapp.rb [-h] [-x] [-e AMBIENTE] [-p PORTA] [-o HOST] [-s SERVIDOR]
1669
- ```
1670
-
1671
- As opções são:
1672
-
1673
- ```
1674
- -h # ajuda
1675
- -p # define a porta (padrão é 4567)
1676
- -o # define o host (padrão é 0.0.0.0)
1677
- -e # define o ambiente (padrão é development)
1678
- -s # especifica o servidor/manipulador rack (padrão é thin)
1679
- -x # ativa o bloqueio (padrão é desligado)
1680
- ```
1681
-
1682
- ### Multi-threading
1683
-
1684
- _Parafraseando [esta resposta no StackOverflow](resposta-so) por Konstantin_
1685
-
1686
- Sinatra não impõe nenhum modelo de concorrencia, mas deixa isso como responsabilidade
1687
- do Rack (servidor) subjacente como o Thin, Puma ou WEBrick. Sinatra por si só é thread-safe,
1688
- então não há nenhum problema se um Rack handler usar um modelo de thread de concorrência. Isso
1689
- significaria que ao iniciar o servidor, você teria que espeficiar o método de invocação correto
1690
- para o Rack handler específico. Os seguintes exemplos é uma demonstração de como iniciar um
1691
- servidor Thin multi-thread:
1692
-
1693
- ```ruby
1694
- # app.rb
1695
-
1696
- require 'sinatra/base'
1697
-
1698
- class App < Sinatra::Base
1699
- get '/' do
1700
- 'Olá mundo'
1701
- end
1702
- end
1703
-
1704
- App.run!
1705
- ```
1706
-
1707
- Para iniciar o servidor seria:
1708
-
1709
- ```shell
1710
- thin --threaded start
1711
- ```
1712
-
1713
- [resposrta-so]: http://stackoverflow.com/questions/6278817/is-sinatra-multi-threaded/6282999#6282999)
1714
-
1715
- ## A última versão
1716
-
1717
- Se você gostaria de utilizar o código da última versão do Sinatra, crie
1718
- um clone local e execute sua aplicação com o diretório `sinatra/lib` no
1719
- `LOAD_PATH`:
1720
-
1721
- ```shell
1722
- cd minhaapp
1723
- git clone git://github.com/sinatra/sinatra.git
1724
- ruby -I sinatra/lib minhaapp.rb
1725
- ```
1726
-
1727
- Alternativamente, você pode adicionar o diretório do `sinatra/lib` no
1728
- `LOAD_PATH` do seu aplicativo:
1729
-
1730
- ```ruby
1731
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/sinatra/lib'
1732
- require 'rubygems'
1733
- require 'sinatra'
1734
-
1735
- get '/sobre' do
1736
- "Estou rodando a versão" + Sinatra::VERSION
1737
- end
1738
- ```
1739
-
1740
- Para atualizar o código do Sinatra no futuro:
1741
-
1742
- ```shell
1743
- cd meuprojeto/sinatra
1744
- git pull
1745
- ```
1746
-
1747
- ## Mais
1748
-
1749
- * [Website do Projeto](http://www.sinatrarb.com/) - Documentação
1750
- adicional, novidades e links para outros recursos.
1751
- * [Contribuir](http://www.sinatrarb.com/contributing) - Encontrar um
1752
- bug? Precisa de ajuda? Tem um patch?
1753
- * [Acompanhar Questões](https://github.com/sinatra/sinatra/issues)
1754
- * [Twitter](https://twitter.com/sinatra)
1755
- * [Lista de Email](http://groups.google.com/group/sinatrarb/topics)
1756
- * [Sinatra Book](https://github.com/sinatra/sinatra-book/) Livro de Receitas
1757
- * Documentação da API para a [última release](http://www.rubydoc.info/gems/sinatra)
1758
- * [IRC: \#sinatra](irc://chat.freenode.net/#sinatra) em
1759
- [freenode.net](http://freenode.net)
1760
- * [Servidor de CI](https://travis-ci.org/sinatra/sinatra)