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 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284 1285 1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378 1379 1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785
|
= Sinatra
<i>ΠΠ½ΠΈΠΌΠ°Π½ΠΈΠ΅: ΠΡΠΎΡ Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠ΅ΡΠ΅Π²ΠΎΠ΄ΠΎΠΌ Π°Π½Π³Π»ΠΈΠΉΡΠΊΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ ΠΈ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΡΡΠ°ΡΠ΅Π²ΡΠΈΠΌ</i>
Sinatra β ΡΡΠΎ ΠΏΡΠ΅Π΄ΠΌΠ΅ΡΠ½ΠΎ-ΠΎΡΠΈΠ΅Π½ΡΠΈΡΠΎΠ²Π°Π½Π½ΡΠΉ ΠΊΠ°ΡΠΊΠ°Ρ (DSL) Π΄Π»Ρ Π±ΡΡΡΡΠΎΠ³ΠΎ ΡΠΎΠ·Π΄Π°Π½ΠΈΡ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΡ
Π²Π΅Π±-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Ruby:
# myapp.rb
require 'sinatra'
get '/' do
'Hello world!'
end
Π£ΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ gem:
gem install sinatra
ΠΈ Π·Π°ΠΏΡΡΡΠΈΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ:
ruby -rubygems myapp.rb
Π Π΅Π·ΡΠ»ΡΡΠ°Ρ ΠΌΠΎΠΆΠ½ΠΎ ΡΠ²ΠΈΠ΄Π΅ΡΡ: http://localhost:4567
Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ thin, ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠΌΠ°Π½Π΄ΠΎΠΉ: <tt>gem install thin</tt>.
Thin - ΡΡΠΎ Π±ΠΎΠ»Π΅Π΅ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΡΠΉ ΠΈ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ Π΄Π»Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π½Π° Sinatra.
== ΠΠ°ΡΡΡΡΡΡ
Π Sinatra ΠΌΠ°ΡΡΡΡΡ β ΡΡΠΎ ΠΏΠ°ΡΠ°: <HTTP ΠΌΠ΅ΡΠΎΠ΄> ΠΈ <ΡΠ°Π±Π»ΠΎΠ½ URL>.
ΠΠ°ΠΆΠ΄ΡΠΉ ΠΌΠ°ΡΡΡΡΡ Π°ΡΡΠΎΡΠΈΠΈΡΠΎΠ²Π°Π½ Ρ Π±Π»ΠΎΠΊΠΎΠΌ ΠΊΠΎΠ΄Π°, ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΠΌΠΎΠ³ΠΎ Π²Π½ΡΡΡΠΈ, ΠΏΡΠΈΠΌΠ΅Ρ:
get '/' do
.. ΡΡΠΎ-ΡΠΎ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ ..
end
post '/' do
.. ΡΡΠΎ-ΡΠΎ ΡΠΎΠ·Π΄Π°ΡΡ ..
end
put '/' do
.. ΡΡΠΎ-ΡΠΎ Π·Π°ΠΌΠ΅Π½ΠΈΡΡ ..
end
patch '/' do
.. ΡΡΠΎ-ΡΠΎ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΡ ..
end
delete '/' do
.. ΡΡΠΎ-ΡΠΎ ΡΠ΄Π°Π»ΠΈΡΡ ..
end
options '/' do
.. ΡΡΠΎ-ΡΠΎ ΠΎΡΠ²Π΅ΡΠΈΡΡ ..
end
ΠΠ°ΡΡΡΡΡΡ ΡΠ²Π΅ΡΡΡΡΡΡ Ρ Π·Π°ΠΏΡΠΎΡΠΎΠΌ Π² ΠΏΠΎΡΡΠ΄ΠΊΠ΅ ΠΎΡΠ΅ΡΠ΅Π΄Π½ΠΎΡΡΠΈ ΠΈΡ
Π·Π°ΠΏΠΈΡΠΈ Π² ΡΠ°ΠΉΠ»Π΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ
Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½ ΠΏΠ΅ΡΠ²ΡΠΉ ΡΠΎΠ²ΠΏΠ°Π²ΡΠΈΠΉ Ρ Π·Π°ΠΏΡΠΎΡΠΎΠΌ ΠΌΠ°ΡΡΡΡΡ.
Π¨Π°Π±Π»ΠΎΠ½Ρ ΠΌΠ°ΡΡΡΡΡΠΎΠ² ΠΌΠΎΠ³ΡΡ Π²ΠΊΠ»ΡΡΠ°ΡΡ Π² ΡΠ΅Π±Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ Π²
<tt>params</tt> xΡΡΠ΅:
get '/hello/:name' do
# ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ "GET /hello/foo" ΠΈ "GET /hello/bar",
# Π³Π΄Π΅ params[:name] 'foo' ΠΈΠ»ΠΈ 'bar'
"Hello #{params[:name]}!"
end
ΠΠΎΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΠΌΠ΅Π½Π½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π² ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ
Π±Π»ΠΎΠΊΠΎΠ²:
get '/hello/:name' do |n|
"Hello #{n}!"
end
Π¨Π°Π±Π»ΠΎΠ½Ρ ΠΌΠ°ΡΡΡΡΡΠΎΠ² ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡΡ Π²ΠΊΠ»ΡΡΠ°ΡΡ splat (ΠΈΠ»ΠΈ '*' ΠΌΠ°ΡΠΊΡ, ΠΎΠ±ΠΎΠ·Π½Π°ΡΠ°ΡΡΡΡ Π»ΡΠ±ΠΎΠΉ ΡΠΈΠΌΠ²ΠΎΠ») ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅
Π² ΠΌΠ°ΡΡΠΈΠ²Π΅ <tt>params[:splat]</tt>:
get '/say/*/to/*' do
# ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ /say/hello/to/world
params[:splat] # => ["hello", "world"]
end
get '/download/*.*' do
# ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ /download/path/to/file.xml
params[:splat] # => ["path/to/file", "xml"]
end
ΠΠ»ΠΈ Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠ°ΠΌΠΈ Π±Π»ΠΎΠΊΠ°:
get '/download/*.*' do |path, ext|
[path, ext] # => ["path/to/file", "xml"]
end
ΠΠ°ΡΡΡΡΡΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡΡ ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΡ ΡΠ΅Π³ΡΠ»ΡΡΠ½ΡΠ΅ Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΡ:
get %r{/hello/([\w]+)} do
"Hello, #{params[:captures].first}!"
end
ΠΠ»ΠΈ Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΎΠΌ Π±Π»ΠΎΠΊΠ°:
get %r{/hello/([\w]+)} do |c|
"Hello, #{c}!"
end
=== Π£ΡΠ»ΠΎΠ²ΠΈΡ
ΠΠ°ΡΡΡΡΡΡ ΠΌΠΎΠ³ΡΡ Π²ΠΊΠ»ΡΡΠ°ΡΡ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠ΅ ΡΡΠ»ΠΎΠ²ΠΈΡ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠΉ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ user agent:
get '/foo', :agent => /Songbird (\d\.\d)[\d\/]*?/ do
"You're using Songbird version #{params[:agent][0]}"
end
get '/foo' do
# ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ non-songbird Π±ΡΠ°ΡΠ·Π΅ΡΠ°ΠΌ
end
ΠΡΡΠ³ΠΈΠΌΠΈ Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌΠΈ ΡΡΠ»ΠΎΠ²ΠΈΡΠΌΠΈ ΡΠ²Π»ΡΡΡΡΡ +host_name+ ΠΈ +provides+:
get '/', :host_name => /^admin\./ do
"Admin Area, Access denied!"
end
get '/', :provides => 'html' do
haml :index
end
get '/', :provides => ['rss', 'atom', 'xml'] do
builder :feed
end
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°Π΄Π°ΡΡ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΡΡΠ»ΠΎΠ²ΠΈΡ:
set(:probability) { |value| condition { rand <= value } }
get '/win_a_car', :probability => 0.1 do
"You won!"
end
get '/win_a_car' do
"Sorry, you lost."
end
=== ΠΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ
ΠΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π±Π»ΠΎΠΊΠ° ΠΌΠ°ΡΡΡΡΡΠ° ΠΎΠ³ΡΠ°Π½ΠΈΡΠΈΠ²Π°Π΅ΡΡΡ ΡΠ΅Π»ΠΎΠΌ ΠΎΡΠ²Π΅ΡΠ°, ΠΊΠΎΡΠΎΡΠΎΠ΅ Π±ΡΠ΄Π΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°Π½ΠΎ HTTP ΠΊΠ»ΠΈΠ΅Π½ΡΡ,
ΠΈΠ»ΠΈ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΉ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΎΠΉ" (middleware) Π² Rack ΡΡΠ΅ΠΊΠ΅. Π§Π°ΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΡΡΠΎ ΡΡΡΠΎΠΊΠ°, ΠΊΠ°ΠΊ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ
Π²ΡΡΠ΅.
ΠΠΎ ΠΈ Π΄ΡΡΠ³ΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΡΠ°ΠΊΠΆΠ΅ ΠΏΡΠΈΠ΅ΠΌΠ»Π΅ΠΌΡ.
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²Π΅ΡΠ½ΡΡΡ Π»ΡΠ±ΠΎΠΉ ΠΎΠ±ΡΠ΅ΠΊΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ Π»ΠΈΠ±ΠΎ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΠΌ Rack ΠΎΡΠ²Π΅ΡΠΎΠΌ, ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ Rack body,
Π»ΠΈΠ±ΠΎ ΠΊΠΎΠ΄ΠΎΠΌ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ HTTP:
* ΠΌΠ°ΡΡΠΈΠ² Ρ ΡΡΠ΅ΠΌΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ: <tt>[status (Fixnum), headers (Hash), response body (Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΠ²Π΅ΡΠ°ΡΡ Π½Π° #each)]</tt>;
* ΠΌΠ°ΡΡΠΈΠ² Ρ Π΄Π²ΡΠΌΡ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌΠΈ: <tt>[status (Fixnum), response body (Π΄ΠΎΠ»ΠΆΠ΅Π½ ΠΎΡΠ²Π΅ΡΠ°ΡΡ Π½Π° #each)]</tt>;
* ΠΎΠ±ΡΠ΅ΠΊΡ, ΠΎΡΠ²Π΅ΡΠ°ΡΡΠΈΠΉ Π½Π° <tt>#each</tt>, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠ΅ΡΠ΅Π΄Π°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ ΡΡΡΠΎΠΊΠΎΠ²ΡΠ΅ ΡΠΈΠΏΡ Π΄Π°Π½Π½ΡΡ
Π² ΡΡΠΎΡ Π±Π»ΠΎΠΊ;
* Fixnum, ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»ΡΡΡΠΈΠΉ ΠΊΠΎΠ΄ ΡΠΎΡΡΠΎΡΠ½ΠΈΡ HTTP.
Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, ΠΌΡ Π»Π΅Π³ΠΊΠΎ ΠΌΠΎΠΆΠ΅ΠΌ ΡΠΎΠ·Π΄Π°ΡΡ ΠΏΠΎΡΠΎΡΠ½ΡΠΉ ΠΏΡΠΈΠΌΠ΅Ρ:
class Stream
def each
100.times { |i| yield "#{i}\n" }
end
end
get('/') { Stream.new }
=== Π‘ΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ Π΄Π΅ΡΠ΅ΠΊΡΠΎΡΡ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠΉ Π΄Π»Ρ ΠΌΠ°ΡΡΡΡΡΠΎΠ²
ΠΠ°ΠΊ ΠΏΠΎΠΊΠ°Π·Π°Π½ΠΎ Π²ΡΡΠ΅, Sinatra ΠΏΠΎΡΡΠ°Π²Π»ΡΠ΅ΡΡΡ ΡΠΎ Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΎΠΉ ΡΡΡΠΎΠΊ ΠΈ
ΡΠ΅Π³ΡΠ»ΡΡΠ½ΡΡ
Π²ΡΡΠ°ΠΆΠ΅Π½ΠΈΠΉ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² URL. ΠΠΎ ΠΈ ΡΡΠΎ Π΅ΡΠ΅ Π½Π΅ Π²ΡΠ΅. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅
Π»Π΅Π³ΠΊΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΡΠ²ΠΎΠΈ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠ΅ Π΄Π΅ΡΠ΅ΠΊΡΠΎΡΡ ΡΠΎΠ²ΠΏΠ°Π΄Π΅Π½ΠΈΠΉ (matchers) Π΄Π»Ρ ΠΌΠ°ΡΡΡΡΡΠΎΠ²:
class AllButPattern
Match = Struct.new(:captures)
def initialize(except)
@except = except
@captures = Match.new([])
end
def match(str)
@captures unless @except === str
end
end
def all_but(pattern)
AllButPattern.new(pattern)
end
get all_but("/index") do
# ...
end
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠΈΠΉ ΠΏΡΠΈΠΌΠ΅Ρ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΡΠ΅ΡΠ΅ΡΡΡΡ ΡΠ»ΠΎΠΆΠ΅Π½, ΠΎΠ½ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ ΠΊΠ°ΠΊ:
get // do
pass if request.path_info == "/index"
# ...
end
ΠΠ»ΠΈ Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π½Π΅Π³Π°ΡΠΈΠ²Π½ΠΎΠ³ΠΎ ΠΏΡΠΎΡΠΌΠΎΡΡΠ° Π²ΠΏΠ΅ΡΠ΅Π΄:
get %r{^(?!/index$)} do
# ...
end
== Π‘ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ
Π‘ΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ ΠΎΡΠ΄Π°ΡΡΡΡ ΠΈΠ· <tt>./public</tt> Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΡ Π΄ΡΡΠ³ΠΎΠ΅ ΠΌΠ΅ΡΡΠΎ,
ΡΠΊΠ°Π·Π°Π² Π΅Π³ΠΎ ΡΠ΅ΡΠ΅Π· ΠΎΠΏΡΠΈΡ <tt>:public_folder</tt>:
set :public_folder, File.dirname(__FILE__) + '/static'
Π£ΡΡΠΈΡΠ΅, ΡΡΠΎ ΠΈΠΌΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ ΡΠΎ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ Π½Π΅ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ Π² URL. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°ΠΉΠ»
<tt>./public/css/style.css</tt> Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΠΊΠ°ΠΊ
<tt>http://example.com/css/style.css</tt>.
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΎΠΏΡΠΈΡ <tt>:static_cache_control</tt> (ΡΠΌ. Π½ΠΈΠΆΠ΅), ΡΡΠΎΠ±Ρ
Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ <tt>Cache-Control</tt>.
== ΠΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ΠΈΡ / Π¨Π°Π±Π»ΠΎΠ½Ρ
ΠΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ ΠΏΡΠ΅Π΄ΡΡΠ°Π²Π»Π΅Π½ ΡΠ²ΠΎΠΈΠΌ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΌ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠΌ. ΠΡΠΈ ΠΌΠ΅ΡΠΎΠ΄Ρ
ΠΏΠΎΠΏΡΠΎΡΡΡ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ ΡΡΡΠΎΠΊΡ:
get '/' do
erb :index
end
ΠΡΠΎΠ±ΡΠ°Π·ΠΈΡ <tt>views/index.erb</tt>.
ΠΠΌΠ΅ΡΡΠΎ ΠΈΠΌΠ΅Π½ΠΈ ΡΠ°Π±Π»ΠΎΠ½Π° Π²Ρ ΡΠ°ΠΊ ΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ ΡΠ°ΠΌΠΎ
ΡΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΡΠ°Π±Π»ΠΎΠ½Π°
get '/' do
code = "<%= Time.now %>"
erb code
end
ΠΡΠΈ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ Π²ΡΠΎΡΠΎΠΉ Π°ΡΠ³ΡΠΌΠ΅Π½Ρ, Ρ
Π΅Ρ Ρ ΠΎΠΏΡΠΈΡΠΌΠΈ:
get '/' do
erb :index, :layout => :post
end
ΠΡΠΎΠ±ΡΠ°Π·ΠΈΡ <tt>views/index.erb</tt>, Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠΌ Π²
<tt>views/post.erb</tt> (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: <tt>views/layout.erb</tt>, Π΅ΡΠ»ΠΈ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ).
ΠΡΠ±ΡΠ΅ ΠΎΠΏΡΠΈΠΈ, Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅ΠΌΡΠ΅ Sinatra, Π±ΡΠ΄ΡΡ ΠΏΠ΅ΡΠ΅Π΄Π°Π½Ρ Π² ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ
get '/' do
haml :index, :format => :html5
end
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°Π΄Π°Π²Π°ΡΡ ΠΎΠΏΡΠΈΠΈ Π΄Π»Ρ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠΎΠ² Π² ΠΎΠ±ΡΠ΅ΠΌ:
set :haml, :format => :html5
get '/' do
haml :index
end
ΠΠΏΡΠΈΠΈ, ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠ΅ Π² ΠΌΠ΅ΡΠΎΠ΄, ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΡΡ ΠΎΠΏΡΠΈΠΈ, Π·Π°Π΄Π°Π½Π½ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ
+set+.
ΠΠΎΡΡΡΠΏΠ½ΡΠ΅ ΠΎΠΏΡΠΈΠΈ:
[locals]
Π‘ΠΏΠΈΡΠΎΠΊ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΡ
ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ
, ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°Π΅ΠΌΡΡ
Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½Ρ.
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ: <tt>erb "<%= foo %>", :locals => {:foo => "bar"}</tt>
[default_encoding]
ΠΠΎΠ΄ΠΈΡΠΎΠ²ΠΊΠ°, ΠΊΠΎΡΠΎΡΡΡ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ, Π΅ΡΠ»ΠΈ Π½Π΅ ΡΠ΄Π°Π»ΠΎΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ
ΠΎΡΠΈΠ³ΠΈΠ½Π°Π»ΡΠ½ΡΡ. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: <tt>settings.default_encoding</tt>.
[views]
ΠΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ Ρ ΡΠ°Π±Π»ΠΎΠ½Π°ΠΌΠΈ. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: <tt>settings.views</tt>.
[layout]
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΈΠ»ΠΈ Π½Π΅Ρ Π»ΡΠΉΠ°ΡΡ (+true+ ΠΈΠ»ΠΈ +false+). ΠΡΠ»ΠΈ ΠΆΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Symbol,
ΡΠΎ ΡΠΊΠ°Π·ΡΠ²Π°Π΅Ρ, ΠΊΠ°ΠΊΠΎΠΉ ΡΠ°Π±Π»ΠΎΠ½ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ Π»ΡΠΉΠ°ΡΡΠ°. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ:
<tt>erb :index, :layout => !request.xhr?</tt>
[content_type]
Content-Type ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ°Π±Π»ΠΎΠ½Π°. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: Π·Π°Π΄Π°Π΅ΡΡΡ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠΎΠΌ.
[scope]
ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ ΡΠ΅Π½Π΄Π΅ΡΡΡΡΡ ΡΠ°Π±Π»ΠΎΠ½Ρ. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. ΠΡΠ»ΠΈ Π²Ρ ΠΈΠ·ΠΌΠ΅Π½ΠΈΡΠ΅ ΡΡΡ ΠΎΠΏΡΠΈΡ, ΡΠΎ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ° ΠΈ
ΠΌΠ΅ΡΠΎΠ΄Ρ-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠΈ ΡΡΠ°Π½ΡΡ Π½Π΅Π΄ΠΎΡΡΡΠΏΠ½ΡΠΌΠΈ Π² Π²Π°ΡΠΈΡ
ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
.
[layout_engine]
Π¨Π°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ Π»ΡΠΉΠ°ΡΡΠ°. ΠΠΎΠ»Π΅Π·Π½Π°Ρ
ΠΎΠΏΡΠΈΡ Π΄Π»Ρ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠΎΠ², Π² ΠΊΠΎΡΠΎΡΡΡ
Π½Π΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠΈ Π»ΡΠΉΠ°ΡΡΠΎΠ². ΠΠΎ
ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: ΡΠΎΡ ΠΆΠ΅ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ, ΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΈ Π΄Π»Ρ ΡΠ°ΠΌΠΎΠ³ΠΎ ΡΠ°Π±Π»ΠΎΠ½Π°.
ΠΡΠΈΠΌΠ΅Ρ: <tt>set :rdoc, :layout_engine => :erb</tt>
ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΡΡΠΈΡΠ°Π΅ΡΡΡ, ΡΡΠΎ ΡΠ°Π±Π»ΠΎΠ½Ρ Π½Π°Ρ
ΠΎΠ΄ΡΡΡΡ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ <tt>./views</tt>.
Π§ΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΄ΡΡΠ³ΡΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ Ρ ΡΠ°Π±Π»ΠΎΠ½Π°ΠΌΠΈ:
set :views, settings.root + '/templates'
ΠΠ°ΠΆΠ½ΠΎΠ΅ Π·Π°ΠΌΠ΅ΡΠ°Π½ΠΈΠ΅: Π²Ρ Π²ΡΠ΅Π³Π΄Π° Π΄ΠΎΠ»ΠΆΠ½Ρ ΡΡΡΠ»Π°ΡΡΡΡ Π½Π° ΡΠ°Π±Π»ΠΎΠ½Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΡΠΈΠΌΠ²ΠΎΠ»ΠΎΠ²
(Symbol), Π΄Π°ΠΆΠ΅ ΠΊΠΎΠ³Π΄Π° ΠΎΠ½ΠΈ Π² ΠΏΠΎΠ΄Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ (Π² ΡΡΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅
<tt>:'subdir/template'</tt>). ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠΈΠΌΠ²ΠΎΠ»Ρ, ΠΏΠΎΡΠΎΠΌΡ ΡΡΠΎ
ΠΈΠ½Π°ΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΡ ΠΏΠΎΠΏΡΠΎΡΡΡ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡ Π»ΡΠ±ΡΠ΅ ΡΡΡΠΎΠΊΠΈ, ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠ΅ ΠΈΠΌ.
=== ΠΠΎΡΡΡΠΏΠ½ΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΡ
ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ·ΡΠΊΠΈ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² ΠΈΠΌΠ΅ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΉ. Π§ΡΠΎΠ±Ρ ΡΠΊΠ°Π·Π°ΡΡ, ΠΊΠ°ΠΊΡΡ
ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ, Π²Π°ΠΌ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΡΠΎΡΡΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΡ Π½ΡΠΆΠ½ΡΡ
Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΡ:
require 'rdiscount' # ΠΈΠ»ΠΈ require 'bluecloth'
get('/') { markdown :index }
=== Haml ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {haml}[http://haml-lang.com/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.haml</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>haml :index, :format => :html5</tt>
=== Erb ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {erubis}[http://www.kuwata-lab.com/erubis/] ΠΈΠ»ΠΈ erb (Π²ΠΊΠ»ΡΡΠ΅Π½ Π² Ruby)
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.erb</tt>, <tt>.rhtml</tt> or <tt>.erubis</tt> (ΡΠΎΠ»ΡΠΊΠΎ Erubis)
ΠΡΠΈΠΌΠ΅Ρ:: <tt>erb :index</tt>
=== Builder ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {builder}[http://builder.rubyforge.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.builder</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>builder { |xml| xml.em "hi" }</tt>
ΠΠ»ΠΎΠΊ ΡΠ°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΈ Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² (ΡΠΌ. ΠΏΡΠΈΠΌΠ΅Ρ).
=== Nokogiri ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {nokogiri}[http://nokogiri.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.nokogiri</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>nokogiri { |xml| xml.em "hi" }</tt>
ΠΠ»ΠΎΠΊ ΡΠ°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΈ Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² (ΡΠΌ. ΠΏΡΠΈΠΌΠ΅Ρ).
=== Sass ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {sass}[http://sass-lang.com/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.sass</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>sass :stylesheet, :style => :expanded</tt>
=== SCSS ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {sass}[http://sass-lang.com/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.scss</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>scss :stylesheet, :style => :expanded</tt>
=== Less ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {less}[http://www.lesscss.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.less</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>less :stylesheet</tt>
=== Liquid ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {liquid}[http://www.liquidmarkup.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.liquid</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>liquid :index, :locals => { :key => 'value' }</tt>
Π’Π°ΠΊ ΠΊΠ°ΠΊ Π² Liquid ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΈΠ· Ruby (ΠΊΡΠΎΠΌΠ΅ yield), ΡΠΎ
Π²Ρ ΠΏΠΎΡΡΠΈ Π²ΡΠ΅Π³Π΄Π° Π±ΡΠ΄Π΅ΡΠ΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π² ΡΠ°Π±Π»ΠΎΠ½ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅.
=== Markdown ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {rdiscount}[https://github.com/rtomayko/rdiscount], {redcarpet}[https://github.com/tanoku/redcarpet], {bluecloth}[http://deveiate.org/projects/BlueCloth], {kramdown}[http://kramdown.rubyforge.org/] ΠΈΠ»ΠΈ {maruku}[http://maruku.rubyforge.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.markdown</tt>, <tt>.mkd</tt> and <tt>.md</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>markdown :index, :layout_engine => :erb</tt>
Π Markdown Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅.
Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, Π²Π°ΠΌ, ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΡΠ°Π±Π»ΠΎΠ½ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ
Ρ Π΄ΡΡΠ³ΠΈΠΌ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠΎΠΌ:
erb :overview, :locals => { :text => markdown(:introduction) }
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ +markdown+ ΠΈΠ· Π΄ΡΡΠ³ΠΈΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ²:
%h1 Hello From Haml!
%p= markdown(:greetings)
ΠΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ Ruby ΠΈΠ· Markdown, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, Π²Ρ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΡΠΉΠ°ΡΡΡ Π½Π° Markdown. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
ΠΎΠ΄ΠΈΠ½ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠ°Π±Π»ΠΎΠ½Π°, Π° Π΄ΡΡΠ³ΠΎΠΉ Π΄Π»Ρ Π»ΡΠΉΠ°ΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ
ΠΎΠΏΡΠΈΠΈ <tt>:layout_engine</tt>.
=== Textile ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {RedCloth}[http://redcloth.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.textile</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>textile :index, :layout_engine => :erb</tt>
Π Textile Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅.
Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, Π²Π°ΠΌ, ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΡΠ°Π±Π»ΠΎΠ½ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ Ρ
Π΄ΡΡΠ³ΠΈΠΌ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠΎΠΌ:
erb :overview, :locals => { :text => textile(:introduction) }
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ +textile+ ΠΈΠ· Π΄ΡΡΠ³ΠΈΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ²:
%h1 Hello From Haml!
%p= textile(:greetings)
ΠΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ Ruby ΠΈΠ· Textile, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, Π²Ρ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΡΠΉΠ°ΡΡΡ Π½Π° Textile. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
ΠΎΠ΄ΠΈΠ½ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠ°Π±Π»ΠΎΠ½Π°, Π° Π΄ΡΡΠ³ΠΎΠΉ Π΄Π»Ρ Π»ΡΠΉΠ°ΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ
ΠΎΠΏΡΠΈΠΈ <tt>:layout_engine</tt>.
=== RDoc ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {rdoc}[http://rdoc.rubyforge.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.rdoc</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>textile :README, :layout_engine => :erb</tt>
Π RDoc Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅.
Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, Π²Π°ΠΌ, ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΡΠ°Π±Π»ΠΎΠ½ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ Ρ
Π΄ΡΡΠ³ΠΈΠΌ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠΎΠΌ:
erb :overview, :locals => { :text => rdoc(:introduction) }
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ +rdoc+ ΠΈΠ· Π΄ΡΡΠ³ΠΈΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ²:
%h1 Hello From Haml!
%p= rdoc(:greetings)
ΠΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ Ruby ΠΈΠ· RDoc, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, Π²Ρ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΡΠΉΠ°ΡΡΡ Π½Π° RDoc. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
ΠΎΠ΄ΠΈΠ½ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠ°Π±Π»ΠΎΠ½Π°, Π° Π΄ΡΡΠ³ΠΎΠΉ Π΄Π»Ρ Π»ΡΠΉΠ°ΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ
ΠΎΠΏΡΠΈΠΈ <tt>:layout_engine</tt>.
=== Radius ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {radius}[http://radius.rubyforge.org/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.radius</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>radius :index, :locals => { :key => 'value' }</tt>
Π’Π°ΠΊ ΠΊΠ°ΠΊ Π² Radius ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΈΠ· Ruby Π½Π°ΠΏΡΡΠΌΡΡ, ΡΠΎ
Π²Ρ ΠΏΠΎΡΡΠΈ Π²ΡΠ΅Π³Π΄Π° Π±ΡΠ΄Π΅ΡΠ΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π² ΡΠ°Π±Π»ΠΎΠ½ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅.
=== Markaby ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {markaby}[http://markaby.github.com/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.mab</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>markaby { h1 "Welcome!" }</tt>
ΠΠ»ΠΎΠΊ ΡΠ°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΈ Π΄Π»Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² (ΡΠΌ. ΠΏΡΠΈΠΌΠ΅Ρ).
=== Slim ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {slim}[http://slim-lang.com/]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.slim</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>slim :index</tt>
=== Creole ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {creole}[https://github.com/minad/creole]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.creole</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>creole :wiki, :layout_engine => :erb</tt>
Π Creole Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅Π΄Π°Π²Π°ΡΡ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅.
Π‘Π»Π΅Π΄ΠΎΠ²Π°ΡΠ΅Π»ΡΠ½ΠΎ, Π²Π°ΠΌ, ΡΠΊΠΎΡΠ΅Π΅ Π²ΡΠ΅Π³ΠΎ, ΠΏΡΠΈΠ΄Π΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎΡ ΡΠ°Π±Π»ΠΎΠ½ ΡΠΎΠ²ΠΌΠ΅ΡΡΠ½ΠΎ Ρ
Π΄ΡΡΠ³ΠΈΠΌ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡΠΎΠΌ:
erb :overview, :locals => { :text => creole(:introduction) }
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ +creole+ ΠΈΠ· Π΄ΡΡΠ³ΠΈΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ²:
%h1 Hello From Haml!
%p= creole(:greetings)
ΠΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π²ΡΠ·ΡΠ²Π°ΡΡ Ruby ΠΈΠ· Creole, ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²Π΅Π½Π½ΠΎ, Π²Ρ Π½Π΅ ΠΌΠΎΠΆΠ΅ΡΠ΅
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΡΠΉΠ°ΡΡΡ Π½Π° Creole. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
ΠΎΠ΄ΠΈΠ½ ΡΠ°Π±Π»ΠΎΠ½ΠΈΠ·Π°ΡΠΎΡ Π΄Π»Ρ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡ ΡΠ°Π±Π»ΠΎΠ½Π°, Π° Π΄ΡΡΠ³ΠΎΠΉ Π΄Π»Ρ Π»ΡΠΉΠ°ΡΡΠ° Ρ ΠΏΠΎΠΌΠΎΡΡΡ
ΠΎΠΏΡΠΈΠΈ <tt>:layout_engine</tt>.
=== CoffeeScript ΡΠ°Π±Π»ΠΎΠ½Ρ
ΠΠ°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ:: {coffee-script}[https://github.com/josh/ruby-coffee-script] ΠΈ {ΡΠΏΠΎΡΠΎΠ± Π·Π°ΠΏΡΡΠΊΠ°ΡΡ javascript}[https://github.com/sstephenson/execjs/blob/master/README.md#readme]
Π Π°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»ΠΎΠ²:: <tt>.coffee</tt>
ΠΡΠΈΠΌΠ΅Ρ:: <tt>coffee :index</tt>
=== ΠΡΡΡΠΎΠ΅Π½Π½ΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½Ρ
get '/' do
haml '%div.title Hello World'
end
ΠΡΠΎΠ±ΡΠ°Π·ΠΈΡ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ ΡΠ°Π±Π»ΠΎΠ½, ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠΉ ΡΡΡΠΎΠΊΠΎΠΉ.
=== ΠΠΎΡΡΡΠΏ ΠΊ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠΌ Π² ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
Π¨Π°Π±Π»ΠΎΠ½Ρ ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠΈΡΡΡΡΡΡ Π² ΡΠΎΠΌ ΠΆΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅, ΡΡΠΎ ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΌΠ°ΡΡΡΡΡΠΎΠ². ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°,
ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΡΠ΅ Π² ΠΏΡΠΎΡΠ΅ΡΡΠ΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΠΌΠ°ΡΡΡΡΡΠΎΠ², Π±ΡΠ΄ΡΡ Π΄ΠΎΡΡΡΠΏΠ½Ρ Π½Π°ΠΏΡΡΠΌΡΡ Π² ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
:
get '/:id' do
@foo = Foo.find(params[:id])
haml '%h1= @foo.name'
end
ΠΠΈΠ±ΠΎ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ ΠΈΡ
ΡΠ΅ΡΠ΅Π· Ρ
Π΅Ρ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΡ
ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ
:
get '/:id' do
foo = Foo.find(params[:id])
haml '%h1= bar.name', :locals => { :bar => foo }
end
ΠΡΠΎ ΠΎΠ±ΡΡΠ½ΡΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄, ΠΊΠΎΠ³Π΄Π° ΡΠ°Π±Π»ΠΎΠ½Ρ ΡΠ΅Π½Π΄Π΅ΡΡΡΡΡ ΠΊΠ°ΠΊ ΡΠ°ΡΡΠΈ Π΄ΡΡΠ³ΠΈΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ².
=== ΠΠ»ΠΎΠΆΠ΅Π½Π½ΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½Ρ
Π¨Π°Π±Π»ΠΎΠ½Ρ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ Π² ΠΊΠΎΠ½ΡΠ΅ ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π°:
require 'sinatra'
get '/' do
haml :index
end
__END__
@@ layout
%html
= yield
@@ index
%div.title Hello world!!!!!
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅: Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½Ρ, ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΠ΅ Π² ΠΈΡΡ
ΠΎΠ΄Π½ΠΎΠΌ ΡΠ°ΠΉΠ»Π΅, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΠ»Π° Sinatra, Π±ΡΠ΄ΡΡ
Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ Π·Π°Π³ΡΡΠΆΠ΅Π½Ρ. ΠΡΠ·ΠΎΠ²ΠΈΡΠ΅ <tt>enable :inline_templates</tt> Π½Π°ΠΏΡΡΠΌΡΡ, Π΅ΡΠ»ΠΈ Ρ Π²Π°Ρ Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΠ΅
ΡΠ°Π±Π»ΠΎΠ½Ρ Π² Π΄ΡΡΠ³ΠΈΡ
ΡΠ°ΠΉΠ»Π°Ρ
.
=== ΠΠΌΠ΅Π½Π½ΡΠ΅ ΡΠ°Π±Π»ΠΎΠ½Ρ
Π¨Π°Π±Π»ΠΎΠ½Ρ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Ρ ΠΏΡΠΈ ΠΏΠΎΠΌΠΎΡΠΈ <tt>template</tt> ΠΌΠ΅ΡΠΎΠ΄Π°:
template :layout do
"%html\n =yield\n"
end
template :index do
'%div.title Hello World!'
end
get '/' do
haml :index
end
ΠΡΠ»ΠΈ ΡΠ°Π±Π»ΠΎΠ½ Ρ ΠΈΠΌΠ΅Π½Π΅ΠΌ "layout" ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ, ΡΠΎ ΠΎΠ½ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ ΠΊΠ°ΠΆΠ΄ΡΠΉ ΡΠ°Π·
ΠΏΡΠΈ ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³Π΅. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΎΡΠΊΠ»ΡΡΠ°ΡΡ Π»ΡΠΉΠ°ΡΡ Π² ΠΊΠ°ΠΆΠ΄ΠΎΠΌ ΠΊΠΎΠ½ΠΊΡΠ΅ΡΠ½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ
<tt>:layout => false</tt> ΠΈΠ»ΠΈ ΠΎΡΠΊΠ»ΡΡΠΈΡΡ Π΅Π³ΠΎ Π΄Π»Ρ Π²ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΡΠ°ΠΊ:
<tt>set :haml, :layout => false</tt>:
get '/' do
haml :index, :layout => !request.xhr?
end
=== ΠΡΠΈΠ²ΡΠ·ΠΊΠ° ΡΠ°ΠΉΠ»ΠΎΠ²ΡΡ
ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΉ
Π§ΡΠΎΠ±Ρ ΡΠ²ΡΠ·Π°ΡΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΉΠ»Π° Ρ Π΄Π²ΠΈΠΆΠΊΠΎΠΌ ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³Π°, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅
<tt>Tilt.register</tt>. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ +tt+
Π΄Π»Ρ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² Textile:
Tilt.register :tt, Tilt[:textile]
=== ΠΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΠΎΠ³ΠΎ Π΄Π²ΠΈΠΆΠΊΠ° ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³Π°
Π‘Π½Π°ΡΠ°Π»Π° Π·Π°ΡΠ΅Π³ΠΈΡΡΡΠΈΡΡΠΉΡΠ΅ ΡΠ²ΠΎΠΉ Π΄Π²ΠΈΠΆΠΎΠΊ Π² Tilt, Π·Π°ΡΠ΅ΠΌ ΡΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄, ΠΎΡΠ²Π΅ΡΠ°ΡΡΠΈΠΉ Π·Π° ΠΎΡΡΠΈΡΠΎΠ²ΠΊΡ:
Tilt.register :myat, MyAwesomeTemplateEngine
helpers do
def myat(*args) render(:myat, *args) end
end
get '/' do
myat :index
end
ΠΡΠΎΠ±ΡΠ°Π·ΠΈΡ <tt>./views/index.myat</tt>. Π§ΡΠΎΠ±Ρ ΡΠ·Π½Π°ΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΠΎ Tilt,
ΡΠΌΠΎΡΡΠΈΡΠ΅ https://github.com/rtomayko/tilt
== Π€ΠΈΠ»ΡΡΡΡ
+before+-ΡΠΈΠ»ΡΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΏΠ΅ΡΠ΅Π΄ ΠΊΠ°ΠΆΠ΄ΡΠΌ Π·Π°ΠΏΡΠΎΡΠΎΠΌ Π² ΡΠΎΠΌ ΠΆΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅, ΡΡΠΎ ΠΈ ΠΌΠ°ΡΡΡΡΡΡ. Π€ΠΈΠ»ΡΡΡΡ ΠΌΠΎΠ³ΡΡ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ
ΠΊΠ°ΠΊ Π·Π°ΠΏΡΠΎΡ, ΡΠ°ΠΊ ΠΈ ΠΎΡΠ²Π΅Ρ Π½Π° Π½Π΅Π³ΠΎ. ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°, ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΡΠ΅ Π² ΡΠΈΠ»ΡΡΡΠ°Ρ
, Π΄ΠΎΡΡΡΠΏΠ½Ρ Π² ΠΌΠ°ΡΡΡΡΡΠ°Ρ
ΠΈ ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
:
before do
@note = 'Hi!'
request.path_info = '/foo/bar/baz'
end
get '/foo/*' do
@note #=> 'Hi!'
params[:splat] #=> 'bar/baz'
end
+after+-ΡΠΈΠ»ΡΡΡΡ Π²ΡΠΏΠΎΠ»Π½ΡΡΡΡΡ ΠΏΠΎΡΠ»Π΅ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ° Π² ΡΠΎΠΌ ΠΆΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅, ΡΡΠΎ ΠΈ ΠΏΡΡΠΈ. Π€ΠΈΠ»ΡΡΡΡ ΠΌΠΎΠ³ΡΡ ΠΈΠ·ΠΌΠ΅Π½ΡΡΡ
ΠΊΠ°ΠΊ Π·Π°ΠΏΡΠΎΡ, ΡΠ°ΠΊ ΠΈ ΠΎΡΠ²Π΅Ρ Π½Π° Π½Π΅Π³ΠΎ. ΠΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°, ΡΡΡΠ°Π½ΠΎΠ²Π»Π΅Π½Π½ΡΠ΅ Π² +before+-ΡΠΈΠ»ΡΡΡΠ°Ρ
ΠΈ ΠΌΠ°ΡΡΡΡΡΠ°Ρ
,
Π±ΡΠ΄ΡΡ Π΄ΠΎΡΡΡΠΏΠ½Ρ Π² +after+-ΡΠΈΠ»ΡΡΡΠ°Ρ
:
after do
puts response.status
end
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅: Π΅ΡΠ»ΠΈ Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ +body+, Π° Π½Π΅ ΠΏΡΠΎΡΡΠΎ Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΡΠ΅ ΡΡΡΠΎΠΊΡ ΠΈΠ·
ΠΌΠ°ΡΡΡΡΡΠ°, ΡΠΎ ΡΠ΅Π»ΠΎ ΠΎΡΠ²Π΅ΡΠ° Π½Π΅ Π±ΡΠ΄Π΅Ρ Π΄ΠΎΡΡΡΠΏΠ½ΠΎ Π² +after+-ΡΠΈΠ»ΡΡΡΠ°Ρ
, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΡΠ³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½ΠΎ ΠΏΠΎΠ·Π΄Π½Π΅Π΅.
Π€ΠΈΠ»ΡΡΡΡ ΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°Π±Π»ΠΎΠ½Ρ URL ΠΈ Π±ΡΠ΄ΡΡ ΠΈΠ½ΡΠ΅ΡΠΏΡΠ΅ΡΠΈΡΠΎΠ²Π°Π½Ρ ΡΠΎΠ»ΡΠΊΠΎ Π΅ΡΠ»ΠΈ ΠΏΡΡΡ Π·Π°ΠΏΡΠΎΡΠ° ΡΠΎΠ²ΠΏΠ°Π΄Π΅Ρ Ρ ΡΡΠΈΠΌ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠΌ:
before '/protected/*' do
authenticate!
end
after '/create/:slug' do |slug|
session[:last_slug] = slug
end
ΠΠ°ΠΊ ΠΈ ΠΌΠ°ΡΡΡΡΡΡ, ΡΠΈΠ»ΡΡΡΡ ΠΌΠΎΠ³ΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠ»ΠΎΠ²ΠΈΡ:
before :agent => /Songbird/ do
# ...
end
after '/blog/*', :host_name => 'example.com' do
# ...
end
== ΠΠ΅ΡΠΎΠ΄Ρ-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠΈ
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ <tt>helpers</tt>, ΡΡΠΎΠ±Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅
Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°Ρ
ΠΌΠ°ΡΡΡΡΡΠΎΠ² ΠΈ ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
:
helpers do
def bar(name)
"#{name}bar"
end
end
get '/:name' do
bar(params[:name])
end
=== ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΠ΅ΡΡΠΈΠΉ
Π‘Π΅ΡΡΠΈΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ, ΡΡΠΎΠ±Ρ ΡΠΎΡ
ΡΠ°Π½ΡΡΡ ΡΠΎΡΡΠΎΡΠ½ΠΈΠ΅ ΠΌΠ΅ΠΆΠ΄Ρ Π·Π°ΠΏΡΠΎΡΠ°ΠΌΠΈ. ΠΡΠ»ΠΈ ΡΡΠ° ΠΎΠΏΡΠΈΡ
Π²ΠΊΠ»ΡΡΠ΅Π½Π°, ΡΠΎ Ρ Π²Π°Ρ Π±ΡΠ΄Π΅Ρ ΠΎΠ΄ΠΈΠ½ Ρ
Π΅Ρ ΡΠ΅ΡΡΠΈΠΈ Π½Π° ΠΎΠ΄Π½Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»ΡΡΠΊΡΡ ΡΠ΅ΡΡΠΈΡ:
enable :sessions
get '/' do
"value = " << session[:value].inspect
end
get '/:value' do
session[:value] = params[:value]
end
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ <tt>enable :sessions</tt> Π²ΡΠ΅ Π΄Π°Π½Π½ΡΠ΅
ΡΠΎΡ
ΡΠ°Π½ΡΡΡΡΡ Π² cookies. ΠΡΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π½Π΅ ΡΠΎΠ²ΡΠ΅ΠΌ ΡΠΎ, ΡΡΠΎ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ,
ΡΠΎΡ
ΡΠ°Π½Π΅Π½ΠΈΠ΅ Π±ΠΎΠ»ΡΡΠΈΡ
ΠΎΠ±ΡΠ΅ΠΌΠΎΠ² Π΄Π°Π½Π½ΡΡ
ΡΠ²Π΅Π»ΠΈΡΠΈΡ Π²Π°Ρ ΡΡΠ°ΡΠΈΠΊ). Π ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ Π²Ρ
ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΡ Rack "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΡ" (middleware), ΡΠ΅Π°Π»ΠΈΠ·ΡΡΡΡΡ
ΠΌΠ΅Ρ
Π°Π½ΠΈΠ·ΠΌ ΡΠ΅ΡΡΠΈΠΉ. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ *Π½Π΅ Π½Π°Π΄ΠΎ* Π²ΡΠ·ΡΠ²Π°ΡΡ <tt>enable :sessions</tt>,
Π²ΠΌΠ΅ΡΡΠΎ ΡΡΠΎΠ³ΠΎ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠΈΡΡ Π΅Π΅ ΡΠ°ΠΊ ΠΆΠ΅, ΠΊΠ°ΠΊ ΠΈ Π»ΡΠ±ΡΡ Π΄ΡΡΠ³ΡΡ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΡ":
use Rack::Session::Pool, :expire_after => 2592000
get '/' do
"value = " << session[:value].inspect
end
get '/:value' do
session[:value] = params[:value]
end
ΠΠ»Ρ ΠΏΠΎΠ²ΡΡΠ΅Π½ΠΈΡ Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎΡΡΠΈ Π΄Π°Π½Π½ΡΠ΅ ΡΠ΅ΡΡΠΈΠΈ Π² ΠΊΡΠΊΠ°Ρ
ΠΏΠΎΠ΄ΠΏΠΈΡΡΠ²Π°ΡΡΡΡ ΡΠ΅ΠΊΡΠ΅ΡΠ½ΡΠΌ
ΠΊΠ»ΡΡΠΎΠΌ. Π‘Π΅ΠΊΡΠ΅ΡΠ½ΡΠΉ ΠΊΠ»ΡΡ Π³Π΅Π½Π΅ΡΠΈΡΡΠ΅ΡΡΡ Sinatra. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΠΎΡ
ΠΊΠ»ΡΡ Π±ΡΠ΄Π΅Ρ ΠΌΠ΅Π½ΡΡΡΡΡ Ρ ΠΊΠ°ΠΆΠ΄ΡΠΌ Π·Π°ΠΏΡΡΠΊΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π²Ρ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π·Π°Ρ
ΠΎΡΠΈΡΠ΅
ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΊΠ»ΡΡ Π²ΡΡΡΠ½ΡΡ, ΡΡΠΎΠ±Ρ Ρ Π²ΡΠ΅Ρ
ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠΎΠ² Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
Π±ΡΠ» ΠΎΠ΄ΠΈΠ½ ΠΈ ΡΠΎΡ ΠΆΠ΅ ΠΊΠ»ΡΡ:
set :session_secret, 'super secret'
ΠΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ Π±ΠΎΠ»ΡΡΠ΅ Π½Π°ΡΡΡΠΎΠ΅ΠΊ Π΄Π»Ρ ΡΠ΅ΡΡΠΈΠΉ, Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°Π΄Π°ΡΡ ΠΈΡ
, ΠΏΠ΅ΡΠ΅Π΄Π°Π² Ρ
Π΅Ρ ΠΎΠΏΡΠΈΠΉ Π² ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ +sessions+:
set :sessions, :domain => 'foo.com'
=== ΠΡΠ΅ΡΡΠ²Π°Π½ΠΈΠ΅
Π§ΡΠΎΠ±Ρ Π½Π΅Π·Π°ΠΌΠ΅Π΄Π»ΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΏΡΠ΅ΡΠ²Π°ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ Π·Π°ΠΏΡΠΎΡΠ° Π²Π½ΡΡΡΠΈ ΡΠΈΠ»ΡΡΡΠ° ΠΈΠ»ΠΈ ΠΌΠ°ΡΡΡΡΡΠ°, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅:
halt
ΠΠΎΠΆΠ½ΠΎ ΡΠ°ΠΊΠΆΠ΅ ΡΠΊΠ°Π·Π°ΡΡ ΡΡΠ°ΡΡΡ ΠΏΡΠΈ ΠΏΡΠ΅ΡΡΠ²Π°Π½ΠΈΠΈ:
halt 410
Π’Π΅Π»ΠΎ:
halt 'this will be the body'
Π ΡΠΎ, ΠΈ Π΄ΡΡΠ³ΠΎΠ΅:
halt 401, 'go away!'
ΠΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Π·Π°ΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ:
halt 402, {'Content-Type' => 'text/plain'}, 'revenge'
Π, ΠΊΠΎΠ½Π΅ΡΠ½ΠΎ, ΠΌΠΎΠΆΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°Π±Π»ΠΎΠ½Ρ Ρ +halt+:
halt erb(:error)
=== ΠΠ΅ΡΠ΅Π΄Π°ΡΠ°
ΠΠ°ΡΡΡΡΡ ΠΌΠΎΠΆΠ΅Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ Π·Π°ΠΏΡΠΎΡΠ° ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠ΅ΠΌΡ ΠΌΠ°ΡΡΡΡΡΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ <tt>pass</tt>:
get '/guess/:who' do
pass unless params[:who] == 'Frank'
'You got me!'
end
get '/guess/*' do
'You missed!'
end
ΠΠ»ΠΎΠΊ ΠΌΠ°ΡΡΡΡΡΠ° ΡΡΠ°Π·Ρ ΠΆΠ΅ ΠΏΡΠ΅ΡΡΠ²Π°Π΅ΡΡΡ, ΠΈ ΠΊΠΎΠ½ΡΡΠΎΠ»Ρ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ΠΈΡ ΠΊ ΡΠ»Π΅Π΄ΡΡΡΠ΅ΠΌΡ ΡΠΎΠ²ΠΏΠ°Π΄Π°ΡΡΠ΅ΠΌΡ ΠΌΠ°ΡΡΡΡΡΡ.
ΠΡΠ»ΠΈ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ ΠΌΠ°ΡΡΡΡΡ Π½Π΅ Π½Π°ΠΉΠ΄Π΅Π½, ΡΠΎ ΠΎΡΠ²Π΅ΡΠΎΠΌ Π½Π° Π·Π°ΠΏΡΠΎΡ Π±ΡΠ΄Π΅Ρ 404.
=== ΠΡΠ·ΠΎΠ² Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΌΠ°ΡΡΡΡΡΠ°
ΠΠ½ΠΎΠ³Π΄Π° +pass+ Π½Π΅ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΠΈΡ, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ
Π²ΡΠ·ΠΎΠ²Π° Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΠΌΠ°ΡΡΡΡΡΠ°. Π ΡΠ°ΠΊΠΎΠΌ ΡΠ»ΡΡΠ°Π΅ ΠΏΡΠΎΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ +call+:
get '/foo' do
status, headers, body = call env.merge("PATH_INFO" => '/bar')
[status, headers, body.map(&:upcase)]
end
get '/bar' do
"bar"
end
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π² ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΎΠ±Π»Π΅Π³ΡΠΈΡΡ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ²ΡΡΠΈΡΡ
ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ, ΠΏΠ΅ΡΠ΅Π½Π΅ΡΡ <tt>"bar"</tt> Π² ΠΌΠ΅ΡΠΎΠ΄-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ
ΠΈ Π² <tt>/foo</tt>, ΠΈ Π² <tt>/bar</tt>.
ΠΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅, ΡΡΠΎΠ±Ρ Π·Π°ΠΏΡΠΎΡ Π±ΡΠ» ΠΎΡΠΏΡΠ°Π²Π»Π΅Π½ Π² ΡΠΎΡ ΠΆΠ΅ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π° Π½Π΅
Π² Π΅Π³ΠΎ ΠΊΠΎΠΏΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ <tt>call!</tt> Π²ΠΌΠ΅ΡΡΠΎ <tt>call</tt>.
ΠΡΠ»ΠΈ Ρ
ΠΎΡΠΈΡΠ΅ ΡΠ·Π½Π°ΡΡ Π±ΠΎΠ»ΡΡΠ΅ ΠΎ <tt>call</tt>, ΡΠΌΠΎΡΡΠΈΡΠ΅ ΡΠΏΠ΅ΡΠΈΡΠΈΠΊΠ°ΡΠΈΡ Rack.
=== ΠΠ°Π΄Π°Π½ΠΈΠ΅ ΡΠ΅Π»Π°, ΠΊΠΎΠ΄Π° ΠΈ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² ΠΎΡΠ²Π΅ΡΠ°
Π₯ΠΎΡΠΎΡΠΈΠΌ ΡΠΎΠ½ΠΎΠΌ ΡΠ²Π»ΡΠ΅ΡΡΡ ΡΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΊΠΎΠ΄Π° ΡΠΎΡΡΠΎΡΠ½ΠΈΡ HTTP ΠΈ ΡΠ΅Π»Π° ΠΎΡΠ²Π΅ΡΠ° Π² Π²ΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΠΎΠΌ
Π·Π½Π°ΡΠ΅Π½ΠΈΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° ΠΌΠ°ΡΡΡΡΡΠ°. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π² Π½Π΅ΠΊΠΎΡΠΎΡΡΡ
ΡΠΈΡΡΠ°ΡΠΈΡΡ
Π²Π°ΠΌ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ,
ΠΏΠΎΠ½Π°Π΄ΠΎΠ±ΠΈΡΡΡ Π·Π°Π΄Π°ΡΡ ΡΠ΅Π»ΠΎ ΠΎΡΠ²Π΅ΡΠ° Π² ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ»ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠ΅ ΠΏΠΎΡΠΎΠΊΠ° ΠΈΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅
ΡΠ΄Π΅Π»Π°ΡΡ ΡΡΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π°-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠ° +body+. ΠΡΠ»ΠΈ Π²Ρ Π·Π°Π΄Π΅ΠΉΡΡΠ²ΡΠ΅ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ +body+,
ΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ ΠΈ Π² Π΄Π°Π»ΡΠ½Π΅ΠΉΡΠ΅ΠΌ, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΠ΅Π»Ρ ΠΎΡΠ²Π΅ΡΠ°.
get '/foo' do
body "bar"
end
after do
puts body
end
Π’Π°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ Π±Π»ΠΎΠΊ Π² ΠΌΠ΅ΡΠΎΠ΄ +body+, ΠΊΠΎΡΠΎΡΡΠΉ Π·Π°ΡΠ΅ΠΌ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½
ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠΌ Rack (ΡΠ°ΠΊΠΎΠΉ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ Π΄Π»Ρ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ ΠΏΠΎΡΠΎΡΠ½ΠΎΠ³ΠΎ
ΠΎΡΠ²Π΅ΡΠ°, ΡΠΌ. "ΠΠΎΠ·Π²ΡΠ°ΡΠ°Π΅ΠΌΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ").
ΠΠ½Π°Π»ΠΎΠ³ΠΈΡΠ½ΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΊΠΎΠ΄ ΠΎΡΠ²Π΅ΡΠ° ΠΈ Π΅Π³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΈ:
get '/foo' do
status 418
headers \
"Allow" => "BREW, POST, GET, PROPFIND, WHEN",
"Refresh" => "Refresh: 20; http://www.ietf.org/rfc/rfc2324.txt"
body "I'm a tea pot!"
end
ΠΠ°ΠΊ ΠΈ +body+, ΠΌΠ΅ΡΠΎΠ΄Ρ +headers+ ΠΈ +status+, Π²ΡΠ·Π²Π°Π½Π½ΡΠ΅ Π±Π΅Π· Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠ², Π²ΠΎΠ·Π²ΡΠ°ΡΠ°ΡΡ
ΡΠ²ΠΎΠΈ ΡΠ΅ΠΊΡΡΠΈΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ.
=== ΠΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
Π ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π·Π°ΠΏΡΠΎΡΠ° ΠΌΠ΅ΡΠΎΠ΄ +logger+ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅Ρ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΡ +Logger+:
get '/' do
logger.info "loading data"
# ...
end
ΠΡΠΎΡ Π»ΠΎΠ³Π΅Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΡΠΈΡΡΠ²Π°Π΅Ρ Π²Π°ΡΠΈ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π² Rack. ΠΡΠ»ΠΈ
Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π²ΡΠΊΠ»ΡΡΠ΅Π½ΠΎ, ΡΠΎ ΡΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ Π²Π΅ΡΠ½Π΅Ρ ΠΏΡΡΡΠΎΠΉ (dummy) ΠΎΠ±ΡΠ΅ΠΊΡ, ΠΏΠΎΡΡΠΎΠΌΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅
ΡΠΌΠ΅Π»ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π΅Π³ΠΎ Π² ΠΌΠ°ΡΡΡΡΡΠ°Ρ
ΠΈ ΡΠΈΠ»ΡΡΡΠ°Ρ
.
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΡΠΎΠ»ΡΠΊΠΎ Π΄Π»Ρ <tt>Sinatra::Application</tt>,
Π° Π΅ΡΠ»ΠΈ Π²Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ -- ΠΏΠΎΠ΄ΠΊΠ»Π°ΡΡ <tt>Sinatra::Base</tt>, ΡΠΎ Π²Ρ, Π½Π°Π²Π΅ΡΠ½ΠΎΠ΅, Π·Π°Ρ
ΠΎΡΠΈΡΠ΅ Π²ΠΊΠ»ΡΡΠΈΡΡ
Π΅Π³ΠΎ Π²ΡΡΡΠ½ΡΡ:
class MyApp < Sinatra::Base
configure(:production, :development) do
enable :logging
end
end
=== Mime-ΡΠΈΠΏΡ
ΠΠΎΠ³Π΄Π° Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ <tt>send_file</tt> ΠΈΠ»ΠΈ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ, Ρ Π²Π°Ρ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ mime-ΡΠΈΠΏΡ, ΠΊΠΎΡΠΎΡΡΠ΅ Sinatra
Π½Π΅ ΠΏΠΎΠ½ΠΈΠΌΠ°Π΅Ρ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ +mime_type+ Π΄Π»Ρ ΠΈΡ
ΡΠ΅Π³ΠΈΡΡΡΠ°ΡΠΈΠΈ ΠΏΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»Π°:
configure do
mime_type :foo, 'text/foo'
end
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΎ Π² +content_type+ ΠΌΠ΅ΡΠΎΠ΄Π΅-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠ΅:
get '/' do
content_type :foo
"foo foo foo"
end
=== ΠΠ΅Π½Π΅ΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ URL
Π§ΡΠΎΠ±Ρ ΡΡΠΎΡΠΌΠΈΡΠΎΠ²Π°ΡΡ URL Π²Π°ΠΌ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ +url+, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π² Haml:
%a{:href => url('/foo')} foo
ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΡΡΠΈΡΡΠ²Π°Π΅Ρ ΠΎΠ±ΡΠ°ΡΠ½ΡΠ΅ ΠΏΡΠΎΠΊΡΠΈ ΠΈ ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΎΡΡ Rack, Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΈ ΠΏΡΠΈΡΡΡΡΡΠ²ΡΡΡ.
ΠΠ°ΡΡΠ΄Ρ Ρ +url+ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ +to+ (ΡΠΌΠΎΡΡΠΈΡΠ΅ ΠΏΡΠΈΠΌΠ΅Ρ Π½ΠΈΠΆΠ΅).
=== ΠΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ (ΡΠ΅Π΄ΠΈΡΠ΅ΠΊΡ)
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²ΠΈΡΡ Π±ΡΠ°ΡΠ·Π΅Ρ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° +redirect+:
get '/foo' do
redirect to('/bar')
end
ΠΡΠ±ΡΠ΅ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ ΠΏΠΎ Π°Π½Π°Π»ΠΎΠ³ΠΈΠΈ Ρ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠ°ΠΌΠΈ ΠΌΠ΅ΡΠΎΠ΄Π° +halt+:
redirect to('/bar'), 303
redirect 'http://google.com', 'wrong place, buddy'
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²ΠΈΡΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ, Π½Π° ΡΡΡΠ°Π½ΠΈΡΡ Ρ ΠΊΠΎΡΠΎΡΠΎΠΉ ΠΎΠ½ ΠΏΡΠΈΡΠ΅Π»,
Ρ ΠΏΠΎΠΌΠΎΡΡΡ <tt>redirect back</tt>:
get '/foo' do
"<a href='/bar'>do something</a>"
end
get '/bar' do
do_something
redirect back
end
Π§ΡΠΎΠ±Ρ ΠΏΠ΅ΡΠ΅Π΄Π°ΡΡ ΠΊΠ°ΠΊΠΈΠ΅-Π»ΠΈΠ±ΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ΠΌ, Π»ΠΈΠ±ΠΎ Π΄ΠΎΠ±Π°Π²ΡΡΠ΅ ΠΈΡ
Π² ΡΡΡΠΎΠΊΡ Π·Π°ΠΏΡΠΎΡΠ°:
redirect to('/bar?sum=42')
Π»ΠΈΠ±ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΠ΅ΡΡΠΈΡ:
enable :sessions
get '/foo' do
session[:secret] = 'foo'
redirect to('/bar')
end
get '/bar' do
session[:secret]
end
=== Π£ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠ΅ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ
Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΡΡ
Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠΎΠ² β ΠΎΡΠ½ΠΎΠ²Π° ΠΏΡΠ°Π²ΠΈΠ»ΡΠ½ΠΎΠ³ΠΎ HTTP ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ.
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π»Π΅Π³ΠΊΠΎ Π²ΡΡΡΠ°Π²ΠΈΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ Cache-Control ΡΠ°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ:
get '/' do
cache_control :public
"cache it!"
end
Π‘ΠΎΠ²Π΅Ρ: Π·Π°Π΄Π°Π²Π°ΠΉΡΠ΅ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Π² +before+-ΡΠΈΠ»ΡΡΡΠ΅:
before do
cache_control :public, :must_revalidate, :max_age => 60
end
ΠΡΠ»ΠΈ Π²Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄ +expires+ Π΄Π»Ρ Π·Π°Π΄Π°Π½ΠΈΡ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠ΅Π³ΠΎ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ°,
ΡΠΎ <tt>Cache-Control</tt> Π±ΡΠ΄Π΅Ρ Π²ΡΡΡΠ°Π²Π»Π΅Π½ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ:
before do
expires 500, :public, :must_revalidate
end
Π§ΡΠΎΠ±Ρ ΠΊΠ°ΠΊ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅, Π²Π°ΠΌ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΏΠΎΠ΄ΡΠΌΠ°ΡΡ ΠΎΠ± ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ
+etag+ ΠΈ +last_modified+. Π Π΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΡΠΈ ΠΌΠ΅ΡΠΎΠ΄Ρ-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠΈ *Π΄ΠΎ*
Π²ΡΠΏΠΎΠ»Π½Π΅Π½ΠΈΡ ΡΠ΅ΡΡΡΡΠΎΠ΅ΠΌΠΊΠΈΡ
Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠΉ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½ΠΈ Π½Π΅ΠΌΠ΅Π΄Π»Π΅Π½Π½ΠΎ ΠΎΡΠΏΡΠ°Π²ΡΡ ΠΎΡΠ²Π΅Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΡ,
Π΅ΡΠ»ΠΈ ΡΠ΅ΠΊΡΡΠ°Ρ Π²Π΅ΡΡΠΈΡ ΡΠΆΠ΅ Π΅ΡΡΡ Π² ΠΈΡ
ΠΊΡΡΠ΅:
get '/article/:id' do
@article = Article.find params[:id]
last_modified @article.updated_at
etag @article.sha1
erb :article
end
Π’Π°ΠΊΠΆΠ΅ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ
{weak ETag}[http://en.wikipedia.org/wiki/HTTP_ETag#Strong_and_weak_validation]:
etag @article.sha1, :weak
ΠΡΠΈ ΠΌΠ΅ΡΠΎΠ΄Ρ-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠΈ Π½Π΅ ΡΡΠ°Π½ΡΡ Π½ΠΈΡΠ΅Π³ΠΎ ΠΊΡΡΠΈΡΠΎΠ²Π°ΡΡ Π΄Π»Ρ Π²Π°Ρ, Π½ΠΎ ΠΎΠ½ΠΈ Π΄Π°Π΄ΡΡ
Π½Π΅ΠΎΠ±Ρ
ΠΎΠ΄ΠΈΠΌΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ Π΄Π»Ρ Π²Π°ΡΠ΅Π³ΠΎ ΠΊΡΡΠ°. ΠΡΠ»ΠΈ Π²Ρ ΠΈΡΠΈΡΠ΅ Π»Π΅Π³ΠΊΠΎΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ
ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΏΠΎΠΏΡΠΎΠ±ΡΠΉΡΠ΅ {rack-cache}[http://rtomayko.github.com/rack-cache/]:
require 'rack/cache'
require 'sinatra'
use Rack::Cache
get '/' do
cache_control :public, :max_age => 36000
sleep 5
"hello"
end
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΎΠΏΡΠΈΡ <tt>:static_cache_control</tt> (ΡΠΌ. Π½ΠΈΠΆΠ΅), ΡΡΠΎΠ±Ρ
Π΄ΠΎΠ±Π°Π²ΠΈΡΡ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ <tt>Cache-Control</tt> ΠΊ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌ ΡΠ°ΠΉΠ»Π°ΠΌ.
=== ΠΡΠΏΡΠ°Π²ΠΊΠ° ΡΠ°ΠΉΠ»ΠΎΠ²
ΠΠ»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠ°ΠΉΠ»ΠΎΠ² ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ <tt>send_file</tt>:
get '/' do
send_file 'foo.png'
end
ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΈΠΌΠ΅Π΅Ρ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠΏΡΠΈΠΉ:
send_file 'foo.png', :type => :jpg
ΠΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ ΠΎΠΏΡΠΈΠΈ:
[filename]
ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: ΡΠ΅Π°Π»ΡΠ½ΠΎΠ΅ ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°.
[last_modified]
Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π΄Π»Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Last-Modified, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: mtime (Π²ΡΠ΅ΠΌΡ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ) ΡΠ°ΠΉΠ»Π°.
[type]
ΡΠΈΠΏ ΡΠ°ΠΉΠ»Π°, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ ΠΏΠΎ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡ ΡΠ°ΠΉΠ»Π°.
[disposition]
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Content-Disposition, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΠ΅ Π·Π½Π°ΡΠ΅Π½ΠΈΡ:
+nil+ (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ), <tt>:attachment</tt> ΠΈ <tt>:inline</tt>.
[length]
Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° Content-Length, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: ΡΠ°Π·ΠΌΠ΅Ρ ΡΠ°ΠΉΠ»Π°.
ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ Π±ΡΠ΄Π΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠΈ Rack ΡΠ΅ΡΠ²Π΅ΡΠ° Π΄Π»Ρ ΠΎΡΠΏΡΠ°Π²ΠΊΠΈ ΡΠ°ΠΉΠ»ΠΎΠ², Π΅ΡΠ»ΠΈ ΠΎΠ½ΠΈ
Π΄ΠΎΡΡΡΠΏΠ½Ρ, Π° Π² ΠΏΡΠΎΡΠΈΠ²Π½ΠΎΠΌ ΡΠ»ΡΡΠ°Π΅, Π±ΡΠ΄Π΅Ρ Π½Π°ΠΏΡΡΠΌΡΡ ΠΎΡΠ΄Π°Π²Π°ΡΡ ΡΠ°ΠΉΠ» ΠΈΠ· Ruby ΠΏΡΠΎΡΠ΅ΡΡΠ°.
ΠΠ΅ΡΠΎΠ΄ <tt>send_file</tt> ΡΠ°ΠΊΠΆΠ΅ ΠΎΠ±Π΅ΡΠΏΠ΅ΡΠΈΠ²Π°Π΅Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ ΡΠ°ΡΡΠΈΡΠ½ΡΡ
(range)
Π·Π°ΠΏΡΠΎΡΠΎΠ² Ρ ΠΏΠΎΠΌΠΎΡΡΡ Sinatra.
=== ΠΠΎΡΡΡΠΏ ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ Π·Π°ΠΏΡΠΎΡΠ°
ΠΠ±ΡΠ΅ΠΊΡ Π²Ρ
ΠΎΠ΄ΡΡΠ΅Π³ΠΎ Π·Π°ΠΏΡΠΎΡΠ° Π΄ΠΎΡΡΡΠΏΠ΅Π½ Π½Π° ΡΡΠΎΠ²Π½Π΅ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ Π·Π°ΠΏΡΠΎΡΠ° (Π² ΡΠΈΠ»ΡΡΡΠ°Ρ
, ΠΌΠ°ΡΡΡΡΡΠ°Ρ
,
ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ°Ρ
ΠΎΡΠΈΠ±ΠΎΠΊ) Ρ ΠΏΠΎΠΌΠΎΡΡΡ <tt>request</tt> ΠΌΠ΅ΡΠΎΠ΄Π°:
# ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡΡΠ΅Π½ΠΎ Π½Π° http://example.com/example
get '/foo' do
t = %w[text/css text/html application/javascript]
request.accept # ['text/html', '*/*']
request.accept? 'text/xml' # true
request.preferred_type(t) # 'text/html'
request.body # ΡΠ΅Π»ΠΎ Π·Π°ΠΏΡΠΎΡΠ°, ΠΏΠΎΡΠ»Π°Π½Π½ΠΎΠ΅ ΠΊΠ»ΠΈΠ΅Π½ΡΠΎΠΌ (ΡΠΌ. Π½ΠΈΠΆΠ΅)
request.scheme # "http"
request.script_name # "/example"
request.path_info # "/foo"
request.port # 80
request.request_method # "GET"
request.query_string # ""
request.content_length # Π΄Π»ΠΈΠ½Π° ΡΠ΅Π»Π° Π·Π°ΠΏΡΠΎΡΠ°
request.media_type # ΠΌΠ΅Π΄ΠΈΠ°ΡΠΈΠΏ ΡΠ΅Π»Π° Π·Π°ΠΏΡΠΎΡΠ°
request.host # "example.com"
request.get? # true (Π΅ΡΡΡ Π°Π½Π°Π»ΠΎΠ³ΠΈ Π΄Π»Ρ Π΄ΡΡΠ³ΠΈΡ
ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ² HTTP)
request.form_data? # false
request["SOME_HEADER"] # Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΊΠ° SOME_HEADER
request.referrer # ΠΈΡΡΠΎΡΠ½ΠΈΠΊ Π·Π°ΠΏΡΠΎΡΠ° ΠΊΠ»ΠΈΠ΅Π½ΡΠ° Π»ΠΈΠ±ΠΎ '/'
request.user_agent # user agent (ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ :agent ΡΡΠ»ΠΎΠ²ΠΈΡ)
request.cookies # Ρ
Π΅Ρ, ΡΠΎΠ΄Π΅ΡΠΆΠ°ΡΠΈΠΉ cookies Π±ΡΠ°ΡΠ·Π΅ΡΠ°
request.xhr? # ΡΠ²Π»ΡΠ΅ΡΡΡ Π»ΠΈ Π·Π°ΠΏΡΠΎΡ ajax Π·Π°ΠΏΡΠΎΡΠΎΠΌ?
request.url # "http://example.com/example/foo"
request.path # "/example/foo"
request.ip # IP-Π°Π΄ΡΠ΅Ρ ΠΊΠ»ΠΈΠ΅Π½ΡΠ°
request.secure? # false (true, Π΅ΡΠ»ΠΈ Π·Π°ΠΏΡΠΎΡ ΡΠ΄Π΅Π»Π°Π½ ΡΠ΅ΡΠ΅Π· SSL)
request.forwarded? # true (Π΅ΡΠ»ΠΈ ΡΠ΅ΡΠ²Π΅Ρ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π·Π° ΠΎΠ±ΡΠ°ΡΠ½ΡΠΌ ΠΏΡΠΎΠΊΡΠΈ)
request.env # "ΡΡΡΠΎΠΉ" env Ρ
Π΅Ρ, ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΠΉ Rack
end
ΠΠ΅ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΠΏΡΠΈΠΈ, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ <tt>script_name</tt> ΠΈΠ»ΠΈ <tt>path_info</tt> Π΄ΠΎΡΡΡΠΏΠ½Ρ Π΄Π»Ρ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ:
before { request.path_info = "/" }
get "/" do
"all requests end up here"
end
<tt>request.body</tt> ΡΠ²Π»ΡΠ΅ΡΡΡ IO ΠΈΠ»ΠΈ StringIO ΠΎΠ±ΡΠ΅ΠΊΡΠΎΠΌ:
post "/api" do
request.body.rewind # Π² ΡΠ»ΡΡΠ°Π΅, Π΅ΡΠ»ΠΈ ΠΊΡΠΎ-ΡΠΎ ΡΠΆΠ΅ ΠΏΡΠΎΡΠΈΡΠ°Π» ΡΠ΅Π»ΠΎ Π·Π°ΠΏΡΠΎΡΠ°
data = JSON.parse request.body.read
"Hello #{data['name']}!"
end
=== ΠΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠ΅ΡΠΎΠ΄ +attachment+, ΡΡΠΎΠ±Ρ ΡΠΊΠ°Π·Π°ΡΡ Π±ΡΠ°ΡΠ·Π΅ΡΡ, ΡΡΠΎ ΠΎΡΠ²Π΅Ρ
ΡΠ΅ΡΠ²Π΅ΡΠ° Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±ΡΡΡ ΡΠΎΡ
ΡΠ°Π½Π΅Π½ Π½Π° Π΄ΠΈΡΠΊ, Π° Π½Π΅ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½:
get '/' do
attachment
"store it!"
end
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠΊΠ°Π·Π°ΡΡ ΠΈΠΌΡ ΡΠ°ΠΉΠ»Π°:
get '/' do
attachment "info.txt"
"store it!"
end
=== ΠΠΎΠΈΡΠΊ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ²
ΠΠ»Ρ ΠΏΠΎΠΈΡΠΊΠ° ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² ΠΈ ΠΈΡ
ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠ΅Π³ΠΎ ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄ <tt>find_template</tt>:
find_template settings.views, 'foo', Tilt[:haml] do |file|
puts "could be #{file}"
end
ΠΡΠΎ Π½Π΅ ΡΠ»ΠΈΡΠΊΠΎΠΌ ΠΏΠΎΠ»Π΅Π·Π½ΡΠΉ ΠΏΡΠΈΠΌΠ΅Ρ. ΠΠ°ΡΠΎ ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΡΠΎΡ ΡΠ°ΠΊΡ, ΡΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΡ
ΡΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄, ΡΡΠΎΠ±Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ²ΠΎΠΉ ΡΠΎΠ±ΡΡΠ²Π΅Π½Π½ΡΠΉ ΠΌΠ΅Ρ
Π°Π½ΠΈΠ·ΠΌ ΠΏΠΎΠΈΡΠΊΠ°. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ Π²Ρ
Ρ
ΠΎΡΠΈΡΠ΅, ΡΡΠΎΠ±Ρ ΠΌΠΎΠΆΠ½ΠΎ Π±ΡΠ»ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΉ Ρ ΡΠ°Π±Π»ΠΎΠ½Π°ΠΌΠΈ:
set :views, ['views', 'templates']
helpers do
def find_template(views, name, engine, &block)
Array(views).each { |v| super(v, name, engine, &block) }
end
end
ΠΡΡΠ³ΠΎΠΉ ΠΏΡΠΈΠΌΠ΅Ρ, Π² ΠΊΠΎΡΠΎΡΠΎΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΡΡ ΡΠ°Π·Π½ΡΠ΅ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ Π΄Π»Ρ Π΄Π²ΠΈΠΆΠΊΠΎΠ² ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³Π°:
set :views, :sass => 'views/sass', :haml => 'templates', :default => 'views'
helpers do
def find_template(views, name, engine, &block)
_, folder = views.detect { |k,v| engine == Tilt[k] }
folder ||= views[:default]
super(folder, name, engine, &block)
end
end
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π»Π΅Π³ΠΊΠΎ Π²ΡΠ½Π΅ΡΡΠΈ ΡΡΠΎΡ ΠΊΠΎΠ΄ Π² ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠ΅ ΠΈ ΠΏΠΎΠ΄Π΅Π»ΠΈΡΡΡΡ ΠΈΠΌ Ρ ΠΎΡΡΠ°Π»ΡΠ½ΡΠΌΠΈ!
ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ <tt>find_template</tt> Π½Π΅ ΠΏΡΠΎΠ²Π΅ΡΡΠ΅Ρ, ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ Π»ΠΈ ΡΠ°ΠΉΠ» Π½Π° ΡΠ°ΠΌΠΎΠΌ Π΄Π΅Π»Π΅,
Π° Π²ΡΠ·ΡΠ²Π°Π΅Ρ Π·Π°Π΄Π°Π½Π½ΡΠΉ Π±Π»ΠΎΠΊ Π΄Π»Ρ Π²ΡΠ΅Ρ
Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΡΡ
ΠΏΡΡΠ΅ΠΉ. ΠΠ΅Π»ΠΎ ΡΡΡ Π½Π΅ Π² ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΠΈ,
Π΄Π΅Π»ΠΎ Π² ΡΠΎΠΌ, ΡΡΠΎ +render+ Π²ΡΠ·ΠΎΠ²Π΅Ρ +break+, ΠΊΠ°ΠΊ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΉΠ» Π½Π΅ Π±ΡΠ΄Π΅Ρ Π½Π°ΠΉΠ΄Π΅Π½.
Π‘ΠΎΠ΄Π΅ΡΠΆΠΈΠΌΠΎΠ΅ ΠΈ ΠΌΠ΅ΡΡΠΎΠ½Π°Ρ
ΠΎΠΆΠ΄Π΅Π½ΠΈΠ΅ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ² Π±ΡΠ΄Π΅Ρ Π·Π°ΠΊΡΡΠΈΡΠΎΠ²Π°Π½ΠΎ, Π΅ΡΠ»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡΡΠ΅Π½ΠΎ Π½Π΅
Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ (set :environment, :development). ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠΌΠ½ΠΈΡΡ ΠΎΠ± ΡΡΠΈΡ
Π½ΡΠ°Π½ΡΠ°Ρ
,
Π΅ΡΠ»ΠΈ ΠΏΠΈΡΠΈΡΠ΅ ΠΏΠΎ-Π½Π°ΡΡΠΎΡΡΠ΅ΠΌΡ "ΡΡΠΌΠ°ΡΡΠ΅Π΄ΡΠΈΠΉ" ΠΌΠ΅ΡΠΎΠ΄.
== ΠΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ
ΠΡΠΎΡ Π±Π»ΠΎΠΊ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΠΎΠ΄ΠΈΠ½ ΡΠ°Π· ΠΏΡΠΈ ΡΡΠ°ΡΡΠ΅ Π² Π»ΡΠ±ΠΎΠΌ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠΈ, ΡΠ΅ΠΆΠΈΠΌΠ΅ (environment):
configure do
# Π·Π°Π΄Π°Π½ΠΈΠ΅ ΠΎΠ΄Π½ΠΎΠΉ ΠΎΠΏΡΠΈΠΈ
set :option, 'value'
# ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΠΌ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΎΠΏΡΠΈΠΉ
set :a => 1, :b => 2
# ΡΠΎ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ΅, ΡΡΠΎ ΠΈ `set :option, true`
enable :option
# ΡΠΎ ΠΆΠ΅ ΡΠ°ΠΌΠΎΠ΅, ΡΡΠΎ ΠΈ `set :option, false`
disable :option
# Ρ Π²Π°Ρ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ "Π΄ΠΈΠ½Π°ΠΌΠΈΡΠ΅ΡΠΊΠΈΠ΅" ΠΎΠΏΡΠΈΠΈ Ρ Π±Π»ΠΎΠΊΠ°ΠΌΠΈ
set(:css_dir) { File.join(views, 'css') }
end
ΠΡΠ΄Π΅Ρ Π·Π°ΠΏΡΡΠ΅Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅ (RACK_ENV ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ) <tt>:production</tt>:
configure :production do
...
end
ΠΡΠ΄Π΅Ρ Π·Π°ΠΏΡΡΠ΅Π½ΠΎ, ΠΊΠΎΠ³Π΄Π° ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅ <tt>:production</tt> ΠΈΠ»ΠΈ <tt>:test</tt>:
configure :production, :test do
...
end
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΡΡΠΈΠΌ ΠΎΠΏΡΠΈΡΠΌ Ρ ΠΏΠΎΠΌΠΎΡΡΡ <tt>settings</tt>:
configure do
set :foo, 'bar'
end
get '/' do
settings.foo? # => true
settings.foo # => 'bar'
...
end
=== ΠΠΎΡΡΡΠΏΠ½ΡΠ΅ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ
[absolute_redirects] Π΅ΡΠ»ΠΈ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΎ, ΡΠΎ Sinatra Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΡΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅
ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΡΡ
ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΠΉ, Π½ΠΎ ΠΏΡΠΈ ΡΡΠΎΠΌ ΠΏΠ΅ΡΠ΅ΡΡΠ°Π½Π΅Ρ
ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΠΎΠ²Π°ΡΡ RFC 2616 (HTTP 1.1), ΠΊΠΎΡΠΎΡΡΠΉ ΡΠ°Π·ΡΠ΅ΡΠ°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ
Π°Π±ΡΠΎΠ»ΡΡΠ½ΡΠ΅ ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ.
ΠΠΊΠ»ΡΡΠ°ΠΉΡΠ΅ ΡΡΡ ΠΎΠΏΡΠΈΡ, Π΅ΡΠ»ΠΈ Π²Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π·Π° ΠΎΠ±ΡΠ°ΡΠ½ΡΠΌ ΠΏΡΠΎΠΊΡΠΈ,
ΠΊΠΎΡΠΎΡΡΠΉ Π½Π°ΡΡΡΠΎΠ΅Π½ Π½Π΅ ΡΠΎΠ²ΡΠ΅ΠΌ ΠΊΠΎΡΡΠ΅ΠΊΡΠ½ΠΎ. ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, ΠΌΠ΅ΡΠΎΠ΄ +url+
Π²ΡΠ΅ ΡΠ°Π²Π½ΠΎ Π±ΡΠ΄Π΅Ρ Π³Π΅Π½Π΅ΡΠΈΡΠΎΠ²Π°ΡΡ Π°Π±ΡΠΎΠ»ΡΡΠ½ΡΠ΅ URL, Π΅ΡΠ»ΠΈ Π²Ρ Π½Π΅ ΠΏΠ΅ΡΠ΅Π΄Π°Π΄ΠΈΡΠ΅
+false+ Π²ΡΠΎΡΡΠΌ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ.
ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΎ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
[add_charsets] mime-ΡΠΈΠΏΡ, ΠΊ ΠΊΠΎΡΠΎΡΡΠΌ ΠΌΠ΅ΡΠΎΠ΄ <tt>content_type</tt> Π±ΡΠ΄Π΅Ρ Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ
Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΡ ΠΎ ΠΊΠΎΠ΄ΠΈΡΠΎΠ²ΠΊΠ΅.
ΠΠ°ΠΌ ΡΠ»Π΅Π΄ΡΠ΅Ρ Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΊ ΡΡΠΎΠΉ ΠΎΠΏΡΠΈΠΈ Π²ΠΌΠ΅ΡΡΠΎ Π΅Π΅ ΠΏΠ΅ΡΠ΅ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ:
settings.add_charsets << "application/foobar"
[app_file] Π³Π»Π°Π²Π½ΡΠΉ ΡΠ°ΠΉΠ» ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π΄Π»Ρ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈΡ ΠΊΠΎΡΠ½Π΅Π²ΠΎΠΉ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ
ΠΏΡΠΎΠ΅ΠΊΡΠ°, Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΉ Ρ ΡΠ°Π±Π»ΠΎΠ½Π°ΠΌΠΈ ΠΈ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠΌΠΈ ΡΠ°ΠΉΠ»Π°ΠΌΠΈ, Π²Π»ΠΎΠΆΠ΅Π½Π½ΡΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ².
[bind] ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌΡΠΉ IP-Π°Π΄ΡΠ΅Ρ (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: 0.0.0.0). ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ
Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ.
[default_encoding] ΠΊΠΎΠ΄ΠΈΡΠΎΠ²ΠΊΠ°, Π΅ΡΠ»ΠΈ Π½Π΅ΠΈΠ·Π²Π΅ΡΡΠ½Π° (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: <tt>"utf-8"</tt>).
[dump_errors] ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡ ΠΎΡΠΈΠ±ΠΊΠΈ Π² Π»ΠΎΠ³Π΅.
[environment] ΡΠ΅ΠΊΡΡΠ΅Π΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ, Π·Π½Π°ΡΠ΅Π½ΠΈΠ΅ <tt>ENV['RACK_ENV']</tt>
ΠΈΠ»ΠΈ <tt>"development"</tt>, Π΅ΡΠ»ΠΈ <tt>ENV['RACK_ENV']</tt> Π½Π΅ Π΄ΠΎΡΡΡΠΏΠ½Π°.
[logging] ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΠΎΠ³Π΅Ρ.
[lock] ΡΠΎΠ·Π΄Π°Π΅Ρ Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ Π΄Π»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ°, ΠΊΠΎΡΠΎΡΠ°Ρ Π³Π°ΡΠ°Π½ΡΠΈΡΡΠ΅Ρ ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΡ
ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄Π½ΠΎΠ³ΠΎ Π·Π°ΠΏΡΠΎΡΠ° Π² ΡΠ΅ΠΊΡΡΠΈΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π² Ruby ΠΏΡΠΎΡΠ΅ΡΡΠ΅.
ΠΠΊΠ»ΡΡΠ°ΠΉΡΠ΅, Π΅ΡΠ»ΠΈ Π²Π°ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π΅ ΠΏΠΎΡΠΎΠΊΠΎ-Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΠΎ (thread-safe).
ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΎ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
[method_override] ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ "ΠΌΠ°Π³ΠΈΡΠ΅ΡΠΊΠΈΠΉ" ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ <tt>_method</tt>, ΡΡΠΎΠ±Ρ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈΡΡ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ PUT/DELETE ΡΠΎΡΠΌ Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ°Ρ
, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡ
ΡΡΠΈ ΠΌΠ΅ΡΠΎΠ΄Ρ.
[port] ΠΏΠΎΡΡ, Π½Π° ΠΊΠΎΡΠΎΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ ΡΠ°Π±ΠΎΡΠ°ΡΡ ΡΠ΅ΡΠ²Π΅Ρ. ΠΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ
Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΌ ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ.
[prefixed_redirects] Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΈΠ»ΠΈ Π½Π΅Ρ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡ <tt>request.script_name</tt> ΠΊ ΡΠ΅Π΄ΠΈΡΠ΅ΠΊΡΠ°ΠΌ,
Π΅ΡΠ»ΠΈ Π½Π΅ Π·Π°Π΄Π°Π½ Π°Π±ΡΠΎΠ»ΡΡΠ½ΡΠΉ ΠΏΡΡΡ. Π’Π°ΠΊΠΈΠΌ ΠΎΠ±ΡΠ°Π·ΠΎΠΌ, <tt>redirect '/foo'</tt>
Π±ΡΠ΄Π΅Ρ Π²Π΅ΡΡΠΈ ΡΠ΅Π±Ρ ΠΊΠ°ΠΊ <tt>redirect to('/foo')</tt>. ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΎ ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ.
[public_folder] Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ, ΠΎΡΠΊΡΠ΄Π° Π±ΡΠ΄ΡΡ ΡΠ°Π·Π΄Π°Π²Π°ΡΡΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ.
[reload_templates] ΠΏΠ΅ΡΠ΅Π·Π°Π³ΡΡΠΆΠ°ΡΡ ΠΈΠ»ΠΈ Π½Π΅Ρ ΡΠ°Π±Π»ΠΎΠ½Ρ Π½Π° ΠΊΠ°ΠΆΠ΄ΡΠΉ Π·Π°ΠΏΡΠΎΡ.
ΠΠΊΠ»ΡΡΠ΅Π½ΠΎ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅ ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ.
[root] ΠΊΠΎΡΠ½Π΅Π²Π°Ρ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ ΠΏΡΠΎΠ΅ΠΊΡΠ°.
[raise_errors] Π²ΡΠ±ΡΠ°ΡΡΠ²Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ (Π±ΡΠ΄Π΅Ρ ΠΎΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅).
[run] Π΅ΡΠ»ΠΈ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ, Sinatra Π±ΡΠ΄Π΅Ρ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ Π²Π΅Π±-ΡΠ΅ΡΠ²Π΅Ρ.
ΠΠ΅ Π²ΠΊΠ»ΡΡΠ°ΠΉΡΠ΅, Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ rackup ΠΈΠ»ΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΡΠ΅ ΡΡΠ΅Π΄ΡΡΠ²Π°.
[running] ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π»ΠΈ ΡΠ΅ΠΉΡΠ°Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ?
ΠΠ΅ ΠΌΠ΅Π½ΡΠΉΡΠ΅ ΡΡΡ ΠΎΠΏΡΠΈΡ!
[server] ΡΠ΅ΡΠ²Π΅Ρ ΠΈΠ»ΠΈ ΡΠΏΠΈΡΠΎΠΊ ΡΠ΅ΡΠ²Π΅ΡΠΎΠ², ΠΊΠΎΡΠΎΡΡΠ΅ ΡΠ»Π΅Π΄ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅
Π²ΡΡΡΠΎΠ΅Π½Π½ΠΎΠ³ΠΎ ΡΠ΅ΡΠ²Π΅ΡΠ°. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ: ['thin', 'mongrel', 'webrick'],
ΠΏΠΎΡΡΠ΄ΠΎΠΊ Π·Π°Π΄Π°Π΅Ρ ΠΏΡΠΈΠΎΡΠΈΡΠ΅Ρ.
[sessions] Π²ΠΊΠ»ΡΡΠΈΡΡ ΡΠ΅ΡΡΠΈΠΈ Π½Π° ΠΎΡΠ½ΠΎΠ²Π΅ ΠΊΡΠΊ (cookie).
[show_exceptions] ΠΏΠΎΠΊΠ°Π·ΡΠ²Π°ΡΡ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡ/ΡΡΠ΅ΠΊ Π²ΡΠ·ΠΎΠ²ΠΎΠ² (stack trace) Π² Π±ΡΠ°ΡΠ·Π΅ΡΠ΅.
[static] Π΄ΠΎΠ»ΠΆΠ½Π° Π»ΠΈ Sinatra ΠΎΡΡΡΠ΅ΡΡΠ²Π»ΡΡΡ ΡΠ°Π·Π΄Π°ΡΡ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΡΠ°ΠΉΠ»ΠΎΠ².
ΠΡΠΊΠ»ΡΡΠΈΡΠ΅, ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ ΠΊΠ°ΠΊΠΎΠΉ-Π»ΠΈΠ±ΠΎ Π²Π΅Π±-ΡΠ΅ΡΠ²Π΅Ρ Π΄Π»Ρ ΡΡΠΎΠΉ ΡΠ΅Π»ΠΈ.
ΠΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π·Π½Π°ΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΡΠ»ΡΡΡΠΈΡ ΠΏΡΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡΠ΅Π»ΡΠ½ΠΎΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ.
ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π²ΠΊΠ»ΡΡΠ΅Π½ΠΎ Π² ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΈ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΎ Π² ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΡ
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡΡ
.
[static_cache_control] ΠΠΎΠ³Π΄Π° Sinatra ΠΎΡΠ΄Π°Π΅Ρ ΡΡΠ°ΡΠΈΡΠ΅ΡΠΊΠΈΠ΅ ΡΠ°ΠΉΠ»Ρ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΡΡΡ ΠΎΠΏΡΠΈΡ,
ΡΡΠΎΠ±Ρ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΈΠΌ Π·Π°Π³ΠΎΠ»ΠΎΠ²ΠΎΠΊ <tt>Cache-Control</tt>. ΠΠ»Ρ ΡΡΠΎΠ³ΠΎ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ +cache_control+. ΠΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΎΡΠΊΠ»ΡΡΠ΅Π½ΠΎ.
ΠΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ ΠΌΠ°ΡΡΠΈΠ², ΠΊΠΎΠ³Π΄Π° Π½Π°Π΄ΠΎ Π·Π°Π΄Π°ΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ Π·Π½Π°ΡΠ΅Π½ΠΈΠΉ:
<tt>set :static_cache_control, [:public, :max_age => 300]</tt>
[views] Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡ Ρ ΡΠ°Π±Π»ΠΎΠ½Π°ΠΌΠΈ.
== ΠΠ±ΡΠ°Π±ΠΎΡΠΊΠ° ΠΎΡΠΈΠ±ΠΎΠΊ
ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ ΠΈΡΠΏΠΎΠ»Π½ΡΡΡΡΡ Π² ΡΠΎΠΌ ΠΆΠ΅ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅, ΡΡΠΎ ΠΈ ΠΌΠ°ΡΡΡΡΡΡ, ΠΈ +before+-ΡΠΈΠ»ΡΡΡΡ, Π° ΡΡΠΎ ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ Π²ΡΡΠΊΠΈΠ΅
ΠΏΡΠ΅Π»Π΅ΡΡΠΈ Π²ΡΠΎΠ΄Π΅ <tt>haml</tt>, <tt>erb</tt>, <tt>halt</tt> ΠΈ Ρ.Π΄. Π΄ΠΎΡΡΡΠΏΠ½Ρ ΠΈ ΠΈΠΌ.
=== Not Found
ΠΠΎΠ³Π΄Π° Π²ΡΠ±ΡΠΎΡΠ΅Π½ΠΎ ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ <tt>Sinatra::NotFound</tt>, ΠΈΠ»ΠΈ ΠΊΠΎΠ΄ΠΎΠΌ ΠΎΡΠ²Π΅ΡΠ° ΡΠ²Π»ΡΠ΅ΡΡΡ 404,
ΡΠΎ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½ <tt>not_found</tt> ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ:
not_found do
'This is nowhere to be found.'
end
=== ΠΡΠΈΠ±ΠΊΠΈ
ΠΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΎΡΠΈΠ±ΠΎΠΊ +error+ Π±ΡΠ΄Π΅Ρ Π²ΡΠ·Π²Π°Π½, ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π²ΡΠ±ΡΠΎΡΠ΅Π½ΠΎ ΠΈΠ· Π±Π»ΠΎΠΊΠ° ΠΌΠ°ΡΡΡΡΡΠ°, Π»ΠΈΠ±ΠΎ ΠΈΠ· ΡΠΈΠ»ΡΡΡΠ°.
ΠΠ±ΡΠ΅ΠΊΡ-ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΠ΅ Π΄ΠΎΡΡΡΠΏΠ΅Π½ ΠΊΠ°ΠΊ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½Π°Ρ <tt>sinatra.error</tt> Π² Rack:
error do
'Sorry there was a nasty error - ' + env['sinatra.error'].name
end
Π§Π°ΡΡΠ½ΡΠ΅ ΠΎΡΠΈΠ±ΠΊΠΈ:
error MyCustomError do
'So what happened was...' + env['sinatra.error'].message
end
Π’ΠΎΠ³Π΄Π°, Π΅ΡΠ»ΠΈ ΡΡΠΎ ΠΏΡΠΎΠΈΠ·ΠΎΡΠ»ΠΎ:
get '/' do
raise MyCustomError, 'something bad'
end
Π’ΠΎ Π²Ρ ΠΏΠΎΠ»ΡΡΠΈΡΠ΅:
So what happened was... something bad
Π’Π°ΠΊΠΆΠ΅ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΡ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊ ΠΎΡΠΈΠ±ΠΎΠΊ Π΄Π»Ρ ΠΊΠΎΠ΄Π° ΡΠΎΡΡΠΎΡΠ½ΠΈΡ HTTP:
error 403 do
'Access forbidden'
end
get '/secret' do
403
end
ΠΠΈΠ±ΠΎ Π½Π°Π±ΠΎΡΠ° ΠΊΠΎΠ΄ΠΎΠ²:
error 400..510 do
'Boom'
end
Sinatra ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅Ρ ΡΠΏΠ΅ΡΠΈΠ°Π»ΡΠ½ΡΠ΅ <tt>not_found</tt> ΠΈ <tt>error</tt> ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ, ΠΊΠΎΠ³Π΄Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π°ΠΏΡΡΠ΅Π½ΠΎ Π² ΡΠ΅ΠΆΠΈΠΌΠ΅
ΡΠ°Π·ΡΠ°Π±ΠΎΡΠΊΠΈ (ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΠ΅ <tt>:development</tt>).
== Rack "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ"
Sinatra ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Rack[http://rack.rubyforge.org/], ΠΌΠΈΠ½ΠΈΠΌΠ°Π»ΡΠ½ΡΠΉ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΉ
ΠΈΠ½ΡΠ΅ΡΡΠ΅ΠΉΡ Π΄Π»Ρ Π²Π΅Π±-ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠΎΠ² Π½Π° Ruby. ΠΠ΄Π½ΠΎΠΉ ΠΈΠ· ΡΠ°ΠΌΡΡ
ΠΈΠ½ΡΠ΅ΡΠ΅ΡΠ½ΡΡ
Π΄Π»Ρ ΡΠ°Π·ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΎΠ² Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΠ΅ΠΉ Rack
ΡΠ²Π»ΡΠ΅ΡΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° "ΠΏΡΠΎΡΠ»ΠΎΠ΅ΠΊ" ("middleware") β ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ²,
Π½Π°Ρ
ΠΎΠ΄ΡΡΠΈΡ
ΡΡ "ΠΌΠ΅ΠΆΠ΄Ρ" ΡΠ΅ΡΠ²Π΅ΡΠΎΠΌ ΠΈ Π²Π°ΡΠΈΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ, ΠΊΠΎΡΠΎΡΡΠ΅ ΠΎΡΡΠ»Π΅ΠΆΠΈΠ²Π°ΡΡ ΠΈ/ΠΈΠ»ΠΈ ΠΌΠ°Π½ΠΈΠΏΡΠ»ΠΈΡΡΡΡ
HTTP Π·Π°ΠΏΡΠΎΡΠ°ΠΌΠΈ/ΠΎΡΠ²Π΅ΡΠ°ΠΌΠΈ Π΄Π»Ρ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»Π΅Π½ΠΈΡ ΡΠ°Π·Π»ΠΈΡΠ½ΠΎΠΉ ΡΡΠ½ΠΊΡΠΈΠΎΠ½Π°Π»ΡΠ½ΠΎΡΡΠΈ.
Π Sinatra ΠΎΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΠΊΠΈΠ΅ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ" Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π° +use+:
require 'sinatra'
require 'my_custom_middleware'
use Rack::Lint
use MyCustomMiddleware
get '/hello' do
'Hello World'
end
Π‘Π΅ΠΌΠ°Π½ΡΠΈΠΊΠ° +use+ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½Π° ΡΠΎΠΉ, ΡΡΠΎ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π° Π΄Π»Ρ
Rack::Builder[http://rack.rubyforge.org/doc/classes/Rack/Builder.html] DSL
(ΡΠ°ΡΠ΅ Π²ΡΠ΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΡΡ Π² rackup ΡΠ°ΠΉΠ»Π°Ρ
). ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΌΠ΅ΡΠΎΠ΄ +use+ ΠΏΡΠΈΠ½ΠΈΠΌΠ°Π΅Ρ
ΠΊΠ°ΠΊ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²Π΅Π½Π½ΡΠ΅ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅, ΡΠ°ΠΊ ΠΈ Π±Π»ΠΎΠΊΠΈ:
use Rack::Auth::Basic do |username, password|
username == 'admin' && password == 'secret'
end
Rack ΡΠ°ΡΠΏΡΠΎΡΡΡΠ°Π½ΡΠ΅ΡΡΡ Ρ ΡΠ°Π·Π»ΠΈΡΠ½ΡΠΌΠΈ ΡΡΠ°Π½Π΄Π°ΡΡΠ½ΡΠΌΠΈ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠ°ΠΌΠΈ"
Π΄Π»Ρ Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΎΡΠ»Π°Π΄ΠΊΠΈ, ΠΌΠ°ΡΡΡΡΡΠΈΠ·Π°ΡΠΈΠΈ URL, Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ, ΠΎΠ±ΡΠ°Π±ΠΎΡΠΊΠΈ ΡΠ΅ΡΡΠΈΠΉ. Sinatra ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ
ΠΌΠ½ΠΎΠ³ΠΈΠ΅ ΠΈΠ· ΡΡΠΈΡ
ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ² Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ, ΠΎΡΠ½ΠΎΠ²ΡΠ²Π°ΡΡΡ Π½Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ, ΡΡΠΎΠ±Ρ Π²Π°ΠΌ Π½Π΅ ΠΏΡΠΈΡ
ΠΎΠ΄ΠΈΠ»ΠΎΡΡ
ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡ (+use+) ΠΈΡ
Π²ΡΡΡΠ½ΡΡ.
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π½Π°ΠΉΡΠΈ ΠΏΠΎΠ»Π΅Π·Π½ΡΠ΅ ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ Π²
{rack}[https://github.com/rack/rack/tree/master/lib/rack],
{rack-contrib}[https://github.com/rack/rack-contrib#readme],
{CodeRack}[http://coderack.org/] ΠΈΠ»ΠΈ Π²
{Rack wiki}[https://github.com/rack/rack/wiki/List-of-Middleware].
== Π’Π΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅
Π’Π΅ΡΡΡ Π΄Π»Ρ Sinatra ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π½Π°ΠΏΠΈΡΠ°Π½Ρ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ, ΡΡΠ΅ΠΉΠΌΠ²ΠΎΡΠΊΠΎΠ², ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΠΈΡ
ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅ Rack. {Rack::Test}[http://rdoc.info/github/brynary/rack-test/master/frames] ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½:
require 'my_sinatra_app'
require 'test/unit'
require 'rack/test'
class MyAppTest < Test::Unit::TestCase
include Rack::Test::Methods
def app
Sinatra::Application
end
def test_my_default
get '/'
assert_equal 'Hello World!', last_response.body
end
def test_with_params
get '/meet', :name => 'Frank'
assert_equal 'Hello Frank!', last_response.body
end
def test_with_rack_env
get '/', {}, 'HTTP_USER_AGENT' => 'Songbird'
assert_equal "You're using Songbird!", last_response.body
end
end
== Sinatra::Base β "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ", Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ ΠΈ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
ΠΠΏΠΈΡΠ°Π½ΠΈΠ΅ ΡΠ²ΠΎΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΡΠ°ΠΌΡΠΌ ΠΏΡΠΎΡΡΠ΅ΠΉΡΠΈΠΌ ΡΠΏΠΎΡΠΎΠ±ΠΎΠΌ (Ρ ΠΏΠΎΠΌΠΎΡΡΡ DSL Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ,
ΠΊΠ°ΠΊ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ°Ρ
Π²ΡΡΠ΅) ΠΎΡΠ»ΠΈΡΠ½ΠΎ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π΄Π»Ρ ΠΊΡΠΎΡ
ΠΎΡΠ½ΡΡ
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ. Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅,
ΡΠ°ΠΊΠΎΠΉ ΠΌΠ΅ΡΠΎΠ΄ ΠΈΠΌΠ΅Π΅Ρ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠΎΠ² ΠΏΡΠΈ ΡΠΎΠ·Π΄Π°Π½ΠΈΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠΎΠ², ΡΠ°ΠΊΠΈΡ
ΠΊΠ°ΠΊ
Rack middleware ("ΠΏΡΠΎΡΠ»ΠΎΠ΅ΠΊ"), Rails metal, ΠΏΡΠΎΡΡΡΡ
Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊ Ρ ΡΠ΅ΡΠ²Π΅ΡΠ½ΡΠΌΠΈ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΠ°ΠΌΠΈ,
ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΉ Sinatra.
DSL Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ "Π·Π°Π³ΡΡΠ·Π½ΡΠ΅Ρ" ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΠ΅Π½ <tt>Object</tt> ΠΈ ΠΏΠΎΠ΄ΡΠ°Π·ΡΠΌΠ΅Π²Π°Π΅Ρ ΡΡΠΈΠ»Ρ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ
ΠΌΠΈΠΊΡΠΎ-ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅Π΄ΠΈΠ½ΡΠΉ ΡΠ°ΠΉΠ» ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, <tt>./public</tt> ΠΈ
<tt>./views</tt> Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ, Π»ΠΎΠ³ΠΈΡΠΎΠ²Π°Π½ΠΈΠ΅, ΡΡΡΠ°Π½ΠΈΡΡ Π΄Π΅ΡΠ°Π»Π΅ΠΉ ΠΎΠ± ΠΈΡΠΊΠ»ΡΡΠ΅Π½ΠΈΡΡ
ΠΈ Ρ.Π΄.). Π ΡΡΡ Π½Π° ΠΏΠΎΠΌΠΎΡΡ ΠΏΡΠΈΡ
ΠΎΠ΄ΠΈΡ <tt>Sinatra::Base</tt>:
require 'sinatra/base'
class MyApp < Sinatra::Base
set :sessions, true
set :foo, 'bar'
get '/' do
'Hello world!'
end
end
ΠΠ΅ΡΠΎΠ΄Ρ, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅ <tt>Sinatra::Base</tt> ΠΏΠΎΠ΄ΠΊΠ»Π°ΡΡΠ°ΠΌ ΠΈΠ΄Π΅Π½ΡΠΈΡΠ½Ρ ΡΠ΅ΠΌ, ΡΡΠΎ Π΄ΠΎΡΡΡΠΏΠ½Ρ
Π² DSL Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ. ΠΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ
ΠΊΠΎΠ½Π²Π΅ΡΡΠΈΡΠΎΠ²Π°Π½Ρ Π² <tt>Sinatra::Base</tt> ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½ΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Π΄Π²ΡΡ
ΠΌΠΎΠ΄ΠΈΡΠΈΠΊΠ°ΡΠΈΠΉ:
* ΠΡ Π΄ΠΎΠ»ΠΆΠ½Ρ ΠΏΠΎΠ΄ΠΊΠ»ΡΡΠ°ΡΡ <tt>sinatra/base</tt> Π²ΠΌΠ΅ΡΡΠΎ +sinatra+,
ΠΈΠ½Π°ΡΠ΅ Π²ΡΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Π»ΡΠ΅ΠΌΡΠ΅ Sinatra, Π±ΡΠ΄ΡΡ ΠΈΠΌΠΏΠΎΡΡΠΈΡΠΎΠ²Π°Π½Ρ Π² Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΠΎΠ΅ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΠ΅Π½.
* ΠΠΎΠΌΠ΅ΡΡΠΈΡΠ΅ Π²ΡΠ΅ ΠΌΠ°ΡΡΡΡΡΡ, ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠΈ ΠΎΡΠΈΠ±ΠΎΠΊ, ΡΠΈΠ»ΡΡΡΡ ΠΈ ΠΎΠΏΡΠΈΠΈ Π² ΠΏΠΎΠ΄ΠΊΠ»Π°ΡΡ <tt>Sinatra::Base</tt>.
<tt>Sinatra::Base</tt> β ΡΡΠΎ ΡΠΈΡΡΡΠΉ Π»ΠΈΡΡ. ΠΠΎΠ»ΡΡΠΈΠ½ΡΡΠ²ΠΎ ΠΎΠΏΡΠΈΠΉ, Π²ΠΊΠ»ΡΡΠ°Ρ Π²ΡΡΡΠΎΠ΅Π½Π½ΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ, ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ ΠΎΡΠΊΠ»ΡΡΠ΅Π½Ρ.
Π‘ΠΌΠΎΡΡΠΈΡΠ΅ {ΠΠΏΡΠΈΠΈ ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ}[http://www.sinatrarb.com/configuration.html] Π΄Π»Ρ Π΄Π΅ΡΠ°Π»ΡΠ½ΠΎΠΉ ΠΈΠ½ΡΠΎΡΠΌΠ°ΡΠΈΠΈ
ΠΎΠ± ΠΎΠΏΡΠΈΡΡ
ΠΈ ΠΈΡ
ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠΈ.
=== ΠΠΎΠ΄ΡΠ»ΡΠ½ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΏΡΠΎΡΠΈΠ² ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΠΎΠΏΡΠ΅ΠΊΠΈ Π²ΡΠ΅ΠΎΠ±ΡΠ΅ΠΌΡ ΡΠ±Π΅ΠΆΠ΄Π΅Π½ΠΈΡ, Π² ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠΌ ΡΡΠΈΠ»Π΅ (ΡΠ°ΠΌΠΎΠΌ ΠΏΡΠΎΡΡΠΎΠΌ) Π½Π΅Ρ Π½ΠΈΡΠ΅Π³ΠΎ ΠΏΠ»ΠΎΡ
ΠΎΠ³ΠΎ.
ΠΡΠ»ΠΈ ΡΡΠΎΡ ΡΡΠΈΠ»Ρ ΠΏΠΎΠ΄Ρ
ΠΎΠ΄ΠΈΡ Π²Π°ΡΠ΅ΠΌΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, Π²Ρ Π½Π΅ ΠΎΠ±ΡΠ·Π°Π½Ρ ΠΏΠ΅ΡΠ΅ΠΏΠΈΡΡΠ²Π°ΡΡ Π΅Π³ΠΎ Π² ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΠΎΠ΅
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅.
Π£ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΎΠ³ΠΎ ΡΡΠΈΠ»Ρ Π΅ΡΡΡ Π²ΡΠ΅Π³ΠΎ Π΄Π²Π° Π½Π΅Π΄ΠΎΡΡΠ°ΡΠΊΠ° ΠΎΡΠ½ΠΎΡΠΈΡΠ΅Π»ΡΠ½ΠΎ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΠΎΠ³ΠΎ:
* Π£ Π²Π°Ρ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄Π½ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Sinatra Π½Π° ΠΎΠ΄ΠΈΠ½ Ruby ΠΏΡΠΎΡΠ΅ΡΡ. ΠΡΠ»ΠΈ Π²Ρ ΠΏΠ»Π°Π½ΠΈΡΡΠ΅ΡΠ΅
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π±ΠΎΠ»ΡΡΠ΅, ΡΠΎ ΠΏΠ΅ΡΠ΅ΠΊΠ»ΡΡΠ°ΠΉΡΠ΅ΡΡ Π½Π° ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠΉ ΡΡΠΈΠ»Ρ.
* ΠΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡΡΠΈΠ΅ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΡΠΈΠ»Ρ, Π΄ΠΎΠ±Π°Π²Π»ΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΊ Object. ΠΡΠ»ΠΈ Π²Ρ
ΠΏΠ»Π°Π½ΠΈΡΡΠ΅ΡΠ΅ ΠΏΠΎΡΡΠ°Π²Π»ΡΡΡ ΡΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π² Π²ΠΈΠ΄Π΅ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ/gem, ΡΠΎ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ΠΈΡΠ΅
Π½Π° ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠΉ ΡΡΠΈΠ»Ρ.
ΠΠ΅ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ ΠΏΡΠΈΡΠΈΠ½, ΠΏΠΎ ΠΊΠΎΡΠΎΡΡΠΌ Π²Ρ Π½Π΅ ΠΌΠΎΠ³Π»ΠΈ Π±Ρ ΡΠΌΠ΅ΡΠΈΠ²Π°ΡΡ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠΉ ΠΈ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΡΡΠΈΠ»ΠΈ.
ΠΠ΅ΡΠ΅Ρ
ΠΎΠ΄Ρ Ρ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΡΡΠΈΠ»Ρ Π½Π° Π΄ΡΡΠ³ΠΎΠΉ, ΠΏΡΠΈΠΌΠΈΡΠ΅ Π²ΠΎ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅ ΡΠ»Π΅Π΄ΡΡΡΠΈΠ΅ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½ΠΈΡ Π² Π½Π°ΡΡΡΠΎΠΉΠΊΠ°Ρ
:
ΠΠΏΡΠΈΡ ΠΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΠΉ ΠΠΎΠ΄ΡΠ»ΡΠ½ΡΠΉ
app_file ΡΠ°ΠΉΠ» Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ ΡΠ°ΠΉΠ» Ρ ΠΏΠΎΠ΄ΠΊΠ»Π°ΡΡΠΎΠΌ Sinatra::Base
run $0 == app_file false
logging true false
method_override true false
inline_templates true false
static true false
=== ΠΠ°ΠΏΡΡΠΊ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΡ
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ
ΠΡΡΡ Π΄Π²Π° ΠΎΠ±ΡΠ΅ΠΏΡΠΈΠ½ΡΡΡΡ
ΡΠΏΠΎΡΠΎΠ±Π° Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ: Π·Π°ΠΏΡΡΠΊ Π½Π°ΠΏΡΡΠΌΡΡ Ρ ΠΏΠΎΠΌΠΎΡΡΡ <tt>run!</tt>:
# my_app.rb
require 'sinatra/base'
class MyApp < Sinatra::Base
# ... Π·Π΄Π΅ΡΡ ΠΊΠΎΠ΄ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ...
# Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ ΡΠ΅ΡΠ²Π΅Ρ, Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»Π½ΡΠ΅ΡΡΡ ΡΠ΅ΠΊΡΡΠΈΠΉ ΡΠ°ΠΉΠ»
run! if app_file == $0
end
Π Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ Ρ ΠΏΠΎΠΌΠΎΡΡΡ:
ruby my_app.rb
ΠΠ»ΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠ³ΠΎ ΡΠ°ΠΉΠ»Π° <tt>config.ru</tt>, ΠΊΠΎΡΠΎΡΡΠΉ ΠΏΠΎΠ·Π²ΠΎΠ»ΡΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π»ΡΠ±ΠΎΠΉ
Rack-ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΠΉ ΡΠ΅ΡΠ²Π΅Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ.
# config.ru
require './my_app'
run MyApp
ΠΠ°ΠΏΡΡΠΊΠ°Π΅ΠΌ:
rackup -p 4567
=== ΠΠ°ΠΏΡΡΠΊ ΠΊΠ»Π°ΡΡΠΈΡΠ΅ΡΠΊΠΈΡ
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ Ρ config.ru
Π€Π°ΠΉΠ» ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ:
# app.rb
require 'sinatra'
get '/' do
'Hello world!'
end
Π ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΡΡΠΈΠΉ <tt>config.ru</tt>:
require './app'
run Sinatra::Application
=== ΠΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ config.ru?
ΠΠΎΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΏΡΠΈΡΠΈΠ½, ΠΏΠΎ ΠΊΠΎΡΠΎΡΡΠΌ Π²Ρ, Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, Π·Π°Ρ
ΠΎΡΠΈΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ <tt>config.ru</tt>:
* Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ ΡΠ°Π·Π²ΠΎΡΠ°ΡΠΈΠ²Π°ΡΡ ΡΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° ΡΠ°Π·Π»ΠΈΡΠ½ΡΡ
Rack-ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡΡ
ΡΠ΅ΡΠ²Π΅ΡΠ°Ρ
(Passenger, Unicorn,
Heroku, ...);
* Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Π±ΠΎΠ»Π΅Π΅ ΠΎΠ΄Π½ΠΎΠ³ΠΎ ΠΏΠΎΠ΄ΠΊΠ»Π°ΡΡΠ° <tt>Sinatra::Base</tt>;
* Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Sinatra ΡΠΎΠ»ΡΠΊΠΎ Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ" Rack.
<b>Π‘ΠΎΠ²ΡΠ΅ΠΌ Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΏΠ΅ΡΠ΅Ρ
ΠΎΠ΄ΠΈΡΡ Π½Π° ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ <tt>config.ru</tt> Π»ΠΈΡΡ ΠΏΠΎΡΠΎΠΌΡ, ΡΡΠΎ Π²Ρ ΡΡΠ°Π»ΠΈ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠΉ ΡΡΠΈΠ»Ρ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ. Π Π½Π΅ΠΎΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΠΎ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΠΌΠΎΠ΄ΡΠ»ΡΠ½ΡΠΉ ΡΡΠΈΠ»Ρ, ΡΡΠΎΠ±Ρ
Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ <tt>config.ru</tt>.</b>
=== ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ Sinatra Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ"
ΠΠ΅ ΡΠΎΠ»ΡΠΊΠΎ ΡΠ°ΠΌΠ° Sinatra ΠΌΠΎΠΆΠ΅Ρ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ" Rack, Π½ΠΎ ΠΈ Π»ΡΠ±ΠΎΠ΅ Sinatra ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅
ΡΠ°ΠΌΠΎ ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΎ ΠΊ Π»ΡΠ±ΠΎΠΌΡ Rack endpoint Π² ΠΊΠ°ΡΠ΅ΡΡΠ²Π΅ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠΈ". ΠΡΠΈΠΌ endpoint (ΠΊΠΎΠ½Π΅ΡΠ½ΠΎΠΉ ΡΠΎΡΠΊΠΎΠΉ)
ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ Π΄ΡΡΠ³ΠΎΠ΅ Sinatra ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΈΠ»ΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΎΡΠ½ΠΎΠ²Π°Π½Π½ΠΎΠ΅ Π½Π° Rack (Rails/Ramaze/Camping/...):
require 'sinatra/base'
class LoginScreen < Sinatra::Base
enable :sessions
get('/login') { haml :login }
post('/login') do
if params[:name] == 'admin' && params[:password] == 'admin'
session['user_name'] = params[:name]
else
redirect '/login'
end
end
end
class MyApp < Sinatra::Base
# "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΠ°" Π±ΡΠ΄Π΅Ρ Π·Π°ΠΏΡΡΠ΅Π½Π° ΠΏΠ΅ΡΠ΅Π΄ ΡΠΈΠ»ΡΡΡΠ°ΠΌΠΈ
use LoginScreen
before do
unless session['user_name']
halt "Access denied, please <a href='/login'>login</a>."
end
end
get('/') { "Hello #{session['user_name']}." }
end
=== Π‘ΠΎΠ·Π΄Π°Π½ΠΈΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠΉ "Π½Π° Π»Π΅ΡΡ"
ΠΠ½ΠΎΠ³Π΄Π° ΡΡΠ΅Π±ΡΠ΅ΡΡΡ ΡΠΎΠ·Π΄Π°Π²Π°ΡΡ Sinatra ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ "Π½Π° Π»Π΅ΡΡ" (Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ,
ΠΈΠ· Π΄ΡΡΠ³ΠΎΠ³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ). ΠΡΠΎ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ <tt>Sinatra.new</tt>:
require 'sinatra/base'
my_app = Sinatra.new { get('/') { "hi" } }
my_app.run!
ΠΡΠΎΡ ΠΌΠ΅ΡΠΎΠ΄ ΠΌΠΎΠΆΠ΅Ρ ΠΏΡΠΈΠ½ΠΈΠΌΠ°ΡΡ Π°ΡΠ³ΡΠΌΠ΅Π½ΡΠΎΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅, ΠΎΡ ΠΊΠΎΡΠΎΡΠΎΠ³ΠΎ
ΡΠ»Π΅Π΄ΡΠ΅Ρ Π½Π°ΡΠ»Π΅Π΄ΠΎΠ²Π°ΡΡΡΡ:
# config.ru
require 'sinatra/base'
controller = Sinatra.new do
enable :logging
helpers MyHelpers
end
map('/a') do
run Sinatra.new(controller) { get('/') { 'a' } }
end
map('/b') do
run Sinatra.new(controller) { get('/') { 'b' } }
end
ΠΡΠΎ ΠΎΡΠΎΠ±Π΅Π½Π½ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ Π΄Π»Ρ ΡΠ΅ΡΡΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΉ Sinatra ΠΈ ΠΏΡΠΈ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Sinatra Π²Π½ΡΡΡΠΈ Π²Π°ΡΠ΅ΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ.
ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ ΡΡΠΎΠΌΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ Sinatra ΠΊΠ°ΠΊ "ΠΏΡΠΎΡΠ»ΠΎΠΉΠΊΡ" ΠΎΡΠ΅Π½Ρ ΠΏΡΠΎΡΡΠΎ:
require 'sinatra/base'
use Sinatra do
get('/') { ... }
end
run RailsProject::Application
== ΠΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΈ ΠΏΡΠΈΠ²ΡΠ·ΠΊΠ°
Π’Π΅ΠΊΡΡΠ°Ρ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅Ρ ΠΌΠ΅ΡΠΎΠ΄Ρ ΠΈ ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΠ΅, Π΄ΠΎΡΡΡΠΏΠ½ΡΠ΅
Π² Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ.
=== ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ / ΠΊΠ»Π°ΡΡΠ°
ΠΡΠ±ΠΎΠ΅ Sinatra ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠΎΠΎΡΠ²Π΅ΡΡΡΠ²ΡΠ΅Ρ ΠΏΠΎΠ΄ΠΊΠ»Π°ΡΡΡ <tt>Sinatra::Base</tt>. ΠΡΠ»ΠΈ Π²Ρ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ DSL Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ (<tt>require 'sinatra'</tt>), ΡΠΎ ΡΡΠΈΠΌ ΠΊΠ»Π°ΡΡΠΎΠΌ Π±ΡΠ΄Π΅Ρ
<tt>Sinatra::Application</tt>, ΠΈΠ½Π°ΡΠ΅ ΡΡΠΎ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ΄ΠΊΠ»Π°ΡΡ, ΠΊΠΎΡΠΎΡΡΠΉ Π²Ρ ΡΠΎΠ·Π΄Π°Π»ΠΈ Π²ΡΡΡΠ½ΡΡ.
ΠΠ° ΡΡΠΎΠ²Π½Π΅ ΠΊΠ»Π°ΡΡΠ° Π²Π°ΠΌ Π±ΡΠ΄ΡΡ Π΄ΠΎΡΡΡΠΏΠ½Ρ ΡΠ°ΠΊΠΈΠ΅ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΠΊΠ°ΠΊ +get+ ΠΈΠ»ΠΈ +before+, Π½ΠΎ Π²Ρ
Π½Π΅ ΡΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΠ°ΠΌ +request+ ΠΈΠ»ΠΈ +session+, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΡΡΡΠ΅ΡΡΠ²ΡΠ΅Ρ
ΡΠΎΠ»ΡΠΊΠΎ ΠΎΠ΄ΠΈΠ½ ΠΊΠ»Π°ΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π΄Π»Ρ Π²ΡΠ΅Ρ
Π·Π°ΠΏΡΠΎΡΠΎΠ².
ΠΠΏΡΠΈΠΈ, ΡΠΎΠ·Π΄Π°Π½Π½ΡΠ΅ Ρ ΠΏΠΎΠΌΠΎΡΡΡ +set+, ΡΠ²Π»ΡΡΡΡΡ ΠΌΠ΅ΡΠΎΠ΄Π°ΠΌΠΈ ΡΡΠΎΠ²Π½Ρ ΠΊΠ»Π°ΡΡΠ°:
class MyApp < Sinatra::Base
# Π― Π² ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ!
set :foo, 42
foo # => 42
get '/foo' do
# Π― Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ Π² ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ!
end
end
Π£ Π²Π°Ρ Π±ΡΠ΄Π΅Ρ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Π²Π½ΡΡΡΠΈ:
* ΡΠ΅Π»Π° Π²Π°ΡΠ΅Π³ΠΎ ΠΊΠ»Π°ΡΡΠ° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ;
* ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ², ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½Π½ΡΡ
ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΡΠΌΠΈ;
* Π±Π»ΠΎΠΊΠ°, ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² +helpers+;
* Π±Π»ΠΎΠΊΠΎΠ², ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½Π½ΡΡ
ΠΊΠ°ΠΊ Π·Π½Π°ΡΠ΅Π½ΠΈΡ Π΄Π»Ρ +set+;
* Π±Π»ΠΎΠΊΠ°, ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΠΎΠ³ΠΎ Π² <tt>Sinatra.new</tt>.
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ ΠΎΠ±ΡΠ΅ΠΊΡΡ ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ (ΠΊΠ»Π°ΡΡΡ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ) ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌΠΈ ΡΠΏΠΎΡΠΎΠ±Π°ΠΌΠΈ:
* ΡΠ΅ΡΠ΅Π· ΠΎΠ±ΡΠ΅ΠΊΡ, ΠΏΠ΅ΡΠ΅Π΄Π°Π½Π½ΡΠΉ Π±Π»ΠΎΠΊΠ°ΠΌ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΠΈ (<tt>configure { |c| ... }</tt>);
* +settings+ Π²Π½ΡΡΡΠΈ ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π·Π°ΠΏΡΠΎΡΠ°.
=== ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π·Π°ΠΏΡΠΎΡΠ°/ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡΠ°
ΠΠ»Ρ ΠΊΠ°ΠΆΠ΄ΠΎΠ³ΠΎ Π²Ρ
ΠΎΠ΄ΡΡΠ΅Π³ΠΎ Π·Π°ΠΏΡΠΎΡΠ° Π±ΡΠ΄Π΅Ρ ΡΠΎΠ·Π΄Π°Π½ Π½ΠΎΠ²ΡΠΉ ΡΠΊΠ·Π΅ΠΌΠΏΠ»ΡΡ Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ,
ΠΈ Π²ΡΠ΅ Π±Π»ΠΎΠΊΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° Π±ΡΠ΄ΡΡ Π·Π°ΠΏΡΡΠ΅Π½Ρ Π² ΡΡΠΎΠΌ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ΅. Π ΡΡΠΎΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ
Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π²Π°ΠΌ Π΄ΠΎΡΡΡΠΏΠ½Ρ +request+ ΠΈ +session+ ΠΎΠ±ΡΠ΅ΠΊΡΡ, Π²ΡΠ·ΠΎΠ²Ρ ΠΌΠ΅ΡΠΎΠ΄ΠΎΠ²
ΡΠ΅Π½Π΄Π΅ΡΠΈΠ½Π³Π°, ΡΠ°ΠΊΠΈΠ΅ ΠΊΠ°ΠΊ +erb+ ΠΈΠ»ΠΈ +haml+. ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΡ Π΄ΠΎΡΡΡΠΏ ΠΊ
ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΈΠ· ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡΠ° Π·Π°ΠΏΡΠΎΡΠ°, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ ΠΌΠ΅ΡΠΎΠ΄-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊ +settings+:
class MyApp < Sinatra::Base
# Π― Π² ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ!
get '/define_route/:name' do
# ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π·Π°ΠΏΡΠΎΡΠ° '/define_route/:name'
@value = 42
settings.get("/#{params[:name]}") do
# ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π·Π°ΠΏΡΠΎΡΠ° "/#{params[:name]}"
@value # => nil (Π΄ΡΡΠ³ΠΎΠΉ Π·Π°ΠΏΡΠΎΡ)
end
"Route defined!"
end
end
Π£ Π²Π°Ρ Π±ΡΠ΄Π΅Ρ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π·Π°ΠΏΡΠΎΡΠ° Π²:
* get/head/post/put/delete/options Π±Π»ΠΎΠΊΠ°Ρ
;
* before/after ΡΠΈΠ»ΡΡΡΠ°Ρ
;
* ΠΌΠ΅ΡΠΎΠ΄Π°Ρ
-ΠΏΠΎΠΌΠΎΡΠ½ΠΈΠΊΠ°Ρ
;
* ΡΠ°Π±Π»ΠΎΠ½Π°Ρ
/ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ΅Π½ΠΈΡΡ
.
=== ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π΄Π΅Π»Π΅Π³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ
ΠΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ Π΄Π΅Π»Π΅Π³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΏΡΠΎΡΡΠΎ ΠΏΠ΅ΡΠ΅Π½Π°ΠΏΡΠ°Π²Π»ΡΠ΅Ρ ΠΌΠ΅ΡΠΎΠ΄Ρ Π² ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΊΠ»Π°ΡΡΠ°.
ΠΠ΄Π½Π°ΠΊΠΎ, ΠΎΠ½Π° Π½Π΅ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π²Π΅Π΄Π΅Ρ ΡΠ΅Π±Ρ ΠΊΠ°ΠΊ ΠΎΠ±Π»Π°ΡΡΡ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΊΠ»Π°ΡΡΠ°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Ρ Π²Π°Ρ Π½Π΅Ρ
ΠΏΡΠΈΠ²ΡΠ·ΠΊΠΈ ΠΊ ΠΊΠ»Π°ΡΡΡ. Π’ΠΎΠ»ΡΠΊΠΎ ΠΌΠ΅ΡΠΎΠ΄Ρ, ΡΠ²Π½ΠΎ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½Π½ΡΠ΅ Π΄Π»Ρ Π΄Π΅Π»Π΅Π³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ, Π±ΡΠ΄ΡΡ Π΄ΠΎΡΡΡΠΏΠ½Ρ,
Π° ΠΏΠ΅ΡΠ΅ΠΌΠ΅Π½Π½ΡΡ
/ΡΠΎΡΡΠΎΡΠ½ΠΈΠΉ ΠΎΠ±Π»Π°ΡΡΠΈ Π²ΠΈΠ΄ΠΈΠΌΠΎΡΡΠΈ ΠΊΠ»Π°ΡΡΠ° Π½Π΅ Π±ΡΠ΄Π΅Ρ (ΠΈΠ½Π°ΡΠ΅ Π³ΠΎΠ²ΠΎΡΡ,
Ρ Π²Π°Ρ Π±ΡΠ΄Π΅Ρ Π΄ΡΡΠ³ΠΎΠΉ +self+ ΠΎΠ±ΡΠ΅ΠΊΡ). ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅
Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡΡ ΠΌΠ΅ΡΠΎΠ΄Ρ Π΄Π΅Π»Π΅Π³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ, ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΡ
<tt>Sinatra::Delegator.delegate :method_name</tt>.
Π£ Π²Π°Ρ Π±ΡΠ΄Π΅Ρ ΠΊΠΎΠ½ΡΠ΅ΠΊΡΡ Π΄Π΅Π»Π΅Π³ΠΈΡΠΎΠ²Π°Π½ΠΈΡ Π²Π½ΡΡΡΠΈ:
* ΠΏΡΠΈΠ²ΡΠ·ΠΊΠΈ Π²Π΅ΡΡ
Π½Π΅Π³ΠΎ ΡΡΠΎΠ²Π½Ρ, Π΅ΡΠ»ΠΈ Π²Ρ ΡΠ΄Π΅Π»Π°Π»ΠΈ <tt>require 'sinatra'</tt>;
* ΠΎΠ±ΡΠ΅ΠΊΡΠ°, ΡΠ°ΡΡΠΈΡΠ΅Π½Π½ΠΎΠ³ΠΎ Ρ ΠΏΠΎΠΌΠΎΡΡΡ <tt>Sinatra::Delegator</tt>.
ΠΠΎΡΠΌΠΎΡΡΠΈΡΠ΅ ΡΠ°ΠΌΠΈ Π² ΠΊΠΎΠ΄: ΡΡΡ
{Sinatra::Delegator ΠΏΡΠΈΠΌΠ΅ΡΡ}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/base.rb#L1128]
Π±ΡΠ΄Π΅Ρ {Π²ΠΊΠ»ΡΡΠ΅Π½Π° Π² Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΠΎΠ΅ ΠΏΡΠΎΡΡΡΠ°Π½ΡΡΠ²ΠΎ ΠΈΠΌΠ΅Π½}[http://github.com/sinatra/sinatra/blob/ceac46f0bc129a6e994a06100aa854f606fe5992/lib/sinatra/main.rb#L28].
== ΠΠΎΠΌΠ°Π½Π΄Π½Π°Ρ ΡΡΡΠΎΠΊΠ°
Sinatra ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ ΠΌΠΎΠ³ΡΡ Π±ΡΡΡ Π·Π°ΠΏΡΡΠ΅Π½Ρ Π½Π°ΠΏΡΡΠΌΡΡ:
ruby myapp.rb [-h] [-x] [-e ENVIRONMENT] [-p PORT] [-o HOST] [-s HANDLER]
ΠΠΏΡΠΈΠΈ Π²ΠΊΠ»ΡΡΠ°ΡΡ:
-h # ΡΠ°Π·Π΄Π΅Π» ΠΏΠΎΠΌΠΎΡΠΈ
-p # ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΠΏΠΎΡΡΠ° (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ 4567)
-o # ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ Ρ
ΠΎΡΡΠ° (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ 0.0.0.0)
-e # ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ ΠΎΠΊΡΡΠΆΠ΅Π½ΠΈΡ, ΡΠ΅ΠΆΠΈΠΌΠ° (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ development)
-s # ΡΠΊΠ°Π·Π°Π½ΠΈΠ΅ rack ΡΠ΅ΡΠ²Π΅ΡΠ°/ΠΎΠ±ΡΠ°Π±ΠΎΡΡΠΈΠΊΠ° (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ thin)
-x # Π²ΠΊΠ»ΡΡΠΈΡΡ ΠΌΡΡΡΠ΅ΠΊΡ-Π±Π»ΠΎΠΊΠΈΡΠΎΠ²ΠΊΡ (ΠΏΠΎ ΡΠΌΠΎΠ»ΡΠ°Π½ΠΈΡ Π²ΡΠΊΠ»ΡΡΠ΅Π½Π°)
== Π‘ΠΈΡΡΠ΅ΠΌΠ½ΡΠ΅ ΡΡΠ΅Π±ΠΎΠ²Π°Π½ΠΈΡ
Π‘Π»Π΅Π΄ΡΡΡΠΈΠ΅ Π²Π΅ΡΡΠΈΠΈ Ruby ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ:
[ Ruby 1.8.7 ]
1.8.7 ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ, ΡΠ΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΠ»ΠΈ Π²Π°Ρ Π½ΠΈΡΡΠΎ Π½Π΅ Π΄Π΅ΡΠΆΠΈΡ Π½Π°
ΡΡΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ, ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡΡΡ Π΄ΠΎ 1.9.2 ΠΈΠ»ΠΈ ΠΏΠ΅ΡΠ΅ΠΉΡΠΈ Π½Π° JRuby ΠΈΠ»ΠΈ Rubinius.
[ Ruby 1.9.2 ]
1.9.2 ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ ΠΈ ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΠΎΠ²Π°Π½Π° ΠΊ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΡ. ΠΠ°ΠΌΠ΅ΡΡΡΠ΅, ΡΡΠΎ Radius ΠΈ Markaby
ΠΏΠΎΠΊΠ° Π½Π΅ΡΠΎΠ²ΠΌΠ΅ΡΡΠΈΠΌΡ Ρ 1.9.2. ΠΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠΉΡΠ΅ 1.9.2p0, ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ, ΡΡΠΎ ΡΡΠ°
Π²Π΅ΡΡΠΈΡ Π²Π΅ΡΡΠΌΠ° Π½Π΅ΡΡΠ°Π±ΠΈΠ»ΡΠ½Π° ΠΏΡΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠΈ Sinatra.
[ Rubinius ]
Rubinius ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ (Rubinius >= 1.2.3), Π²ΡΡ, Π²ΠΊΠ»ΡΡΠ°Ρ Π²ΡΠ΅
ΡΠ·ΡΠΊΠΈ ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ², ΡΠ°Π±ΠΎΡΠ°Π΅Ρ.
[ JRuby ]
JRuby ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ (JRuby >= 1.6.1). ΠΠ΅Ρ Π½ΠΈΠΊΠ°ΠΊΠΈΡ
ΠΏΡΠΎΠ±Π»Π΅ΠΌ Ρ
ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ΠΌ Π°Π»ΡΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΡΡ
ΡΠ°Π±Π»ΠΎΠ½ΠΎΠ². Π’Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Π΅ΡΠ»ΠΈ Π²Ρ Π²ΡΠ±ΠΈΡΠ°Π΅ΡΠ΅
JRuby, ΡΠΎ, ΠΏΠΎΠΆΠ°Π»ΡΠΉΡΡΠ°, ΠΏΠΎΡΠΌΠΎΡΡΠΈΡΠ΅ Π½Π° JRuby Rack-ΡΠ΅ΡΠ²Π΅ΡΠ°, ΡΠ°ΠΊ ΠΊΠ°ΠΊ Thin Π½Π΅
ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ ΠΏΠΎΠ»Π½ΠΎΡΡΡΡ Π½Π° JRuby. ΠΠΎΠ΄Π΄Π΅ΡΠΆΠΊΠ° ΡΠ°ΡΡΠΈΡΠ΅Π½ΠΈΠΉ Π½Π° C Π² JRuby Π²ΡΠ΅
Π΅ΡΠ΅ ΡΠΊΡΠΏΠ΅ΡΠΈΠΌΠ΅Π½ΡΠ°Π»ΡΠ½Π°Ρ, ΡΡΠΎ Π½Π° Π΄Π°Π½Π½ΡΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ Π·Π°ΡΡΠ°Π³ΠΈΠ²Π°Π΅Ρ ΡΠΎΠ»ΡΠΊΠΎ RDiscount ΠΈ
Redcarpet.
<b>Ruby 1.8.6 Π±ΠΎΠ»ΡΡΠ΅ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ.</b> ΠΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΡΠ²ΠΎΠ΅
ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π½Π° 1.8.6, ΠΎΡΠΊΠ°ΡΠΈΡΠ΅ΡΡ Π΄ΠΎ Sinatra 1.2, ΠΊΠΎΡΠΎΡΠ°Ρ Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ»ΡΡΠ°ΡΡ Π²ΡΠ΅
ΠΈΡΠΏΡΠ°Π²Π»Π΅Π½ΠΈΡ ΠΎΡΠΈΠ±ΠΎΠΊ Π΄ΠΎ ΡΠ΅Ρ
ΠΏΠΎΡ, ΠΏΠΎΠΊΠ° Π½Π΅ Π±ΡΠ΄Π΅Ρ Π²ΡΠΏΡΡΠ΅Π½Π° Sinatra 1.4.0
ΠΡ ΡΠ°ΠΊΠΆΠ΅ ΡΠ»Π΅Π΄ΠΈΠΌ Π·Π° ΠΏΡΠ΅Π΄ΡΡΠΎΡΡΠΈΠΌΠΈ ΠΊ Π²ΡΡ
ΠΎΠ΄Ρ Π²Π΅ΡΡΠΈΡΠΌΠΈ Ruby.
Π‘Π»Π΅Π΄ΡΡΡΠΈΠ΅ ΡΠ΅Π°Π»ΠΈΠ·Π°ΡΠΈΠΈ Ruby Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ, Π½ΠΎ ΠΈΠ·Π²Π΅ΡΡΠ½ΠΎ, ΡΡΠΎ Π½Π°
Π½ΠΈΡ
Π·Π°ΠΏΡΡΠΊΠ°Π΅ΡΡΡ Sinatra:
* ΡΡΠ°ΡΡΠ΅ Π²Π΅ΡΡΠΈΠΈ JRuby ΠΈ Rubinius;
* MacRuby, Maglev, IronRuby;
* Ruby 1.9.0 ΠΈ 1.9.1;
* Ruby 1.8.6 Ρ ΠΏΠΎΠΌΠΎΡΡΡ {backports}[https://github.com/marcandre/backports/#readme].
Π’ΠΎ, ΡΡΠΎ Π²Π΅ΡΡΠΈΡ ΠΎΡΠΈΡΠΈΠ°Π»ΡΠ½ΠΎ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΡΡΡ, ΠΎΠ·Π½Π°ΡΠ°Π΅Ρ, ΡΡΠΎ, Π΅ΡΠ»ΠΈ ΡΡΠΎ-ΡΠΎ Π½Π΅
ΡΠ°Π±ΠΎΡΠ°Π΅Ρ Π½Π° ΡΡΠΎΠΉ Π²Π΅ΡΡΠΈΠΈ, Π° Π½Π° ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°Π΅ΠΌΠΎΠΉ ΡΠ°Π±ΠΎΡΠ°Π΅Ρ - ΡΡΠΎ Π½Π΅ Π½Π°ΡΠ° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°, Π° ΠΈΡ
.
ΠΡ ΡΠ°ΠΊΠΆΠ΅ Π·Π°ΠΏΡΡΠΊΠ°Π΅ΠΌ Π½Π°ΡΠΈ CI-ΡΠ΅ΡΡΡ Π½Π° ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ Π²Π΅ΡΡΠΈΠΈ Ruby (ΠΏΡΠ΅Π΄ΡΡΠΎΡΡΠ΅ΠΉ 1.9.3),
Π½ΠΎ ΠΌΡ Π½Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π½ΠΈΡΠ΅Π³ΠΎ Π³Π°ΡΠ°Π½ΡΠΈΡΠΎΠ²Π°ΡΡ, ΡΠ°ΠΊ ΠΊΠ°ΠΊ ΠΎΠ½Π° ΠΏΠΎΡΡΠΎΡΠ½Π½ΠΎ ΡΠ°Π·Π²ΠΈΠ²Π°Π΅ΡΡΡ.
ΠΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°Π΅ΡΡΡ, ΡΡΠΎ 1.9.3p0 Π±ΡΠ΄Π΅Ρ ΠΏΠΎΠ΄Π΄Π΅ΡΠΆΠΈΠ²Π°ΡΡΡΡ.
Sinatra Π΄ΠΎΠ»ΠΆΠ½Π° ΡΠ°Π±ΠΎΡΠ°ΡΡ Π½Π° Π»ΡΠ±ΠΎΠΉ ΠΎΠΏΠ΅ΡΠ°ΡΠΈΠΎΠ½Π½ΠΎΠΉ ΡΠΈΡΡΠ΅ΠΌΠ΅, Π² ΠΊΠΎΡΠΎΡΠΎΠΉ Π΅ΡΡΡ ΠΎΠ΄Π½Π° ΠΈΠ· ΡΠΊΠ°Π·Π°Π½Π½ΡΡ
Π²ΡΡΠ΅ Π²Π΅ΡΡΠΈΠΉ Ruby.
== ΠΠ° ΠΎΡΡΡΠΈΠ΅
ΠΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ ΡΠ°ΠΌΡΠΉ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΉ ΠΊΠΎΠ΄ Sinatra, Π½Π΅ Π±ΠΎΠΉΡΠ΅ΡΡ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ
ΡΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π²ΠΌΠ΅ΡΡΠ΅ Ρ ΠΊΠΎΠ΄ΠΎΠΌ ΠΈΠ· master Π²Π΅ΡΠΊΠΈ Sinatra, ΠΎΠ½Π° Π²Π΅ΡΡΠΌΠ° ΡΡΠ°Π±ΠΈΠ»ΡΠ½Π°.
ΠΡ ΡΠ°ΠΊΠΆΠ΅ Π²ΡΠ΅ΠΌΡ ΠΎΡ Π²ΡΠ΅ΠΌΠ΅Π½ΠΈ Π²ΡΠΏΡΡΠΊΠ°Π΅ΠΌ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»ΡΠ½ΡΠ΅ Π²Π΅ΡΡΠΈΠΈ, ΡΠ°ΠΊ ΡΡΠΎ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π΅Π»Π°ΡΡ ΡΠ°ΠΊ:
gem install sinatra --pre
Π§ΡΠΎΠ±Ρ Π²ΠΎΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡΡΡ Π½Π΅ΠΊΠΎΡΠΎΡΡΠΌΠΈ ΡΠ°ΠΌΡΠΌΠΈ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΠΌΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡΡΠΌΠΈ.
=== Π‘ ΠΏΠΎΠΌΠΎΡΡΡ Bundler
ΠΡΠ»ΠΈ Π²Ρ Ρ
ΠΎΡΠΈΡΠ΅ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΡΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΉ Π²Π΅ΡΡΠΈΠ΅ΠΉ Sinatra, ΡΠΎ
ΡΠ΅ΠΊΠΎΠΌΠ΅Π½Π΄ΡΠ΅ΠΌ ΠΈΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΡ {Bundler}[http://gembundler.com/].
Π‘Π½Π°ΡΠ°Π»Π° ΡΡΡΠ°Π½ΠΎΠ²ΠΈΡΠ΅ Bundler, Π΅ΡΠ»ΠΈ Ρ Π²Π°Ρ Π΅Π³ΠΎ Π΅ΡΠ΅ Π½Π΅Ρ:
gem install bundler
ΠΠ°ΡΠ΅ΠΌ ΡΠΎΠ·Π΄Π°ΠΉΡΠ΅ ΡΠ°ΠΉΠ» +Gemfile+ Π² Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠΈ Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΎΠ΅ΠΊΡΠ°:
source :rubygems
gem 'sinatra', :git => "git://github.com/sinatra/sinatra.git"
# Π΄ΡΡΠ³ΠΈΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ
gem 'haml' # Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, Π΅ΡΠ»ΠΈ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΡΠ΅ haml
gem 'activerecord', '~> 3.0' # ΠΌΠΎΠΆΠ΅Ρ Π±ΡΡΡ, Π²Π°ΠΌ Π½ΡΠΆΠ΅Π½ ΠΈ ActiveRecord 3.x
ΠΠ±ΡΠ°ΡΠΈΡΠ΅ Π²Π½ΠΈΠΌΠ°Π½ΠΈΠ΅, Π²Π°ΠΌ Π½ΡΠΆΠ½ΠΎ Π±ΡΠ΄Π΅Ρ ΡΠΊΠ°Π·ΡΠ²Π°ΡΡ Π²ΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Π²Π°ΡΠ΅Π³ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ
Π² ΡΡΠΎΠΌ ΡΠ°ΠΉΠ»Π΅. ΠΠ΄Π½Π°ΠΊΠΎ, Π½Π΅ΠΏΠΎΡΡΠ΅Π΄ΡΡΠ²Π΅Π½Π½ΡΠ΅ Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡΠΈ Sinatra (Rack ΠΈ Tilt) Bundler
Π°Π²ΡΠΎΠΌΠ°ΡΠΈΡΠ΅ΡΠΊΠΈ ΡΠΊΠ°ΡΠ°Π΅Ρ ΠΈ Π΄ΠΎΠ±Π°Π²ΠΈΡ.
Π’Π΅ΠΏΠ΅ΡΡ Π²Ρ ΠΌΠΎΠΆΠ΅ΡΠ΅ Π·Π°ΠΏΡΡΠΊΠ°ΡΡ ΡΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ ΡΠ°ΠΊ:
bundle exec ruby myapp.rb
=== ΠΡΡΡΠ½ΡΡ
Π‘ΠΎΠ·Π΄Π°ΠΉΡΠ΅ Π»ΠΎΠΊΠ°Π»ΡΠ½ΡΠΉ ΠΊΠ»ΠΎΠ½ ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ ΠΈ Π·Π°ΠΏΡΡΠΊΠ°ΠΉΡΠ΅ ΡΠ²ΠΎΠ΅ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ <tt>sinatra/lib</tt>
Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΠ΅ΠΉ Π² <tt>$LOAD_PATH</tt>:
cd myapp
git clone git://github.com/sinatra/sinatra.git
ruby -Isinatra/lib myapp.rb
Π§ΡΠΎΠ±Ρ ΠΎΠ±Π½ΠΎΠ²ΠΈΡΡ ΠΈΡΡ
ΠΎΠ΄Π½ΠΈΠΊΠΈ Sinatra:
cd myapp/sinatra
git pull
=== Π£ΡΡΠ°Π½ΠΎΠ²ΠΊΠ° Π³Π»ΠΎΠ±Π°Π»ΡΠ½ΠΎ
ΠΡ ΠΌΠΎΠΆΠ΅ΡΠ΅ ΡΠ°ΠΌΠΎΡΡΠΎΡΡΠ΅Π»ΡΠ½ΠΎ ΡΠΎΠ±ΡΠ°ΡΡ gem:
git clone git://github.com/sinatra/sinatra.git
cd sinatra
rake sinatra.gemspec
rake install
ΠΡΠ»ΠΈ Π²Ρ ΡΡΡΠ°Π½Π°Π²Π»ΠΈΠ²Π°Π΅ΡΠ΅ ΠΏΠ°ΠΊΠ΅ΡΡ (gem) ΠΎΡ ΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°ΡΠ΅Π»Ρ root, ΡΠΎ Π²Π°ΡΠΈΠΌ ΡΠ»Π΅Π΄ΡΡΡΠΈΠΌ ΡΠ°Π³ΠΎΠΌ Π΄ΠΎΠ»ΠΆΠ½Π° Π±ΡΡΡ ΠΊΠΎΠΌΠ°Π½Π΄Π°
sudo rake install
== ΠΠ΅ΡΡΠΈΠΈ
Sinatra ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ {Semantic Versioning}[http://semver.org/], SemVer ΠΈ
SemVerTag.
== ΠΠ°Π»ΡΠ½Π΅ΠΉΡΠ΅Π΅ ΡΡΠ΅Π½ΠΈΠ΅
* {ΠΠ΅Π±-ΡΠ°ΠΉΡ ΠΏΡΠΎΠ΅ΠΊΡΠ°}[http://www.sinatrarb.com/] - ΠΠΎΠΏΠΎΠ»Π½ΠΈΡΠ΅Π»ΡΠ½Π°Ρ Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ,
Π½ΠΎΠ²ΠΎΡΡΠΈ ΠΈ ΡΡΡΠ»ΠΊΠΈ Π½Π° Π΄ΡΡΠ³ΠΈΠ΅ ΡΠ΅ΡΡΡΡΡ.
* {Π£ΡΠ°ΡΡΠΈΠ΅ Π² ΠΏΡΠΎΠ΅ΠΊΡΠ΅}[http://www.sinatrarb.com/contributing] - ΠΠ±Π½Π°ΡΡΠΆΠΈΠ»ΠΈ Π±Π°Π³? ΠΡΠΆΠ½Π° ΠΏΠΎΠΌΠΎΡΡ? ΠΠ°ΠΏΠΈΡΠ°Π»ΠΈ ΠΏΠ°ΡΡ?
* {Π‘Π»Π΅ΠΆΠ΅Π½ΠΈΠ΅ Π·Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°ΠΌΠΈ/ΠΎΡΠΈΠ±ΠΊΠ°ΠΌΠΈ}[http://github.com/sinatra/sinatra/issues]
* {Twitter}[http://twitter.com/sinatra]
* {ΠΡΡΠΏΠΏΡ ΡΠ°ΡΡΡΠ»ΠΊΠΈ}[http://groups.google.com/group/sinatrarb/topics]
* {IRC: #sinatra}[irc://chat.freenode.net/#sinatra] Π½Π° http://freenode.net
* {Sinatra Book}[http://sinatra-book.gittr.com] ΡΡΠ΅Π±Π½ΠΈΠΊ ΠΈ ΡΠ±ΠΎΡΠ½ΠΈΠΊ ΡΠ΅ΡΠ΅ΠΏΡΠΎΠ²
* {Sinatra Recipes}[http://recipes.sinatrarb.com/] ΡΠ±ΠΎΡΠ½ΠΈΠΊ ΡΠ΅ΡΠ΅ΠΏΡΠΎΠ²
* API Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡ ΠΊ {ΠΏΠΎΡΠ»Π΅Π΄Π½Π΅ΠΌΡ ΡΠ΅Π»ΠΈΠ·Ρ}[http://rubydoc.info/gems/sinatra]
ΠΈΠ»ΠΈ {ΡΠ΅ΠΊΡΡΠ΅ΠΌΡ HEAD}[http://rubydoc.info/github/sinatra/sinatra] Π½Π°
http://rubydoc.info
|