/
README.ko.html
2250 lines (1960 loc) · 145 KB
/
README.ko.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<div class='toc'>
<ol class='level-1'>
<li><a href='#%EB%9D%BC%EC%9A%B0%ED%84%B0(Routes)'>라우터(Routes)</a></li>
<ol class='level-2'>
<li><a href='#%EC%A1%B0%EA%B1%B4(Conditions)'>조건(Conditions)</a></li>
<li><a href='#%EB%B0%98%ED%99%98%EA%B0%92(Return%20Values)'>반환값(Return Values)</a></li>
<li><a href='#%EC%BB%A4%EC%8A%A4%ED%85%80%20%EB%9D%BC%EC%9A%B0%ED%84%B0%20%EB%A7%A4%EC%B2%98(Custom%20Route%20Matchers)'>커스텀 라우터 매처(Custom Route Matchers)</a></li>
</ol>
<li><a href='#%EC%A0%95%EC%A0%81%20%ED%8C%8C%EC%9D%BC(Static%20Files)'>정적 파일(Static Files)</a></li>
<li><a href='#%EB%B7%B0%20/%20%ED%85%9C%ED%94%8C%EB%A6%BF(Views%20/%20Templates)'>뷰 / 템플릿(Views / Templates)</a></li>
<ol class='level-2'>
<li><a href='#%EA%B0%80%EB%8A%A5%ED%95%9C%20%ED%85%9C%ED%94%8C%EB%A6%BF%20%EC%96%B8%EC%96%B4%EB%93%A4(Available%20Template%20Languages)'>가능한 템플릿 언어들(Available Template Languages)</a></li>
<li><a href='#Haml%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Haml 템플릿</a></li>
<li><a href='#Erb%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Erb 템플릿</a></li>
<li><a href='#Builder%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Builder 템플릿</a></li>
<li><a href='#Nokogiri%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Nokogiri 템플릿</a></li>
<li><a href='#Sass%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Sass 템플릿</a></li>
<li><a href='#SCSS%20%ED%85%9C%ED%94%8C%EB%A6%BF'>SCSS 템플릿</a></li>
<li><a href='#Less%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Less 템플릿</a></li>
<li><a href='#Liquid%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Liquid 템플릿</a></li>
<li><a href='#Markdown%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Markdown 템플릿</a></li>
<li><a href='#Textile%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Textile 템플릿</a></li>
<li><a href='#RDoc%20%ED%85%9C%ED%94%8C%EB%A6%BF'>RDoc 템플릿</a></li>
<li><a href='#Radius%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Radius 템플릿</a></li>
<li><a href='#Markaby%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Markaby 템플릿</a></li>
<li><a href='#RABL%20%ED%85%9C%ED%94%8C%EB%A6%BF'>RABL 템플릿</a></li>
<li><a href='#Slim%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Slim 템플릿</a></li>
<li><a href='#Creole%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Creole 템플릿</a></li>
<li><a href='#CoffeeScript%20%ED%85%9C%ED%94%8C%EB%A6%BF'>CoffeeScript 템플릿</a></li>
<li><a href='#Yajl%20%ED%85%9C%ED%94%8C%EB%A6%BF'>Yajl 템플릿</a></li>
<li><a href='#%EB%82%B4%EC%9E%A5%EB%90%9C(Embedded)%20%ED%85%9C%ED%94%8C%EB%A6%BF'>내장된(Embedded) 템플릿</a></li>
<li><a href='#%ED%85%9C%ED%94%8C%EB%A6%BF%EC%97%90%EC%84%9C%20%EB%B3%80%EC%88%98%EC%97%90%20%EC%A0%91%EA%B7%BC%ED%95%98%EA%B8%B0'>템플릿에서 변수에 접근하기</a></li>
<li><a href='#%EC%9D%B8%EB%9D%BC%EC%9D%B8%20%ED%85%9C%ED%94%8C%EB%A6%BF'>인라인 템플릿</a></li>
<li><a href='#%EC%9D%B4%EB%A6%84%EC%9D%84%20%EA%B0%80%EC%A7%80%EB%8A%94%20%ED%85%9C%ED%94%8C%EB%A6%BF(Named%20Templates)'>이름을 가지는 템플릿(Named Templates)</a></li>
<li><a href='#%ED%8C%8C%EC%9D%BC%20%ED%99%95%EC%9E%A5%EC%9E%90%20%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0'>파일 확장자 연결하기</a></li>
<li><a href='#%EB%82%98%EB%A7%8C%EC%9D%98%20%EA%B3%A0%EC%9C%A0%ED%95%9C%20%ED%85%9C%ED%94%8C%EB%A6%BF%20%EC%97%94%EC%A7%84%20%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0'>나만의 고유한 템플릿 엔진 추가하기</a></li>
</ol>
<li><a href='#%ED%95%84%ED%84%B0(Filters)'>필터(Filters)</a></li>
<li><a href='#%ED%97%AC%ED%8D%BC(Helpers)'>헬퍼(Helpers)</a></li>
<ol class='level-2'>
<li><a href='#%EC%84%B8%EC%85%98(Sessions)%20%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0'>세션(Sessions) 사용하기</a></li>
<li><a href='#%EC%A4%91%EB%8B%A8%ED%95%98%EA%B8%B0(Halting)'>중단하기(Halting)</a></li>
<li><a href='#%EB%84%98%EA%B8%B0%EA%B8%B0(Passing)'>넘기기(Passing)</a></li>
<li><a href='#%EB%8B%A4%EB%A5%B8%20%EB%9D%BC%EC%9A%B0%ED%84%B0%20%EB%B6%80%EB%A5%B4%EA%B8%B0(Triggering%20Another%20Route)'>다른 라우터 부르기(Triggering Another Route)</a></li>
<li><a href='#%EB%B3%B8%EB%AC%B8,%20%EC%83%81%ED%83%9C%20%EC%BD%94%EB%93%9C%20%EB%B0%8F%20%ED%97%A4%EB%8D%94%20%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0'>본문, 상태 코드 및 헤더 설정하기</a></li>
<li><a href='#%EC%9D%91%EB%8B%B5%20%EC%8A%A4%ED%8A%B8%EB%A6%AC%EB%B0%8D(Streaming%20Responses)'>응답 스트리밍(Streaming Responses)</a></li>
<li><a href='#%EB%A1%9C%EA%B9%85(Logging)'>로깅(Logging)</a></li>
<li><a href='#%EB%A7%88%EC%9E%84%20%ED%83%80%EC%9E%85(Mime%20Types)'>마임 타입(Mime Types)</a></li>
<li><a href='#URL%20%EC%83%9D%EC%84%B1%ED%95%98%EA%B8%B0'>URL 생성하기</a></li>
<li><a href='#%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%80%20%EC%9E%AC%EC%A7%80%EC%A0%95(Browser%20Redirect)'>브라우저 재지정(Browser Redirect)</a></li>
<li><a href='#%EC%BA%90%EC%8B%9C%20%EC%BB%A8%ED%8A%B8%EB%A1%A4(Cache%20Control)'>캐시 컨트롤(Cache Control)</a></li>
<li><a href='#%ED%8C%8C%EC%9D%BC%20%EC%A0%84%EC%86%A1%ED%95%98%EA%B8%B0(Sending%20Files)'>파일 전송하기(Sending Files)</a></li>
<li><a href='#%EC%9A%94%EC%B2%AD%20%EA%B0%9D%EC%B2%B4%EC%97%90%20%EC%A0%91%EA%B7%BC%ED%95%98%EA%B8%B0(Accessing%20the%20Request%20Object)'>요청 객체에 접근하기(Accessing the Request Object)</a></li>
<li><a href='#%EC%B2%A8%EB%B6%80(Attachments)'>첨부(Attachments)</a></li>
<li><a href='#%EB%82%A0%EC%A7%9C%EC%99%80%20%EC%8B%9C%EA%B0%84%20%EB%8B%A4%EB%A3%A8%EA%B8%B0'>날짜와 시간 다루기</a></li>
<li><a href='#%ED%85%9C%ED%94%8C%EB%A6%BF%20%ED%8C%8C%EC%9D%BC%20%EC%B0%B8%EC%A1%B0%ED%95%98%EA%B8%B0'>템플릿 파일 참조하기</a></li>
</ol>
<li><a href='#%EC%84%A4%EC%A0%95(Configuration)'>설정(Configuration)</a></li>
<ol class='level-2'>
<li><a href='#%EA%B3%B5%EA%B2%A9%20%EB%B0%A9%EC%96%B4%20%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0(Configuring%20attack%20protection)'>공격 방어 설정하기(Configuring attack protection)</a></li>
<li><a href='#%EA%B0%80%EB%8A%A5%ED%95%9C%20%EC%84%A4%EC%A0%95%EB%93%A4(Available%20Settings)'>가능한 설정들(Available Settings)</a></li>
</ol>
<li><a href='#%ED%99%98%EA%B2%BD(Environments)'>환경(Environments)</a></li>
<li><a href='#%EC%98%88%EC%99%B8%20%EC%B2%98%EB%A6%AC(Error%20Handling)'>예외 처리(Error Handling)</a></li>
<ol class='level-2'>
<li><a href='#%EC%B0%BE%EC%9D%84%20%EC%88%98%20%EC%97%86%EC%9D%8C(Not%20Found)'>찾을 수 없음(Not Found)</a></li>
<li><a href='#%EC%98%A4%EB%A5%98(Error)'>오류(Error)</a></li>
</ol>
<li><a href='#Rack%20%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4(Rack%20Middleware)'>Rack 미들웨어(Rack Middleware)</a></li>
<li><a href='#%ED%85%8C%EC%8A%A4%ED%8C%85(Testing)'>테스팅(Testing)</a></li>
<li><a href='#Sinatra::Base%20-%20%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4(Middleware),%20%EB%9D%BC%EC%9D%B4%EB%B8%8C%EB%9F%AC%EB%A6%AC(Libraries),%20%EA%B7%B8%EB%A6%AC%EA%B3%A0%20%EB%AA%A8%EB%93%88%20%EC%95%B1(Modular%20Apps)'>Sinatra::Base - 미들웨어(Middleware), 라이브러리(Libraries), 그리고 모듈 앱(Modular Apps)</a></li>
<ol class='level-2'>
<li><a href='#%EB%AA%A8%EB%93%88(Modular)%20vs.%20%EC%A0%84%ED%86%B5%EC%A0%81%20%EB%B0%A9%EC%8B%9D(Classic%20Style)'>모듈(Modular) vs. 전통적 방식(Classic Style)</a></li>
<li><a href='#%EB%AA%A8%EB%93%88%20%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98(Modular%20Application)%20%EC%A0%9C%EA%B3%B5%ED%95%98%EA%B8%B0'>모듈 애플리케이션(Modular Application) 제공하기</a></li>
<li><a href='#config.ru%EB%A1%9C%20%EC%A0%84%ED%86%B5%EC%A0%81%20%EB%B0%A9%EC%8B%9D%EC%9D%98%20%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98%20%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0'>config.ru로 전통적 방식의 애플리케이션 사용하기</a></li>
<li><a href='#%EC%96%B8%EC%A0%9C%20config.ru%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%A0%EA%B9%8C?'>언제 config.ru를 사용할까?</a></li>
<li><a href='#Sinatra%EB%A5%BC%20%EB%AF%B8%EB%93%A4%EC%9B%A8%EC%96%B4%EB%A1%9C%20%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0'>Sinatra를 미들웨어로 사용하기</a></li>
<li><a href='#%EB%8F%99%EC%A0%81%EC%9D%B8%20%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98%20%EC%83%9D%EC%84%B1(Dynamic%20Application%20Creation)'>동적인 애플리케이션 생성(Dynamic Application Creation)</a></li>
</ol>
<li><a href='#%EB%B2%94%EC%9C%84(Scopes)%EC%99%80%20%EB%B0%94%EC%9D%B8%EB%94%A9(Binding)'>범위(Scopes)와 바인딩(Binding)</a></li>
<ol class='level-2'>
<li><a href='#%EC%95%A0%ED%94%8C%EB%A6%AC%EC%BC%80%EC%9D%B4%EC%85%98/%ED%81%B4%EB%9E%98%EC%8A%A4%20%EB%B2%94%EC%9C%84'>애플리케이션/클래스 범위</a></li>
<li><a href='#%EC%9A%94%EC%B2%AD/%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4%20%EB%B2%94%EC%9C%84'>요청/인스턴스 범위</a></li>
<li><a href='#%EC%9C%84%EC%9E%84%20%EB%B2%94%EC%9C%84(Delegation%20Scope)'>위임 범위(Delegation Scope)</a></li>
</ol>
<li><a href='#%EB%AA%85%EB%A0%B9%ED%96%89(Command%20Line)'>명령행(Command Line)</a></li>
<li><a href='#%EC%9A%94%EA%B5%AC%EC%82%AC%ED%95%AD(Requirement)'>요구사항(Requirement)</a></li>
<li><a href='#%EC%B5%9C%EC%8B%A0(The%20Bleeding%20Edge)'>최신(The Bleeding Edge)</a></li>
<ol class='level-2'>
<li><a href='#Bundler%EB%A5%BC%20%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC'>Bundler를 사용하여</a></li>
<li><a href='#%EC%A7%81%EC%A0%91%20%ED%95%98%EA%B8%B0(Roll%20Your%20Own)'>직접 하기(Roll Your Own)</a></li>
<li><a href='#%EC%A0%84%EC%97%AD%EC%9C%BC%EB%A1%9C%20%EC%84%A4%EC%B9%98(Install%20Globally)'>전역으로 설치(Install Globally)</a></li>
</ol>
<li><a href='#%EB%B2%84%EC%A0%80%EB%8B%9D(Versioning)'>버저닝(Versioning)</a></li>
<li><a href='#%EB%8D%94%20%EC%9D%BD%EC%9D%84%20%EA%B1%B0%EB%A6%AC(Further%20Reading)'>더 읽을 거리(Further Reading)</a></li>
</ol>
</div>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p><em>주의: 이 문서는 영문판의 번역본이며 최신판 문서와 다를 수 있음.</em></p>
<p>Sinatra는 최소한의 노력으로 루비 기반 웹 애플리케이션을 신속하게 만들 수 있게 해 주는 <a href="http://en.wikipedia.org/wiki/Domain-specific_language">DSL</a>이다:</p>
<pre class="highlight ruby"><span class="c1"># myapp.rb</span>
<span class="nb">require</span> <span class="s1">'sinatra'</span>
<span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="s1">'Hello world!'</span>
<span class="k">end</span>
</pre>
<p>다음과 같이 젬을 설치하고 실행한다:</p>
<pre class="highlight ruby"><span class="n">gem</span> <span class="n">install</span> <span class="n">sinatra</span>
<span class="n">ruby</span> <span class="n">myapp</span><span class="nf">.rb</span>
</pre>
<p>확인: http://localhost:4567</p>
<p><code>gem install thin</code>도 함께 실행하기를 권장하며, 그럴 경우 Sinatra는 thin을 부른다.</p>
<a name='%EB%9D%BC%EC%9A%B0%ED%84%B0(Routes)'></a>
<h2>라우터(Routes)</h2>
<p>Sinatra에서, 라우터(route)는 URL-매칭 패턴과 쌍을 이루는 HTTP 메서드다.
각각의 라우터는 블록과 연결된다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="nf">..</span> <span class="err">무언가</span> <span class="err">보여주기</span><span class="p">(</span><span class="n">show</span><span class="p">)</span> <span class="nf">..</span>
<span class="k">end</span>
<span class="n">post</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="nf">..</span> <span class="err">무언가</span> <span class="err">만들기</span><span class="p">(</span><span class="n">create</span><span class="p">)</span> <span class="nf">..</span>
<span class="k">end</span>
<span class="n">put</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="nf">..</span> <span class="err">무언가</span> <span class="err">대체하기</span><span class="p">(</span><span class="n">replace</span><span class="p">)</span> <span class="nf">..</span>
<span class="k">end</span>
<span class="n">patch</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="nf">..</span> <span class="err">무언가</span> <span class="err">수정하기</span><span class="p">(</span><span class="n">modify</span><span class="p">)</span> <span class="nf">..</span>
<span class="k">end</span>
<span class="n">delete</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="nf">..</span> <span class="err">무언가</span> <span class="err">없애기</span><span class="p">(</span><span class="n">annihilate</span><span class="p">)</span> <span class="nf">..</span>
<span class="k">end</span>
<span class="n">options</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="nf">..</span> <span class="err">무언가</span> <span class="err">주기</span><span class="p">(</span><span class="n">appease</span><span class="p">)</span> <span class="nf">..</span>
<span class="k">end</span>
</pre>
<p>라우터는 정의된 순서에 따라 매치되며 매칭된 첫 번째 라우터가 호출된다.</p>
<p>라우터 패턴에는 이름을 가진 매개변수가 포함될 수있으며, <code>params</code> 해시로 접근할 수 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/hello/:name'</span> <span class="k">do</span>
<span class="c1"># "GET /hello/foo" 및 "GET /hello/bar"와 매치</span>
<span class="c1"># params[:name]은 'foo' 또는 'bar'</span>
<span class="s2">"Hello </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="si">}</span><span class="s2">!"</span>
<span class="k">end</span>
</pre>
<p>또한 블록 매개변수를 통하여도 이름을 가진 매개변수에 접근할 수 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/hello/:name'</span> <span class="k">do</span> <span class="o">|</span><span class="n">n</span><span class="o">|</span>
<span class="s2">"Hello </span><span class="si">#{</span><span class="n">n</span><span class="si">}</span><span class="s2">!"</span>
<span class="k">end</span>
</pre>
<p>라우터 패턴에는 스플랫(splat, 또는 와일드카드)도 포함될 수 있으며, 이럴 경우 <code>params[:splat]</code> 배열로 접근할 수 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/say/*/to/*'</span> <span class="k">do</span>
<span class="c1"># /say/hello/to/world와 매치</span>
<span class="n">params</span><span class="o">[</span><span class="ss">:splat</span><span class="o">]</span> <span class="c1"># => ["hello", "world"]</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/download/*.*'</span> <span class="k">do</span>
<span class="c1"># /download/path/to/file.xml과 매치</span>
<span class="n">params</span><span class="o">[</span><span class="ss">:splat</span><span class="o">]</span> <span class="c1"># => ["path/to/file", "xml"]</span>
<span class="k">end</span>
</pre>
<p>또는 블록 매개변수도 가능하다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/download/*.*'</span> <span class="k">do</span> <span class="o">|</span><span class="n">path</span><span class="p">,</span> <span class="n">ext</span><span class="o">|</span>
<span class="o">[</span><span class="n">path</span><span class="p">,</span> <span class="n">ext</span><span class="o">]</span> <span class="c1"># => ["path/to/file", "xml"]</span>
<span class="k">end</span>
</pre>
<p>정규표현식을 이용한 라우터 매칭:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="sr">%r{/hello/([</span><span class="se">\w</span><span class="sr">]+)}</span> <span class="k">do</span>
<span class="s2">"Hello, </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:captures</span><span class="o">]</span><span class="nf">.first</span><span class="si">}</span><span class="s2">!"</span>
<span class="k">end</span>
</pre>
<p>또는 블록 매개변수로도 가능:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="sr">%r{/hello/([</span><span class="se">\w</span><span class="sr">]+)}</span> <span class="k">do</span> <span class="o">|</span><span class="n">c</span><span class="o">|</span>
<span class="s2">"Hello, </span><span class="si">#{</span><span class="n">c</span><span class="si">}</span><span class="s2">!"</span>
<span class="k">end</span>
</pre>
<p>라우터 패턴에는 선택적인(optional) 매개변수도 올 수 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/posts.?:format?'</span> <span class="k">do</span>
<span class="c1"># "GET /posts" 및 "GET /posts.json", "GET /posts.xml" 와 같은 어떤 확장자와도 매칭</span>
<span class="k">end</span>
</pre>
<p>한편, 경로 탐색 공격 방지(path traversal attack protection, 아래 참조)를 비활성화시키지 않았다면,
요청 경로는 라우터와 매칭되기 이전에 수정될 수 있다.</p>
<a name='%EC%A1%B0%EA%B1%B4(Conditions)'></a>
<h3>조건(Conditions)</h3>
<p>라우터는 예를 들면 사용자 에이전트(user agent)와 같은 다양한 매칭 조건을 포함할 수 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/foo'</span><span class="p">,</span> <span class="ss">:agent</span> <span class="o">=></span> <span class="sr">/Songbird (\d\.\d)[\d\/]*?/</span> <span class="k">do</span>
<span class="s2">"Songbird 버전 </span><span class="si">#{</span><span class="n">params</span><span class="o">[</span><span class="ss">:agent</span><span class="o">][</span><span class="mi">0</span><span class="o">]</span><span class="si">}</span><span class="s2">을 사용하는군요!"</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/foo'</span> <span class="k">do</span>
<span class="c1"># songbird 브라우저가 아닌 경우 매치</span>
<span class="k">end</span>
</pre>
<p>그 밖에 다른 조건으로는 <code>host_name</code>과 <code>provides</code>가 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span><span class="p">,</span> <span class="ss">:host_name</span> <span class="o">=></span> <span class="sr">/^admin\./</span> <span class="k">do</span>
<span class="s2">"Admin Area, Access denied!"</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/'</span><span class="p">,</span> <span class="ss">:provides</span> <span class="o">=></span> <span class="s1">'html'</span> <span class="k">do</span>
<span class="n">haml</span> <span class="ss">:index</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/'</span><span class="p">,</span> <span class="ss">:provides</span> <span class="o">=></span> <span class="o">[</span><span class="s1">'rss'</span><span class="p">,</span> <span class="s1">'atom'</span><span class="p">,</span> <span class="s1">'xml'</span><span class="o">]</span> <span class="k">do</span>
<span class="n">builder</span> <span class="ss">:feed</span>
<span class="k">end</span>
</pre>
<p>여러분만의 조건도 쉽게 정의할 수 있다:</p>
<pre class="highlight ruby"><span class="n">set</span><span class="p">(</span><span class="ss">:probability</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">value</span><span class="o">|</span> <span class="n">condition</span> <span class="p">{</span> <span class="nb">rand</span> <span class="o"><=</span> <span class="n">value</span> <span class="p">}</span> <span class="p">}</span>
<span class="n">get</span> <span class="s1">'/win_a_car'</span><span class="p">,</span> <span class="ss">:probability</span> <span class="o">=></span> <span class="mi">0</span><span class="o">.</span><span class="mi">1</span> <span class="k">do</span>
<span class="s2">"내가 졌소!"</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/win_a_car'</span> <span class="k">do</span>
<span class="s2">"미안해서 어쩌나."</span>
<span class="k">end</span>
</pre>
<p>여러 값을 받는 조건에는 스플랫(splat)을 사용하자:</p>
<pre class="highlight ruby"><span class="n">set</span><span class="p">(</span><span class="ss">:auth</span><span class="p">)</span> <span class="k">do</span> <span class="o">|*</span><span class="n">roles</span><span class="o">|</span> <span class="c1"># <- 이게 스플랫</span>
<span class="n">condition</span> <span class="k">do</span>
<span class="k">unless</span> <span class="n">logged_in?</span> <span class="o">&&</span> <span class="n">roles</span><span class="nf">.any?</span> <span class="p">{</span><span class="o">|</span><span class="n">role</span><span class="o">|</span> <span class="n">current_user</span><span class="nf">.in_role?</span> <span class="n">role</span> <span class="p">}</span>
<span class="n">redirect</span> <span class="s2">"/login/"</span><span class="p">,</span> <span class="mi">303</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s2">"/my/account/"</span><span class="p">,</span> <span class="ss">:auth</span> <span class="o">=></span> <span class="o">[</span><span class="ss">:user</span><span class="p">,</span> <span class="ss">:admin</span><span class="o">]</span> <span class="k">do</span>
<span class="s2">"내 계정 정보"</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s2">"/only/admin/"</span><span class="p">,</span> <span class="ss">:auth</span> <span class="o">=></span> <span class="ss">:admin</span> <span class="k">do</span>
<span class="s2">"관리자 외 접근불가!"</span>
<span class="k">end</span>
</pre>
<a name='%EB%B0%98%ED%99%98%EA%B0%92(Return%20Values)'></a>
<h3>반환값(Return Values)</h3>
<p>라우터 블록의 반환값은 HTTP 클라이언트로 전달되는 응답 본문을 결정하거나, 또는 Rack 스택에서 다음 번 미들웨어를 결정한다.
대부분의 경우, 이 반환값은 위의 예제에서 보듯 문자열이지만, 다른 값도 가능하다.</p>
<p>유효한 Rack 응답, Rack 본문 객체 또는 HTTP 상태 코드가 되는 어떠한 객체라도 반환할 수 있다:</p>
<p>이에 따라 우리는, 예를 들면, 스트리밍(streaming) 예제를 쉽게 구현할 수 있다:</p>
<pre class="highlight ruby"><span class="k">class</span> <span class="nc">Stream</span>
<span class="k">def</span> <span class="nf">each</span>
<span class="mi">100</span><span class="nf">.times</span> <span class="p">{</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span> <span class="k">yield</span> <span class="s2">"</span><span class="si">#{</span><span class="n">i</span><span class="si">}</span><span class="se">\n</span><span class="s2">"</span> <span class="p">}</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">get</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span> <span class="p">{</span> <span class="no">Stream</span><span class="nf">.new</span> <span class="p">}</span>
</pre>
<p>이런 번거로움을 줄이기 위해 <code>stream</code> 헬퍼 메서드(아래 참조)를 사용하여 스트리밍 로직을 라우터 속에 둘 수도 있다.</p>
<a name='%EC%BB%A4%EC%8A%A4%ED%85%80%20%EB%9D%BC%EC%9A%B0%ED%84%B0%20%EB%A7%A4%EC%B2%98(Custom%20Route%20Matchers)'></a>
<h3>커스텀 라우터 매처(Custom Route Matchers)</h3>
<p>위에서 보듯, Sinatra에는 문자열 패턴 및 정규표현식을 이용한 라우터 매칭 지원이 내장되어 있다.
그렇지만, 그게 끝이 아니다. 여러분 만의 매처(matcher)도 쉽게 정의할 수 있다:</p>
<pre class="highlight ruby"><span class="k">class</span> <span class="nc">AllButPattern</span>
<span class="nc">Match</span> <span class="o">=</span> <span class="no">Struct</span><span class="nf">.new</span><span class="p">(</span><span class="ss">:captures</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">initialize</span><span class="p">(</span><span class="n">except</span><span class="p">)</span>
<span class="vi">@except</span> <span class="o">=</span> <span class="n">except</span>
<span class="vi">@captures</span> <span class="o">=</span> <span class="no">Match</span><span class="nf">.new</span><span class="p">(</span><span class="o">[]</span><span class="p">)</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">match</span><span class="p">(</span><span class="n">str</span><span class="p">)</span>
<span class="vi">@captures</span> <span class="k">unless</span> <span class="vi">@except</span> <span class="o">===</span> <span class="n">str</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="k">def</span> <span class="nf">all_but</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span>
<span class="no">AllButPattern</span><span class="nf">.new</span><span class="p">(</span><span class="n">pattern</span><span class="p">)</span>
<span class="k">end</span>
<span class="n">get</span> <span class="n">all_but</span><span class="p">(</span><span class="s2">"/index"</span><span class="p">)</span> <span class="k">do</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre>
<p>사실 위의 예제는 조금 과하게 작성된 면이 있다. 다음과 같이 표현할 수도 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="sr">//</span> <span class="k">do</span>
<span class="n">pass</span> <span class="k">if</span> <span class="n">request</span><span class="nf">.path_info</span> <span class="o">==</span> <span class="s2">"/index"</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre>
<p>또는 네거티브 룩어헤드(negative look ahead)를 사용할 수도 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="sr">%r{^(?!/index$)}</span> <span class="k">do</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre>
<a name='%EC%A0%95%EC%A0%81%20%ED%8C%8C%EC%9D%BC(Static%20Files)'></a>
<h2>정적 파일(Static Files)</h2>
<p>정적 파일들은 <code>./public</code>에서 제공된다.
위치를 다른 곳으로 변경하려면 <code>:public_folder</code> 옵션을 사용하면 된다:</p>
<pre class="highlight ruby"><span class="n">set</span> <span class="ss">:public_folder</span><span class="p">,</span> <span class="no">File</span><span class="nf">.dirname</span><span class="p">(</span><span class="kp">__FILE__</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'/static'</span>
</pre>
<p>이 때 public 디렉터리명은 URL에 포함되지 않는다는 점에 유의.
<code>./public/css/style.css</code> 파일은 <code>http://example.com/css/style.css</code> 로 접근할 수 있다.</p>
<p><code>Cache-Control</code> 헤더 정보를 추가하려면 <code>:static_cache_control</code> 설정(아래 참조)을 사용하면 된다.</p>
<a name='%EB%B7%B0%20/%20%ED%85%9C%ED%94%8C%EB%A6%BF(Views%20/%20Templates)'></a>
<h2>뷰 / 템플릿(Views / Templates)</h2>
<p>각 템플릿 언어는 그들만의 고유한 렌더링 메서드를 통해 표출된다.
이들 메서드는 단순히 문자열을 반환한다.</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">erb</span> <span class="ss">:index</span>
<span class="k">end</span>
</pre>
<p>이 메서드는 <code>views/index.erb</code>를 렌더한다.</p>
<p>템플릿 이름 대신 템플릿의 내용을 직접 전달할 수도 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">code</span> <span class="o">=</span> <span class="s2">"<%= Time.now %>"</span>
<span class="n">erb</span> <span class="n">code</span>
<span class="k">end</span>
</pre>
<p>템플릿은 두 번째 인자로 옵션값의 해시를 받는다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">erb</span> <span class="ss">:index</span><span class="p">,</span> <span class="ss">:layout</span> <span class="o">=></span> <span class="ss">:post</span>
<span class="k">end</span>
</pre>
<p>이렇게 하면 <code>views/post.erb</code> 속에 내장된 <code>views/index.erb</code>를 렌더한다.
(기본값은 <code>views/layout.erb</code>이며, 이 파일이 존재할 경우에만 먹는다).</p>
<p>Sinatra가 이해하지 못하는 모든 옵션값들은 템플릿 엔진으로 전달될 것이다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">haml</span> <span class="ss">:index</span><span class="p">,</span> <span class="ss">:format</span> <span class="o">=></span> <span class="ss">:html5</span>
<span class="k">end</span>
</pre>
<p>옵션값은 템플릿 언어별로 일반적으로 설정할 수도 있다:</p>
<pre class="highlight ruby"><span class="n">set</span> <span class="ss">:haml</span><span class="p">,</span> <span class="ss">:format</span> <span class="o">=></span> <span class="ss">:html5</span>
<span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">haml</span> <span class="ss">:index</span>
<span class="k">end</span>
</pre>
<p>render 메서드에서 전달된 옵션값들은 <code>set</code>을 통해 설정한 옵션값을 덮어 쓴다.</p>
<p>가능한 옵션값들:</p>
<dl>
<dt>locals</dt>
<dd>문서로 전달되는 local 목록. 파셜과 함께 사용하기 좋음.
예제: <tt>erb "", :locals => {:foo => "bar"}</tt>
</dd>
<dt>default_encoding</dt>
<dd>불확실한 경우에 사용할 문자열 인코딩. 기본값은 <tt>settings.default_encoding</tt>.</dd>
<dt>views</dt>
<dd>템플릿을 로드할 뷰 폴더. 기본값은 <tt>settings.views</tt>.</dd>
<dt>layout</dt>
<dd>레이아웃을 사용할지 여부 (<tt>true</tt> 또는 <tt>false</tt>), 만약 이 값이 심볼일 경우,
사용할 템플릿을 지정. 예제: <tt>erb :index, :layout => !request.xhr?</tt>
</dd>
<dt>content_type</dt>
<dd>템플릿이 생성하는 Content-Type, 기본값은 템플릿 언어에 의존.</dd>
<dt>scope</dt>
<dd>템플릿을 렌더링하는 범위. 기본값은 어플리케이션 인스턴스.
만약 이 값을 변경하면, 인스턴스 변수와 헬퍼 메서드들을 사용할 수 없게 됨.</dd>
<dt>layout_engine</dt>
<dd>
레이아웃 렌더링에 사용할 템플릿 엔진. 레이아웃을 지원하지 않는 언어인 경우에 유용.
기본값은 템플릿에서 사용하는 엔진. 예제: <tt>set :rdoc, :layout_engine => :erb</tt>
</dd>
</dl>
<p>템플릿은 <code>./views</code> 아래에 놓이는 것으로 가정됨. 만약 뷰 디렉터리를 다른 곳으로 두려면:</p>
<pre class="highlight ruby"><span class="n">set</span> <span class="ss">:views</span><span class="p">,</span> <span class="n">settings</span><span class="nf">.root</span> <span class="o">+</span> <span class="s1">'/templates'</span>
</pre>
<p>꼭 알아야 할 중요한 점 한 가지는 템플릿은 언제나 심볼로 참조된다는 것이며,
템플릿이 하위 디렉터리에 위치한 경우라도 마찬가지임(그럴 경우에는 <code>:'subdir/template'</code>을 사용).
반드시 심볼이어야 하는 이유는, 만약 그렇게 하지 않으면 렌더링 메서드가 전달된 문자열을 직접 렌더하려 할 것이기 때문임.</p>
<a name='%EA%B0%80%EB%8A%A5%ED%95%9C%20%ED%85%9C%ED%94%8C%EB%A6%BF%20%EC%96%B8%EC%96%B4%EB%93%A4(Available%20Template%20Languages)'></a>
<h3>가능한 템플릿 언어들(Available Template Languages)</h3>
<p>일부 언어는 여러 개의 구현이 있음. 어느 구현을 사용할지 저정하려면(그리고 스레드-안전thread-safe 모드로 하려면),
먼저 require 시키기만 하면 됨:</p>
<pre class="highlight ruby"><span class="nb">require</span> <span class="s1">'rdiscount'</span> <span class="c1"># or require 'bluecloth'</span>
<span class="n">get</span><span class="p">(</span><span class="s1">'/'</span><span class="p">)</span> <span class="p">{</span> <span class="n">markdown</span> <span class="ss">:index</span> <span class="p">}</span>
</pre>
<a name='Haml%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Haml 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://haml.info/">haml</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.haml</tt></td>
</tr>
<tr>
<td>예</td>
<td><tt>haml :index, :format => :html5</tt></td>
</tr>
</table>
<a name='Erb%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Erb 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td>
<a href="http://www.kuwata-lab.com/erubis/">erubis</a> 또는 erb (루비 속에 포함)</td>
</tr>
<tr>
<td>파일 확장자</td>
<td>
<tt>.erb</tt>, <tt>.rhtml</tt> 또는 <tt>.erubis</tt> (Erubis만 해당)</td>
</tr>
<tr>
<td>예제</td>
<td><tt>erb :index</tt></td>
</tr>
</table>
<a name='Builder%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Builder 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://builder.rubyforge.org/">builder</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.builder</tt></td>
</tr>
<tr>
<td>Example</td>
<td><tt>builder { |xml| xml.em "hi" }</tt></td>
</tr>
</table>
<p>인라인 템플릿으로 블록을 받음(예제 참조).</p>
<a name='Nokogiri%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Nokogiri 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://nokogiri.org/">nokogiri</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.nokogiri</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>nokogiri { |xml| xml.em "hi" }</tt></td>
</tr>
</table>
<p>인라인 템플릿으로 블록을 받음(예제 참조).</p>
<a name='Sass%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Sass 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://sass-lang.com/">sass</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.sass</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>sass :stylesheet, :style => :expanded</tt></td>
</tr>
</table>
<a name='SCSS%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>SCSS 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://sass-lang.com/">sass</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.scss</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>scss :stylesheet, :style => :expanded</tt></td>
</tr>
</table>
<a name='Less%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Less 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://www.lesscss.org/">less</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.less</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>less :stylesheet</tt></td>
</tr>
</table>
<a name='Liquid%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Liquid 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://www.liquidmarkup.org/">liquid</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.liquid</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>liquid :index, :locals => { :key => 'value' }</tt></td>
</tr>
</table>
<p>Liquid 템플릿에서는 루비 메서드(<code>yield</code> 제외)를 호출할 수 없기 때문에, 거의 대부분의 경우 locals를 전달해야 함.</p>
<a name='Markdown%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Markdown 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td>
<a href="https://github.com/rtomayko/rdiscount">rdiscount</a>,
<a href="https://github.com/vmg/redcarpet">redcarpet</a>,
<a href="http://deveiate.org/projects/BlueCloth">bluecloth</a>,
<a href="http://kramdown.rubyforge.org/">kramdown</a> *또는*
<a href="http://maruku.rubyforge.org/">maruku</a>
</td>
</tr>
<tr>
<td>파일 확장</td>
<td>
<tt>.markdown</tt>, <tt>.mkd</tt>, <tt>.md</tt>
</td>
</tr>
<tr>
<td>예제</td>
<td><tt>markdown :index, :layout_engine => :erb</tt></td>
</tr>
</table>
<p>마크다운에서는 메서드 호출 뿐 아니라 locals 전달도 안됨.
따라서 일반적으로는 다른 렌더링 엔진과 함께 사용하게 될 것임:</p>
<pre class="highlight ruby"><span class="n">erb</span> <span class="ss">:overview</span><span class="p">,</span> <span class="ss">:locals</span> <span class="o">=></span> <span class="p">{</span> <span class="ss">:text</span> <span class="o">=></span> <span class="n">markdown</span><span class="p">(</span><span class="ss">:introduction</span><span class="p">)</span> <span class="p">}</span>
</pre>
<p>또한 다른 템플릿 속에서 <code>markdown</code> 메서드를 호출할 수도 있음:</p>
<pre class="highlight ruby"><span class="o">%</span><span class="n">h1</span> <span class="err">안녕</span> <span class="no">Haml</span><span class="o">!</span>
<span class="o">%</span><span class="nb">p</span><span class="o">=</span> <span class="n">markdown</span><span class="p">(</span><span class="ss">:greetings</span><span class="p">)</span>
</pre>
<p>Markdown에서 루비를 호출할 수 없기 때문에, Markdown으로 작성된 레이아웃은 사용할 수 없음.
단, <code>:layout_engine</code> 옵션으로 템플릿의 레이아웃은 다른 렌더링 엔진을 사용하는 것은 가능.</p>
<a name='Textile%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Textile 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://redcloth.org/">RedCloth</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.textile</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>textile :index, :layout_engine => :erb</tt></td>
</tr>
</table>
<p>Textile에서 메서드를 호출하거나 locals를 전달하는 것은 불가능함.
따라서 일반적으로 다른 렌더링 엔진과 함께 사용하게 될 것임:</p>
<pre class="highlight ruby"><span class="n">erb</span> <span class="ss">:overview</span><span class="p">,</span> <span class="ss">:locals</span> <span class="o">=></span> <span class="p">{</span> <span class="ss">:text</span> <span class="o">=></span> <span class="n">textile</span><span class="p">(</span><span class="ss">:introduction</span><span class="p">)</span> <span class="p">}</span>
</pre>
<p>또한 다른 템플릿 속에서 <code>textile</code> 메서드를 호출할 수도 있음:</p>
<pre class="highlight ruby"><span class="o">%</span><span class="n">h1</span> <span class="err">안녕</span> <span class="no">Haml</span><span class="o">!</span>
<span class="o">%</span><span class="nb">p</span><span class="o">=</span> <span class="n">textile</span><span class="p">(</span><span class="ss">:greetings</span><span class="p">)</span>
</pre>
<p>Textile에서 루비를 호출할 수 없기 때문에, Textile로 작성된 레이아웃은 사용할 수 없음.
단, <code>:layout_engine</code> 옵션으로 템플릿의 레이아웃은 다른 렌더링 엔진을 사용하는 것은 가능.</p>
<a name='RDoc%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>RDoc 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://rdoc.rubyforge.org/">rdoc</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.rdoc</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>rdoc :README, :layout_engine => :erb</tt></td>
</tr>
</table>
<p>rdoc에서 메서드를 호출하거나 locals를 전달하는 것은 불가능함.
따라서 일반적으로 다른 렌더링 엔진과 함께 사용하게 될 것임:</p>
<pre class="highlight ruby"><span class="n">erb</span> <span class="ss">:overview</span><span class="p">,</span> <span class="ss">:locals</span> <span class="o">=></span> <span class="p">{</span> <span class="ss">:text</span> <span class="o">=></span> <span class="n">rdoc</span><span class="p">(</span><span class="ss">:introduction</span><span class="p">)</span> <span class="p">}</span>
</pre>
<p>또한 다른 템플릿 속에서 <code>rdoc</code> 메서드를 호출할 수도 있음:</p>
<pre class="highlight ruby"><span class="o">%</span><span class="n">h1</span> <span class="no">Hello</span> <span class="no">From</span> <span class="no">Haml</span><span class="o">!</span>
<span class="o">%</span><span class="nb">p</span><span class="o">=</span> <span class="n">rdoc</span><span class="p">(</span><span class="ss">:greetings</span><span class="p">)</span>
</pre>
<p>RDoc에서 루비를 호출할 수 없기 때문에, RDoc로 작성된 레이아웃은 사용할 수 없음.
단, <code>:layout_engine</code> 옵션으로 템플릿의 레이아웃은 다른 렌더링 엔진을 사용하는 것은 가능.</p>
<a name='Radius%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Radius 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://radius.rubyforge.org/">radius</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.radius</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>radius :index, :locals => { :key => 'value' }</tt></td>
</tr>
</table>
<p>Radius 템플릿에서는 루비 메서드를 호출할 수 없기 때문에, 거의 대부분의 경우 locals로 전달하게 될 것임.</p>
<a name='Markaby%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Markaby 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://markaby.github.com/">markaby</a></td>
</tr>
<tr>
<td>파일확장</td>
<td><tt>.mab</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>markaby { h1 "Welcome!" }</tt></td>
</tr>
</table>
<p>인라인 템플릿으로 블록을 받을 수도 있음(예제 참조).</p>
<a name='RABL%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>RABL 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="https://github.com/nesquena/rabl">rabl</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.rabl</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>rabl :index</tt></td>
</tr>
</table>
<a name='Slim%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Slim 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="http://slim-lang.com/">slim</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.slim</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>slim :index</tt></td>
</tr>
</table>
<a name='Creole%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Creole 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="https://github.com/minad/creole">creole</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.creole</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>creole :wiki, :layout_engine => :erb</tt></td>
</tr>
</table>
<p>creole에서는 루비 메서드를 호출할 수 없고 locals도 전달할 수 없음.
따라서 일반적으로는 다른 렌더링 엔진과 함께 사용하게 될 것임.</p>
<pre class="highlight ruby"><span class="n">erb</span> <span class="ss">:overview</span><span class="p">,</span> <span class="ss">:locals</span> <span class="o">=></span> <span class="p">{</span> <span class="ss">:text</span> <span class="o">=></span> <span class="n">creole</span><span class="p">(</span><span class="ss">:introduction</span><span class="p">)</span> <span class="p">}</span>
</pre>
<p>또한 다른 템플릿 속에서 <code>creole</code> 메서드를 호출할 수도 있음:</p>
<pre class="highlight ruby"><span class="o">%</span><span class="n">h1</span> <span class="no">Hello</span> <span class="no">From</span> <span class="no">Haml</span><span class="o">!</span>
<span class="o">%</span><span class="nb">p</span><span class="o">=</span> <span class="n">creole</span><span class="p">(</span><span class="ss">:greetings</span><span class="p">)</span>
</pre>
<p>Creole에서 루비를 호출할 수 없기 때문에, Creole로 작성된 레이아웃은 사용할 수 없음.
단, <code>:layout_engine</code> 옵션으로 템플릿의 레이아웃은 다른 렌더링 엔진을 사용하는 것은 가능.</p>
<a name='CoffeeScript%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>CoffeeScript 템플릿</h3>
<table>
<tr>
<td>의존성</td>
<td>
<a href="https://github.com/josh/ruby-coffee-script">coffee-script</a>
와 <a href="https://github.com/sstephenson/execjs/blob/master/README.md#readme">자바스크립트 실행법</a>
</td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.coffee</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>coffee :index</tt></td>
</tr>
</table>
<a name='Yajl%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>Yajl 템플릿</h3>
<table>
<tr>
<td>의존</td>
<td><a href="https://github.com/brianmario/yajl-ruby">yajl-ruby</a></td>
</tr>
<tr>
<td>파일 확장자</td>
<td><tt>.yajl</tt></td>
</tr>
<tr>
<td>예제</td>
<td><tt>yajl :index, :locals => { :key => 'qux' }, :callback => 'present', :variable => 'resource' </tt></td>
</tr>
</table>
<p>The template source is evaluated as a Ruby string, and the resulting json variable is converted #to<em>json.
템플릿 소스는 루비 문자열로 평가(evaluate)되고, 결과인 json 변수는 #to</em>json으로 변환됨.</p>
<pre class="highlight ruby"><span class="n">json</span> <span class="o">=</span> <span class="p">{</span> <span class="ss">:foo</span> <span class="o">=></span> <span class="s1">'bar'</span> <span class="p">}</span>
<span class="n">json</span><span class="o">[</span><span class="ss">:baz</span><span class="o">]</span> <span class="o">=</span> <span class="n">key</span>
</pre>
<p><code>:callback</code>과 <code>:variable</code> 옵션은 렌더된 객체를 꾸미는데(decorate) 사용할 수 있음.</p>
<pre class="highlight ruby"><span class="n">var</span> <span class="n">resource</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"foo"</span><span class="ss">:"bar"</span><span class="p">,</span><span class="s2">"baz"</span><span class="ss">:"qux"</span><span class="p">};</span> <span class="n">present</span><span class="p">(</span><span class="n">resource</span><span class="p">);</span>
</pre>
<a name='%EB%82%B4%EC%9E%A5%EB%90%9C(Embedded)%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>내장된(Embedded) 템플릿</h3>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">haml</span> <span class="s1">'%div.title Hello World'</span>
<span class="k">end</span>
</pre>
<p>내장된 템플릿 문자열을 렌더함.</p>
<a name='%ED%85%9C%ED%94%8C%EB%A6%BF%EC%97%90%EC%84%9C%20%EB%B3%80%EC%88%98%EC%97%90%20%EC%A0%91%EA%B7%BC%ED%95%98%EA%B8%B0'></a>
<h3>템플릿에서 변수에 접근하기</h3>
<p>Templates are evaluated within the same context as route handlers. Instance
variables set in route handlers are directly accessible by templates:
템플릿은 라우터 핸들러와 같은 맥락(context)에서 평가된다.
라우터 핸들러에서 설정한 인스턴스 변수들은 템플릿에서 접근 가능하다: </p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/:id'</span> <span class="k">do</span>
<span class="vi">@foo</span> <span class="o">=</span> <span class="no">Foo</span><span class="nf">.find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span>
<span class="n">haml</span> <span class="s1">'%h1= @foo.name'</span>
<span class="k">end</span>
</pre>
<p>또는, 명시적으로 로컬 변수의 해시를 지정: </p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/:id'</span> <span class="k">do</span>
<span class="n">foo</span> <span class="o">=</span> <span class="no">Foo</span><span class="nf">.find</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:id</span><span class="o">]</span><span class="p">)</span>
<span class="n">haml</span> <span class="s1">'%h1= bar.name'</span><span class="p">,</span> <span class="ss">:locals</span> <span class="o">=></span> <span class="p">{</span> <span class="ss">:bar</span> <span class="o">=></span> <span class="n">foo</span> <span class="p">}</span>
<span class="k">end</span>
</pre>
<p>This is typically used when rendering templates as partials from within
other templates.
이 방법은 통상적으로 템플릿을 다른 템플릿 속에서 파셜(partial)로 렌더링할 때 사용된다.</p>
<a name='%EC%9D%B8%EB%9D%BC%EC%9D%B8%20%ED%85%9C%ED%94%8C%EB%A6%BF'></a>
<h3>인라인 템플릿</h3>
<p>템플릿은 소스 파일의 마지막에서 정의할 수도 있다:</p>
<pre class="highlight ruby"><span class="nb">require</span> <span class="s1">'sinatra'</span>
<span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">haml</span> <span class="ss">:index</span>
<span class="k">end</span>
<span class="cp">__END__
@@ layout
%html
= yield
@@ index
%div.title Hello world.
</span></pre>
<p>참고: require sinatra 시킨 소스 파일에 정의된 인라인 템플릿은 자동으로 로드된다.
다른 소스 파일에서 인라인 템플릿을 사용하려면 명시적으로 <code>enable :inline_templates</code>을 호출하면 됨.</p>
<a name='%EC%9D%B4%EB%A6%84%EC%9D%84%20%EA%B0%80%EC%A7%80%EB%8A%94%20%ED%85%9C%ED%94%8C%EB%A6%BF(Named%20Templates)'></a>
<h3>이름을 가지는 템플릿(Named Templates)</h3>
<p>템플릿은 톱 레벨(top-level)에서 <code>template</code>메서드를 사용하여 정의할 수 있다:</p>
<pre class="highlight ruby"><span class="n">template</span> <span class="ss">:layout</span> <span class="k">do</span>
<span class="s2">"%html</span><span class="se">\n</span><span class="s2"> =yield</span><span class="se">\n</span><span class="s2">"</span>
<span class="k">end</span>
<span class="n">template</span> <span class="ss">:index</span> <span class="k">do</span>
<span class="s1">'%div.title Hello World!'</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">haml</span> <span class="ss">:index</span>
<span class="k">end</span>
</pre>
<p>"layout"이라는 이름의 템플릿이 존재하면, 매번 템플릿이 렌더될 때마다 사용될 것이다.
이 때 <code>:layout => false</code>를 전달하여 개별적으로 레이아웃을 비활성시키거나
또는 <code>set :haml, :layout => false</code>으로 기본값을 비활성으로 둘 수 있다:</p>
<pre class="highlight ruby"><span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">haml</span> <span class="ss">:index</span><span class="p">,</span> <span class="ss">:layout</span> <span class="o">=></span> <span class="o">!</span><span class="n">request</span><span class="nf">.xhr?</span>
<span class="k">end</span>
</pre>
<a name='%ED%8C%8C%EC%9D%BC%20%ED%99%95%EC%9E%A5%EC%9E%90%20%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0'></a>
<h3>파일 확장자 연결하기</h3>
<p>어떤 파일 확장자를 특정 템플릿 엔진과 연결하려면, <code>Tilt.register</code>를 사용하면 된다.
예를 들어, <code>tt</code>라는 파일 확장자를 Textile 템플릿과 연결하고 싶다면, 다음과 같이 하면 된다:</p>
<pre class="highlight ruby"><span class="no">Tilt</span><span class="nf">.register</span> <span class="ss">:tt</span><span class="p">,</span> <span class="no">Tilt</span><span class="o">[</span><span class="ss">:textile</span><span class="o">]</span>
</pre>
<a name='%EB%82%98%EB%A7%8C%EC%9D%98%20%EA%B3%A0%EC%9C%A0%ED%95%9C%20%ED%85%9C%ED%94%8C%EB%A6%BF%20%EC%97%94%EC%A7%84%20%EC%B6%94%EA%B0%80%ED%95%98%EA%B8%B0'></a>
<h3>나만의 고유한 템플릿 엔진 추가하기</h3>
<p>우선, Tilt로 여러분 엔진을 등록하고, 그런 다음 렌더링 메서드를 생성하자:</p>
<pre class="highlight ruby"><span class="no">Tilt</span><span class="nf">.register</span> <span class="ss">:myat</span><span class="p">,</span> <span class="no">MyAwesomeTemplateEngine</span>
<span class="n">helpers</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">myat</span><span class="p">(</span><span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="n">render</span><span class="p">(</span><span class="ss">:myat</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">)</span> <span class="k">end</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="n">myat</span> <span class="ss">:index</span>
<span class="k">end</span>
</pre>
<p><code>./views/index.myat</code> 를 렌더함.
Tilt에 대한 더 자세한 내용은 https://github.com/rtomayko/tilt 참조.</p>
<a name='%ED%95%84%ED%84%B0(Filters)'></a>
<h2>필터(Filters)</h2>
<p>사전 필터(before filter)는 라우터와 동일한 맥락에서 매 요청 전에 평가되며 요청과 응답을 변형할 수 있다.
필터에서 설정된 인스턴스 변수들은 라우터와 템플릿 속에서 접근 가능하다:</p>
<pre class="highlight ruby"><span class="n">before</span> <span class="k">do</span>
<span class="vi">@note</span> <span class="o">=</span> <span class="s1">'Hi!'</span>
<span class="n">request</span><span class="nf">.path_info</span> <span class="o">=</span> <span class="s1">'/foo/bar/baz'</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/foo/*'</span> <span class="k">do</span>
<span class="vi">@note</span> <span class="c1">#=> 'Hi!'</span>
<span class="n">params</span><span class="o">[</span><span class="ss">:splat</span><span class="o">]</span> <span class="c1">#=> 'bar/baz'</span>
<span class="k">end</span>
</pre>
<p>사후 필터(after filter)는 라우터와 동일한 맥락에서 매 요청 이후에 평가되며 마찬가지로 요청과 응답을 변형할 수 있다.
사전 필터와 라우터에서 설정된 인스턴스 변수들은 사후 필터에서 접근 가능하다:</p>
<pre class="highlight ruby"><span class="n">after</span> <span class="k">do</span>
<span class="nb">puts</span> <span class="n">response</span><span class="nf">.status</span>
<span class="k">end</span>
</pre>
<p>참고: 만약 라우터에서 <code>body</code> 메서드를 사용하지 않고 그냥 문자열만 반환한 경우라면, body는 나중에 생성되는 탓에, 아직 사후 필터에서 사용할 수 없을 것이다.</p>
<p>필터는 선택적으로 패턴을 취할 수 있으며, 이 경우 요청 경로가 그 패턴과 매치할 경우에만 필터가 평가될 것이다.</p>
<pre class="highlight ruby"><span class="n">before</span> <span class="s1">'/protected/*'</span> <span class="k">do</span>
<span class="n">authenticate!</span>
<span class="k">end</span>
<span class="n">after</span> <span class="s1">'/create/:slug'</span> <span class="k">do</span> <span class="o">|</span><span class="n">slug</span><span class="o">|</span>
<span class="n">session</span><span class="o">[</span><span class="ss">:last_slug</span><span class="o">]</span> <span class="o">=</span> <span class="n">slug</span>
<span class="k">end</span>
</pre>
<p>라우터와 마찬가지로, 필터 역시 조건을 갖는다:</p>
<pre class="highlight ruby"><span class="n">before</span> <span class="ss">:agent</span> <span class="o">=></span> <span class="sr">/Songbird/</span> <span class="k">do</span>
<span class="c1"># ...</span>
<span class="k">end</span>
<span class="n">after</span> <span class="s1">'/blog/*'</span><span class="p">,</span> <span class="ss">:host_name</span> <span class="o">=></span> <span class="s1">'example.com'</span> <span class="k">do</span>
<span class="c1"># ...</span>
<span class="k">end</span>
</pre>
<a name='%ED%97%AC%ED%8D%BC(Helpers)'></a>
<h2>헬퍼(Helpers)</h2>
<p>톱-레벨의 <code>helpers</code> 메서드를 사용하여 라우터 핸들러와 템플릿에서 사용할 헬퍼 메서드들을 정의할 수 있다:</p>
<pre class="highlight ruby"><span class="n">helpers</span> <span class="k">do</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span>
<span class="s2">"</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">bar"</span>
<span class="k">end</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/:name'</span> <span class="k">do</span>
<span class="n">bar</span><span class="p">(</span><span class="n">params</span><span class="o">[</span><span class="ss">:name</span><span class="o">]</span><span class="p">)</span>
<span class="k">end</span>
</pre>
<p>또는, 헬퍼 메서드는 별도의 모듈 속에 정의할 수도 있다:</p>
<pre class="highlight ruby"><span class="k">module</span> <span class="nn">FooUtils</span>
<span class="k">def</span> <span class="nf">foo</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span> <span class="s2">"</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">foo"</span> <span class="k">end</span>
<span class="k">end</span>
<span class="k">module</span> <span class="nn">BarUtils</span>
<span class="k">def</span> <span class="nf">bar</span><span class="p">(</span><span class="nb">name</span><span class="p">)</span> <span class="s2">"</span><span class="si">#{</span><span class="nb">name</span><span class="si">}</span><span class="s2">bar"</span> <span class="k">end</span>
<span class="k">end</span>
<span class="n">helpers</span> <span class="no">FooUtils</span><span class="p">,</span> <span class="no">BarUtils</span>
</pre>
<p>이 경우 모듈을 애플리케이션 클래스에 포함(include)시킨 것과 동일한 효과를 갖는다.</p>
<a name='%EC%84%B8%EC%85%98(Sessions)%20%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0'></a>
<h3>세션(Sessions) 사용하기</h3>
<p>세션은 요청 동안에 상태를 유지하기 위해 사용한다.
세션이 활성화되면, 사용자 세션 당 session 해시 하나씩을 갖게 된다:</p>
<pre class="highlight ruby"><span class="n">enable</span> <span class="ss">:sessions</span>
<span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="s2">"value = "</span> <span class="o"><<</span> <span class="n">session</span><span class="o">[</span><span class="ss">:value</span><span class="o">]</span><span class="nf">.inspect</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/:value'</span> <span class="k">do</span>
<span class="n">session</span><span class="o">[</span><span class="ss">:value</span><span class="o">]</span> <span class="o">=</span> <span class="n">params</span><span class="o">[</span><span class="ss">:value</span><span class="o">]</span>
<span class="k">end</span>
</pre>
<p><code>enable :sessions</code>은 실은 모든 데이터를 쿠키 속에 저장함에 유의하자.
항상 이렇게 하고 싶지 않을 수도 있을 것이다(예를 들어, 많은 양의 데이터를 저장하게 되면 트래픽이 높아진다).
이 때는 여러 가지 랙 세션 미들웨어(Rack session middleware)를 사용할 수 있을 것이다:
이렇게 할 경우라면, <code>enable :sessions</code>을 호출하지 <em>말고</em>,
대신 여러분이 선택한 미들웨어를 다른 모든 미들웨어들처럼 포함시키면 된다:</p>
<pre class="highlight ruby"><span class="n">use</span> <span class="no">Rack</span><span class="o">::</span><span class="no">Session</span><span class="o">::</span><span class="no">Pool</span><span class="p">,</span> <span class="ss">:expire_after</span> <span class="o">=></span> <span class="mi">2592000</span>
<span class="n">get</span> <span class="s1">'/'</span> <span class="k">do</span>
<span class="s2">"value = "</span> <span class="o"><<</span> <span class="n">session</span><span class="o">[</span><span class="ss">:value</span><span class="o">]</span><span class="nf">.inspect</span>
<span class="k">end</span>
<span class="n">get</span> <span class="s1">'/:value'</span> <span class="k">do</span>
<span class="n">session</span><span class="o">[</span><span class="ss">:value</span><span class="o">]</span> <span class="o">=</span> <span class="n">params</span><span class="o">[</span><span class="ss">:value</span><span class="o">]</span>
<span class="k">end</span>
</pre>
<p>보안을 위해서, 쿠키 속의 세션 데이터는 세션 시크릿(secret)으로 사인(sign)된다.
Sinatra는 여러분을 위해 무작위 시크릿을 생성한다.
그렇지만, 이 시크릿은 여러분 애플리케이션 시작 시마다 변경될 수 있기 때문에,
여러분은 여러분 애플리케이션의 모든 인스턴스들이 공유할 시크릿을 직접 만들고 싶을 수도 있다:</p>
<pre class="highlight ruby"><span class="n">set</span> <span class="ss">:session_secret</span><span class="p">,</span> <span class="s1">'super secret'</span>
</pre>
<p>조금 더 세부적인 설정이 필요하다면, <code>sessions</code> 설정에서 옵션이 있는 해시를 저장할 수도 있을 것이다:</p>
<pre class="highlight ruby"><span class="n">set</span> <span class="ss">:sessions</span><span class="p">,</span> <span class="ss">:domain</span> <span class="o">=></span> <span class="s1">'foo.com'</span>
</pre>
<a name='%EC%A4%91%EB%8B%A8%ED%95%98%EA%B8%B0(Halting)'></a>
<h3>중단하기(Halting)</h3>
<p>필터나 라우터에서 요청을 즉각 중단하고 싶을 때 사용하라:</p>
<pre class="highlight ruby"><span class="n">halt</span>
</pre>
<p>중단할 때 상태를 지정할 수도 있다:</p>
<pre class="highlight ruby"><span class="n">halt</span> <span class="mi">410</span>
</pre>
<p>또는 본문을 넣을 수도 있다:</p>
<pre class="highlight ruby"><span class="n">halt</span> <span class="s1">'this will be the body'</span>