Comparar commits
1245 Commits
| Autor | SHA1 | Data | |
|---|---|---|---|
| 80f4d08e8b | |||
| 07c9cae923 | |||
| d867cc9271 | |||
| 3a1fe1e295 | |||
| 3cacf050df | |||
| 1536d73d1b | |||
| 55143a9d44 | |||
| c92e193916 | |||
| d12452fc49 | |||
| 3d8400a40c | |||
| 1fe0aea0b0 | |||
| 5df2544883 | |||
| acbf224277 | |||
| d0d17a0d35 | |||
| f7b53d33bc | |||
| 92be06874b | |||
| f327455d9d | |||
| 54415bf2af | |||
| bac62dfcd9 | |||
| 820b43c1f3 | |||
| a5b69290d5 | |||
| 5c7a9c86f6 | |||
| 7f83f916f6 | |||
| c15a949cc3 | |||
| ce47f96570 | |||
| 57b035cd94 | |||
| f1f126171c | |||
| 71e1bcd855 | |||
| b5579b6307 | |||
| 110b0fe14a | |||
| d7488bbb62 | |||
| 2007407e7b | |||
| d152e7e780 | |||
| d4f4b6682d | |||
| 7f4a12f4cd | |||
| 07d06adf86 | |||
| 47dc188d57 | |||
| 85d22541d2 | |||
| 90ec1031f9 | |||
| 9bc9ad13a4 | |||
| 1782c7d778 | |||
| e85752c527 | |||
| dfdbbb514f | |||
| 976f5ca93e | |||
| 2086f8d34c | |||
| 6873a68216 | |||
| 9eb2c61760 | |||
| 543e791206 | |||
| b6e8b3fa84 | |||
| 6f8e406b7b | |||
| 93bc54b65c | |||
| 3bf0ac4a36 | |||
| bc01bfff21 | |||
| 0d4eaf03fc | |||
| 2bb0412473 | |||
| 07ce5d3158 | |||
| 131970b3e5 | |||
| 00e1dbfbd9 | |||
| 4c274c524d | |||
| 5581ca2751 | |||
| 5cd9a9540f | |||
| 1db2efa75a | |||
| c1a82bf3ea | |||
| 7705042cac | |||
| b9e311e893 | |||
| 460998497d | |||
| 022c5e1411 | |||
| 60daf0d6c7 | |||
| 0b6a941624 | |||
| 1fc520b45a | |||
| cbbee38be8 | |||
| 2dae6d8285 | |||
| 65c8a956f1 | |||
| 2b907e9a8c | |||
| 25e520c243 | |||
| 2124c8465a | |||
| a49e1f4f3d | |||
| 32be4a7812 | |||
| 92967d3457 | |||
| d70fee7432 | |||
| 97b8e75932 | |||
| 8a62f8cef0 | |||
| 10f4f523fa | |||
| 1e392d2628 | |||
| eb6ff62113 | |||
| 64da2621da | |||
| 61aec6e961 | |||
| 42f3ad436d | |||
| 2f7b78c03a | |||
| 402d37d613 | |||
| 96327c979c | |||
| 9d1b3f59d5 | |||
| 14bd50efe4 | |||
| 631c1f95e7 | |||
| 50006f7e43 | |||
| 4c9503158b | |||
| 6c8e461db5 | |||
| aaa8415169 | |||
| 51e964498c | |||
| 0cddc70ff5 | |||
| 99dcf7508f | |||
| 7822d1f148 | |||
| a572a7126c | |||
| a1609faba0 | |||
| 9bf823d893 | |||
| ca184e7725 | |||
| 5054507487 | |||
| ab93be0178 | |||
| 8b0993bb10 | |||
| 0a034bb3ea | |||
| 4ce815a3ed | |||
| 4da860eae1 | |||
| 27e4bdb814 | |||
| dd9406cd52 | |||
| 509312773d | |||
| 42d2758c36 | |||
| ef1c858ffc | |||
| 7fd47c0ac6 | |||
| a63b232ef1 | |||
| acb502e5e3 | |||
| 3661922bb0 | |||
| 0704f149be | |||
| 334604de5d | |||
| 530328ac15 | |||
| 9914a1eb3f | |||
| 5db5710d3f | |||
| 9e9f55a8e3 | |||
| 0800141a9d | |||
| dc6d469f0c | |||
| 89299d77e4 | |||
| 27d8bf6311 | |||
| 8c229a8560 | |||
| 29eed65a67 | |||
| f0e0073a09 | |||
| b70bde58be | |||
| 635fac776d | |||
| 7753d4e91d | |||
| 66a6214216 | |||
| 6cae1f09f1 | |||
| c4432ee827 | |||
| 80a5bf2063 | |||
| 5b3d5fc431 | |||
| cd38fb4177 | |||
| 9b1cc75b36 | |||
| db8b2883e2 | |||
| 59a74ecce4 | |||
| 9099c61df9 | |||
| 50521281ce | |||
| 0cc6abf741 | |||
| fe266ae4fe | |||
| 7c15cdeb69 | |||
| 848086947c | |||
| 5ec4ea754c | |||
| 41467d54df | |||
| 8261437764 | |||
| 54eac368d0 | |||
| 72511ea1e9 | |||
| da7921f2c6 | |||
| cd519e97e7 | |||
| 2a7a5aeefe | |||
| bdbacb41da | |||
| 2dd736a201 | |||
| ec3c797105 | |||
| 770f05c060 | |||
| 6993a27d8e | |||
| 68fd658536 | |||
| 9fc349965d | |||
| 0a667ff741 | |||
| d37ad85f72 | |||
| 2b63568611 | |||
| fcf9f93825 | |||
| 07efc0b73b | |||
| 6813b48c7e | |||
| d58444c6d2 | |||
| dd8a0bd30f | |||
| b65b0636aa | |||
| 9ec6321261 | |||
| 07eb66c205 | |||
| 0e790e6fb5 | |||
| 08186924a4 | |||
| e9faf5cf94 | |||
| 8c0efe09e5 | |||
| 32d2c96d22 | |||
| e958988989 | |||
| 131f10bd80 | |||
| a61615a196 | |||
| 4fdb6910a5 | |||
| 67c4c90351 | |||
| 16f7288b19 | |||
| 36a7e87ae4 | |||
| 16badda118 | |||
| 99820e7edc | |||
| 6a03a92f5f | |||
| 80c3b98a84 | |||
| afd2b4b387 | |||
| df49769f3d | |||
| 05c2946322 | |||
| 2ed392edbf | |||
| 3d597a554d | |||
| 42af4e40ae | |||
| 242efc7219 | |||
| a6bacb857d | |||
| eab54724a1 | |||
| 49885cfeff | |||
| 4330f49011 | |||
| 7687299275 | |||
| 79ba787b03 | |||
| 5a184a205f | |||
| 4b5a6b597a | |||
| 9e9c3eeb79 | |||
| cd996f9dbf | |||
| ab4c91158a | |||
| 1130a23e5b | |||
| 9ac6943220 | |||
| 0f55284b77 | |||
| c75046de3f | |||
| e7df82f110 | |||
| ee4c7d3007 | |||
| 2895303421 | |||
| 3f16f05525 | |||
| fb33671923 | |||
| 482fb5b6e2 | |||
| b1004b61f9 | |||
| 27af9b2605 | |||
| e28ac866f8 | |||
| 5e0a80f227 | |||
| ec0982ca1f | |||
| e7c442d21c | |||
| a9db47fdd3 | |||
| b856a72886 | |||
| 03da0d31f9 | |||
| 1c40e4374b | |||
| d7df1426f2 | |||
| 5035e86f59 | |||
| 0af91265ab | |||
| 8e63d04e66 | |||
| 5ac0c6deb0 | |||
| 6b0d82fb0c | |||
| 2bfdfe366c | |||
| 898fb0f320 | |||
| f53686a2f3 | |||
| eae1670f54 | |||
| 544d68833c | |||
| c24a6b2359 | |||
| b720b57d1d | |||
| 365b7fe90a | |||
| c7ab833e66 | |||
| 9536f288e9 | |||
| e64d4039d0 | |||
| 5f077e56f0 | |||
| a9253a24e0 | |||
| 749136b526 | |||
| 36a8b7b7f3 | |||
| a29908c865 | |||
| 57d87c27cd | |||
| 1c2e9a476c | |||
| 5d87133df0 | |||
| fd2f67b73f | |||
| d3abcaf67b | |||
| 14dce5ac2b | |||
| abd002071a | |||
| 77add42eeb | |||
| bba049b4bf | |||
| 4e41c3520c | |||
| 4144af3351 | |||
| 30f749a2a2 | |||
| 6e9f282af7 | |||
| 4491be01dd | |||
| 8c163fd980 | |||
| 9f6a158fc2 | |||
| 19965fa3c8 | |||
| 6bb42ffafc | |||
| 4a1edc0720 | |||
| a5a016bf33 | |||
| 4be4f597a3 | |||
| dfbbd4f784 | |||
| 2662dae560 | |||
| 6f6f9f08f8 | |||
| a76fba57c4 | |||
| 680766f29b | |||
| adcfd4ca4d | |||
| e276a49a91 | |||
| 5995f763b1 | |||
| a123639b5c | |||
| 8a118d53c8 | |||
| d572391532 | |||
| 58ae7a0402 | |||
| f843093a8c | |||
| 3e06586f81 | |||
| 60f148326a | |||
| 02e1413ca5 | |||
| 7b4b85ee54 | |||
| 6c0a416f16 | |||
| 23cc88bf92 | |||
| 5528f0ddf2 | |||
| 8d3296fb1b | |||
| 136f9209a3 | |||
| a290134fd2 | |||
| a54e59666a | |||
| 42ea6af1eb | |||
| f9b741766b | |||
| 09359329a0 | |||
| 647bb41ddf | |||
| f25c14d48d | |||
| 81a3d559f5 | |||
| 4e0ee7a5da | |||
| 1c80a258d2 | |||
| 129ed6a07b | |||
| df09a0c73b | |||
| ff5c958354 | |||
| 4f90c89db6 | |||
| 524b515fdb | |||
| 163256b001 | |||
| 05bbc65dcc | |||
| 6624f6b7f9 | |||
| f32279dec5 | |||
| a90fd85907 | |||
| 9815b27e94 | |||
| ebbe481fe7 | |||
| 9e337faa33 | |||
| 37826e0261 | |||
| 20e4342796 | |||
| 51be16950d | |||
| be866a78ff | |||
| f9d2432c69 | |||
| 6543a3d75a | |||
| a77936981e | |||
| 6f2120bb59 | |||
| 98e18239fd | |||
| 3d159015be | |||
| f5af66a1ab | |||
| 540192ff96 | |||
| c1cfd4a8c6 | |||
| 322300c329 | |||
| 1ac18f7903 | |||
| 4f4987e9ea | |||
| 65bf562ff4 | |||
| f47032e7e9 | |||
| 379f3ec8dd | |||
| 8d7e35b723 | |||
| 1349eea0d0 | |||
| bed5157f32 | |||
| 12c7f51a1e | |||
| 7e32c8de4d | |||
| 3a42350c21 | |||
| 1a54597202 | |||
| 39f4eb9940 | |||
| 4b996651af | |||
| 884d40f321 | |||
| 3d2b41da08 | |||
| 1bf2dbb7df | |||
| e0dfb77dd1 | |||
| 578fddc1b7 | |||
| 089355d706 | |||
| 6b2c3caf03 | |||
| 065c37cb28 | |||
| 3a40025fd3 | |||
| 8dc341d868 | |||
| 0ed121ddbd | |||
| 969f4229dc | |||
| 27a940184e | |||
| 77fa09a506 | |||
| 8836104ab2 | |||
| 396837517d | |||
| 38b3f1bde2 | |||
| 4780168ba8 | |||
| d1a790d103 | |||
| 3ad6ab8c6a | |||
| 1e189da85e | |||
| a094c50873 | |||
| ad324410c6 | |||
| 9f4b7368a0 | |||
| c8ddedb8d0 | |||
| 7deab2826b | |||
| 643879f779 | |||
| ce2a18f483 | |||
| 487d067f75 | |||
| c4d5e1b4f3 | |||
| 0e0cc30039 | |||
| a766cc791b | |||
| d017c3e248 | |||
| cc27ee04a8 | |||
| 87459bf24b | |||
| 5091c9e10f | |||
| 14a22d9033 | |||
| 7ded5a2de5 | |||
| 6b436a0192 | |||
| 52343686f5 | |||
| eec9d05b19 | |||
| 89703fd430 | |||
| dc246946a7 | |||
| 944e1120cb | |||
| cccda60df8 | |||
| e338e748eb | |||
| 0526a24cf3 | |||
| c4ba1b025a | |||
| 252f330658 | |||
| 45590415a6 | |||
| e562adc752 | |||
| 1e2fd44a6b | |||
| 1c903320be | |||
| 74eaf3a268 | |||
| 6fcd74c713 | |||
| 33136c6553 | |||
| cb225db203 | |||
| 0dbd5006ea | |||
| 08b3677ce8 | |||
| b08549a25b | |||
| 221bc4cb5d | |||
| b655b8e97b | |||
| 03e7b5dcc6 | |||
| 5f09e829df | |||
| e6759919dc | |||
| 6c65a3fc74 | |||
| e0ffd31123 | |||
| 4c1597113a | |||
| 4006506b64 | |||
| 14facdbcd2 | |||
| 726ace49d8 | |||
| f45d383367 | |||
| 3a32e2b53a | |||
| dc45e93cea | |||
| c0f9642719 | |||
| da8d036997 | |||
| 3c911cc785 | |||
| 4071f15f27 | |||
| 90de7923db | |||
| c28f1535a3 | |||
| 704e9c132e | |||
| 713d6f5f76 | |||
| 1a6d245eae | |||
| d909dd2a32 | |||
| 7bb466dd86 | |||
| e09bf5cc40 | |||
| 129e21e7c3 | |||
| 87dcd2909d | |||
| e47ec4f551 | |||
| d6cfcbe149 | |||
| 7a713807e9 | |||
| 6e49b5bc30 | |||
| adbc5b86f5 | |||
| 071ea955af | |||
| 806aefa966 | |||
| 5b7d23186d | |||
| 0cb4677e80 | |||
| bd65ecf17b | |||
| 9da2adff4c | |||
| a2a1aad109 | |||
| dcc530a389 | |||
| 97037a87f3 | |||
| 4e67efc0d6 | |||
| 7cbb73719e | |||
| d3f139c31e | |||
| 8940b6e5a3 | |||
| 1c9831a9f4 | |||
| 7da27435cc | |||
| bd18f86517 | |||
| 41f66b435b | |||
| 48481a7230 | |||
| dde6bc1f80 | |||
| e39fd1de0e | |||
| 2fc9a81e9e | |||
| f65874d751 | |||
| 3914895784 | |||
| 0bc7e24d0a | |||
| 2a40ceced7 | |||
| d4868f2cc2 | |||
| e87d63779d | |||
| 6672d65018 | |||
| 1f78c520f5 | |||
| 687e435a38 | |||
| b3222dc107 | |||
| ebba6caa3d | |||
| 88bbef9003 | |||
| 712771a139 | |||
| 9033b0ded7 | |||
| 877cfe9393 | |||
| 347aa56acb | |||
| 0fc410139c | |||
| 51528235db | |||
| 003599cbda | |||
| bacfad37a9 | |||
| 6ef6ba7b8a | |||
| 93c0da0367 | |||
| 268d19e8a3 | |||
| a383b302c2 | |||
| 95ebbf2608 | |||
| f880574c78 | |||
| 350c310906 | |||
| 5026f7686e | |||
| ab3337ddf5 | |||
| c9268f2e3d | |||
| fa01388f97 | |||
| d8dc89ac7b | |||
| a659fd1fa9 | |||
| 27fa3ba34c | |||
| 663f42948e | |||
| baca8f0cdb | |||
| c5c3a82b23 | |||
| c0617864e1 | |||
| d9ef9ab497 | |||
| 65d9f783e1 | |||
| f70232d1b0 | |||
| b083aed245 | |||
| 0faac20d53 | |||
| cef14ca7cd | |||
| 090debe0df | |||
| 296f1270ee | |||
| 334a18a114 | |||
| dd4ddae082 | |||
| 4983e967bc | |||
| 0b5e2f14ed | |||
| 70102aecb5 | |||
| ae75153561 | |||
| dd23d60513 | |||
| db95481b76 | |||
| 3e0da535b9 | |||
| c74602551e | |||
| 1722e2c7a5 | |||
| 8a845e2951 | |||
| 72765bada0 | |||
| b380f180cc | |||
| f1799799a1 | |||
| 4bc8a8673d | |||
| cbdd907393 | |||
| aa7ff3ef47 | |||
| ebdf6434eb | |||
| 9b7470d204 | |||
| 9f3ab8683c | |||
| fa464aca90 | |||
| 2724ce368a | |||
| 89f7cbe877 | |||
| fab9af2206 | |||
| 4d01b4fa59 | |||
| c3365aa37e | |||
| 426e80d4c3 | |||
| 30a282d126 | |||
| 0a96621e3e | |||
| d9d30abe7a | |||
| 03b56d8140 | |||
| 1f79ce4e96 | |||
| 8d80f23a0f | |||
| d89b951451 | |||
| 1906a38ec8 | |||
| 8d91a3e3b8 | |||
| 3324259977 | |||
| ec2db2d541 | |||
| 5cf248c7f3 | |||
| 3876a566ff | |||
| 334e6cc618 | |||
| 64033fcfc2 | |||
| fbe3af4719 | |||
| 699ed4ee85 | |||
| 903f67a154 | |||
| 9a89dab9e0 | |||
| 435a2565b8 | |||
| 8267b8da57 | |||
| 8b5773c246 | |||
| fd4c88d202 | |||
| 9b26623aa5 | |||
| b115ec7c14 | |||
| a2e6e2a06a | |||
| f0eab06a8b | |||
| b6c839d693 | |||
| 177a724d58 | |||
| 949803dcf6 | |||
| b763a88e60 | |||
| 18c7f164a8 | |||
| e037ff6bba | |||
| 95bfda1ff0 | |||
| b9992e0b45 | |||
| f6ba793885 | |||
| bbe65a8ea3 | |||
| 20af7371d0 | |||
| a33fb0c439 | |||
| 87003c8b5b | |||
| ddd48ee79f | |||
| a9819df3ee | |||
| 15dffb22aa | |||
| 6ef5f1ff62 | |||
| acc28c68a4 | |||
| 6c2da60eb0 | |||
| 490081077d | |||
| f4a08092da | |||
| 0116efd4a3 | |||
| 9719a24f8a | |||
| 3a7d5a099b | |||
| 27dba655fc | |||
| a25dd387bf | |||
| a89767cc16 | |||
| a13df5b68d | |||
| 6a689504ff | |||
| 6521d2bcfb | |||
| 26d55b15de | |||
| 041b7e8a29 | |||
| 6eeb425e7a | |||
| d2d0eb829e | |||
| 058505b664 | |||
| 8adecedb40 | |||
| 838a51db21 | |||
| 4d4dfc27fc | |||
| 1444439cf3 | |||
| e64fc8d5ab | |||
| 9a31f772d9 | |||
| 12876ee4ce | |||
| a4a349da45 | |||
| ecbc3cae71 | |||
| 57609c87fb | |||
| bb2e24e028 | |||
| 5cafb26e93 | |||
| f74ef7b293 | |||
| 7ef8f531e7 | |||
| afb65c7b19 | |||
| 74a0673663 | |||
| 20fae6e512 | |||
| 509cd242f7 | |||
| f01ec516eb | |||
| 394b1000d2 | |||
| e0b9fba788 | |||
| 378ee29cc2 | |||
| 02bcef71dd | |||
| 248e7c8003 | |||
| a2e93ebd56 | |||
| 21a9454de1 | |||
| ec286eed08 | |||
| f16978d1fe | |||
| fa3adc7606 | |||
| 192144fc5d | |||
| a4d155c5e4 | |||
| 6c56e9d199 | |||
| bb18f87a98 | |||
| dda6a31381 | |||
| 6e25e18e98 | |||
| ffd978c24f | |||
| 4c4af03a5a | |||
| c0739bb8b7 | |||
| 5add7cb0b1 | |||
| 99f49f1061 | |||
| 401eaca9ab | |||
| da784fe02b | |||
| d507b29559 | |||
| 35ca13b38d | |||
| 04b92a31a8 | |||
| dd311d759d | |||
| b504ca9f0a | |||
| bd61c5c721 | |||
| 24694b0047 | |||
| 5258154285 | |||
| 221f993b46 | |||
| ae5ea70b93 | |||
| f59ffbeb63 | |||
| ce55275634 | |||
| 20c5892f9a | |||
| 9231245a3f | |||
| cbfed20e6f | |||
| 640274ed52 | |||
| 1507a39a2b | |||
| e6405653d8 | |||
| be1541a646 | |||
| f37f9bf5e3 | |||
| a5c39ca8c8 | |||
| cb7e7b2a74 | |||
| 2e8e705bab | |||
| ab3812432b | |||
| d2acb36e3b | |||
| 601743ff7a | |||
| 7eca74ac05 | |||
| 02b4ec04bb | |||
| 8ead9014d0 | |||
| 4920e82dd6 | |||
| 3150253661 | |||
| baa423b45a | |||
| 77e5d8ea96 | |||
| 9a8166d649 | |||
| da8c0cd2db | |||
| fc2711b543 | |||
| b4327bd36c | |||
| f7f75923aa | |||
| 0b4388bc5b | |||
| f08883071f | |||
| bb8a2ee3a6 | |||
| 6bfa7595d8 | |||
| 8308e501cd | |||
| 25909c0d9d | |||
| 2844b1ac38 | |||
| 6fd62b1cee | |||
| 1579f53a61 | |||
| 7af7851952 | |||
| 5dbd1a6dcc | |||
| 24881537a1 | |||
| 631c29b26b | |||
| ab249d4032 | |||
| 5bfa3f6274 | |||
| 82ee25dfaa | |||
| fd9a24553f | |||
| ae1c20fad9 | |||
| 734f777ff9 | |||
| 498115d5d9 | |||
| 033ff06b68 | |||
| c145a8e1a1 | |||
| ae5b0dbc29 | |||
| 95aa957c80 | |||
| 7dff9ddeeb | |||
| b4e755747f | |||
| 348fa402be | |||
| 344218ff3d | |||
| 90a1a2febf | |||
| e234a24894 | |||
| d9beb75bd6 | |||
| dadea8c83d | |||
| 31d40e5509 | |||
| a917e84b51 | |||
| f30b497206 | |||
| 706e32c20b | |||
| 4d98552c37 | |||
| 5311bd3f4e | |||
| 8d716fb7ba | |||
| 01b3caaf49 | |||
| cd73c0b9ca | |||
| 7ec5230402 | |||
| 9dbe026f83 | |||
| 3fae10da3e | |||
| d775154b92 | |||
| 6c306b3542 | |||
| 58b46ffeac | |||
| 0bb7b7c60e | |||
| 58adf9a385 | |||
| d6ba968ace | |||
| 1706721a62 | |||
| 7f88bd2eaf | |||
| b819366265 | |||
| 47ff7d9dba | |||
| e5f5254877 | |||
| 4778f728f9 | |||
| e80e4573be | |||
| fdf0f3f282 | |||
| a81fce47d0 | |||
| 2cd6989b11 | |||
| 21abb0d205 | |||
| 5e1a271ca2 | |||
| 868e4c41e1 | |||
| a6e23bb713 | |||
| 446406dd62 | |||
| 091f9f7eae | |||
| 10b1e06263 | |||
| a8865a51fd | |||
| 32343297fc | |||
| aaa5deb0c0 | |||
| 808c519a1f | |||
| 262b110f9f | |||
| d0fe19f996 | |||
| 8e6675677f | |||
| 82dbae6185 | |||
| 943f1df325 | |||
| 018abcfe5f | |||
| 6b4f716508 | |||
| 82b6ff0c28 | |||
| d0c3132a63 | |||
| 02f0252dea | |||
| 74b3921eee | |||
| 1695c79021 | |||
| a3b0534b86 | |||
| a13f94d40f | |||
| 73288420a8 | |||
| e224387eb4 | |||
| 626d322639 | |||
| 7dce7a84c7 | |||
| 6234268f10 | |||
| 7a1525c568 | |||
| fe99eb7147 | |||
| d691ecbea3 | |||
| f60bcca893 | |||
| 75661a2266 | |||
| 1026f361ef | |||
| 69fe203006 | |||
| f8ccaa3a81 | |||
| c10a0a0cdf | |||
| aceb6ab666 | |||
| c3a2aff9d3 | |||
| c9e41db826 | |||
| 1e7a12fff5 | |||
| ba88e48f6a | |||
| 52979662c5 | |||
| 50e6d80065 | |||
| 16a24cfeac | |||
| bab095e5b5 | |||
| b1a3b078e9 | |||
| baae44610a | |||
| 8d2dffe5b4 | |||
| 7b3eb23af8 | |||
| fb526846fe | |||
| 6bd1371283 | |||
| 3c8c7af196 | |||
| 929b43ed48 | |||
| a947064b7d | |||
| 5bc9866f43 | |||
| 61d82e210a | |||
| a876ac9386 | |||
| da1502c463 | |||
| 76bb782f64 | |||
| e6f4b043cb | |||
| d651ffaf2e | |||
| e554378b5e | |||
| b463bd797e | |||
| 699e6e16c9 | |||
| f8477c41e1 | |||
| 9a63333aec | |||
| 6e40914258 | |||
| 56a1dd931e | |||
| 57fd2e6a52 | |||
| 113db06cdd | |||
| 4ee5c59cfd | |||
| 15812678a3 | |||
| ee0379b321 | |||
| dcf279177d | |||
| 01115824f7 | |||
| b68473ae11 | |||
| a65c203c9b | |||
| 0a848240d4 | |||
| d03821b88a | |||
| 4d32762899 | |||
| 2cb4b6d16d | |||
| b770e566dd | |||
| 51ebc88f0c | |||
| a04a75724d | |||
| 6e5af3d799 | |||
| 0283a73a32 | |||
| 5f593031f0 | |||
| 0eeef2d4bd | |||
| bb6164e30b | |||
| d3beae4871 | |||
| 8df0df32f8 | |||
| b0228dd0fd | |||
| ffca2dee1d | |||
| cba985bfea | |||
| 6a10a67205 | |||
| 880fb5bd89 | |||
| 6a0ade074d | |||
| 6cf4629d0f | |||
| ce23e5fa9e | |||
| d16fb838ca | |||
| 6b9eb8aae3 | |||
| 78008d1fea | |||
| 69fb9bb39b | |||
| 92f1557235 | |||
| 8e487ba36d | |||
| 7eb088b5ed | |||
| 9ef8ea95b0 | |||
| eedf54b485 | |||
| a461815957 | |||
| 687c2f08f6 | |||
| 2294f23e5f | |||
| bdfd81322b | |||
| 3ceb0de8d8 | |||
| c4b5208867 | |||
| 9c3f6b0c10 | |||
| 0550755c7d | |||
| 47602f267a | |||
| 656e67ef90 | |||
| c53883b635 | |||
| c4278c81f1 | |||
| c94dcf5940 | |||
| 08ca3eff12 | |||
| b40a241b2e | |||
| f86f1e83ad | |||
| be85701abe | |||
| 190eb474a6 | |||
| 8db1138081 | |||
| afbfd4d3fa | |||
| 9b8efbfdd5 | |||
| cacada87f3 | |||
| 8a36c54318 | |||
| 879d411669 | |||
| b38be2ce7b | |||
| 1810c9b61c | |||
| 98737f14f1 | |||
| b311118a04 | |||
| 8a337f1faf | |||
| dbc5bd4104 | |||
| a9c3f566da | |||
| 6d9c9cd964 | |||
| 25c8883e49 | |||
| 793943fc2f | |||
| e98f86c540 | |||
| 1c8ff48f92 | |||
| 1fb73e2211 | |||
| 5279ade0e7 | |||
| 984134fb9d | |||
| eb8f1f24b7 | |||
| e49dc8bcfa | |||
| e742da24a7 | |||
| 203b65475c | |||
| 576c5f4c9e | |||
| d2434b5591 | |||
| 634c008fcd | |||
| 83f1ccb8ad | |||
| cea401c513 | |||
| 6b54c1b6d4 | |||
| 193c4a953e | |||
| d389134036 | |||
| d8b140e341 | |||
| 5931e1143b | |||
| e6d0c4b79f | |||
| 44a4a18320 | |||
| 2f96506a6e | |||
| f904606b32 | |||
| 99bb14680a | |||
| 83df3dda95 | |||
| 5e4d67209c | |||
| 2798af1668 | |||
| f0e41ce4c7 | |||
| 300602dd32 | |||
| 136f6778e2 | |||
| 2fa7907054 | |||
| f3803c4c22 | |||
| 5d37927b0a | |||
| 6227f5cfa2 | |||
| 9fbb9fa5e1 | |||
| de81ee7ee6 | |||
| 5fcf971e28 | |||
| 492f70fc4b | |||
| 3ced7b7212 | |||
| 7b55867ea7 | |||
| 3e15ef1c86 | |||
| 0cdc836054 | |||
| 1aad62b95d | |||
| ed1c88920e | |||
| e6ca20c4a2 | |||
| cfa3470df6 | |||
| 479f297cf6 | |||
| 7e1b222f90 | |||
| 69baa6ea1a | |||
| 0fce93be37 | |||
| 51611ec2bb | |||
| 228a78136d | |||
| 34d10ace7a | |||
| 57bd0a5628 | |||
| 42e4860855 | |||
| ea1c9f70d7 | |||
| d3085b0450 | |||
| 63d02f1d5f | |||
| dfecbe5bfa | |||
| bcf9f00de5 | |||
| a8e8e35678 | |||
| 2ec4a8b4ce | |||
| 6c3d3dee81 | |||
| 40b3116ed7 | |||
| df7582b138 | |||
| b08dab9aa1 | |||
| da5a4804df | |||
| d12f43498e | |||
| f9f2facd76 | |||
| eaee3954c1 | |||
| eb235e11b6 | |||
| 0c5fe61ed3 | |||
| 76052b443a | |||
| 5a48248e1e | |||
| bedff3278f | |||
| 0bb48153a5 | |||
| b75246e3ca | |||
| 2d31f0d7fe | |||
| 87cfca721e | |||
| 54d36f3337 | |||
| a4a17d171a | |||
| 7c2673fc66 | |||
| c77ecbb10f | |||
| f0ba57ba23 | |||
| 893aa80361 | |||
| 59ac3d1d45 | |||
| 247a9478c8 | |||
| 1c64d858c2 | |||
| 91a1d7faaf | |||
| 214bbfa7b6 | |||
| 3ee4492b3c | |||
| 38c453b3c6 | |||
| 3d41c61991 | |||
| 1f9f47f97e | |||
| 41cc2923b1 | |||
| 4c180f3eed | |||
| 5f9a64dbea | |||
| 9d37bfdcf1 | |||
| d738c3aca6 | |||
| 836c4313ab | |||
| 91c6478add | |||
| fce527a55b | |||
| 9a1f62fc1f | |||
| 018d8656d3 | |||
| 2636e1ba45 | |||
| caed07dfc1 | |||
| 373cf3328d | |||
| 0370c3fa01 | |||
| f5143a7d63 | |||
| 346b2a27cb | |||
| 38281e6361 | |||
| 6e8413f568 | |||
| cb04364381 | |||
| 83d2555123 | |||
| 0ace97c8d4 | |||
| 9e3a0c61b8 | |||
| 2fda5c7873 | |||
| e29868c8ce | |||
| ac560be870 | |||
| 5a29cbf4a7 | |||
| dc77894f68 | |||
| 74432a6b9d | |||
| 2b2fa7e77c | |||
| c3f71b33aa | |||
| 927aae72d1 | |||
| 2a674f4e8d | |||
| 0b86ce2bda | |||
| 548a0709f4 | |||
| da84c0bb4d | |||
| 9e68a5b9ab | |||
| 6982bdaa28 | |||
| c1809232fe | |||
| 3c06c82eb7 | |||
| 1bcccb3134 | |||
| cdf49dc87e | |||
| 0a0fb8f803 | |||
| 60cfd56369 | |||
| 73050d38c5 | |||
| c50e941972 | |||
| 7c59fd21e2 | |||
| b095a4221c | |||
| 1ef39fa3b8 | |||
| fcf4530d83 | |||
| 0515e14d27 | |||
| ddbef0bd79 | |||
| bc5d31f86a | |||
| 09147a2aab | |||
| a75a119e2f | |||
| c1b3546161 | |||
| 8338432c7b | |||
| 8beae065cf | |||
| 0e7d39aa13 | |||
| 74063ad735 | |||
| 55a29808c9 | |||
| 40f3de3939 | |||
| 5d94ab09e3 | |||
| b34ff6853d | |||
| e2570be957 | |||
| 95e6fff3da | |||
| 9de12b7385 | |||
| beffe906e4 | |||
| e850d1073d | |||
| c02a2ba5ba | |||
| f92bb6690b | |||
| 5842a3bba6 | |||
| fcf691d97c | |||
| a32c7d5f07 | |||
| edfb18b75a | |||
| 5544c5d5d4 | |||
| 22100f7c3a | |||
| 8ece01ccda | |||
| 9b68039a62 | |||
| a914326e75 | |||
| 2b7dd35e05 | |||
| 15e41169ad | |||
| f8c5219c12 | |||
| c570b67dda | |||
| 456fac1700 | |||
| 41e58c394b | |||
| 5aeda5f67b | |||
| c96adf168c | |||
| 40c5bc01ff | |||
| 09dabef70c | |||
| 96edee806e | |||
| e58f4683d1 | |||
| 9750817bf0 | |||
| 7099d730e6 | |||
| 13c290e99f | |||
| cf37966e39 | |||
| 9449c4b9b5 | |||
| 046172e5d9 | |||
| c74446e38c | |||
| 7897460993 | |||
| 4b59583bca | |||
| 41f73559f2 | |||
| d3090c0965 | |||
| dc5caebbf8 | |||
| 14280dfedb | |||
| 8fdf11135a | |||
| c8baa8f349 | |||
| a6e25b46af | |||
| 395d14ab58 | |||
| 0d4b57df7a | |||
| 416e7617b3 | |||
| 838c470017 | |||
| f0a09665db | |||
| 1397fa64d5 | |||
| ac17a6afcf | |||
| 35af1bab30 | |||
| 1fe7bb271a | |||
| 774e25d944 | |||
| 6770e8541d | |||
| 70e94e4dde | |||
| 0ffbc6e345 | |||
| 25e796753f | |||
| 70d9ef4f77 | |||
| fd67c9a589 | |||
| f0917ff774 | |||
| 843281dec0 | |||
| 3a21588429 | |||
| 21eeb09a3c | |||
| 900c5ed358 | |||
| 195c8a92d1 | |||
| 7c651e6093 | |||
| 860b899f0c | |||
| 87b7524de9 | |||
| 29641ae16a | |||
| 02e32a7a9d | |||
| 3056369c6e | |||
| 3da75726d3 | |||
| b7346de47d | |||
| 7a69100b2f | |||
| 2732d2b9d3 | |||
| 87bb27cc4f | |||
| bafa300b0f | |||
| 939cf4542f | |||
| 874975da54 | |||
| f0bebd4c33 | |||
| c444a11862 | |||
| 4c0704e338 | |||
| 77f4cd5d58 | |||
| 9858d3c5a8 | |||
| 414acbc9ec | |||
| 21f904db42 | |||
| f6ca253849 | |||
| 3f989191e3 | |||
| 2bea014e89 | |||
| 84fc19a75f | |||
| d803924ef0 | |||
| 889f8d9d30 | |||
| 1dcb7eaf1f | |||
| 5f9e4ace2f | |||
| 6386330973 | |||
| fd89b9755e | |||
| 730f454278 | |||
| e2fca29c91 | |||
| f97a222cf5 | |||
| c75105e977 | |||
| 7096471d65 | |||
| cc1cee8a38 | |||
| 5f2680889f | |||
| b3ae8bb606 | |||
| 72d9f37845 | |||
| fdfccafd84 | |||
| a784f946ba | |||
| a04af6c4bd | |||
| 64b24a96c8 | |||
| a62a5d0d7b | |||
| 3043d1e839 | |||
| a3aefb6902 | |||
| a42aaa270c | |||
| f8b471c17b | |||
| 87adff44db | |||
| 767bba9c04 | |||
| 0c827521d0 | |||
| 80cec7d12f | |||
| 5f916357e9 | |||
| ea82eea9bb | |||
| 22222d7db4 | |||
| cebee369d1 | |||
| faf809851c | |||
| d05aafd76b | |||
| 8d52721873 | |||
| 66c6152cd2 | |||
| 32cd51d3a5 | |||
| 497a28401e | |||
| e46912047c | |||
| 56b573ede5 | |||
| 0276be1789 | |||
| 7db4c60fc3 | |||
| 95cc01dd91 | |||
| cce1dddf42 | |||
| 0938b57841 | |||
| aef8550e2f | |||
| 71bf0bde32 | |||
| 750623b9b1 | |||
| 1f12c53b65 | |||
| 8717ea1b95 | |||
| db2eb658ca | |||
| 70483484ce | |||
| d21afc43a1 | |||
| 7ad0803f2e | |||
| ec4bfd55f9 | |||
| f65174a0db | |||
| 8b1fcd4dd7 | |||
| 9509237958 | |||
| f20fd20a06 | |||
| 8e48120fb7 | |||
| 44cc5ac883 | |||
| 9a43cc8c4b | |||
| 8dfc0d54f4 | |||
| 77febd21de | |||
| 84a997c66b | |||
| b900a59fc2 | |||
| ca782dbc58 | |||
| 746cda27ec | |||
| 16d1651656 | |||
| 4735fb2377 | |||
| ec6b518fd2 | |||
| 580ad1b192 | |||
| 23d8810486 | |||
| d579d62eb6 | |||
| 529f785e3c | |||
| 0581ae87b4 | |||
| cda1059336 | |||
| 1aed6b5c30 | |||
| 4e68705b24 | |||
| 216cb1ea12 | |||
| 8ef6a0b432 | |||
| 5dc152c46e | |||
| c3a21437e4 | |||
| 32bc8dcbf9 | |||
| 677ca7b4aa | |||
| dfc2331104 | |||
| cd06bbfb8d | |||
| 1d596bcbac | |||
| 0cb7b9c13d | |||
| a180efeca7 | |||
| eef24ea29c | |||
| 458bb3d7f7 | |||
| ffb23d92c0 | |||
| 0ce39a4cf6 | |||
| a24c70e490 | |||
| 8d4ef6e883 | |||
| 54865ebdee | |||
| cb8e704d5c | |||
| 57f4978442 | |||
| b8833f4c9e | |||
| 5c40cbc675 | |||
| a455dcc919 | |||
| 289487cc46 | |||
| 42b28d5bd6 | |||
| 46bee05d93 | |||
| 49bed5cd5f | |||
| 624cf93e2e | |||
| 6ab76cda51 | |||
| 15beb81368 | |||
| 6a6cce03b7 | |||
| 970ff87ef6 | |||
| 8b6c4d322f | |||
| b0884ad7c3 | |||
| cf09f86df2 |
@@ -1,7 +1,10 @@
|
||||
.DS_Store
|
||||
lib-cov
|
||||
*.seed
|
||||
*.log
|
||||
*.csv
|
||||
*.dat
|
||||
*.out
|
||||
benchmarks/graphs
|
||||
*.pid
|
||||
benchmarks/graphs
|
||||
testing.js
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
[submodule "lib/support/ext"]
|
||||
path = lib/support/ext
|
||||
url = git://github.com/visionmedia/ext.js.git
|
||||
[submodule "lib/support/sass"]
|
||||
path = lib/support/sass
|
||||
url = git://github.com/visionmedia/sass.js.git
|
||||
[submodule "lib/support/class"]
|
||||
path = lib/support/class
|
||||
url = git://github.com/visionmedia/class.js.git
|
||||
[submodule "lib/support/haml"]
|
||||
path = lib/support/haml
|
||||
[submodule "support/expresso"]
|
||||
path = support/expresso
|
||||
url = git://github.com/visionmedia/expresso.git
|
||||
[submodule "support/haml"]
|
||||
path = support/haml
|
||||
url = git://github.com/visionmedia/haml.js.git
|
||||
[submodule "lib/support/multipart"]
|
||||
path = lib/support/multipart
|
||||
url = git://github.com/isaacs/multipart-js.git
|
||||
[submodule "support/ejs"]
|
||||
path = support/ejs
|
||||
url = git://github.com/visionmedia/ejs.git
|
||||
[submodule "support/connect-form"]
|
||||
path = support/connect-form
|
||||
url = git://github.com/visionmedia/connect-form.git
|
||||
[submodule "support/connect"]
|
||||
path = support/connect
|
||||
url = git://github.com/senchalabs/connect.git
|
||||
[submodule "support/should"]
|
||||
path = support/should
|
||||
url = git://github.com/visionmedia/should.js.git
|
||||
[submodule "support/formidable"]
|
||||
path = support/formidable
|
||||
url = git://github.com/felixge/node-formidable.git
|
||||
[submodule "support/jade"]
|
||||
path = support/jade
|
||||
url = git://github.com/visionmedia/jade.git
|
||||
[submodule "support/qs"]
|
||||
path = support/qs
|
||||
url = git://github.com/visionmedia/node-querystring.git
|
||||
[submodule "support/mime"]
|
||||
path = support/mime
|
||||
url = https://github.com/bentomas/node-mime.git
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
.git*
|
||||
docs/
|
||||
examples/
|
||||
support/
|
||||
test/
|
||||
testing.js
|
||||
.DS_Store
|
||||
@@ -1,4 +1,321 @@
|
||||
|
||||
2.0.0rc / 2011-03-14
|
||||
==================
|
||||
|
||||
* Fixed; expose `HTTPSServer` constructor
|
||||
* Fixed express(1) default test charset. Closes #579 [reported by secoif]
|
||||
* Fixed; default charset to utf-8 instead of utf8 for lame IE [reported by NickP]
|
||||
|
||||
2.0.0beta3 / 2011-03-09
|
||||
==================
|
||||
|
||||
* Added support for `res.contentType()` literal
|
||||
The original `res.contentType('.json')`,
|
||||
`res.contentType('application/json')`, and `res.contentType('json')`
|
||||
will work now.
|
||||
* Added `res.render()` status option support back
|
||||
* Added charset option for `res.render()`
|
||||
* Added `.charset` support (via connect 1.0.4)
|
||||
* Added view resolution hints when in development and a lookup fails
|
||||
* Added layout lookup support relative to the page view.
|
||||
For example while rendering `./views/user/index.jade` if you create
|
||||
`./views/user/layout.jade` it will be used in favour of the root layout.
|
||||
* Fixed `res.redirect()`. RFC states absolute url [reported by unlink]
|
||||
* Fixed; default `res.send()` string charset to utf8
|
||||
* Removed `Partial` constructor (not currently used)
|
||||
|
||||
2.0.0beta2 / 2011-03-07
|
||||
==================
|
||||
|
||||
* Added res.render() `.locals` support back to aid in migration process
|
||||
* Fixed flash example
|
||||
|
||||
2.0.0beta / 2011-03-03
|
||||
==================
|
||||
|
||||
* Added HTTPS support
|
||||
* Added `res.cookie()` maxAge support
|
||||
* Added `req.header()` _Referrer_ / _Referer_ special-case, either works
|
||||
* Added mount support for `res.redirect()`, now respects the mount-point
|
||||
* Added `union()` util, taking place of `merge(clone())` combo
|
||||
* Added stylus support to express(1) generated app
|
||||
* Added secret to session middleware used in examples and generated app
|
||||
* Added `res.local(name, val)` for progressive view locals
|
||||
* Added default param support to `req.param(name, default)`
|
||||
* Added `app.disabled()` and `app.enabled()`
|
||||
* Added `app.register()` support for omitting leading ".", either works
|
||||
* Added `res.partial()`, using the same interface as `partial()` within a view. Closes #539
|
||||
* Added `app.param()` to map route params to async/sync logic
|
||||
* Added; aliased `app.helpers()` as `app.locals()`. Closes #481
|
||||
* Added extname with no leading "." support to `res.contentType()`
|
||||
* Added `cache views` setting, defaulting to enabled in "production" env
|
||||
* Added index file partial resolution, eg: partial('user') may try _views/user/index.jade_.
|
||||
* Added `req.accepts()` support for extensions
|
||||
* Changed; `res.download()` and `res.sendfile()` now utilize Connect's
|
||||
static file server `connect.static.send()`.
|
||||
* Changed; replaced `connect.utils.mime()` with npm _mime_ module
|
||||
* Changed; allow `req.query` to be pre-defined (via middleware or other parent
|
||||
* Changed view partial resolution, now relative to parent view
|
||||
* Changed view engine signature. no longer `engine.render(str, options, callback)`, now `engine.compile(str, options) -> Function`, the returned function accepts `fn(locals)`.
|
||||
* Fixed `req.param()` bug returning Array.prototype methods. Closes #552
|
||||
* Fixed; using `Stream#pipe()` instead of `sys.pump()` in `res.sendfile()`
|
||||
* Fixed; using _qs_ module instead of _querystring_
|
||||
* Fixed; strip unsafe chars from jsonp callbacks
|
||||
* Removed "stream threshold" setting
|
||||
|
||||
1.0.8 / 2011-03-01
|
||||
==================
|
||||
|
||||
* Allow `req.query` to be pre-defined (via middleware or other parent app)
|
||||
* "connect": ">= 0.5.0 < 1.0.0". Closes #547
|
||||
* Removed the long deprecated __EXPRESS_ENV__ support
|
||||
|
||||
1.0.7 / 2011-02-07
|
||||
==================
|
||||
|
||||
* Fixed `render()` setting inheritance.
|
||||
Mounted apps would not inherit "view engine"
|
||||
|
||||
1.0.6 / 2011-02-07
|
||||
==================
|
||||
|
||||
* Fixed `view engine` setting bug when period is in dirname
|
||||
|
||||
1.0.5 / 2011-02-05
|
||||
==================
|
||||
|
||||
* Added secret to generated app `session()` call
|
||||
|
||||
1.0.4 / 2011-02-05
|
||||
==================
|
||||
|
||||
* Added `qs` dependency to _package.json_
|
||||
* Fixed namespaced `require()`s for latest connect support
|
||||
|
||||
1.0.3 / 2011-01-13
|
||||
==================
|
||||
|
||||
* Remove unsafe characters from JSONP callback names [Ryan Grove]
|
||||
|
||||
1.0.2 / 2011-01-10
|
||||
==================
|
||||
|
||||
* Removed nested require, using `connect.router`
|
||||
|
||||
1.0.1 / 2010-12-29
|
||||
==================
|
||||
|
||||
* Fixed for middleware stacked via `createServer()`
|
||||
previously the `foo` middleware passed to `createServer(foo)`
|
||||
would not have access to Express methods such as `res.send()`
|
||||
or props like `req.query` etc.
|
||||
|
||||
1.0.0 / 2010-11-16
|
||||
==================
|
||||
|
||||
* Added; deduce partial object names from the last segment.
|
||||
For example by default `partial('forum/post', postObject)` will
|
||||
give you the _post_ object, providing a meaningful default.
|
||||
* Added http status code string representation to `res.redirect()` body
|
||||
* Added; `res.redirect()` supporting _text/plain_ and _text/html_ via __Accept__.
|
||||
* Added `req.is()` to aid in content negotiation
|
||||
* Added partial local inheritance [suggested by masylum]. Closes #102
|
||||
providing access to parent template locals.
|
||||
* Added _-s, --session[s]_ flag to express(1) to add session related middleware
|
||||
* Added _--template_ flag to express(1) to specify the
|
||||
template engine to use.
|
||||
* Added _--css_ flag to express(1) to specify the
|
||||
stylesheet engine to use (or just plain css by default).
|
||||
* Added `app.all()` support [thanks aheckmann]
|
||||
* Added partial direct object support.
|
||||
You may now `partial('user', user)` providing the "user" local,
|
||||
vs previously `partial('user', { object: user })`.
|
||||
* Added _route-separation_ example since many people question ways
|
||||
to do this with CommonJS modules. Also view the _blog_ example for
|
||||
an alternative.
|
||||
* Performance; caching view path derived partial object names
|
||||
* Fixed partial local inheritance precedence. [reported by Nick Poulden] Closes #454
|
||||
* Fixed jsonp support; _text/javascript_ as per mailinglist discussion
|
||||
|
||||
1.0.0rc4 / 2010-10-14
|
||||
==================
|
||||
|
||||
* Added _NODE_ENV_ support, _EXPRESS_ENV_ is deprecated and will be removed in 1.0.0
|
||||
* Added route-middleware support (very helpful, see the [docs](http://expressjs.com/guide.html#Route-Middleware))
|
||||
* Added _jsonp callback_ setting to enable/disable jsonp autowrapping [Dav Glass]
|
||||
* Added callback query check on response.send to autowrap JSON objects for simple webservice implementations [Dav Glass]
|
||||
* Added `partial()` support for array-like collections. Closes #434
|
||||
* Added support for swappable querystring parsers
|
||||
* Added session usage docs. Closes #443
|
||||
* Added dynamic helper caching. Closes #439 [suggested by maritz]
|
||||
* Added authentication example
|
||||
* Added basic Range support to `res.sendfile()` (and `res.download()` etc)
|
||||
* Changed; `express(1)` generated app using 2 spaces instead of 4
|
||||
* Default env to "development" again [aheckmann]
|
||||
* Removed _context_ option is no more, use "scope"
|
||||
* Fixed; exposing _./support_ libs to examples so they can run without installs
|
||||
* Fixed mvc example
|
||||
|
||||
1.0.0rc3 / 2010-09-20
|
||||
==================
|
||||
|
||||
* Added confirmation for `express(1)` app generation. Closes #391
|
||||
* Added extending of flash formatters via `app.flashFormatters`
|
||||
* Added flash formatter support. Closes #411
|
||||
* Added streaming support to `res.sendfile()` using `sys.pump()` when >= "stream threshold"
|
||||
* Added _stream threshold_ setting for `res.sendfile()`
|
||||
* Added `res.send()` __HEAD__ support
|
||||
* Added `res.clearCookie()`
|
||||
* Added `res.cookie()`
|
||||
* Added `res.render()` headers option
|
||||
* Added `res.redirect()` response bodies
|
||||
* Added `res.render()` status option support. Closes #425 [thanks aheckmann]
|
||||
* Fixed `res.sendfile()` responding with 403 on malicious path
|
||||
* Fixed `res.download()` bug; when an error occurs remove _Content-Disposition_
|
||||
* Fixed; mounted apps settings now inherit from parent app [aheckmann]
|
||||
* Fixed; stripping Content-Length / Content-Type when 204
|
||||
* Fixed `res.send()` 204. Closes #419
|
||||
* Fixed multiple _Set-Cookie_ headers via `res.header()`. Closes #402
|
||||
* Fixed bug messing with error handlers when `listenFD()` is called instead of `listen()`. [thanks guillermo]
|
||||
|
||||
|
||||
1.0.0rc2 / 2010-08-17
|
||||
==================
|
||||
|
||||
* Added `app.register()` for template engine mapping. Closes #390
|
||||
* Added `res.render()` callback support as second argument (no options)
|
||||
* Added callback support to `res.download()`
|
||||
* Added callback support for `res.sendfile()`
|
||||
* Added support for middleware access via `express.middlewareName()` vs `connect.middlewareName()`
|
||||
* Added "partials" setting to docs
|
||||
* Added default expresso tests to `express(1)` generated app. Closes #384
|
||||
* Fixed `res.sendfile()` error handling, defer via `next()`
|
||||
* Fixed `res.render()` callback when a layout is used [thanks guillermo]
|
||||
* Fixed; `make install` creating ~/.node_libraries when not present
|
||||
* Fixed issue preventing error handlers from being defined anywhere. Closes #387
|
||||
|
||||
1.0.0rc / 2010-07-28
|
||||
==================
|
||||
|
||||
* Added mounted hook. Closes #369
|
||||
* Added connect dependency to _package.json_
|
||||
|
||||
* Removed "reload views" setting and support code
|
||||
development env never caches, production always caches.
|
||||
|
||||
* Removed _param_ in route callbacks, signature is now
|
||||
simply (req, res, next), previously (req, res, params, next).
|
||||
Use _req.params_ for path captures, _req.query_ for GET params.
|
||||
|
||||
* Fixed "home" setting
|
||||
* Fixed middleware/router precedence issue. Closes #366
|
||||
* Fixed; _configure()_ callbacks called immediately. Closes #368
|
||||
|
||||
1.0.0beta2 / 2010-07-23
|
||||
==================
|
||||
|
||||
* Added more examples
|
||||
* Added; exporting `Server` constructor
|
||||
* Added `Server#helpers()` for view locals
|
||||
* Added `Server#dynamicHelpers()` for dynamic view locals. Closes #349
|
||||
* Added support for absolute view paths
|
||||
* Added; _home_ setting defaults to `Server#route` for mounted apps. Closes #363
|
||||
* Added Guillermo Rauch to the contributor list
|
||||
* Added support for "as" for non-collection partials. Closes #341
|
||||
* Fixed _install.sh_, ensuring _~/.node_libraries_ exists. Closes #362 [thanks jf]
|
||||
* Fixed `res.render()` exceptions, now passed to `next()` when no callback is given [thanks guillermo]
|
||||
* Fixed instanceof `Array` checks, now `Array.isArray()`
|
||||
* Fixed express(1) expansion of public dirs. Closes #348
|
||||
* Fixed middleware precedence. Closes #345
|
||||
* Fixed view watcher, now async [thanks aheckmann]
|
||||
|
||||
1.0.0beta / 2010-07-15
|
||||
==================
|
||||
|
||||
* Re-write
|
||||
- much faster
|
||||
- much lighter
|
||||
- Check [ExpressJS.com](http://expressjs.com) for migration guide and updated docs
|
||||
|
||||
0.14.0 / 2010-06-15
|
||||
==================
|
||||
|
||||
* Utilize relative requires
|
||||
* Added Static bufferSize option [aheckmann]
|
||||
* Fixed caching of view and partial subdirectories [aheckmann]
|
||||
* Fixed mime.type() comments now that ".ext" is not supported
|
||||
* Updated haml submodule
|
||||
* Updated class submodule
|
||||
* Removed bin/express
|
||||
|
||||
0.13.0 / 2010-06-01
|
||||
==================
|
||||
|
||||
* Added node v0.1.97 compatibility
|
||||
* Added support for deleting cookies via Request#cookie('key', null)
|
||||
* Updated haml submodule
|
||||
* Fixed not-found page, now using using charset utf-8
|
||||
* Fixed show-exceptions page, now using using charset utf-8
|
||||
* Fixed view support due to fs.readFile Buffers
|
||||
* Changed; mime.type() no longer accepts ".type" due to node extname() changes
|
||||
|
||||
0.12.0 / 2010-05-22
|
||||
==================
|
||||
|
||||
* Added node v0.1.96 compatibility
|
||||
* Added view `helpers` export which act as additional local variables
|
||||
* Updated haml submodule
|
||||
* Changed ETag; removed inode, modified time only
|
||||
* Fixed LF to CRLF for setting multiple cookies
|
||||
* Fixed cookie complation; values are now urlencoded
|
||||
* Fixed cookies parsing; accepts quoted values and url escaped cookies
|
||||
|
||||
0.11.0 / 2010-05-06
|
||||
==================
|
||||
|
||||
* Added support for layouts using different engines
|
||||
- this.render('page.html.haml', { layout: 'super-cool-layout.html.ejs' })
|
||||
- this.render('page.html.haml', { layout: 'foo' }) // assumes 'foo.html.haml'
|
||||
- this.render('page.html.haml', { layout: false }) // no layout
|
||||
* Updated ext submodule
|
||||
* Updated haml submodule
|
||||
* Fixed EJS partial support by passing along the context. Issue #307
|
||||
|
||||
0.10.1 / 2010-05-03
|
||||
==================
|
||||
|
||||
* Fixed binary uploads.
|
||||
|
||||
0.10.0 / 2010-04-30
|
||||
==================
|
||||
|
||||
* Added charset support via Request#charset (automatically assigned to 'UTF-8' when respond()'s
|
||||
encoding is set to 'utf8' or 'utf-8'.
|
||||
* Added "encoding" option to Request#render(). Closes #299
|
||||
* Added "dump exceptions" setting, which is enabled by default.
|
||||
* Added simple ejs template engine support
|
||||
* Added error reponse support for text/plain, application/json. Closes #297
|
||||
* Added callback function param to Request#error()
|
||||
* Added Request#sendHead()
|
||||
* Added Request#stream()
|
||||
* Added support for Request#respond(304, null) for empty response bodies
|
||||
* Added ETag support to Request#sendfile()
|
||||
* Added options to Request#sendfile(), passed to fs.createReadStream()
|
||||
* Added filename arg to Request#download()
|
||||
* Performance enhanced due to pre-reversing plugins so that plugins.reverse() is not called on each request
|
||||
* Performance enhanced by preventing several calls to toLowerCase() in Router#match()
|
||||
* Changed; Request#sendfile() now streams
|
||||
* Changed; Renamed Request#halt() to Request#respond(). Closes #289
|
||||
* Changed; Using sys.inspect() instead of JSON.encode() for error output
|
||||
* Changed; run() returns the http.Server instance. Closes #298
|
||||
* Changed; Defaulting Server#host to null (INADDR_ANY)
|
||||
* Changed; Logger "common" format scale of 0.4f
|
||||
* Removed Logger "request" format
|
||||
* Fixed; Catching ENOENT in view caching, preventing error when "views/partials" is not found
|
||||
* Fixed several issues with http client
|
||||
* Fixed Logger Content-Length output
|
||||
* Fixed bug preventing Opera from retaining the generated session id. Closes #292
|
||||
|
||||
0.9.0 / 2010-04-14
|
||||
==================
|
||||
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
'Software'), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
@@ -1,46 +1,52 @@
|
||||
|
||||
AB = ab
|
||||
ABFLAGS = -n 3000 -c 50
|
||||
NODE = node
|
||||
COFFEE = coffee
|
||||
PREFIX = /usr/local
|
||||
|
||||
all: test
|
||||
|
||||
install: bin/express
|
||||
ln -fs $< $(PREFIX)/bin/express
|
||||
DOCS = docs/index.md \
|
||||
docs/screencasts.md \
|
||||
docs/executable.md \
|
||||
docs/contrib.md \
|
||||
docs/guide.md \
|
||||
docs/migrate.md \
|
||||
docs/applications.md
|
||||
|
||||
uninstall:
|
||||
rm -f $(PREFIX)/bin/express
|
||||
MANPAGES =$(DOCS:.md=.1)
|
||||
HTMLDOCS =$(DOCS:.md=.html)
|
||||
|
||||
test:
|
||||
@$(NODE) spec/node.js all
|
||||
|
||||
app: app-chat
|
||||
|
||||
prof:
|
||||
@$(NODE) --prof --prof_auto examples/chat/app.js
|
||||
|
||||
app-chat:
|
||||
@$(NODE) examples/chat/app.js
|
||||
@NODE_ENV=test ./support/expresso/bin/expresso \
|
||||
-I lib \
|
||||
-I support \
|
||||
-I support/connect/lib \
|
||||
-I support/haml/lib \
|
||||
-I support/jade/lib \
|
||||
-I support/ejs/lib \
|
||||
$(TESTFLAGS) \
|
||||
test/*.test.js
|
||||
|
||||
app-hello-world:
|
||||
@$(NODE) examples/hello-world/app.js
|
||||
test-cov:
|
||||
@TESTFLAGS=--cov $(MAKE) test
|
||||
|
||||
app-upload:
|
||||
@$(NODE) examples/upload/app.js
|
||||
|
||||
app-coffee-upload: compile-coffee
|
||||
@$(NODE) examples/coffee-upload/app.js
|
||||
|
||||
compile-coffee:
|
||||
@$(COFFEE) examples/coffee-upload/app.coffee
|
||||
docs: $(MANPAGES) $(HTMLDOCS)
|
||||
@ echo "... generating TOC"
|
||||
@./support/toc.js docs/guide.html
|
||||
|
||||
benchmark: benchmarks/run
|
||||
@./benchmarks/run
|
||||
@./benchmarks/graph
|
||||
%.1: %.md
|
||||
@echo "... $< -> $@"
|
||||
@ronn -r --pipe $< > $@
|
||||
|
||||
graphs:
|
||||
@./benchmarks/graph
|
||||
%.html: %.md
|
||||
@echo "... $< -> $@"
|
||||
@ronn -5 --pipe --fragment $< \
|
||||
| cat docs/layout/head.html - docs/layout/foot.html \
|
||||
| sed 's/NAME/Express/g' \
|
||||
> $@
|
||||
|
||||
.PHONY: install test app benchmark graphs
|
||||
site:
|
||||
rm -fr /tmp/docs \
|
||||
&& cp -fr docs /tmp/docs \
|
||||
&& git checkout gh-pages \
|
||||
&& cp -fr /tmp/docs/* . \
|
||||
&& echo "done"
|
||||
|
||||
docclean:
|
||||
rm -f docs/*.{1,html}
|
||||
|
||||
.PHONY: site test test-cov docs docclean
|
||||
@@ -2,113 +2,80 @@
|
||||
# Express
|
||||
|
||||
Insanely fast (and small) server-side JavaScript web development framework
|
||||
built on **node.js** and the **V8 JavaScript engine**.
|
||||
|
||||
* Visit the [Wiki](http://wiki.github.com/visionmedia/express) for documentation
|
||||
* Visit the [Google Group](http://groups.google.com/group/express-js) for discussion
|
||||
|
||||
## Features (so far)
|
||||
|
||||
* Sexy DSL with robust sinatra-like routing
|
||||
* High performance
|
||||
* Session support
|
||||
* Cache API
|
||||
* RESTful HTTP client
|
||||
* Mime helpers
|
||||
* Redirection helpers
|
||||
* Multipart file upload support
|
||||
* Test helpers (mock requests etc)
|
||||
* Environment based configuration
|
||||
* Light-weight JavaScript class implementation via [class.js](http://github.com/visionmedia/class.js/)
|
||||
* Persistent flash messages
|
||||
* Route passing
|
||||
* View support (ejs, haml, sass, etc)
|
||||
* View partials
|
||||
* Full test coverage
|
||||
* Logger plugin with several formats
|
||||
* Upload size restrictions
|
||||
* Extremely readable specs
|
||||
* Cookie support
|
||||
built on [node](http://nodejs.org) and [Connect](http://github.com/senchalabs/connect).
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('Hello World');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
|
||||
## Installation
|
||||
|
||||
Install the [Kiwi package manager for nodejs](http://github.com/visionmedia/kiwi)
|
||||
and run:
|
||||
|
||||
$ kiwi -v install express
|
||||
|
||||
or
|
||||
$ npm install express
|
||||
|
||||
Install via git clone:
|
||||
|
||||
$ git clone git://github.com/visionmedia/express.git && cd express && git submodule update --init
|
||||
## Features
|
||||
|
||||
## Examples
|
||||
* Robust routing
|
||||
* Redirection helpers
|
||||
* Dynamic view helpers
|
||||
* Content negotiation
|
||||
* Focus on high performance
|
||||
* View rendering and partials support
|
||||
* Environment based configuration
|
||||
* Session based flash notifications
|
||||
* Built on [Connect](http://github.com/senchalabs/connect)
|
||||
* High test coverage
|
||||
* Executable for generating applications quickly
|
||||
* Application level view options
|
||||
|
||||
Below is a tiny Express application. View the [Wiki](http://wiki.github.com/visionmedia/express/) for detailed information.
|
||||
Via Connect:
|
||||
|
||||
require.paths.unshift('express/lib')
|
||||
require('express')
|
||||
|
||||
configure(function(){
|
||||
set('root', __dirname)
|
||||
})
|
||||
|
||||
get('/user', function(){
|
||||
this.redirect('/user/' + this.currentUser.id)
|
||||
})
|
||||
|
||||
get('/user/:id', function(id){
|
||||
this.render('user.haml.html', {
|
||||
locals: {
|
||||
user: this.currentUser,
|
||||
usersOnline: Session.store.length()
|
||||
}
|
||||
})
|
||||
})
|
||||
* Session support
|
||||
* Cache API
|
||||
* Mime helpers
|
||||
* ETag support
|
||||
* Persistent flash notifications
|
||||
* Cookie support
|
||||
* JSON-RPC
|
||||
* Logging
|
||||
* and _much_ more!
|
||||
|
||||
run()
|
||||
|
||||
## Running Tests
|
||||
|
||||
Express uses the [JSpec](http://jspec.info) BDD JavaScript testing
|
||||
framework to write and run elegant spec suites. JSpec is frozen
|
||||
to spec/lib and **does not** require separate installation.
|
||||
|
||||
$ make test
|
||||
|
||||
Run individual suites:
|
||||
|
||||
$ node spec/node.js core
|
||||
$ node spec/node.js mime
|
||||
$ node spec/node.js routing
|
||||
...
|
||||
|
||||
The latest release of Express is compatible with node --version:
|
||||
v0.1.93
|
||||
|
||||
With _EDGE_ Express we do our best to keep up to date with node's _EDGE_
|
||||
|
||||
## More Information
|
||||
|
||||
* [JavaScript Extensions & Utilities](http://github.com/visionmedia/ext.js)
|
||||
* [JavaScript Sass](http://github.com/visionmedia/sass.js)
|
||||
* Featured in [Advanced JavaScript e-book](http://www.dev-mag.com/2010/02/18/advanced-javascript/) for only $4
|
||||
* [0.9.0 release details](http://tjholowaychuk.com/post/522036176/express-0-9-0-released)
|
||||
* [Express vs Sinatra Benchmarks](http://tjholowaychuk.com/post/543953703/express-vs-sinatra-benchmarks)
|
||||
|
||||
## Contributors
|
||||
|
||||
* TJ Holowaychuk (visionmedia) <tj@vision-media.ca>
|
||||
* Aaron Heckmann (aheckmann) <aaron.heckmann+github@gmail.com>
|
||||
* Ciaran Jessup (ciaranj) <ciaranj@gmail.com>
|
||||
* Gareth Jones (csausdev) <gareth.jones@sensis.com.au>
|
||||
|
||||
The following are the major contributors of Express (in no specific order).
|
||||
|
||||
* TJ Holowaychuk ([visionmedia](http://github.com/visionmedia))
|
||||
* Ciaran Jessup ([ciaranj](http://github.com/ciaranj))
|
||||
* Aaron Heckmann ([aheckmann](http://github.com/aheckmann))
|
||||
* Guillermo Rauch ([guille](http://github.com/guille))
|
||||
|
||||
## More Information
|
||||
|
||||
* [express-configure](http://github.com/visionmedia/express-configure) async configuration support
|
||||
* [express-messages](http://github.com/visionmedia/express-messages) flash notification rendering helper
|
||||
* [express-namespace](http://github.com/visionmedia/express-namespace) namespaced route support
|
||||
* Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates
|
||||
* [Google Group](http://groups.google.com/group/express-js) for discussion
|
||||
* Visit the [Wiki](http://github.com/visionmedia/express/wiki)
|
||||
* Screencast - [Introduction](http://bit.ly/eRYu0O)
|
||||
* Screencast - [View Partials](http://bit.ly/dU13Fx)
|
||||
* Screencast - [Route Specific Middleware](http://bit.ly/hX4IaH)
|
||||
* Screencast - [Route Path Placeholder Preconditions](http://bit.ly/eNqmVs)
|
||||
|
||||
## Node Compatibility
|
||||
|
||||
Express 1.x is compatible with node 0.2.x and connect < 1.0.
|
||||
|
||||
Express 2.x is compatible with node 0.4.x and connect 1.x
|
||||
|
||||
## License
|
||||
|
||||
(The MIT License)
|
||||
|
||||
Copyright (c) 2009 TJ Holowaychuk <tj@vision-media.ca>
|
||||
Copyright (c) 2009-2011 TJ Holowaychuk <tj@vision-media.ca>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
|
||||
require.paths.unshift('lib')
|
||||
require('express')
|
||||
require('express/plugins')
|
||||
|
||||
configure(function(){
|
||||
//enable('cache view contents')
|
||||
set('root', __dirname)
|
||||
set('views', __dirname + '/../shared')
|
||||
})
|
||||
|
||||
get('/', function(){
|
||||
this.render('page.html.haml')
|
||||
})
|
||||
|
||||
run()
|
||||
@@ -1,16 +0,0 @@
|
||||
|
||||
require.paths.unshift('lib')
|
||||
require('express')
|
||||
require('express/plugins')
|
||||
|
||||
configure(function(){
|
||||
//enable('cache view contents')
|
||||
set('root', __dirname)
|
||||
set('views', __dirname + '/../shared')
|
||||
})
|
||||
|
||||
get('/', function(){
|
||||
this.render('style.css.sass', { layout: false })
|
||||
})
|
||||
|
||||
run()
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
require.paths.unshift('lib')
|
||||
require('express')
|
||||
|
||||
get('/', function(){
|
||||
return 'Hello World'
|
||||
})
|
||||
|
||||
run()
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
require.paths.unshift('lib')
|
||||
require('express')
|
||||
require('express/plugins')
|
||||
|
||||
configure(function(){
|
||||
use(Static)
|
||||
set('root', __dirname)
|
||||
})
|
||||
|
||||
get('/', function(){
|
||||
this.sendfile('benchmarks/shared/jquery.js', { bufferSize: 8 * 1024 })
|
||||
})
|
||||
|
||||
run()
|
||||
@@ -1,15 +0,0 @@
|
||||
|
||||
require.paths.unshift('lib')
|
||||
require('express')
|
||||
require('express/plugins')
|
||||
|
||||
configure(function(){
|
||||
use(Static)
|
||||
set('root', __dirname)
|
||||
})
|
||||
|
||||
get('/', function(){
|
||||
this.sendfile('benchmarks/shared/huge.js', { bufferSize: 8 * 1024 })
|
||||
})
|
||||
|
||||
run()
|
||||
@@ -1,84 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
COL=${COL-9}
|
||||
|
||||
#
|
||||
# Log <msg ...>
|
||||
#
|
||||
# <msg ...>
|
||||
#
|
||||
|
||||
log(){
|
||||
echo "... $@"
|
||||
}
|
||||
|
||||
#
|
||||
# Output gnuplot script for line graph.
|
||||
#
|
||||
# <title> <node> <express> <sinatra>
|
||||
#
|
||||
|
||||
function line() {
|
||||
cat <<-EOF
|
||||
set terminal png
|
||||
set output "benchmarks/graphs/$1.png"
|
||||
set title "$1"
|
||||
set size 1,0.7
|
||||
set grid y
|
||||
set key left top
|
||||
set xlabel "request"
|
||||
set ylabel "response time (ms)"
|
||||
plot "benchmarks/$2" using $COL smooth sbezier with lines title "node", \\
|
||||
"benchmarks/$3" using $COL smooth sbezier with lines title "express", \\
|
||||
"benchmarks/$4" using $COL smooth sbezier with lines title "sinatra thin"
|
||||
EOF
|
||||
}
|
||||
|
||||
#
|
||||
# Output gnuplot script for bar graph.
|
||||
#
|
||||
# <title> <node> <express> <sinatra>
|
||||
#
|
||||
|
||||
function bar() {
|
||||
cat <<-EOF
|
||||
set terminal png
|
||||
set output "benchmarks/graphs/$1.rps.png"
|
||||
set title "$1"
|
||||
set size 0.7,0.5
|
||||
set grid y
|
||||
set key left top
|
||||
set ylabel "requests per second"
|
||||
plot "benchmarks/$1.rps.dat" using 2: xtic(1) with histogram title ""
|
||||
EOF
|
||||
}
|
||||
|
||||
mkdir -p benchmarks/graphs
|
||||
|
||||
for type in simple haml sass static static.large; do
|
||||
plot=benchmarks/graphs/$type.p
|
||||
log generating benchmarks/graphs/$type.png
|
||||
line $type \
|
||||
node/$type.js.dat \
|
||||
express/$type.js.dat \
|
||||
thin/$type.ru.dat \
|
||||
> $plot
|
||||
gnuplot $plot
|
||||
|
||||
log generating benchmarks/graphs/$type.rps.png
|
||||
plot=benchmarks/graphs/$type.rps.p
|
||||
dat=benchmarks/$type.rps.dat
|
||||
:> $dat
|
||||
for server in node express thin; do
|
||||
case $server in
|
||||
node|express) ext=js ;;
|
||||
thin) ext=ru ;;
|
||||
esac
|
||||
rps=$(cat benchmarks/$server/$type.$ext.out | grep "Requests per second:" | awk '{ print $4 }')
|
||||
echo $server $rps >> $dat
|
||||
done
|
||||
bar $type > $plot
|
||||
gnuplot $plot
|
||||
done
|
||||
|
||||
rm benchmarks/graphs/*.p
|
||||
@@ -1,8 +0,0 @@
|
||||
|
||||
var fs = require('fs'),
|
||||
http = require('http')
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain', 'Content-Length': 11 })
|
||||
res.end('Hello World', 'ascii')
|
||||
}).listen(3000, 'localhost')
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
var fs = require('fs'),
|
||||
http = require('http')
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked' })
|
||||
fs.createReadStream('benchmarks/shared/jquery.js')
|
||||
.addListener('data', function(data){
|
||||
res.write(data, 'binary')
|
||||
})
|
||||
.addListener('end', function(){
|
||||
res.end()
|
||||
})
|
||||
}).listen(3000, 'localhost')
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
var fs = require('fs'),
|
||||
http = require('http')
|
||||
|
||||
http.createServer(function(req, res) {
|
||||
res.writeHead(200, { 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked' })
|
||||
fs.createReadStream('benchmarks/shared/huge.js')
|
||||
.addListener('data', function(data){
|
||||
res.write(data, 'binary')
|
||||
})
|
||||
.addListener('end', function(){
|
||||
res.end()
|
||||
})
|
||||
}).listen(3000, 'localhost')
|
||||
@@ -1,61 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
SLEEP=${SLEEP-2}
|
||||
ABFLAGS=${ABFLAGS-"-n 2000 -c 50"}
|
||||
ADDR=${ADDR-http://127.0.0.1:3000/}
|
||||
AB=${AB-ab}
|
||||
|
||||
#
|
||||
# Log <msg ...>
|
||||
#
|
||||
# <msg ...>
|
||||
#
|
||||
|
||||
log(){
|
||||
echo "... $@"
|
||||
}
|
||||
|
||||
#
|
||||
# Benchmark <type> and <file>
|
||||
#
|
||||
# - starts the server
|
||||
# - allows $SLEEP seconds for startup
|
||||
# - runs $AB
|
||||
# - kills the server process
|
||||
#
|
||||
# <type> <file>
|
||||
#
|
||||
|
||||
bm(){
|
||||
local type=$1
|
||||
local file=$2
|
||||
log benchmarking $type $file
|
||||
case $type in
|
||||
node|express)
|
||||
node benchmarks/$type/$file &
|
||||
;;
|
||||
thin)
|
||||
thin -R benchmarks/thin/$file -p 3000 start &
|
||||
;;
|
||||
esac
|
||||
pid=$!
|
||||
sleep $SLEEP
|
||||
$AB $ABFLAGS -g benchmarks/$type/$file.dat $ADDR > benchmarks/$type/$file.out
|
||||
log $(cat benchmarks/$type/$file.out | grep Requests)
|
||||
kill -KILL $pid
|
||||
}
|
||||
|
||||
log ab $ABFLAGS $ADDR
|
||||
bm node simple.js
|
||||
bm node static.js
|
||||
bm node static.large.js
|
||||
bm express simple.js
|
||||
bm express static.js
|
||||
bm express static.large.js
|
||||
bm express haml.js
|
||||
bm express sass.js
|
||||
bm thin simple.ru
|
||||
bm thin static.ru
|
||||
bm thin static.large.ru
|
||||
bm thin haml.ru
|
||||
bm thin sass.ru
|
||||
@@ -1,6 +0,0 @@
|
||||
!!!
|
||||
%html
|
||||
%head
|
||||
%title Wahoo
|
||||
%body
|
||||
#primary= yield
|
||||
@@ -1,6 +0,0 @@
|
||||
!!!
|
||||
%html
|
||||
%head
|
||||
%title Wahoo
|
||||
%body
|
||||
#primary!= body
|
||||
@@ -1,10 +0,0 @@
|
||||
%h1 Some title
|
||||
%ul
|
||||
%li a
|
||||
%li b
|
||||
%li c
|
||||
%li
|
||||
%ol
|
||||
%li d
|
||||
%li e
|
||||
%li f
|
||||
@@ -1,10 +0,0 @@
|
||||
%h1 Some title
|
||||
%ul
|
||||
%li a
|
||||
%li b
|
||||
%li c
|
||||
%li
|
||||
%ol
|
||||
%li d
|
||||
%li e
|
||||
%li f
|
||||
@@ -1,73 +0,0 @@
|
||||
body
|
||||
:font-family "Helvetica Neue", "Lucida Grande", "Arial"
|
||||
:font-size 13px
|
||||
:text-align center
|
||||
:color #555
|
||||
|
||||
h1, h2
|
||||
:margin 0
|
||||
:font-size 22px
|
||||
:color #343434
|
||||
h1
|
||||
:text-shadow 1px 2px 2px #ddd
|
||||
:font-size 60px
|
||||
|
||||
img.bubble
|
||||
:position absolute
|
||||
:top -25px
|
||||
:left 120px
|
||||
|
||||
#wrapper
|
||||
:position relative
|
||||
:margin 100px auto
|
||||
:width 500px
|
||||
:text-align left
|
||||
|
||||
ul
|
||||
:margin 0
|
||||
:padding 0
|
||||
:max-height 300px
|
||||
:overflow-x hidden
|
||||
li
|
||||
:margin 5px 0
|
||||
:padding 3px 8px
|
||||
:list-style none
|
||||
:border 1px solid #eee
|
||||
li:hover
|
||||
:cursor pointer
|
||||
:color #2E2E2E
|
||||
|
||||
input[type=text]
|
||||
:padding 5px
|
||||
:border 1px solid #ddd
|
||||
:outline none
|
||||
input[type=text]:focus
|
||||
:border-color #00C3FF
|
||||
|
||||
input[type=submit]
|
||||
:padding 6px 10px
|
||||
:border solid 1px #999
|
||||
:background -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ddd))
|
||||
:color #333
|
||||
:text-decoration none
|
||||
:cursor pointer
|
||||
:display inline-block
|
||||
:text-align center
|
||||
:text-shadow 0px 1px 1px #fff
|
||||
:line-height 1
|
||||
input[type=submit]:hover
|
||||
:background -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#E6E4E4))
|
||||
input[type=submit]:active
|
||||
:background -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#c7c7c7))
|
||||
input[name=name]
|
||||
:width 80px
|
||||
|
||||
a
|
||||
:color #1ABFF1
|
||||
a:hover
|
||||
:padding 0 5px
|
||||
a:hover:before
|
||||
:content 'visit: '
|
||||
|
||||
#online
|
||||
:font-size 12px
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
require 'rubygems'
|
||||
require 'sinatra'
|
||||
require 'haml'
|
||||
|
||||
configure do
|
||||
set 'views', File.dirname(__FILE__) + '/../shared'
|
||||
end
|
||||
|
||||
get '/' do
|
||||
haml :page, :ugly => true
|
||||
end
|
||||
|
||||
run Sinatra::Application
|
||||
@@ -1,14 +0,0 @@
|
||||
|
||||
require 'rubygems'
|
||||
require 'sinatra'
|
||||
require 'sass'
|
||||
|
||||
configure do
|
||||
set 'views', File.dirname(__FILE__) + '/../shared'
|
||||
end
|
||||
|
||||
get '/' do
|
||||
sass :'style.css'
|
||||
end
|
||||
|
||||
run Sinatra::Application
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
require 'rubygems'
|
||||
require 'sinatra'
|
||||
|
||||
get '/' do
|
||||
'Hello World'
|
||||
end
|
||||
|
||||
run Sinatra::Application
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
require 'rubygems'
|
||||
require 'sinatra'
|
||||
|
||||
get '/' do
|
||||
send_file 'benchmarks/shared/huge.js'
|
||||
end
|
||||
|
||||
run Sinatra::Application
|
||||
@@ -1,9 +0,0 @@
|
||||
|
||||
require 'rubygems'
|
||||
require 'sinatra'
|
||||
|
||||
get '/' do
|
||||
send_file 'benchmarks/shared/jquery.js'
|
||||
end
|
||||
|
||||
run Sinatra::Application
|
||||
@@ -1,142 +1,450 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/usr/bin/env node
|
||||
|
||||
#
|
||||
# Output usage information and exit.
|
||||
#
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
function usage() {
|
||||
echo 'usage: express [options] [dir]'
|
||||
exit 1
|
||||
var fs = require('fs')
|
||||
, exec = require('child_process').exec;
|
||||
|
||||
/**
|
||||
* Framework version.
|
||||
*/
|
||||
|
||||
var version = '2.0.0rc';
|
||||
|
||||
/**
|
||||
* Add session support.
|
||||
*/
|
||||
|
||||
var sessions = false;
|
||||
|
||||
/**
|
||||
* CSS engine to utilize.
|
||||
*/
|
||||
|
||||
var cssEngine;
|
||||
|
||||
/**
|
||||
* Template engine to utilize.
|
||||
*/
|
||||
|
||||
var templateEngine = 'jade';
|
||||
|
||||
/**
|
||||
* Usage documentation.
|
||||
*/
|
||||
|
||||
var usage = ''
|
||||
+ '\x1b[1mUsage\x1b[0m: express [options] [PATH]\n'
|
||||
+ '\n'
|
||||
+ '\x1b[1mOptions\x1b[0m:\n'
|
||||
+ ' -s, --sessions Add session support\n'
|
||||
+ ' -t, --template ENGINE Add template ENGINE support (jade|ejs). Defaults to jade\n'
|
||||
+ ' -c, --css ENGINE Add stylesheet ENGINE support (less|sass|stylus). Defaults to plain css\n'
|
||||
+ ' -v, --version Output framework version\n'
|
||||
+ ' -h, --help Output help information\n'
|
||||
;
|
||||
|
||||
/**
|
||||
* Jade layout template.
|
||||
*/
|
||||
|
||||
var jadeLayout = [
|
||||
'!!!'
|
||||
, 'html'
|
||||
, ' head'
|
||||
, ' title= title'
|
||||
, ' link(rel=\'stylesheet\', href=\'/stylesheets/style.css\')'
|
||||
, ' body!= body'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* Jade index template.
|
||||
*/
|
||||
|
||||
var jadeIndex = [
|
||||
'h1= title'
|
||||
, 'p Welcome to #{title}'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* EJS layout template.
|
||||
*/
|
||||
|
||||
var ejsLayout = [
|
||||
'<!DOCTYPE html>'
|
||||
, '<html>'
|
||||
, ' <head>'
|
||||
, ' <title><%= title %></title>'
|
||||
, ' <link rel=\'stylesheet\' href=\'/stylesheets/style.css\' />'
|
||||
, ' </head>'
|
||||
, ' <body>'
|
||||
, ' <%- body %>'
|
||||
, ' </body>'
|
||||
, '</html>'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* EJS index template.
|
||||
*/
|
||||
|
||||
var ejsIndex = [
|
||||
'<h1><%= title %></h1>'
|
||||
, '<p>Welcome to <%= title %></p>'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* Default css template.
|
||||
*/
|
||||
|
||||
var css = [
|
||||
'body {'
|
||||
, ' padding: 50px;'
|
||||
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;'
|
||||
, '}'
|
||||
, ''
|
||||
, 'a {'
|
||||
, ' color: #00B7FF;'
|
||||
, '}'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* Default less template.
|
||||
*/
|
||||
|
||||
var less = [
|
||||
'body {'
|
||||
, ' padding: 50px;'
|
||||
, ' font: 14px "Lucida Grande", Helvetica, Arial, sans-serif;'
|
||||
, '}'
|
||||
, ''
|
||||
, 'a {'
|
||||
, ' color: #00B7FF;'
|
||||
, '}'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* Default sass template.
|
||||
*/
|
||||
|
||||
var sass = [
|
||||
'body'
|
||||
, ' :padding 50px'
|
||||
, ' :font 14px "Lucida Grande", Helvetica, Arial, sans-serif'
|
||||
, 'a'
|
||||
, ' :color #00B7FF'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* Default stylus template.
|
||||
*/
|
||||
|
||||
var stylus = [
|
||||
'body'
|
||||
, ' padding 50px'
|
||||
, ' font 14px "Lucida Grande", Helvetica, Arial, sans-serif'
|
||||
, 'a'
|
||||
, ' color #00B7FF'
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* App test template.
|
||||
*/
|
||||
|
||||
var appTest = [
|
||||
""
|
||||
, "// Run $ expresso"
|
||||
, ""
|
||||
, "/**"
|
||||
, " * Module dependencies."
|
||||
, " */"
|
||||
, ""
|
||||
, "var app = require('../app')"
|
||||
, " , assert = require('assert');"
|
||||
, "",
|
||||
, "module.exports = {"
|
||||
, " 'GET /': function(){"
|
||||
, " assert.response(app,"
|
||||
, " { url: '/' },"
|
||||
, " { status: 200, headers: { 'Content-Type': 'text/html; charset=utf-8' }},"
|
||||
, " function(res){"
|
||||
, " assert.includes(res.body, '<title>Express</title>');"
|
||||
, " });"
|
||||
, " }"
|
||||
, "};"
|
||||
].join('\n');
|
||||
|
||||
/**
|
||||
* App template.
|
||||
*/
|
||||
|
||||
var app = [
|
||||
''
|
||||
, '/**'
|
||||
, ' * Module dependencies.'
|
||||
, ' */'
|
||||
, ''
|
||||
, 'var express = require(\'express\');'
|
||||
, ''
|
||||
, 'var app = module.exports = express.createServer();'
|
||||
, ''
|
||||
, '// Configuration'
|
||||
, ''
|
||||
, 'app.configure(function(){'
|
||||
, ' app.set(\'views\', __dirname + \'/views\');'
|
||||
, ' app.set(\'view engine\', \':TEMPLATE\');'
|
||||
, ' app.use(express.bodyParser());'
|
||||
, ' app.use(express.methodOverride());{sess}{css}'
|
||||
, ' app.use(app.router);'
|
||||
, ' app.use(express.static(__dirname + \'/public\'));'
|
||||
, '});'
|
||||
, ''
|
||||
, 'app.configure(\'development\', function(){'
|
||||
, ' app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); '
|
||||
, '});'
|
||||
, ''
|
||||
, 'app.configure(\'production\', function(){'
|
||||
, ' app.use(express.errorHandler()); '
|
||||
, '});'
|
||||
, ''
|
||||
, '// Routes'
|
||||
, ''
|
||||
, 'app.get(\'/\', function(req, res){'
|
||||
, ' res.render(\'index\', {'
|
||||
, ' title: \'Express\''
|
||||
, ' });'
|
||||
, '});'
|
||||
, ''
|
||||
, '// Only listen on $ node app.js'
|
||||
, ''
|
||||
, 'if (!module.parent) {'
|
||||
, ' app.listen(3000);'
|
||||
, ' console.log("Express server listening on port %d", app.address().port);'
|
||||
, '}'
|
||||
, ''
|
||||
].join('\n');
|
||||
|
||||
// Parse arguments
|
||||
|
||||
var args = process.argv.slice(2)
|
||||
, path = '.';
|
||||
|
||||
while (args.length) {
|
||||
var arg = args.shift();
|
||||
switch (arg) {
|
||||
case '-h':
|
||||
case '--help':
|
||||
abort(usage);
|
||||
break;
|
||||
case '-v':
|
||||
case '--version':
|
||||
abort(version);
|
||||
break;
|
||||
case '-s':
|
||||
case '--session':
|
||||
case '--sessions':
|
||||
sessions = true;
|
||||
break;
|
||||
case '-c':
|
||||
case '--css':
|
||||
args.length
|
||||
? (cssEngine = args.shift())
|
||||
: abort('--css requires an argument');
|
||||
break;
|
||||
case '-t':
|
||||
case '--template':
|
||||
args.length
|
||||
? (templateEngine = args.shift())
|
||||
: abort('--template requires an argument');
|
||||
break;
|
||||
default:
|
||||
path = arg;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Create template in the givin [dir] or cwd.
|
||||
#
|
||||
# [dir]
|
||||
#
|
||||
// Generate application
|
||||
|
||||
function create_template() {
|
||||
local dir=${1-.}
|
||||
mkdir -p $dir
|
||||
[[ $(ls $dir) ]] && confirm "$dir is not empty, continue?"
|
||||
mkdir -p $dir/public/{javascripts,stylesheets,images}
|
||||
mkdir -p $dir/views/partials
|
||||
app_template > $dir/app.js
|
||||
layout_template > $dir/views/layout.html.haml
|
||||
front_template > $dir/views/front.html.haml
|
||||
sass_template > $dir/views/style.css.sass
|
||||
echo template created in $dir
|
||||
(function createApplication(path) {
|
||||
emptyDirectory(path, function(empty){
|
||||
if (empty) {
|
||||
createApplicationAt(path);
|
||||
} else {
|
||||
confirm('destination is not empty, continue? ', function(ok){
|
||||
if (ok) {
|
||||
process.stdin.destroy();
|
||||
createApplicationAt(path);
|
||||
} else {
|
||||
abort('aborting');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})(path);
|
||||
|
||||
/**
|
||||
* Create application at the given directory `path`.
|
||||
*
|
||||
* @param {String} path
|
||||
*/
|
||||
|
||||
function createApplicationAt(path) {
|
||||
mkdir(path, function(){
|
||||
mkdir(path + '/pids');
|
||||
mkdir(path + '/logs');
|
||||
mkdir(path + '/public/javascripts');
|
||||
mkdir(path + '/public/images');
|
||||
mkdir(path + '/public/stylesheets', function(){
|
||||
switch (cssEngine) {
|
||||
case 'stylus':
|
||||
write(path + '/public/stylesheets/style.styl', stylus);
|
||||
break;
|
||||
case 'less':
|
||||
write(path + '/public/stylesheets/style.less', less);
|
||||
break;
|
||||
case 'sass':
|
||||
write(path + '/public/stylesheets/style.sass', sass);
|
||||
break;
|
||||
default:
|
||||
write(path + '/public/stylesheets/style.css', css);
|
||||
}
|
||||
});
|
||||
mkdir(path + '/views', function(){
|
||||
switch (templateEngine) {
|
||||
case 'ejs':
|
||||
write(path + '/views/layout.ejs', ejsLayout);
|
||||
write(path + '/views/index.ejs', ejsIndex);
|
||||
break;
|
||||
case 'jade':
|
||||
write(path + '/views/layout.jade', jadeLayout);
|
||||
write(path + '/views/index.jade', jadeIndex);
|
||||
break;
|
||||
}
|
||||
});
|
||||
mkdir(path + '/test', function(){
|
||||
write(path + '/test/app.test.js', appTest);
|
||||
});
|
||||
|
||||
// CSS Engine support
|
||||
switch (cssEngine) {
|
||||
case 'sass':
|
||||
case 'less':
|
||||
app = app.replace('{css}', '\n app.use(express.compiler({ src: __dirname + \'/public\', enable: [\'' + cssEngine + '\'] }));');
|
||||
break;
|
||||
case 'stylus':
|
||||
app = app.replace('{css}', '\n app.use(require(\'stylus\').middleware({ src: __dirname + \'/public\' }));');
|
||||
break;
|
||||
default:
|
||||
app = app.replace('{css}', '');
|
||||
}
|
||||
|
||||
// Session support
|
||||
app = app.replace('{sess}', sessions
|
||||
? '\n app.use(express.cookieParser());\n app.use(express.session({ secret: \'your secret here\' }));'
|
||||
: '');
|
||||
|
||||
// Template support
|
||||
app = app.replace(':TEMPLATE', templateEngine);
|
||||
|
||||
write(path + '/app.js', app);
|
||||
|
||||
// Suggestions
|
||||
process.on('exit', function(){
|
||||
if (cssEngine) {
|
||||
console.log(' - make sure you have installed %s: \x1b[33m$ npm install %s\x1b[0m'
|
||||
, cssEngine
|
||||
, cssEngine);
|
||||
}
|
||||
console.log(' - make sure you have installed %s: \x1b[33m$ npm install %s\x1b[0m'
|
||||
, templateEngine
|
||||
, templateEngine);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#
|
||||
# views/style.css.sass
|
||||
#
|
||||
/**
|
||||
* Check if the given directory `path` is empty.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} fn
|
||||
*/
|
||||
|
||||
function sass_template() {
|
||||
cat <<-EOF
|
||||
blue: #03ADF0
|
||||
light: #4d4d4d
|
||||
lighter: #eee
|
||||
|
||||
body
|
||||
:margin 80px
|
||||
:font 14px/1.5 "Helvetica Nueue", "Lucida Grande", "Arial", sans-serif
|
||||
|
||||
code
|
||||
:padding 3px 10px
|
||||
:border 1px solid !lighter
|
||||
:color !light
|
||||
|
||||
a
|
||||
:color !blue
|
||||
:text-decoration none
|
||||
&:hover
|
||||
:text-decoration underline
|
||||
EOF
|
||||
function emptyDirectory(path, fn) {
|
||||
fs.readdir(path, function(err, files){
|
||||
if (err && 'ENOENT' != err.code) throw err;
|
||||
fn(!files || !files.length);
|
||||
});
|
||||
}
|
||||
|
||||
#
|
||||
# views/front.html.haml
|
||||
#
|
||||
/**
|
||||
* echo str > path.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {String} str
|
||||
*/
|
||||
|
||||
function front_template() {
|
||||
cat <<-EOF
|
||||
%h1 Express
|
||||
%p
|
||||
Generated by the
|
||||
<code>express</code>
|
||||
executable.
|
||||
%p
|
||||
Visit
|
||||
%a{ href: 'http://expressjs.com' } ExpressJS.com
|
||||
for more information.
|
||||
EOF
|
||||
function write(path, str) {
|
||||
fs.writeFile(path, str);
|
||||
console.log(' \x1b[36mcreate\x1b[0m : ' + path);
|
||||
}
|
||||
|
||||
#
|
||||
# views/layout.html.haml
|
||||
#
|
||||
/**
|
||||
* Prompt confirmation with the given `msg`.
|
||||
*
|
||||
* @param {String} msg
|
||||
* @param {Function} fn
|
||||
*/
|
||||
|
||||
function layout_template() {
|
||||
cat <<-EOF
|
||||
!!! strict
|
||||
%html
|
||||
%head
|
||||
%title Express
|
||||
%link{ rel: 'stylesheet', href: 'style.css' }
|
||||
%body!= body
|
||||
EOF
|
||||
function confirm(msg, fn) {
|
||||
prompt(msg, function(val){
|
||||
fn(/^ *y(es)?/i.test(val));
|
||||
});
|
||||
}
|
||||
|
||||
#
|
||||
# app.js
|
||||
#
|
||||
/**
|
||||
* Prompt input with the given `msg` and callback `fn`.
|
||||
*
|
||||
* @param {String} msg
|
||||
* @param {Function} fn
|
||||
*/
|
||||
|
||||
function app_template() {
|
||||
cat <<-EOF
|
||||
// If you are using the kiwi package manager
|
||||
var kiwi = require('kiwi'),
|
||||
express = kiwi.require('express')
|
||||
function prompt(msg, fn) {
|
||||
// prompt
|
||||
if (' ' == msg[msg.length - 1]) {
|
||||
process.stdout.write(msg);
|
||||
} else {
|
||||
console.log(msg);
|
||||
}
|
||||
|
||||
// Otherwise you will need to expose the path to express
|
||||
// require.paths.unshift('path/to/express/lib')
|
||||
// require('express')
|
||||
|
||||
configure(function(){
|
||||
set('root', __dirname)
|
||||
})
|
||||
|
||||
get('/', function(){
|
||||
this.render('front.html.haml')
|
||||
})
|
||||
|
||||
get('/*.css', function(path){
|
||||
this.render(path + '.css.sass', { layout: false })
|
||||
})
|
||||
|
||||
run()
|
||||
EOF
|
||||
// stdin
|
||||
process.stdin.setEncoding('ascii');
|
||||
process.stdin.once('data', function(data){
|
||||
fn(data);
|
||||
}).resume();
|
||||
}
|
||||
|
||||
#
|
||||
# Confirm <msg> or exit.
|
||||
#
|
||||
# <msg>
|
||||
#
|
||||
/**
|
||||
* Mkdir -p.
|
||||
*
|
||||
* @param {String} path
|
||||
* @param {Function} fn
|
||||
*/
|
||||
|
||||
function confirm() {
|
||||
echo -n "$1 "
|
||||
read answer
|
||||
case $answer in
|
||||
n|N|no) exit 1 ;;
|
||||
y|Y|yes) ;;
|
||||
*) confirm "yes or no?" ;;
|
||||
esac
|
||||
function mkdir(path, fn) {
|
||||
exec('mkdir -p ' + path, function(err){
|
||||
if (err) throw err;
|
||||
console.log(' \x1b[36mcreate\x1b[0m : ' + path);
|
||||
fn && fn();
|
||||
});
|
||||
}
|
||||
|
||||
# Process arguments
|
||||
/**
|
||||
* Exit with the given `str`.
|
||||
*
|
||||
* @param {String} str
|
||||
*/
|
||||
|
||||
case $1 in
|
||||
-h|--help|help) usage ;;
|
||||
*) create_template $1 ;;
|
||||
esac
|
||||
function abort(str) {
|
||||
console.error(str);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "APPLICATIONS" "" "March 2011" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBapplications\fR
|
||||
.
|
||||
.P
|
||||
Learnboost \fIhttp://learnboost\.com\fR is a free online gradebook application, aimed to crush the competition with innovative, realtime, enjoyable features\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://learnboost\.com\fR
|
||||
.
|
||||
.P
|
||||
Storify \fIhttp://storify\.com\fR lets you turn what people post on social media websites into compelling stories\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://storify\.com\fR
|
||||
.
|
||||
.P
|
||||
Pakistan Survey \fIhttp://pakistansurvey\.org/\fR by Development Seed \fIhttp://developmentseed\.org\fR, provides in\-depth agency\-specific analysis from regional experts with data from 1,000 interviews across 120 villages in all seven tribal agencies and mapping of 142 reported drone strikes in FATA through July 2010\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://pakistansurvey\.org\fR
|
||||
.
|
||||
.P
|
||||
Markup\.IO \fIhttp://markup\.io\fR allows you to draw directly on \fIany\fR website, then share with others to share your thoughts\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://markup\.io\fR
|
||||
.
|
||||
.P
|
||||
Scrabb\.ly \fIhttp://scrabb\.ly\fR is a massively multiplayer scrabble game initially created for the Node Knockout \fIhttp://nodeknockout\.com/\fR competition\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://scrabb\.ly\fR
|
||||
.
|
||||
.P
|
||||
ClickDummy \fIhttp://clickdummy\.net/\fR is a rapid mockup prototyping application for designers and dummies\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://clickdummy\.net\fR
|
||||
.
|
||||
.P
|
||||
Node Knockout \fIhttp://nodeknockout\.com\fR organized the first ever node\-specific competition with hundreds of contestants\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://nodeknockout\.com\fR
|
||||
.
|
||||
.P
|
||||
Widescript \fIhttp://widescript\.com\fR is an innovative app that helps you focus and interact with your texts \- on your desktop, your couch or on the go\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://widescript\.com\fR
|
||||
.
|
||||
.P
|
||||
e\-resistable \fIhttp://www\.e\-resistible\.co\.uk/\fR is an online order takeaway system providing an intuitive way to fill your belly from your computer!
|
||||
.
|
||||
.P
|
||||
\fIhttp://www\.e\-resistible\.co\.uk\fR
|
||||
.
|
||||
.P
|
||||
Top Twitter Trends \fIhttp://toptwittertrends\.com\fR utilizes MongoDB, Socket\.IO, jQuery and many other exciting libraries to bring you trending tweets in realtime\.
|
||||
.
|
||||
.P
|
||||
\fIhttp://toptwittertrends\.com\fR
|
||||
.
|
||||
.P
|
||||
The applications shown above are not listed in any specific order\. To have an application added or removed please contact TJ Holowaychuk \fIhttp://github\.com/visionmedia\fR\.
|
||||
@@ -0,0 +1,252 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Express - node web framework</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<style>
|
||||
#tagline {
|
||||
margin-left: 75px;
|
||||
margin-bottom: 30px;
|
||||
color: rgba(255,255,255,0.7); }
|
||||
html {
|
||||
background: #1c1c1c url(images/bg.tile.jpg); }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: url(images/bg.jpg) 50% 0 no-repeat;
|
||||
color: #8b8b8b; }
|
||||
|
||||
* {
|
||||
outline: none; }
|
||||
|
||||
em {
|
||||
color: white; }
|
||||
|
||||
a img {
|
||||
border: none !important; }
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
a:hover {
|
||||
opacity: 0.8; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 45px 0 0 0;
|
||||
color: white;
|
||||
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
|
||||
|
||||
h3 {
|
||||
font-size: 18px; }
|
||||
h4 {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 10px;
|
||||
padding: 25px 20px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border: 1px solid #323232;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px; }
|
||||
|
||||
code {
|
||||
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
|
||||
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 35px; }
|
||||
ul li {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style: square; }
|
||||
ul li ul {
|
||||
margin: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.man-name, #Express { display:none; }
|
||||
|
||||
.sect {
|
||||
margin-left: 40px; }
|
||||
img {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
margin-left: 30%;
|
||||
margin-bottom: 30px;
|
||||
width: 194px;
|
||||
height: 51px;
|
||||
background: url(images/logo.png) 0 0 no-repeat;
|
||||
text-indent: -99999px; }
|
||||
#logo:hover {
|
||||
opacity: 0.7; }
|
||||
#logo:active {
|
||||
opacity: 0.3; }
|
||||
|
||||
#ribbon {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2; }
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
background: url(images/top.png) 0 0 repeat-x; }
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
padding-top: 80px;
|
||||
width: 550px; }
|
||||
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 15px;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
border-right: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
#toc li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#toc li a {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu {
|
||||
margin-left: 75px;
|
||||
padding: 0;
|
||||
padding-bottom: 30px; }
|
||||
#menu li {
|
||||
display: inline;
|
||||
list-style: none; }
|
||||
#menu li a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 2px;
|
||||
padding: 3px 15px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
#menu li a:hover,
|
||||
#menu li a.active {
|
||||
background: rgba(0,0,0,0.5); }
|
||||
#menu li a:active {
|
||||
background: rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('.section').hide();
|
||||
$('.toggle, a.section-title').toggle(function(){
|
||||
$(this).siblings('ul').fadeIn(300);
|
||||
return false;
|
||||
}, function(){
|
||||
$(this).siblings('ul').fadeOut(300);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href='http://github.com/visionmedia/express'>
|
||||
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
|
||||
<p id="tagline">
|
||||
High performance, high class web development for
|
||||
<a href="http://nodejs.org">Node.js</a>
|
||||
</p>
|
||||
<ul id="menu">
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="guide.html">Guide</a></li>
|
||||
<li><a href="screencasts.html">Screencasts</a></li>
|
||||
<li><a href="applications.html">Applications</a></li>
|
||||
</ul>
|
||||
<div class='mp'>
|
||||
<h2 id="Express">Express</h2>
|
||||
<p class="man-name">
|
||||
<code>applications</code>
|
||||
</p>
|
||||
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<p><a href="http://learnboost.com">Learnboost</a> is a free online gradebook application, aimed to crush the competition with innovative, realtime, enjoyable features.</p>
|
||||
|
||||
<p><a href="http://learnboost.com"><img src="images/apps/learnboost.png" alt="LearnBoost" /></a></p>
|
||||
|
||||
<p><a href="http://storify.com">Storify</a> lets you turn what people post on social media websites into compelling stories.</p>
|
||||
|
||||
<p><a href="http://storify.com"><img src="images/apps/storify.png" alt="Storify" /></a></p>
|
||||
|
||||
<p><a href="http://pakistansurvey.org/">Pakistan Survey</a> by <a href="http://developmentseed.org">Development Seed</a>, provides in-depth agency-specific analysis from regional experts with data from 1,000 interviews across 120 villages in all seven tribal agencies and mapping of 142 reported drone strikes in FATA through July 2010.</p>
|
||||
|
||||
<p><a href="http://pakistansurvey.org"><img src="images/apps/developmentseed.png" alt="Pakistan Survey" /></a></p>
|
||||
|
||||
<p><a href="http://markup.io">Markup.IO</a> allows you to draw directly on <em>any</em> website, then share with others to share your thoughts.</p>
|
||||
|
||||
<p><a href="http://markup.io"><img src="images/apps/markupio.png" alt="Markup.IO" /></a></p>
|
||||
|
||||
<p><a href="http://scrabb.ly">Scrabb.ly</a> is a massively multiplayer scrabble game initially created for the <a href="http://nodeknockout.com/">Node Knockout</a> competition.</p>
|
||||
|
||||
<p><a href="http://scrabb.ly"><img src="images/apps/scrabbly.png" alt="Online Realtime Scrabble" /></a></p>
|
||||
|
||||
<p><a href="http://clickdummy.net/">ClickDummy</a> is a rapid mockup prototyping application for designers and dummies.</p>
|
||||
|
||||
<p><a href="http://clickdummy.net"><img src="images/apps/clickdummy.png" alt="Mockup Prototying" /></a></p>
|
||||
|
||||
<p><a href="http://nodeknockout.com">Node Knockout</a> organized the first ever node-specific competition with hundreds of contestants.</p>
|
||||
|
||||
<p><a href="http://nodeknockout.com"><img src="images/apps/nodeko.png" alt="Node Knockout Competition Express" /></a></p>
|
||||
|
||||
<p><a href="http://widescript.com">Widescript</a> is an innovative app that helps you focus and interact with your texts - on your desktop, your couch or on the go.</p>
|
||||
|
||||
<p><a href="http://widescript.com"><img src="images/apps/widescript.png" alt="Widescript" /></a></p>
|
||||
|
||||
<p><a href="http://www.e-resistible.co.uk/">e-resistable</a> is an online order takeaway system providing an intuitive way to fill your belly from your computer!</p>
|
||||
|
||||
<p><a href="http://www.e-resistible.co.uk"><img src="images/apps/e-resistable.png" alt="Online Takeaway" /></a></p>
|
||||
|
||||
<p><a href="http://toptwittertrends.com">Top Twitter Trends</a> utilizes MongoDB, Socket.IO, jQuery and many other exciting libraries to bring you trending tweets in realtime.</p>
|
||||
|
||||
<p><a href="http://toptwittertrends.com"><img src="images/apps/toptwittertrends.png" alt="Twitter Trends" /></a></p>
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
<p>The applications shown above are not listed in any specific order. To have an application added or removed please contact <a href="http://github.com/visionmedia">TJ Holowaychuk</a>.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
<br />
|
||||
|
||||
[Learnboost](http://learnboost.com) is a free online gradebook application, aimed to crush the competition with innovative, realtime, enjoyable features.
|
||||
|
||||
[](http://learnboost.com)
|
||||
|
||||
[Storify](http://storify.com) lets you turn what people post on social media websites into compelling stories.
|
||||
|
||||
[](http://storify.com)
|
||||
|
||||
|
||||
[Pakistan Survey](http://pakistansurvey.org/) by [Development Seed](http://developmentseed.org), provides in-depth agency-specific analysis from regional experts with data from 1,000 interviews across 120 villages in all seven tribal agencies and mapping of 142 reported drone strikes in FATA through July 2010.
|
||||
|
||||
[](http://pakistansurvey.org)
|
||||
|
||||
[Markup.IO](http://markup.io) allows you to draw directly on _any_ website, then share with others to share your thoughts.
|
||||
|
||||
[](http://markup.io)
|
||||
|
||||
[Scrabb.ly](http://scrabb.ly) is a massively multiplayer scrabble game initially created for the [Node Knockout](http://nodeknockout.com/) competition.
|
||||
|
||||
[](http://scrabb.ly)
|
||||
|
||||
[ClickDummy](http://clickdummy.net/) is a rapid mockup prototyping application for designers and dummies.
|
||||
|
||||
[](http://clickdummy.net)
|
||||
|
||||
[Node Knockout](http://nodeknockout.com) organized the first ever node-specific competition with hundreds of contestants.
|
||||
|
||||
[](http://nodeknockout.com)
|
||||
|
||||
[Widescript](http://widescript.com) is an innovative app that helps you focus and interact with your texts - on your desktop, your couch or on the go.
|
||||
|
||||
[](http://widescript.com)
|
||||
|
||||
[e-resistable](http://www.e-resistible.co.uk/) is an online order takeaway system providing an intuitive way to fill your belly from your computer!
|
||||
|
||||
[](http://www.e-resistible.co.uk)
|
||||
|
||||
[Top Twitter Trends](http://toptwittertrends.com) utilizes MongoDB, Socket.IO, jQuery and many other exciting libraries to bring you trending tweets in realtime.
|
||||
|
||||
[](http://toptwittertrends.com)
|
||||
|
||||
<br />
|
||||
|
||||
The applications shown above are not listed in any specific order. To have an application added or removed please contact [TJ Holowaychuk](http://github.com/visionmedia).
|
||||
@@ -0,0 +1,82 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "CONTRIB" "" "March 2011" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBcontrib\fR
|
||||
.
|
||||
.SS "Development Dependencies"
|
||||
Express development dependencies are stored within the \fI\./support\fR directory\. To update them execute:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
$ git submodule update \-\-init
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "Running Tests"
|
||||
Express uses the Expresso \fIhttp://github\.com/visionmedia/expresso\fR TDD framework to write and run elegant test suites extremely fast\. To run all test suites simply execute:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
$ make test
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
To target specific suites we may specify the files via:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
$ make test TESTS=test/view\.test\.js
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
To check test coverage run:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
$ make test\-cov
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "Contributions"
|
||||
To accept a contribution, you should follow these guidelines:
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
All tests \fImust\fR pass
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Your alterations or additions \fImust\fR include tests
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Your commit(s) should be \fIfocused\fR, do not commit once for several changes
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Do \fInot\fR alter release information such as the \fIversion\fR, or \fIHistory\.md\fR
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Indents are \fI2\fR spaces\.
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "Documentation"
|
||||
To contribute documentation edit the markdown files in \fI\./docs\fR, however do \fInot\fR run \fImake docs\fR, as they will be re\-built and published with each release\.
|
||||
@@ -0,0 +1,247 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Express - node web framework</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<style>
|
||||
#tagline {
|
||||
margin-left: 75px;
|
||||
margin-bottom: 30px;
|
||||
color: rgba(255,255,255,0.7); }
|
||||
html {
|
||||
background: #1c1c1c url(images/bg.tile.jpg); }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: url(images/bg.jpg) 50% 0 no-repeat;
|
||||
color: #8b8b8b; }
|
||||
|
||||
* {
|
||||
outline: none; }
|
||||
|
||||
em {
|
||||
color: white; }
|
||||
|
||||
a img {
|
||||
border: none !important; }
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
a:hover {
|
||||
opacity: 0.8; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 45px 0 0 0;
|
||||
color: white;
|
||||
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
|
||||
|
||||
h3 {
|
||||
font-size: 18px; }
|
||||
h4 {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 10px;
|
||||
padding: 25px 20px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border: 1px solid #323232;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px; }
|
||||
|
||||
code {
|
||||
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
|
||||
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 35px; }
|
||||
ul li {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style: square; }
|
||||
ul li ul {
|
||||
margin: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.man-name, #Express { display:none; }
|
||||
|
||||
.sect {
|
||||
margin-left: 40px; }
|
||||
img {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
margin-left: 30%;
|
||||
margin-bottom: 30px;
|
||||
width: 194px;
|
||||
height: 51px;
|
||||
background: url(images/logo.png) 0 0 no-repeat;
|
||||
text-indent: -99999px; }
|
||||
#logo:hover {
|
||||
opacity: 0.7; }
|
||||
#logo:active {
|
||||
opacity: 0.3; }
|
||||
|
||||
#ribbon {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2; }
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
background: url(images/top.png) 0 0 repeat-x; }
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
padding-top: 80px;
|
||||
width: 550px; }
|
||||
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 15px;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
border-right: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
#toc li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#toc li a {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu {
|
||||
margin-left: 75px;
|
||||
padding: 0;
|
||||
padding-bottom: 30px; }
|
||||
#menu li {
|
||||
display: inline;
|
||||
list-style: none; }
|
||||
#menu li a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 2px;
|
||||
padding: 3px 15px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
#menu li a:hover,
|
||||
#menu li a.active {
|
||||
background: rgba(0,0,0,0.5); }
|
||||
#menu li a:active {
|
||||
background: rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('.section').hide();
|
||||
$('.toggle, a.section-title').toggle(function(){
|
||||
$(this).siblings('ul').fadeIn(300);
|
||||
return false;
|
||||
}, function(){
|
||||
$(this).siblings('ul').fadeOut(300);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href='http://github.com/visionmedia/express'>
|
||||
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
|
||||
<p id="tagline">
|
||||
High performance, high class web development for
|
||||
<a href="http://nodejs.org">Node.js</a>
|
||||
</p>
|
||||
<ul id="menu">
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="guide.html">Guide</a></li>
|
||||
<li><a href="screencasts.html">Screencasts</a></li>
|
||||
<li><a href="applications.html">Applications</a></li>
|
||||
</ul>
|
||||
<div class='mp'>
|
||||
<h2 id="Express">Express</h2>
|
||||
<p class="man-name">
|
||||
<code>contrib</code>
|
||||
</p>
|
||||
<h3 id="Development-Dependencies">Development Dependencies</h3>
|
||||
|
||||
<p>Express development dependencies are stored within the <em>./support</em> directory. To
|
||||
update them execute:</p>
|
||||
|
||||
<pre><code>$ git submodule update --init
|
||||
</code></pre>
|
||||
|
||||
<h3 id="Running-Tests">Running Tests</h3>
|
||||
|
||||
<p>Express uses the <a href="http://github.com/visionmedia/expresso">Expresso</a> TDD
|
||||
framework to write and run elegant test suites extremely fast. To run all test suites
|
||||
simply execute:</p>
|
||||
|
||||
<pre><code>$ make test
|
||||
</code></pre>
|
||||
|
||||
<p>To target specific suites we may specify the files via:</p>
|
||||
|
||||
<pre><code>$ make test TESTS=test/view.test.js
|
||||
</code></pre>
|
||||
|
||||
<p>To check test coverage run:</p>
|
||||
|
||||
<pre><code>$ make test-cov
|
||||
</code></pre>
|
||||
|
||||
<h3 id="Contributions">Contributions</h3>
|
||||
|
||||
<p>To accept a contribution, you should follow these guidelines:</p>
|
||||
|
||||
<ul>
|
||||
<li>All tests <em>must</em> pass</li>
|
||||
<li>Your alterations or additions <em>must</em> include tests</li>
|
||||
<li>Your commit(s) should be <em>focused</em>, do not commit once for several changes</li>
|
||||
<li>Do <em>not</em> alter release information such as the <em>version</em>, or <em>History.md</em></li>
|
||||
<li>Indents are <em>2</em> spaces.</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h3 id="Documentation">Documentation</h3>
|
||||
|
||||
<p>To contribute documentation edit the markdown files in <em>./docs</em>, however
|
||||
do <em>not</em> run <em>make docs</em>, as they will be re-built and published with each release.</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
### Development Dependencies
|
||||
|
||||
Express development dependencies are stored within the _./support_ directory. To
|
||||
update them execute:
|
||||
|
||||
$ git submodule update --init
|
||||
|
||||
### Running Tests
|
||||
|
||||
Express uses the [Expresso](http://github.com/visionmedia/expresso) TDD
|
||||
framework to write and run elegant test suites extremely fast. To run all test suites
|
||||
simply execute:
|
||||
|
||||
$ make test
|
||||
|
||||
To target specific suites we may specify the files via:
|
||||
|
||||
$ make test TESTS=test/view.test.js
|
||||
|
||||
To check test coverage run:
|
||||
|
||||
$ make test-cov
|
||||
|
||||
### Contributions
|
||||
|
||||
To accept a contribution, you should follow these guidelines:
|
||||
|
||||
* All tests _must_ pass
|
||||
* Your alterations or additions _must_ include tests
|
||||
* Your commit(s) should be _focused_, do not commit once for several changes
|
||||
* Do _not_ alter release information such as the _version_, or _History.md_
|
||||
* Indents are _2_ spaces.
|
||||
|
||||
### Documentation
|
||||
|
||||
To contribute documentation edit the markdown files in _./docs_, however
|
||||
do _not_ run _make docs_, as they will be re-built and published with each release.
|
||||
@@ -0,0 +1,31 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "EXECUTABLE" "" "March 2011" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBexecutable\fR
|
||||
.
|
||||
.SH "Synopsis"
|
||||
.
|
||||
.nf
|
||||
|
||||
express [options] [PATH]
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.SH "Description"
|
||||
The \fIexpress\fR executable generates apps at the given \fBPATH\fR or the current working directory\. Although Express is not bound to a specific application structure, this executable creates a maintainable base app\.
|
||||
.
|
||||
.SH "Options"
|
||||
.
|
||||
.nf
|
||||
|
||||
\-s, \-\-sessions Add session support
|
||||
\-t, \-\-template ENGINE Add template ENGINE support (jade|ejs)\. Defaults to jade
|
||||
\-c, \-\-css ENGINE Add stylesheet ENGINE support (less|sass|stylus)\. Defaults to plain css
|
||||
\-v, \-\-version Output framework version
|
||||
\-h, \-\-help Output help information
|
||||
.
|
||||
.fi
|
||||
|
||||
@@ -0,0 +1,222 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Express - node web framework</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<style>
|
||||
#tagline {
|
||||
margin-left: 75px;
|
||||
margin-bottom: 30px;
|
||||
color: rgba(255,255,255,0.7); }
|
||||
html {
|
||||
background: #1c1c1c url(images/bg.tile.jpg); }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: url(images/bg.jpg) 50% 0 no-repeat;
|
||||
color: #8b8b8b; }
|
||||
|
||||
* {
|
||||
outline: none; }
|
||||
|
||||
em {
|
||||
color: white; }
|
||||
|
||||
a img {
|
||||
border: none !important; }
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
a:hover {
|
||||
opacity: 0.8; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 45px 0 0 0;
|
||||
color: white;
|
||||
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
|
||||
|
||||
h3 {
|
||||
font-size: 18px; }
|
||||
h4 {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 10px;
|
||||
padding: 25px 20px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border: 1px solid #323232;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px; }
|
||||
|
||||
code {
|
||||
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
|
||||
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 35px; }
|
||||
ul li {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style: square; }
|
||||
ul li ul {
|
||||
margin: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.man-name, #Express { display:none; }
|
||||
|
||||
.sect {
|
||||
margin-left: 40px; }
|
||||
img {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
margin-left: 30%;
|
||||
margin-bottom: 30px;
|
||||
width: 194px;
|
||||
height: 51px;
|
||||
background: url(images/logo.png) 0 0 no-repeat;
|
||||
text-indent: -99999px; }
|
||||
#logo:hover {
|
||||
opacity: 0.7; }
|
||||
#logo:active {
|
||||
opacity: 0.3; }
|
||||
|
||||
#ribbon {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2; }
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
background: url(images/top.png) 0 0 repeat-x; }
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
padding-top: 80px;
|
||||
width: 550px; }
|
||||
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 15px;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
border-right: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
#toc li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#toc li a {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu {
|
||||
margin-left: 75px;
|
||||
padding: 0;
|
||||
padding-bottom: 30px; }
|
||||
#menu li {
|
||||
display: inline;
|
||||
list-style: none; }
|
||||
#menu li a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 2px;
|
||||
padding: 3px 15px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
#menu li a:hover,
|
||||
#menu li a.active {
|
||||
background: rgba(0,0,0,0.5); }
|
||||
#menu li a:active {
|
||||
background: rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('.section').hide();
|
||||
$('.toggle, a.section-title').toggle(function(){
|
||||
$(this).siblings('ul').fadeIn(300);
|
||||
return false;
|
||||
}, function(){
|
||||
$(this).siblings('ul').fadeOut(300);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href='http://github.com/visionmedia/express'>
|
||||
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
|
||||
<p id="tagline">
|
||||
High performance, high class web development for
|
||||
<a href="http://nodejs.org">Node.js</a>
|
||||
</p>
|
||||
<ul id="menu">
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="guide.html">Guide</a></li>
|
||||
<li><a href="screencasts.html">Screencasts</a></li>
|
||||
<li><a href="applications.html">Applications</a></li>
|
||||
</ul>
|
||||
<div class='mp'>
|
||||
<h2 id="Express">Express</h2>
|
||||
<p class="man-name">
|
||||
<code>executable</code>
|
||||
</p>
|
||||
<h2 id="Synopsis">Synopsis</h2>
|
||||
|
||||
<pre><code>express [options] [PATH]
|
||||
</code></pre>
|
||||
|
||||
<h2 id="Description">Description</h2>
|
||||
|
||||
<p>The <em>express</em> executable generates apps at the given <strong>PATH</strong> or the
|
||||
current working directory. Although Express is not bound to a specific
|
||||
application structure, this executable creates a maintainable base app.</p>
|
||||
|
||||
<h2 id="Options">Options</h2>
|
||||
|
||||
<pre><code> -s, --sessions Add session support
|
||||
-t, --template ENGINE Add template ENGINE support (jade|ejs). Defaults to jade
|
||||
-c, --css ENGINE Add stylesheet ENGINE support (less|sass|stylus). Defaults to plain css
|
||||
-v, --version Output framework version
|
||||
-h, --help Output help information
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
|
||||
## Synopsis
|
||||
|
||||
express [options] [PATH]
|
||||
|
||||
## Description
|
||||
|
||||
The _express_ executable generates apps at the given **PATH** or the
|
||||
current working directory. Although Express is not bound to a specific
|
||||
application structure, this executable creates a maintainable base app.
|
||||
|
||||
## Options
|
||||
|
||||
-s, --sessions Add session support
|
||||
-t, --template ENGINE Add template ENGINE support (jade|ejs). Defaults to jade
|
||||
-c, --css ENGINE Add stylesheet ENGINE support (less|sass|stylus). Defaults to plain css
|
||||
-v, --version Output framework version
|
||||
-h, --help Output help information
|
||||
|
||||
|
||||
|
||||
|
Depois Largura: | Altura: | Tamanho: 108 KiB |
|
Depois Largura: | Altura: | Tamanho: 159 KiB |
|
Depois Largura: | Altura: | Tamanho: 145 KiB |
|
Depois Largura: | Altura: | Tamanho: 145 KiB |
|
Depois Largura: | Altura: | Tamanho: 154 KiB |
|
Depois Largura: | Altura: | Tamanho: 181 KiB |
|
Depois Largura: | Altura: | Tamanho: 200 KiB |
|
Depois Largura: | Altura: | Tamanho: 236 KiB |
|
Depois Largura: | Altura: | Tamanho: 112 KiB |
|
Depois Largura: | Altura: | Tamanho: 88 KiB |
|
Depois Largura: | Altura: | Tamanho: 127 KiB |
|
Depois Largura: | Altura: | Tamanho: 108 KiB |
|
Depois Largura: | Altura: | Tamanho: 7.0 KiB |
|
Depois Largura: | Altura: | Tamanho: 7.2 KiB |
|
Depois Largura: | Altura: | Tamanho: 143 B |
@@ -0,0 +1,126 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "INDEX" "" "March 2011" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBindex\fR
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
var app = express\.createServer();
|
||||
|
||||
app\.get(\'/\', function(req, res){
|
||||
res\.send(\'Hello World\');
|
||||
});
|
||||
|
||||
app\.listen(3000);
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SH "Features"
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Robust routing
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Redirection helpers
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Dynamic view helpers
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Application level view options
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Content negotiation
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Application mounting
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Focus on high performance
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
View rendering and partials support
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Environment based configuration
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Session based flash notifications
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Built on Connect \fIhttp://github\.com/senchalabs/connect\fR
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Executable \fIexecutable\.html\fR for generating applications quickly
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
High test coverage
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SH "Contributors"
|
||||
The following are the major contributors of Express (in no specific order)\.
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
TJ Holowaychuk (visionmedia \fIhttp://github\.com/visionmedia\fR)
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Ciaran Jessup (ciaranj \fIhttp://github\.com/ciaranj\fR)
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Aaron Heckmann (aheckmann \fIhttp://github\.com/aheckmann\fR)
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Guillermo Rauch (guille \fIhttp://github\.com/guille\fR)
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SH "Third\-Party Modules"
|
||||
The following modules compliment or extend Express directly:
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
express\-resource \fIhttp://github\.com/visionmedia/express\-resource\fR provides resourceful routing
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
express\-messages \fIhttp://github\.com/visionmedia/express\-messages\fR flash message notification rendering
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
express\-configure \fIhttp://github\.com/visionmedia/express\-configure\fR async configuration support (load settings from redis etc)
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
express\-namespace \fIhttp://github\.com/visionmedia/express\-namespace\fR namespaced routing support
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SH "More Information"
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Google Group \fIhttp://groups\.google\.com/group/express\-js\fR for discussion
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
Follow tjholowaychuk \fIhttp://twitter\.com/tjholowaychuk\fR on twitter for updates
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
View the Connect \fIhttp://senchalabs\.github\.com/connect\fR documentation
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
View the Connect Wiki \fIhttp://wiki\.github\.com/senchalabs/connect/\fR for contrib middleware
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
View the examples \fIhttp://github\.com/visionmedia/express/tree/master/examples/\fR
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
View the source \fIhttp://github\.com/visionmedia/express\fR
|
||||
.
|
||||
.IP "\(bu" 4
|
||||
View the contrib guide \fIcontrib\.html\fR
|
||||
.
|
||||
.IP "" 0
|
||||
|
||||
@@ -0,0 +1,267 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Express - node web framework</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<style>
|
||||
#tagline {
|
||||
margin-left: 75px;
|
||||
margin-bottom: 30px;
|
||||
color: rgba(255,255,255,0.7); }
|
||||
html {
|
||||
background: #1c1c1c url(images/bg.tile.jpg); }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: url(images/bg.jpg) 50% 0 no-repeat;
|
||||
color: #8b8b8b; }
|
||||
|
||||
* {
|
||||
outline: none; }
|
||||
|
||||
em {
|
||||
color: white; }
|
||||
|
||||
a img {
|
||||
border: none !important; }
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
a:hover {
|
||||
opacity: 0.8; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 45px 0 0 0;
|
||||
color: white;
|
||||
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
|
||||
|
||||
h3 {
|
||||
font-size: 18px; }
|
||||
h4 {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 10px;
|
||||
padding: 25px 20px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border: 1px solid #323232;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px; }
|
||||
|
||||
code {
|
||||
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
|
||||
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 35px; }
|
||||
ul li {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style: square; }
|
||||
ul li ul {
|
||||
margin: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.man-name, #Express { display:none; }
|
||||
|
||||
.sect {
|
||||
margin-left: 40px; }
|
||||
img {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
margin-left: 30%;
|
||||
margin-bottom: 30px;
|
||||
width: 194px;
|
||||
height: 51px;
|
||||
background: url(images/logo.png) 0 0 no-repeat;
|
||||
text-indent: -99999px; }
|
||||
#logo:hover {
|
||||
opacity: 0.7; }
|
||||
#logo:active {
|
||||
opacity: 0.3; }
|
||||
|
||||
#ribbon {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2; }
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
background: url(images/top.png) 0 0 repeat-x; }
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
padding-top: 80px;
|
||||
width: 550px; }
|
||||
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 15px;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
border-right: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
#toc li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#toc li a {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu {
|
||||
margin-left: 75px;
|
||||
padding: 0;
|
||||
padding-bottom: 30px; }
|
||||
#menu li {
|
||||
display: inline;
|
||||
list-style: none; }
|
||||
#menu li a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 2px;
|
||||
padding: 3px 15px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
#menu li a:hover,
|
||||
#menu li a.active {
|
||||
background: rgba(0,0,0,0.5); }
|
||||
#menu li a:active {
|
||||
background: rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('.section').hide();
|
||||
$('.toggle, a.section-title').toggle(function(){
|
||||
$(this).siblings('ul').fadeIn(300);
|
||||
return false;
|
||||
}, function(){
|
||||
$(this).siblings('ul').fadeOut(300);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href='http://github.com/visionmedia/express'>
|
||||
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
|
||||
<p id="tagline">
|
||||
High performance, high class web development for
|
||||
<a href="http://nodejs.org">Node.js</a>
|
||||
</p>
|
||||
<ul id="menu">
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="guide.html">Guide</a></li>
|
||||
<li><a href="screencasts.html">Screencasts</a></li>
|
||||
<li><a href="applications.html">Applications</a></li>
|
||||
</ul>
|
||||
<div class='mp'>
|
||||
<h2 id="Express">Express</h2>
|
||||
<p class="man-name">
|
||||
<code>index</code>
|
||||
</p>
|
||||
<pre><code>var app = express.createServer();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('Hello World');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
</code></pre>
|
||||
|
||||
<h2 id="Features">Features</h2>
|
||||
|
||||
<ul>
|
||||
<li>Robust routing</li>
|
||||
<li>Redirection helpers</li>
|
||||
<li>Dynamic view helpers</li>
|
||||
<li>Application level view options</li>
|
||||
<li>Content negotiation</li>
|
||||
<li>Application mounting</li>
|
||||
<li>Focus on high performance</li>
|
||||
<li>View rendering and partials support</li>
|
||||
<li>Environment based configuration</li>
|
||||
<li>Session based flash notifications</li>
|
||||
<li>Built on <a href="http://github.com/senchalabs/connect">Connect</a></li>
|
||||
<li><a href="executable.html">Executable</a> for generating applications quickly</li>
|
||||
<li>High test coverage</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Contributors">Contributors</h2>
|
||||
|
||||
<p>The following are the major contributors of Express (in no specific order).</p>
|
||||
|
||||
<ul>
|
||||
<li>TJ Holowaychuk (<a href="http://github.com/visionmedia">visionmedia</a>)</li>
|
||||
<li>Ciaran Jessup (<a href="http://github.com/ciaranj">ciaranj</a>)</li>
|
||||
<li>Aaron Heckmann (<a href="http://github.com/aheckmann">aheckmann</a>)</li>
|
||||
<li>Guillermo Rauch (<a href="http://github.com/guille">guille</a>)</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="Third-Party-Modules">Third-Party Modules</h2>
|
||||
|
||||
<p>The following modules compliment or extend Express directly:</p>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://github.com/visionmedia/express-resource">express-resource</a> provides resourceful routing</li>
|
||||
<li><a href="http://github.com/visionmedia/express-messages">express-messages</a> flash message notification rendering</li>
|
||||
<li><a href="http://github.com/visionmedia/express-configure">express-configure</a> async configuration support (load settings from redis etc)</li>
|
||||
<li><a href="http://github.com/visionmedia/express-namespace">express-namespace</a> namespaced routing support</li>
|
||||
</ul>
|
||||
|
||||
|
||||
<h2 id="More-Information">More Information</h2>
|
||||
|
||||
<ul>
|
||||
<li><a href="http://groups.google.com/group/express-js">Google Group</a> for discussion</li>
|
||||
<li>Follow <a href="http://twitter.com/tjholowaychuk">tjholowaychuk</a> on twitter for updates</li>
|
||||
<li>View the <a href="http://senchalabs.github.com/connect">Connect</a> documentation</li>
|
||||
<li>View the <a href="http://wiki.github.com/senchalabs/connect/">Connect Wiki</a> for contrib middleware</li>
|
||||
<li>View the <a href="http://github.com/visionmedia/express/tree/master/examples/">examples</a></li>
|
||||
<li>View the <a href="http://github.com/visionmedia/express">source</a></li>
|
||||
<li>View the <a href="contrib.html">contrib guide</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,52 @@
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('Hello World');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
|
||||
## Features
|
||||
|
||||
* Robust routing
|
||||
* Redirection helpers
|
||||
* Dynamic view helpers
|
||||
* Application level view options
|
||||
* Content negotiation
|
||||
* Application mounting
|
||||
* Focus on high performance
|
||||
* View rendering and partials support
|
||||
* Environment based configuration
|
||||
* Session based flash notifications
|
||||
* Built on [Connect](http://github.com/senchalabs/connect)
|
||||
* [Executable](executable.html) for generating applications quickly
|
||||
* High test coverage
|
||||
|
||||
## Contributors
|
||||
|
||||
The following are the major contributors of Express (in no specific order).
|
||||
|
||||
* TJ Holowaychuk ([visionmedia](http://github.com/visionmedia))
|
||||
* Ciaran Jessup ([ciaranj](http://github.com/ciaranj))
|
||||
* Aaron Heckmann ([aheckmann](http://github.com/aheckmann))
|
||||
* Guillermo Rauch ([guille](http://github.com/guille))
|
||||
|
||||
## Third-Party Modules
|
||||
|
||||
The following modules compliment or extend Express directly:
|
||||
|
||||
* [express-resource](http://github.com/visionmedia/express-resource) provides resourceful routing
|
||||
* [express-messages](http://github.com/visionmedia/express-messages) flash message notification rendering
|
||||
* [express-configure](http://github.com/visionmedia/express-configure) async configuration support (load settings from redis etc)
|
||||
* [express-namespace](http://github.com/visionmedia/express-namespace) namespaced routing support
|
||||
|
||||
## More Information
|
||||
|
||||
* [Google Group](http://groups.google.com/group/express-js) for discussion
|
||||
* Follow [tjholowaychuk](http://twitter.com/tjholowaychuk) on twitter for updates
|
||||
* View the [Connect](http://senchalabs.github.com/connect) documentation
|
||||
* View the [Connect Wiki](http://wiki.github.com/senchalabs/connect/) for contrib middleware
|
||||
* View the [examples](http://github.com/visionmedia/express/tree/master/examples/)
|
||||
* View the [source](http://github.com/visionmedia/express)
|
||||
* View the [contrib guide](contrib.html)
|
||||
@@ -0,0 +1,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,192 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Express - node web framework</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<style>
|
||||
#tagline {
|
||||
margin-left: 75px;
|
||||
margin-bottom: 30px;
|
||||
color: rgba(255,255,255,0.7); }
|
||||
html {
|
||||
background: #1c1c1c url(images/bg.tile.jpg); }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: url(images/bg.jpg) 50% 0 no-repeat;
|
||||
color: #8b8b8b; }
|
||||
|
||||
* {
|
||||
outline: none; }
|
||||
|
||||
em {
|
||||
color: white; }
|
||||
|
||||
a img {
|
||||
border: none !important; }
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
a:hover {
|
||||
opacity: 0.8; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 45px 0 0 0;
|
||||
color: white;
|
||||
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
|
||||
|
||||
h3 {
|
||||
font-size: 18px; }
|
||||
h4 {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 10px;
|
||||
padding: 25px 20px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border: 1px solid #323232;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px; }
|
||||
|
||||
code {
|
||||
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
|
||||
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 35px; }
|
||||
ul li {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style: square; }
|
||||
ul li ul {
|
||||
margin: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.man-name, #Express { display:none; }
|
||||
|
||||
.sect {
|
||||
margin-left: 40px; }
|
||||
img {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
margin-left: 30%;
|
||||
margin-bottom: 30px;
|
||||
width: 194px;
|
||||
height: 51px;
|
||||
background: url(images/logo.png) 0 0 no-repeat;
|
||||
text-indent: -99999px; }
|
||||
#logo:hover {
|
||||
opacity: 0.7; }
|
||||
#logo:active {
|
||||
opacity: 0.3; }
|
||||
|
||||
#ribbon {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2; }
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
background: url(images/top.png) 0 0 repeat-x; }
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
padding-top: 80px;
|
||||
width: 550px; }
|
||||
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 15px;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
border-right: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
#toc li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#toc li a {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu {
|
||||
margin-left: 75px;
|
||||
padding: 0;
|
||||
padding-bottom: 30px; }
|
||||
#menu li {
|
||||
display: inline;
|
||||
list-style: none; }
|
||||
#menu li a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 2px;
|
||||
padding: 3px 15px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
#menu li a:hover,
|
||||
#menu li a.active {
|
||||
background: rgba(0,0,0,0.5); }
|
||||
#menu li a:active {
|
||||
background: rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('.section').hide();
|
||||
$('.toggle, a.section-title').toggle(function(){
|
||||
$(this).siblings('ul').fadeIn(300);
|
||||
return false;
|
||||
}, function(){
|
||||
$(this).siblings('ul').fadeOut(300);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href='http://github.com/visionmedia/express'>
|
||||
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
|
||||
<p id="tagline">
|
||||
High performance, high class web development for
|
||||
<a href="http://nodejs.org">Node.js</a>
|
||||
</p>
|
||||
<ul id="menu">
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="guide.html">Guide</a></li>
|
||||
<li><a href="screencasts.html">Screencasts</a></li>
|
||||
<li><a href="applications.html">Applications</a></li>
|
||||
</ul>
|
||||
@@ -0,0 +1,272 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "MIGRATE" "" "March 2011" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBmigrate\fR
|
||||
.
|
||||
.SS "Express 1\.x to 2\.x Migration"
|
||||
.
|
||||
.SS "HTTPS"
|
||||
Creating an HTTPS server is simply, simply pass the TLS options to \fIexpress\.createServer()\fR:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
var app = express\.createServer({
|
||||
key: \.\.\.
|
||||
, cert: \.\.\.
|
||||
});
|
||||
|
||||
app\.listen(443);
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "req\.header() Referrer"
|
||||
Previously if anyone was doing something similar to:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
req\.headers\.referrer || req\.headers\.referer
|
||||
req\.header(\'Referrer\') || req\.header(\'Referer\')
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
With the new special\-case we may now simply use \fIReferrer\fR which will return either if defined:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
req\.header(\'Referrer\')
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "res\.local(name, val)"
|
||||
Previously all local variables had to be passed to \fIres\.render()\fR, or either \fIapp\.helpers()\fR or \fIapp\.dynamicHelpers()\fR, now we may do this at the request\-level progressively\. The \fIres\.local()\fR method accepts a \fIname\fR and \fIval\fR, however the locals passed to \fIres\.render()\fR will take precedence\.
|
||||
.
|
||||
.P
|
||||
For example we may utilize this feature to create locals in middleware:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
function loadUser(req, res, next) {
|
||||
User\.get(req\.params\.id, function(err, user){
|
||||
res\.local(\'user\', user);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
app\.get(\'/user/:id\', loadUser, function(req, res){
|
||||
res\.render(\'user\');
|
||||
});
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "req\.param(name[, defaultValue])"
|
||||
Previously only \fIname\fR was accepted, so some of you may have been doing the following:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
var id = req\.param(\'id\') || req\.user\.id;
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
The new \fIdefaultValue\fR argument can handle this nicely:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
var id = req\.param(\'id\', req\.user\.id);
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "app\.helpers() / app\.locals()"
|
||||
\fIapp\.locals()\fR is now an alias of \fIapp\.helpers()\fR, as helpers makes more sense for functions\.
|
||||
.
|
||||
.SS "req\.accepts(type)"
|
||||
\fIreq\.accepts()\fR now accepts extensions:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
// Accept: text/html
|
||||
req\.accepts(\'html\');
|
||||
req\.accepts(\'\.html\');
|
||||
// => true
|
||||
|
||||
// Accept: text/*; application/json
|
||||
req\.accepts(\'html\');
|
||||
req\.accepts(\'text/*\');
|
||||
req\.accepts(\'text/plain\');
|
||||
req\.accepts(\'application/json\');
|
||||
// => true
|
||||
|
||||
req\.accepts(\'image/png\');
|
||||
req\.accepts(\'png\');
|
||||
// => false
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "res\.cookie()"
|
||||
Previously only directly values could be passed, so for example:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
res\.cookie(\'rememberme\', \'yes\', { expires: new Date(Date\.now() + 900000) });
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
However now we have the alternative \fImaxAge\fR property which may be used to set \fIexpires\fR relative to \fIDate\.now()\fR in milliseconds, so our example above can now become:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
res\.cookie(\'rememberme\', \'yes\', { maxAge: 900000 });
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "res\.download() / res\.sendfile()"
|
||||
Both of these methods now utilize Connect\'s static file server behind the scenes (actually the previous Express code was ported to Connect 1\.0)\. With this change comes a change to the callback as well\. Previously the \fIpath\fR and \fIstream\fR were passed, however now only an \fIerror\fR is passed, when no error has occurred the callback will be invoked indicating that the file transfer is complete\. The callback remains optional:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
res\.download(\'/path/to/file\');
|
||||
|
||||
res\.download(\'/path/to/file\', function(err){
|
||||
if (err) {
|
||||
console\.error(err);
|
||||
} else {
|
||||
console\.log(\'transferred\');
|
||||
}
|
||||
});
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
The \fIstream threshold\fR setting was removed\.
|
||||
.
|
||||
.SS "res\.render()"
|
||||
Previously locals were passed as a separate key:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
res\.render(\'user\', { layout: false, locals: { user: user }});
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
In Express 2\.0 both the locals and the options are one in the same, meaning you cannot have a local variable named \fIlayout\fR as it is reserved for express, however this cleans up the API:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
res\.render(\'user\', { layout: false, user: user });
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "res\.partial()"
|
||||
Express 2\.0 adds the \fIres\.partial()\fR method, helpful for rendering partial fragments over WebSockets or Ajax requests etc\. The API is identical to the \fIpartial()\fR calls within views\.
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
// render a collection of comments
|
||||
res\.partial(\'comment\', [comment1, comment2]);
|
||||
|
||||
// render a single comment
|
||||
res\.partial(\'comment\', comment);
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "Template Engine Compliance"
|
||||
To comply with Express previously engines needed the following signature:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
engine\.render(str, options, function(err){});
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.P
|
||||
Now they must export a \fIcompile()\fR function, returning a function which when called with local variables will render the template\. This allows Express to cache the compiled function in memory during production\.
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
var fn = engine\.compile(str, options);
|
||||
fn(locals);
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
.
|
||||
.SS "View Partial Lookup"
|
||||
Previously partials were loaded relative to the now removed \fIview partials\fR directory setting, or by default \fIviews/partials\fR, now they are relative to the view calling them, read more on view lookup \fIguide\.html#View\-Lookup\fR\.
|
||||
.
|
||||
.SS "Mime Types"
|
||||
Express and Connect now utilize the \fImime\fR module in npm, so to add more use:
|
||||
.
|
||||
.IP "" 4
|
||||
.
|
||||
.nf
|
||||
|
||||
require(\'mime\')\.define({ \'foo/bar\': [\'foo\', \'bar\'] });
|
||||
.
|
||||
.fi
|
||||
.
|
||||
.IP "" 0
|
||||
|
||||
@@ -0,0 +1,360 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Express - node web framework</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<style>
|
||||
#tagline {
|
||||
margin-left: 75px;
|
||||
margin-bottom: 30px;
|
||||
color: rgba(255,255,255,0.7); }
|
||||
html {
|
||||
background: #1c1c1c url(images/bg.tile.jpg); }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: url(images/bg.jpg) 50% 0 no-repeat;
|
||||
color: #8b8b8b; }
|
||||
|
||||
* {
|
||||
outline: none; }
|
||||
|
||||
em {
|
||||
color: white; }
|
||||
|
||||
a img {
|
||||
border: none !important; }
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
a:hover {
|
||||
opacity: 0.8; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 45px 0 0 0;
|
||||
color: white;
|
||||
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
|
||||
|
||||
h3 {
|
||||
font-size: 18px; }
|
||||
h4 {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 10px;
|
||||
padding: 25px 20px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border: 1px solid #323232;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px; }
|
||||
|
||||
code {
|
||||
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
|
||||
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 35px; }
|
||||
ul li {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style: square; }
|
||||
ul li ul {
|
||||
margin: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.man-name, #Express { display:none; }
|
||||
|
||||
.sect {
|
||||
margin-left: 40px; }
|
||||
img {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
margin-left: 30%;
|
||||
margin-bottom: 30px;
|
||||
width: 194px;
|
||||
height: 51px;
|
||||
background: url(images/logo.png) 0 0 no-repeat;
|
||||
text-indent: -99999px; }
|
||||
#logo:hover {
|
||||
opacity: 0.7; }
|
||||
#logo:active {
|
||||
opacity: 0.3; }
|
||||
|
||||
#ribbon {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2; }
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
background: url(images/top.png) 0 0 repeat-x; }
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
padding-top: 80px;
|
||||
width: 550px; }
|
||||
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 15px;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
border-right: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
#toc li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#toc li a {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu {
|
||||
margin-left: 75px;
|
||||
padding: 0;
|
||||
padding-bottom: 30px; }
|
||||
#menu li {
|
||||
display: inline;
|
||||
list-style: none; }
|
||||
#menu li a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 2px;
|
||||
padding: 3px 15px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
#menu li a:hover,
|
||||
#menu li a.active {
|
||||
background: rgba(0,0,0,0.5); }
|
||||
#menu li a:active {
|
||||
background: rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('.section').hide();
|
||||
$('.toggle, a.section-title').toggle(function(){
|
||||
$(this).siblings('ul').fadeIn(300);
|
||||
return false;
|
||||
}, function(){
|
||||
$(this).siblings('ul').fadeOut(300);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href='http://github.com/visionmedia/express'>
|
||||
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
|
||||
<p id="tagline">
|
||||
High performance, high class web development for
|
||||
<a href="http://nodejs.org">Node.js</a>
|
||||
</p>
|
||||
<ul id="menu">
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="guide.html">Guide</a></li>
|
||||
<li><a href="screencasts.html">Screencasts</a></li>
|
||||
<li><a href="applications.html">Applications</a></li>
|
||||
</ul>
|
||||
<div class='mp'>
|
||||
<h2 id="Express">Express</h2>
|
||||
<p class="man-name">
|
||||
<code>migrate</code>
|
||||
</p>
|
||||
<h3 id="Express-1-x-to-2-x-Migration">Express 1.x to 2.x Migration</h3>
|
||||
|
||||
<h3 id="HTTPS">HTTPS</h3>
|
||||
|
||||
<p> Creating an HTTPS server is simply, simply pass the TLS options to <em>express.createServer()</em>:</p>
|
||||
|
||||
<pre><code> var app = express.createServer({
|
||||
key: ...
|
||||
, cert: ...
|
||||
});
|
||||
|
||||
app.listen(443);
|
||||
</code></pre>
|
||||
|
||||
<h3 id="req-header-Referrer">req.header() Referrer</h3>
|
||||
|
||||
<p> Previously if anyone was doing something similar to:</p>
|
||||
|
||||
<pre><code> req.headers.referrer || req.headers.referer
|
||||
req.header('Referrer') || req.header('Referer')
|
||||
</code></pre>
|
||||
|
||||
<p> With the new special-case we may now simply use <em>Referrer</em> which will return either if defined:</p>
|
||||
|
||||
<pre><code> req.header('Referrer')
|
||||
</code></pre>
|
||||
|
||||
<h3 id="res-local-name-val-">res.local(name, val)</h3>
|
||||
|
||||
<p> Previously all local variables had to be passed to <em>res.render()</em>, or either <em>app.helpers()</em> or <em>app.dynamicHelpers()</em>, now we may do this at the request-level progressively. The <em>res.local()</em> method accepts a <em>name</em> and <em>val</em>, however the locals passed to <em>res.render()</em> will take precedence.</p>
|
||||
|
||||
<p> For example we may utilize this feature to create locals in middleware:</p>
|
||||
|
||||
<pre><code> function loadUser(req, res, next) {
|
||||
User.get(req.params.id, function(err, user){
|
||||
res.local('user', user);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
app.get('/user/:id', loadUser, function(req, res){
|
||||
res.render('user');
|
||||
});
|
||||
</code></pre>
|
||||
|
||||
<h3 id="req-param-name-defaultValue-">req.param(name[, defaultValue])</h3>
|
||||
|
||||
<p> Previously only <em>name</em> was accepted, so some of you may have been doing the following:</p>
|
||||
|
||||
<pre><code> var id = req.param('id') || req.user.id;
|
||||
</code></pre>
|
||||
|
||||
<p> The new <em>defaultValue</em> argument can handle this nicely:</p>
|
||||
|
||||
<pre><code> var id = req.param('id', req.user.id);
|
||||
</code></pre>
|
||||
|
||||
<h3 id="app-helpers-app-locals-">app.helpers() / app.locals()</h3>
|
||||
|
||||
<p> <em>app.locals()</em> is now an alias of <em>app.helpers()</em>, as helpers makes more sense for functions.</p>
|
||||
|
||||
<h3 id="req-accepts-type-">req.accepts(type)</h3>
|
||||
|
||||
<p> <em>req.accepts()</em> now accepts extensions:</p>
|
||||
|
||||
<pre><code> // Accept: text/html
|
||||
req.accepts('html');
|
||||
req.accepts('.html');
|
||||
// => true
|
||||
|
||||
// Accept: text/*; application/json
|
||||
req.accepts('html');
|
||||
req.accepts('text/*');
|
||||
req.accepts('text/plain');
|
||||
req.accepts('application/json');
|
||||
// => true
|
||||
|
||||
req.accepts('image/png');
|
||||
req.accepts('png');
|
||||
// => false
|
||||
</code></pre>
|
||||
|
||||
<h3 id="res-cookie-">res.cookie()</h3>
|
||||
|
||||
<p> Previously only directly values could be passed, so for example:</p>
|
||||
|
||||
<pre><code>res.cookie('rememberme', 'yes', { expires: new Date(Date.now() + 900000) });
|
||||
</code></pre>
|
||||
|
||||
<p>However now we have the alternative <em>maxAge</em> property which may be used to set <em>expires</em> relative to <em>Date.now()</em> in milliseconds, so our example above can now become:</p>
|
||||
|
||||
<pre><code>res.cookie('rememberme', 'yes', { maxAge: 900000 });
|
||||
</code></pre>
|
||||
|
||||
<h3 id="res-download-res-sendfile-">res.download() / res.sendfile()</h3>
|
||||
|
||||
<p> Both of these methods now utilize Connect's static file server behind the scenes (actually the previous Express code was ported to Connect 1.0). With this change comes a change to the callback as well. Previously the <em>path</em> and <em>stream</em> were passed, however now only an <em>error</em> is passed, when no error has occurred the callback will be invoked indicating that the file transfer is complete. The callback remains optional:</p>
|
||||
|
||||
<pre><code> res.download('/path/to/file');
|
||||
|
||||
res.download('/path/to/file', function(err){
|
||||
if (err) {
|
||||
console.error(err);
|
||||
} else {
|
||||
console.log('transferred');
|
||||
}
|
||||
});
|
||||
</code></pre>
|
||||
|
||||
<p> The <em>stream threshold</em> setting was removed.</p>
|
||||
|
||||
<h3 id="res-render-">res.render()</h3>
|
||||
|
||||
<p> Previously locals were passed as a separate key:</p>
|
||||
|
||||
<pre><code> res.render('user', { layout: false, locals: { user: user }});
|
||||
</code></pre>
|
||||
|
||||
<p> In Express 2.0 both the locals and the options are one in the same, meaning you cannot have a local variable named <em>layout</em> as it is reserved for express, however this cleans up the API:</p>
|
||||
|
||||
<pre><code> res.render('user', { layout: false, user: user });
|
||||
</code></pre>
|
||||
|
||||
<h3 id="res-partial-">res.partial()</h3>
|
||||
|
||||
<p> Express 2.0 adds the <em>res.partial()</em> method, helpful for rendering partial fragments over WebSockets or Ajax requests etc. The API is identical to the <em>partial()</em> calls within views.</p>
|
||||
|
||||
<pre><code> // render a collection of comments
|
||||
res.partial('comment', [comment1, comment2]);
|
||||
|
||||
// render a single comment
|
||||
res.partial('comment', comment);
|
||||
</code></pre>
|
||||
|
||||
<h3 id="Template-Engine-Compliance">Template Engine Compliance</h3>
|
||||
|
||||
<p> To comply with Express previously engines needed the following signature:</p>
|
||||
|
||||
<pre><code> engine.render(str, options, function(err){});
|
||||
</code></pre>
|
||||
|
||||
<p> Now they must export a <em>compile()</em> function, returning a function which when called with local variables will render the template. This allows Express to cache the compiled function in memory during production.</p>
|
||||
|
||||
<pre><code> var fn = engine.compile(str, options);
|
||||
fn(locals);
|
||||
</code></pre>
|
||||
|
||||
<h3 id="View-Partial-Lookup">View Partial Lookup</h3>
|
||||
|
||||
<p> Previously partials were loaded relative to the now removed <em>view partials</em> directory setting, or by default <em>views/partials</em>, now they are relative to the view calling them, read more on <a href="guide.html#View-Lookup">view lookup</a>.</p>
|
||||
|
||||
<h3 id="Mime-Types">Mime Types</h3>
|
||||
|
||||
<p> Express and Connect now utilize the <em>mime</em> module in npm, so to add more use:</p>
|
||||
|
||||
<pre><code> require('mime').define({ 'foo/bar': ['foo', 'bar'] });
|
||||
</code></pre>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,154 @@
|
||||
|
||||
### Express 1.x to 2.x Migration
|
||||
|
||||
### HTTPS
|
||||
|
||||
Creating an HTTPS server is simply, simply pass the TLS options to _express.createServer()_:
|
||||
|
||||
var app = express.createServer({
|
||||
key: ...
|
||||
, cert: ...
|
||||
});
|
||||
|
||||
app.listen(443);
|
||||
|
||||
### req.header() Referrer
|
||||
|
||||
Previously if anyone was doing something similar to:
|
||||
|
||||
req.headers.referrer || req.headers.referer
|
||||
req.header('Referrer') || req.header('Referer')
|
||||
|
||||
With the new special-case we may now simply use _Referrer_ which will return either if defined:
|
||||
|
||||
req.header('Referrer')
|
||||
|
||||
### res.local(name, val)
|
||||
|
||||
Previously all local variables had to be passed to _res.render()_, or either _app.helpers()_ or _app.dynamicHelpers()_, now we may do this at the request-level progressively. The _res.local()_ method accepts a _name_ and _val_, however the locals passed to _res.render()_ will take precedence.
|
||||
|
||||
For example we may utilize this feature to create locals in middleware:
|
||||
|
||||
function loadUser(req, res, next) {
|
||||
User.get(req.params.id, function(err, user){
|
||||
res.local('user', user);
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
app.get('/user/:id', loadUser, function(req, res){
|
||||
res.render('user');
|
||||
});
|
||||
|
||||
### req.param(name[, defaultValue])
|
||||
|
||||
Previously only _name_ was accepted, so some of you may have been doing the following:
|
||||
|
||||
var id = req.param('id') || req.user.id;
|
||||
|
||||
The new _defaultValue_ argument can handle this nicely:
|
||||
|
||||
var id = req.param('id', req.user.id);
|
||||
|
||||
### app.helpers() / app.locals()
|
||||
|
||||
_app.locals()_ is now an alias of _app.helpers()_, as helpers makes more sense for functions.
|
||||
|
||||
### req.accepts(type)
|
||||
|
||||
_req.accepts()_ now accepts extensions:
|
||||
|
||||
|
||||
// Accept: text/html
|
||||
req.accepts('html');
|
||||
req.accepts('.html');
|
||||
// => true
|
||||
|
||||
// Accept: text/*; application/json
|
||||
req.accepts('html');
|
||||
req.accepts('text/*');
|
||||
req.accepts('text/plain');
|
||||
req.accepts('application/json');
|
||||
// => true
|
||||
|
||||
req.accepts('image/png');
|
||||
req.accepts('png');
|
||||
// => false
|
||||
|
||||
### res.cookie()
|
||||
|
||||
Previously only directly values could be passed, so for example:
|
||||
|
||||
res.cookie('rememberme', 'yes', { expires: new Date(Date.now() + 900000) });
|
||||
|
||||
However now we have the alternative _maxAge_ property which may be used to set _expires_ relative to _Date.now()_ in milliseconds, so our example above can now become:
|
||||
|
||||
res.cookie('rememberme', 'yes', { maxAge: 900000 });
|
||||
|
||||
### res.download() / res.sendfile()
|
||||
|
||||
Both of these methods now utilize Connect's static file server behind the scenes (actually the previous Express code was ported to Connect 1.0). With this change comes a change to the callback as well. Previously the _path_ and _stream_ were passed, however now only an _error_ is passed, when no error has occurred the callback will be invoked indicating that the file transfer is complete. The callback remains optional:
|
||||
|
||||
res.download('/path/to/file');
|
||||
|
||||
res.download('/path/to/file', function(err){
|
||||
if (err) {
|
||||
console.error(err);
|
||||
} else {
|
||||
console.log('transferred');
|
||||
}
|
||||
});
|
||||
|
||||
The _stream threshold_ setting was removed.
|
||||
|
||||
### res.render()
|
||||
|
||||
Previously locals were passed as a separate key:
|
||||
|
||||
res.render('user', { layout: false, locals: { user: user }});
|
||||
|
||||
In Express 2.0 both the locals and the options are one in the same, meaning you cannot have a local variable named _layout_ as it is reserved for express, however this cleans up the API:
|
||||
|
||||
res.render('user', { layout: false, user: user });
|
||||
|
||||
### res.partial()
|
||||
|
||||
Express 2.0 adds the _res.partial()_ method, helpful for rendering partial fragments over WebSockets or Ajax requests etc. The API is identical to the _partial()_ calls within views.
|
||||
|
||||
// render a collection of comments
|
||||
res.partial('comment', [comment1, comment2]);
|
||||
|
||||
// render a single comment
|
||||
res.partial('comment', comment);
|
||||
|
||||
### Template Engine Compliance
|
||||
|
||||
To comply with Express previously engines needed the following signature:
|
||||
|
||||
engine.render(str, options, function(err){});
|
||||
|
||||
Now they must export a _compile()_ function, returning a function which when called with local variables will render the template. This allows Express to cache the compiled function in memory during production.
|
||||
|
||||
var fn = engine.compile(str, options);
|
||||
fn(locals);
|
||||
|
||||
### View Partial Lookup
|
||||
|
||||
Previously partials were loaded relative to the now removed _view partials_ directory setting, or by default _views/partials_, now they are relative to the view calling them, read more on [view lookup](guide.html#View-Lookup).
|
||||
|
||||
### Mime Types
|
||||
|
||||
Express and Connect now utilize the _mime_ module in npm, so to add more use:
|
||||
|
||||
require('mime').define({ 'foo/bar': ['foo', 'bar'] });
|
||||
|
||||
### static() middleware
|
||||
|
||||
Previously named `staticProvider()`, the now `static()` middleware takes a single directory path, followed by options.
|
||||
|
||||
app.use(express.static(__dirname + '/public', { maxAge: oneYear }));
|
||||
|
||||
Previously when using options the `root` option would be used for this:
|
||||
|
||||
app.use(express.staticProvider({ root: __dirname + '/public', maxAge: oneYear }));
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
.\" generated with Ronn/v0.7.3
|
||||
.\" http://github.com/rtomayko/ronn/tree/0.7.3
|
||||
.
|
||||
.TH "SCREENCASTS" "" "March 2011" "" ""
|
||||
.
|
||||
.SH "NAME"
|
||||
\fBscreencasts\fR
|
||||
.
|
||||
.SS "Introduction"
|
||||
This introduction screencast covers the basics of Express, and how to get started with your first application\.
|
||||
.
|
||||
.P
|
||||
.
|
||||
.SS "View Partials"
|
||||
In this screencast we work with partials to display a collection of users using the Jade \fIhttp://jade\-lang\.com\fR template engine, and learn about view path resolution\.
|
||||
.
|
||||
.P
|
||||
.
|
||||
.SS "Route Specific Middleware"
|
||||
In the screencast below we learn about the benefits of route\-specific middleware\.
|
||||
.
|
||||
.P
|
||||
.
|
||||
.SS "Route Param Preconditions"
|
||||
Learn about route parameter (\fI/user/:id\fR) pre\-conditions, providing automated validation, and loading of data via the named route param segments\.
|
||||
.
|
||||
.P
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Express - node web framework</title>
|
||||
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
|
||||
<style>
|
||||
#tagline {
|
||||
margin-left: 75px;
|
||||
margin-bottom: 30px;
|
||||
color: rgba(255,255,255,0.7); }
|
||||
html {
|
||||
background: #1c1c1c url(images/bg.tile.jpg); }
|
||||
|
||||
body {
|
||||
margin: 0;
|
||||
padding-bottom: 30px;
|
||||
font: 14px/1.4 "Helvetica Neue", "Lucida Grande", "Arial";
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
background: url(images/bg.jpg) 50% 0 no-repeat;
|
||||
color: #8b8b8b; }
|
||||
|
||||
* {
|
||||
outline: none; }
|
||||
|
||||
em {
|
||||
color: white; }
|
||||
|
||||
a img {
|
||||
border: none !important; }
|
||||
|
||||
a {
|
||||
font-weight: bold;
|
||||
text-decoration: none;
|
||||
color: white;
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, padding, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
a:hover {
|
||||
opacity: 0.8; }
|
||||
|
||||
h1, h2, h3, h4 {
|
||||
margin: 45px 0 0 0;
|
||||
color: white;
|
||||
text-shadow: 1px 2px 2px rgba(0,0,0,0.6); }
|
||||
|
||||
h3 {
|
||||
font-size: 18px; }
|
||||
h4 {
|
||||
margin-left: 10px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
pre {
|
||||
margin: 20px 10px;
|
||||
padding: 25px 20px;
|
||||
background: rgba(0,0,0,0.5);
|
||||
border: 1px solid #323232;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px; }
|
||||
|
||||
code {
|
||||
font-family: "Helvetica Neue", "Lucida Grande", "Arial"; }
|
||||
|
||||
ul {
|
||||
margin: 15px 0;
|
||||
padding: 0 0 0 35px; }
|
||||
ul li {
|
||||
margin: 0;
|
||||
padding: 2px 0;
|
||||
list-style: square; }
|
||||
ul li ul {
|
||||
margin: 0;
|
||||
padding-left: 12px;
|
||||
}
|
||||
|
||||
.man-name, #Express { display:none; }
|
||||
|
||||
.sect {
|
||||
margin-left: 40px; }
|
||||
img {
|
||||
margin-left: 20px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#logo {
|
||||
display: block;
|
||||
margin-left: 30%;
|
||||
margin-bottom: 30px;
|
||||
width: 194px;
|
||||
height: 51px;
|
||||
background: url(images/logo.png) 0 0 no-repeat;
|
||||
text-indent: -99999px; }
|
||||
#logo:hover {
|
||||
opacity: 0.7; }
|
||||
#logo:active {
|
||||
opacity: 0.3; }
|
||||
|
||||
#ribbon {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 2; }
|
||||
|
||||
#wrapper {
|
||||
width: 100%;
|
||||
min-height: 800px;
|
||||
background: url(images/top.png) 0 0 repeat-x; }
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
padding-top: 80px;
|
||||
width: 550px; }
|
||||
|
||||
#toc {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
margin: 0 0 0 15px;
|
||||
padding: 15px;
|
||||
height: 100%;
|
||||
background: rgba(0,0,0,0.2);
|
||||
overflow: auto;
|
||||
border-right: 1px solid rgba(255,255,255,0.05);
|
||||
}
|
||||
#toc li {
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
}
|
||||
#toc li a {
|
||||
font-size: 11px;
|
||||
}
|
||||
#menu {
|
||||
margin-left: 75px;
|
||||
padding: 0;
|
||||
padding-bottom: 30px; }
|
||||
#menu li {
|
||||
display: inline;
|
||||
list-style: none; }
|
||||
#menu li a {
|
||||
display: block;
|
||||
float: left;
|
||||
margin: 0 2px;
|
||||
padding: 3px 15px;
|
||||
background: rgba(0,0,0,0.2);
|
||||
-webkit-border-radius: 8px;
|
||||
-moz-border-radius: 8px;
|
||||
-webkit-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-moz-box-shadow: 1px 2px 2px rgba(0,0,0,0.6);
|
||||
-webkit-transition-property: opacity, -webkit-transform, color, background-color, -webkit-box-shadow;
|
||||
-webkit-transition-duration: 0.15s;
|
||||
-webkit-transition-timing-function: ease-out; }
|
||||
#menu li a:hover,
|
||||
#menu li a.active {
|
||||
background: rgba(0,0,0,0.5); }
|
||||
#menu li a:active {
|
||||
background: rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px 1px 1px rgba(0,0,0,0.4);
|
||||
-moz-box-shadow: 1px 1px 1px rgba(0,0,0,0.4); }
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
$('.section').hide();
|
||||
$('.toggle, a.section-title').toggle(function(){
|
||||
$(this).siblings('ul').fadeIn(300);
|
||||
return false;
|
||||
}, function(){
|
||||
$(this).siblings('ul').fadeOut(300);
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a href='http://github.com/visionmedia/express'>
|
||||
<img alt='Fork me on GitHub' id='ribbon' src='http://s3.amazonaws.com/github/ribbons/forkme_right_white_ffffff.png' />
|
||||
</a>
|
||||
<div id="wrapper">
|
||||
<div id="container">
|
||||
<a href='http://github.com/visionmedia/express' id='logo'>Express</a>
|
||||
<p id="tagline">
|
||||
High performance, high class web development for
|
||||
<a href="http://nodejs.org">Node.js</a>
|
||||
</p>
|
||||
<ul id="menu">
|
||||
<li><a href="index.html">Home</a></li>
|
||||
<li><a href="guide.html">Guide</a></li>
|
||||
<li><a href="screencasts.html">Screencasts</a></li>
|
||||
<li><a href="applications.html">Applications</a></li>
|
||||
</ul>
|
||||
<div class='mp'>
|
||||
<h2 id="Express">Express</h2>
|
||||
<p class="man-name">
|
||||
<code>screencasts</code>
|
||||
</p>
|
||||
<h3 id="Introduction">Introduction</h3>
|
||||
|
||||
<p>This introduction screencast covers the basics of Express, and how to get started with your first application.</p>
|
||||
|
||||
<p><object height="345" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0"><param name="movie" value="http://screenr.com/Content/assets/screenr_1116090935.swf" /><param name="flashvars" value="i=139583" /><param name="allowFullScreen" value="true" /><embed pluginspage="http://www.macromedia.com/go/getflashplayer" allowfullscreen="true" src="http://screenr.com/Content/assets/screenr_1116090935.swf" height="345" flashvars="i=139583" width="560"></embed></object></p>
|
||||
|
||||
<h3 id="View-Partials">View Partials</h3>
|
||||
|
||||
<p>In this screencast we work with partials to display a collection of users using the <a href="http://jade-lang.com">Jade</a> template engine, and learn about view path resolution.</p>
|
||||
|
||||
<p><object height="345" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0"><param name="movie" value="http://screenr.com/Content/assets/screenr_1116090935.swf" /><param name="flashvars" value="i=139591" /><param name="allowFullScreen" value="true" /><embed pluginspage="http://www.macromedia.com/go/getflashplayer" allowfullscreen="true" src="http://screenr.com/Content/assets/screenr_1116090935.swf" height="345" flashvars="i=139591" width="560"></embed></object></p>
|
||||
|
||||
<h3 id="Route-Specific-Middleware">Route Specific Middleware</h3>
|
||||
|
||||
<p>In the screencast below we learn about the benefits of route-specific middleware.</p>
|
||||
|
||||
<p><object height="345" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0"><param name="movie" value="http://screenr.com/Content/assets/screenr_1116090935.swf" /><param name="flashvars" value="i=140296" /><param name="allowFullScreen" value="true" /><embed pluginspage="http://www.macromedia.com/go/getflashplayer" allowfullscreen="true" src="http://screenr.com/Content/assets/screenr_1116090935.swf" height="345" flashvars="i=140296" width="560"></embed></object></p>
|
||||
|
||||
<h3 id="Route-Param-Preconditions">Route Param Preconditions</h3>
|
||||
|
||||
<p>Learn about route parameter (<em>/user/:id</em>) pre-conditions, providing automated validation, and loading of data via the named route param segments.</p>
|
||||
|
||||
<p><object height="345" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="560" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0"><param name="movie" value="http://screenr.com/Content/assets/screenr_1116090935.swf" /><param name="flashvars" value="i=140300" /><param name="allowFullScreen" value="true" /><embed pluginspage="http://www.macromedia.com/go/getflashplayer" allowfullscreen="true" src="http://screenr.com/Content/assets/screenr_1116090935.swf" height="345" flashvars="i=140300" width="560"></embed></object></p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,24 @@
|
||||
|
||||
### Introduction
|
||||
|
||||
This introduction screencast covers the basics of Express, and how to get started with your first application.
|
||||
|
||||
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=139583' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=139583' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object>
|
||||
|
||||
### View Partials
|
||||
|
||||
In this screencast we work with partials to display a collection of users using the [Jade](http://jade-lang.com) template engine, and learn about view path resolution.
|
||||
|
||||
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=139591' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=139591' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object>
|
||||
|
||||
### Route Specific Middleware
|
||||
|
||||
In the screencast below we learn about the benefits of route-specific middleware.
|
||||
|
||||
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=140296' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=140296' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object>
|
||||
|
||||
### Route Param Preconditions
|
||||
|
||||
Learn about route parameter (_/user/:id_) pre-conditions, providing automated validation, and loading of data via the named route param segments.
|
||||
|
||||
<object classid='clsid:d27cdb6e-ae6d-11cf-96b8-444553540000' codebase='http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,115,0' width='560' height='345'><param name='movie' value='http://screenr.com/Content/assets/screenr_1116090935.swf' /><param name='flashvars' value='i=140300' /><param name='allowFullScreen' value='true' /><embed src='http://screenr.com/Content/assets/screenr_1116090935.swf' flashvars='i=140300' allowFullScreen='true' width='560' height='345' pluginspage='http://www.macromedia.com/go/getflashplayer'></embed></object>
|
||||
@@ -0,0 +1,126 @@
|
||||
|
||||
// Expose modules in ./support for demo purposes
|
||||
require.paths.unshift(__dirname + '/../../support');
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express')
|
||||
, crypto = require('crypto');
|
||||
|
||||
var app = express.createServer(
|
||||
express.bodyParser()
|
||||
, express.cookieParser()
|
||||
, express.session({ secret: 'keyboard cat' })
|
||||
);
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'ejs');
|
||||
|
||||
// Message helper, ideally we would use req.flash()
|
||||
// however this is more light-weight for an example
|
||||
|
||||
app.dynamicHelpers({
|
||||
message: function(req){
|
||||
var err = req.session.error
|
||||
, msg = req.session.success;
|
||||
delete req.session.error;
|
||||
delete req.session.success;
|
||||
if (err) return '<p class="msg error">' + err + '</p>';
|
||||
if (msg) return '<p class="msg success">' + msg + '</p>';
|
||||
}
|
||||
});
|
||||
|
||||
// Generate a salt for the user to prevent rainbow table attacks
|
||||
|
||||
var users = {
|
||||
tj: {
|
||||
name: 'tj'
|
||||
, salt: 'randomly-generated-salt'
|
||||
, pass: md5('foobar' + 'randomly-generated-salt')
|
||||
}
|
||||
};
|
||||
|
||||
// Used to generate a hash of the plain-text password + salt
|
||||
|
||||
function md5(str) {
|
||||
return crypto.createHash('md5').update(str).digest('hex');
|
||||
}
|
||||
|
||||
// Authenticate using our plain-object database of doom!
|
||||
|
||||
function authenticate(name, pass, fn) {
|
||||
var user = users[name];
|
||||
// query the db for the given username
|
||||
if (!user) return fn(new Error('cannot find user'));
|
||||
// apply the same algorithm to the POSTed password, applying
|
||||
// the md5 against the pass / salt, if there is a match we
|
||||
// found the user
|
||||
if (user.pass == md5(pass + user.salt)) return fn(null, user);
|
||||
// Otherwise password is invalid
|
||||
fn(new Error('invalid password'));
|
||||
}
|
||||
|
||||
function restrict(req, res, next) {
|
||||
if (req.session.user) {
|
||||
next();
|
||||
} else {
|
||||
req.session.error = 'Access denied!';
|
||||
res.redirect('/login');
|
||||
}
|
||||
}
|
||||
|
||||
function accessLogger(req, res, next) {
|
||||
console.log('/restricted accessed by %s', req.session.user.name);
|
||||
next();
|
||||
}
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.redirect('/login');
|
||||
});
|
||||
|
||||
app.get('/restricted', restrict, accessLogger, function(req, res){
|
||||
res.send('Wahoo! restricted area');
|
||||
});
|
||||
|
||||
app.get('/logout', function(req, res){
|
||||
// destroy the user's session to log them out
|
||||
// will be re-created next request
|
||||
req.session.destroy(function(){
|
||||
res.redirect('home');
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/login', function(req, res){
|
||||
if (req.session.user) {
|
||||
req.session.success = 'Authenticated as ' + req.session.user.name
|
||||
+ ' click to <a href="/logout">logout</a>. '
|
||||
+ ' You may now access <a href="/restricted">/restricted</a>.';
|
||||
}
|
||||
res.render('login');
|
||||
});
|
||||
|
||||
app.post('/login', function(req, res){
|
||||
authenticate(req.body.username, req.body.password, function(err, user){
|
||||
if (user) {
|
||||
// Regenerate session when signing in
|
||||
// to prevent fixation
|
||||
req.session.regenerate(function(){
|
||||
// Store the user's primary key
|
||||
// in the session store to be retrieved,
|
||||
// or in this case the entire user object
|
||||
req.session.user = user;
|
||||
res.redirect('back');
|
||||
});
|
||||
} else {
|
||||
req.session.error = 'Authentication failed, please check your '
|
||||
+ ' username and password.'
|
||||
+ ' (use "tj" and "foobar")';
|
||||
res.redirect('back');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
@@ -0,0 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Authentication Example</title>
|
||||
<style>
|
||||
body {
|
||||
padding: 50px;
|
||||
font: 13px Helvetica, Arial, sans-serif;
|
||||
}
|
||||
.error {
|
||||
color: red
|
||||
}
|
||||
.success {
|
||||
color: green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<%- body %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,16 @@
|
||||
<h1>Login</h1>
|
||||
<%- message %>
|
||||
Try accessing <a href="/restricted">/restricted</a>.
|
||||
<form method="post" action="/login">
|
||||
<p>
|
||||
<label>Username:</label>
|
||||
<input type="text" name="username">
|
||||
</p>
|
||||
<p>
|
||||
<label>Password:</label>
|
||||
<input type="text" name="password">
|
||||
</p>
|
||||
<p>
|
||||
<input type="submit" value="Login">
|
||||
</p>
|
||||
</form>
|
||||
@@ -0,0 +1,61 @@
|
||||
|
||||
// Expose modules in ./support for demo purposes
|
||||
require.paths.unshift(__dirname + '/../../support');
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express')
|
||||
, messages = require('express-contrib/messages');
|
||||
|
||||
var app = module.exports = express.createServer();
|
||||
|
||||
// Config
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'jade');
|
||||
|
||||
// mount hook
|
||||
|
||||
app.mounted(function(other){
|
||||
console.log('ive been mounted!');
|
||||
});
|
||||
|
||||
// Flash message helper provided by express-contrib
|
||||
// $ npm install express-contrib
|
||||
|
||||
app.dynamicHelpers({
|
||||
messages: messages
|
||||
, base: function(){
|
||||
// return the app's mount-point
|
||||
// so that urls can adjust. For example
|
||||
// if you run this example /post/add works
|
||||
// however if you run the mounting example
|
||||
// it adjusts to /blog/post/add
|
||||
return '/' == app.route ? '' : app.route;
|
||||
}
|
||||
});
|
||||
|
||||
// Middleware
|
||||
|
||||
app.configure(function(){
|
||||
app.use(express.logger('\x1b[33m:method\x1b[0m \x1b[32m:url\x1b[0m :response-time'));
|
||||
app.use(express.bodyParser());
|
||||
app.use(express.methodOverride());
|
||||
app.use(express.cookieParser());
|
||||
app.use(express.session({ secret: 'keyboard cat' }));
|
||||
app.use(app.router);
|
||||
app.use(express.static(__dirname + '/public'));
|
||||
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
|
||||
});
|
||||
|
||||
// Routes
|
||||
|
||||
require('./routes/site')(app);
|
||||
require('./routes/post')(app);
|
||||
|
||||
if (!module.parent) {
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
|
||||
// Fake data store
|
||||
|
||||
var ids = 0
|
||||
, db = {};
|
||||
|
||||
var Post = exports = module.exports = function Post(title, body) {
|
||||
this.id = ++ids;
|
||||
this.title = title;
|
||||
this.body = body;
|
||||
this.createdAt = new Date;
|
||||
};
|
||||
|
||||
Post.prototype.save = function(fn){
|
||||
db[this.id] = this;
|
||||
fn();
|
||||
};
|
||||
|
||||
Post.prototype.validate = function(fn){
|
||||
if (!this.title) return fn(new Error('_title_ required'));
|
||||
if (!this.body) return fn(new Error('_body_ required'));
|
||||
if (this.body.length < 10) {
|
||||
return fn(new Error(
|
||||
'_body_ should be at least **10** characters long, was only _' + this.title.length + '_'));
|
||||
}
|
||||
fn();
|
||||
};
|
||||
|
||||
|
||||
Post.prototype.update = function(data, fn){
|
||||
this.updatedAt = new Date;
|
||||
for (var key in data) {
|
||||
if (undefined != data[key]) {
|
||||
this[key] = data[key];
|
||||
}
|
||||
}
|
||||
this.save(fn);
|
||||
};
|
||||
|
||||
Post.prototype.destroy = function(fn){
|
||||
exports.destroy(this.id, fn);
|
||||
};
|
||||
|
||||
exports.count = function(fn){
|
||||
fn(null, Object.keys(db).length);
|
||||
};
|
||||
|
||||
exports.all = function(fn){
|
||||
var arr = Object.keys(db).reduce(function(arr, id){
|
||||
arr.push(db[id]);
|
||||
return arr;
|
||||
}, []);
|
||||
fn(null, arr);
|
||||
};
|
||||
|
||||
exports.get = function(id, fn){
|
||||
fn(null, db[id]);
|
||||
};
|
||||
|
||||
exports.destroy = function(id, fn) {
|
||||
if (db[id]) {
|
||||
delete db[id];
|
||||
fn();
|
||||
} else {
|
||||
fn(new Error('post ' + id + ' does not exist'));
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,58 @@
|
||||
body {
|
||||
font: 13px "Helvetica Neue", Arial, sans-serif;
|
||||
color: #111;
|
||||
padding: 60px 80px;
|
||||
}
|
||||
h1, h2 {
|
||||
color: #c00;
|
||||
}
|
||||
a {
|
||||
color: #c00;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
label {
|
||||
padding: 6px 0;
|
||||
display: block;
|
||||
text-transform: lowercase;
|
||||
}
|
||||
textarea,
|
||||
input {
|
||||
outline: none;
|
||||
padding: 5px;
|
||||
background: #f1f1f1;
|
||||
border: 1px solid #aaa;
|
||||
}
|
||||
textarea:focus,
|
||||
input:focus {
|
||||
background: #fff;
|
||||
}
|
||||
textarea {
|
||||
width: 500px;
|
||||
height: 200px;
|
||||
}
|
||||
a.edit {
|
||||
margin-left: 10px;
|
||||
font-size: 11px;
|
||||
font-weight: normal;
|
||||
}
|
||||
.date {
|
||||
font-size: 11px;
|
||||
}
|
||||
#messages ul {
|
||||
padding: 10px;
|
||||
border: 1px solid;
|
||||
}
|
||||
#messages ul li {
|
||||
list-style: none;
|
||||
}
|
||||
#messages ul.info {
|
||||
color: #2EBBE6;
|
||||
background: #F7FBFD;
|
||||
}
|
||||
#messages ul.error {
|
||||
color: #E4250C;
|
||||
background: #FDEAE7;
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var basicAuth = require('../../../lib/express').basicAuth
|
||||
, Post = require('../models/post');
|
||||
|
||||
module.exports = function(app){
|
||||
/**
|
||||
* Apply basic auth to all post related routes
|
||||
*/
|
||||
|
||||
app.all('/post(/*)?', basicAuth(function(user, pass){
|
||||
return 'admin' == user && 'express' == pass;
|
||||
}));
|
||||
|
||||
/**
|
||||
* Map :post to the database, loading
|
||||
* every time :post is present.
|
||||
*/
|
||||
|
||||
app.param('post', function(req, res, next, id){
|
||||
Post.get(id, function(err, post){
|
||||
if (err) return next(err);
|
||||
if (!post) return next(new Error('failed to load post ' + id));
|
||||
req.post = post;
|
||||
next();
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Add a post.
|
||||
*/
|
||||
|
||||
app.get('/post/add', function(req, res){
|
||||
res.render('post/form', { post: {}});
|
||||
});
|
||||
|
||||
/**
|
||||
* Save a post.
|
||||
*/
|
||||
|
||||
app.post('/post', function(req, res){
|
||||
var data = req.body.post
|
||||
, post = new Post(data.title, data.body);
|
||||
|
||||
post.validate(function(err){
|
||||
if (err) {
|
||||
req.flash('error', err.message);
|
||||
return res.redirect('back');
|
||||
}
|
||||
|
||||
post.save(function(err){
|
||||
req.flash('info', 'Successfully created post _%s_', post.title);
|
||||
res.redirect('/post/' + post.id);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Display the post.
|
||||
*/
|
||||
|
||||
app.get('/post/:post', function(req, res){
|
||||
res.render('post', { post: req.post });
|
||||
});
|
||||
|
||||
/**
|
||||
* Display the post edit form.
|
||||
*/
|
||||
|
||||
app.get('/post/:post/edit', function(req, res){
|
||||
res.render('post/form', { post: req.post });
|
||||
});
|
||||
|
||||
/**
|
||||
* Update post. Typically a data layer would handle this stuff.
|
||||
*/
|
||||
|
||||
app.put('/post/:post', function(req, res, next){
|
||||
var post = req.post;
|
||||
post.validate(function(err){
|
||||
if (err) {
|
||||
req.flash('error', err.message);
|
||||
return res.redirect('back');
|
||||
}
|
||||
post.update(req.body.post, function(err){
|
||||
if (err) return next(err);
|
||||
req.flash('info', 'Successfully updated post');
|
||||
res.redirect('back');
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var Post = require('../models/post');
|
||||
|
||||
module.exports = function(app){
|
||||
app.get('/', function(req, res){
|
||||
Post.count(function(err, count){
|
||||
Post.all(function(err, posts){
|
||||
res.render('index', {
|
||||
count: count
|
||||
, posts: posts
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
h1 Blog
|
||||
|
||||
!= messages()
|
||||
|
||||
- if (count)
|
||||
p Display all #{count} post(s)
|
||||
#posts!= partial('post', posts)
|
||||
- else
|
||||
p
|
||||
| It looks like you have no posts!
|
||||
p
|
||||
| Click
|
||||
a(href=base + '/post/add') here
|
||||
| to create a post. Login
|
||||
| as
|
||||
em "admin"
|
||||
| and
|
||||
em "express"
|
||||
| .
|
||||
@@ -0,0 +1,7 @@
|
||||
!!! 5
|
||||
html
|
||||
head
|
||||
title Blog
|
||||
link(rel='stylesheet', href=base + '/style.css')
|
||||
body
|
||||
#container!= body
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
- if (post.title)
|
||||
h1 Editing #{post.title}
|
||||
- else
|
||||
h1 New Post
|
||||
|
||||
!= messages()
|
||||
|
||||
form#post(action=base + '/post' + (post.title ? '/' + post.id : ''), method='post')
|
||||
- if (post.title)
|
||||
input(type='hidden', name='_method', value='put')
|
||||
p
|
||||
label(for='post[title]') Title:
|
||||
input(type='text', name='post[title]', value=post.title)
|
||||
p
|
||||
label(for='post[body]') Body:
|
||||
textarea(name='post[body]')= post.body || ''
|
||||
p
|
||||
input(type='submit', value=post.title ? 'Update' : 'Create')
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
.post
|
||||
// title
|
||||
h2
|
||||
= post.title
|
||||
a.edit(href=base + '/post/' + post.id + '/edit') Edit
|
||||
|
||||
// flash messages
|
||||
!= messages()
|
||||
|
||||
// dates
|
||||
p.date.created Created at #{post.createdAt}
|
||||
- if (post.updatedAt)
|
||||
p.date.updated Updated at #{post.updatedAt}
|
||||
|
||||
// body
|
||||
pre.body= post.body
|
||||
@@ -1,80 +0,0 @@
|
||||
|
||||
require.paths.unshift('lib')
|
||||
require('express')
|
||||
require('express/plugins')
|
||||
|
||||
var messages = [],
|
||||
utils = require('express/utils'),
|
||||
http = require('express/http')
|
||||
|
||||
configure(function(){
|
||||
use(Logger)
|
||||
use(MethodOverride)
|
||||
use(ContentLength)
|
||||
use(Cookie)
|
||||
use(Cache, { lifetime: (5).minutes, reapInterval: (1).minute })
|
||||
use(Session, { lifetime: (15).minutes, reapInterval: (1).minute })
|
||||
use(Static)
|
||||
set('root', __dirname)
|
||||
})
|
||||
|
||||
get('/', function(){
|
||||
this.pass('/chat')
|
||||
})
|
||||
|
||||
get('/chat', function(){
|
||||
var self = this
|
||||
Session.store.length(function(err, len){
|
||||
self.render('chat.html.haml', {
|
||||
locals: {
|
||||
title: 'Chat',
|
||||
messages: messages,
|
||||
name: self.session.name,
|
||||
usersOnline: len
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
post('/chat', function(){
|
||||
this.session.name = this.param('name')
|
||||
messages
|
||||
.push(utils.escape(this.param('name')) + ': ' + utils.escape(this.param('message'))
|
||||
.replace(/(http:\/\/[^\s]+)/g, '<a href="$1" target="express-chat">$1</a>')
|
||||
.replace(/:\)/g, '<img src="http://icons3.iconfinder.netdna-cdn.com/data/icons/ledicons/emoticon_smile.png">'))
|
||||
this.respond(200)
|
||||
})
|
||||
|
||||
get('/chat/messages', function(){
|
||||
var self = this,
|
||||
previousLength = messages.length,
|
||||
timer = setInterval(function(){
|
||||
if (messages.length > previousLength)
|
||||
self.contentType('json'),
|
||||
previousLength = messages.length,
|
||||
self.respond(200, JSON.encode(messages)),
|
||||
clearInterval(timer)
|
||||
}, 100)
|
||||
})
|
||||
|
||||
get('/*.css', function(file){
|
||||
this.render(file + '.css.sass', { layout: false })
|
||||
})
|
||||
|
||||
get('/error/view', function(){
|
||||
this.render('does.not.exist')
|
||||
})
|
||||
|
||||
get('/error', function(){
|
||||
throw new Error('oh noes!')
|
||||
})
|
||||
|
||||
get('/simple', function(){
|
||||
return 'Hello :)'
|
||||
})
|
||||
|
||||
get('/favicon.ico', function(){
|
||||
this.notFound()
|
||||
})
|
||||
|
||||
run()
|
||||
|
Antes Largura: | Altura: | Tamanho: 5.2 KiB |
@@ -1,28 +0,0 @@
|
||||
|
||||
$(function(){
|
||||
// Send message
|
||||
$('form').submit(function(){
|
||||
var message = $('input[name=message]'),
|
||||
name = $('input[name=name]')
|
||||
if (message.val())
|
||||
$.post('/chat', { name: name.val(), message: message.val() }, function(){
|
||||
message.val('')
|
||||
})
|
||||
else
|
||||
message.css('border', '1px solid red')
|
||||
return false
|
||||
})
|
||||
|
||||
// Longpoll
|
||||
;(function poll(){
|
||||
$.getJSON('/chat/messages', function(messages){
|
||||
$('#messages').empty()
|
||||
$.each(messages, function(i, msg){
|
||||
$('#messages')
|
||||
.append('<li>' + msg + '</li>')
|
||||
.get(0).scrollTop = $('#messages').get(0).scrollHeight
|
||||
})
|
||||
poll()
|
||||
})
|
||||
})()
|
||||
})
|
||||
@@ -1,9 +0,0 @@
|
||||
%h1 Chat
|
||||
%img.bubble{ src: '/public/images/bubble.png' }
|
||||
%ul#messages
|
||||
!= this.partial('message.html.haml', { collection: messages })
|
||||
%form{ method: 'post' }
|
||||
%input{ type: 'hidden', name: '_method', value: 'put' }
|
||||
%input{ type: 'text', name: 'name', value: name || 'guest' }
|
||||
%input{ type: 'text', name: 'message' }
|
||||
%input{ type: 'submit', value: 'Send' }
|
||||
@@ -1,12 +0,0 @@
|
||||
%html
|
||||
%head
|
||||
%title= title
|
||||
%script{ src: '/public/javascripts/jquery.js' }
|
||||
%script{ src: '/public/javascripts/app.js' }
|
||||
%link{ rel: 'stylesheet', href: '/style.css' }
|
||||
%body
|
||||
#wrapper
|
||||
!= body
|
||||
#online
|
||||
Online:
|
||||
%strong= usersOnline
|
||||
@@ -1 +0,0 @@
|
||||
%li= message
|
||||
@@ -1,81 +0,0 @@
|
||||
body
|
||||
:font-family "Helvetica Neue", "Lucida Grande", "Arial"
|
||||
:font-size 13px
|
||||
:text-align center
|
||||
=text-stroke 1px rgba(255, 255, 255, 0.1)
|
||||
:color #555
|
||||
|
||||
h1, h2
|
||||
:margin 0
|
||||
:font-size 22px
|
||||
:color #343434
|
||||
h1
|
||||
:text-shadow 1px 2px 2px #ddd
|
||||
:font-size 60px
|
||||
|
||||
img.bubble
|
||||
:position absolute
|
||||
:top -25px
|
||||
:left 120px
|
||||
|
||||
#wrapper
|
||||
:position relative
|
||||
:margin 100px auto
|
||||
:width 500px
|
||||
:text-align left
|
||||
|
||||
ul
|
||||
:margin 0
|
||||
:padding 0
|
||||
:max-height 300px
|
||||
:overflow-x hidden
|
||||
li
|
||||
:margin 5px 0
|
||||
:padding 3px 8px
|
||||
:list-style none
|
||||
:border 1px solid #eee
|
||||
=border-radius 3px
|
||||
=border-radius 3px
|
||||
li:hover
|
||||
:cursor pointer
|
||||
:color #2E2E2E
|
||||
|
||||
input[type=text]
|
||||
:padding 5px
|
||||
:border 1px solid #ddd
|
||||
:outline none
|
||||
=border-radius 2px
|
||||
input[type=text]:focus
|
||||
:border-color #00C3FF
|
||||
|
||||
input[type=submit]
|
||||
=border-radius 2px
|
||||
=box-shadow 0 1px 2px #ddd
|
||||
:padding 6px 10px
|
||||
:border solid 1px #999
|
||||
:background -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#ddd))
|
||||
:color #333
|
||||
:text-decoration none
|
||||
:cursor pointer
|
||||
:display inline-block
|
||||
:text-align center
|
||||
:text-shadow 0px 1px 1px #fff
|
||||
:line-height 1
|
||||
input[type=submit]:hover
|
||||
:background -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#E6E4E4))
|
||||
input[type=submit]:active
|
||||
:background -webkit-gradient(linear, 0% 0%, 0% 100%, from(#fff), to(#c7c7c7))
|
||||
input[name=name]
|
||||
:width 80px
|
||||
|
||||
a
|
||||
:color #1ABFF1
|
||||
=transition-property padding
|
||||
=transition-duration 0.15s
|
||||
a:hover
|
||||
:padding 0 5px
|
||||
a:hover:before
|
||||
:content 'visit: '
|
||||
|
||||
#online
|
||||
:font-size 12px
|
||||
@@ -1,38 +0,0 @@
|
||||
|
||||
require.paths.unshift 'lib'
|
||||
require 'express'
|
||||
require 'express/plugins'
|
||||
|
||||
sys: require 'sys'
|
||||
|
||||
configure ->
|
||||
use MethodOverride
|
||||
use ContentLength
|
||||
use Cookie
|
||||
use Session
|
||||
use Flash
|
||||
use Logger
|
||||
use Static
|
||||
set 'root', __dirname
|
||||
set 'views', __dirname + '/../upload/views'
|
||||
|
||||
get '/', ->
|
||||
@redirect('/upload')
|
||||
|
||||
get '/upload', ->
|
||||
@render 'upload.html.haml', {
|
||||
locals: {
|
||||
flashes: @flash 'info'
|
||||
}
|
||||
}
|
||||
|
||||
post '/upload', ->
|
||||
@param('images').each (image) =>
|
||||
sys.puts image.filename + ' -> ' + image.tempfile
|
||||
@flash 'info', 'Uploaded ' + image.filename
|
||||
@redirect '/upload'
|
||||
|
||||
get '/*.css', (file) ->
|
||||
@render file + '.css.sass', { layout: no }
|
||||
|
||||
run()
|
||||
@@ -0,0 +1,49 @@
|
||||
|
||||
// Expose modules in ./support for demo purposes
|
||||
require.paths.unshift(__dirname + '/../../support');
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express');
|
||||
|
||||
var app = express.createServer(
|
||||
// Place default Connect favicon above logger so it is not in
|
||||
// the logging output
|
||||
express.favicon(),
|
||||
|
||||
// Custom logger format
|
||||
express.logger({ format: '\x1b[1m:method\x1b[0m \x1b[33m:url\x1b[0m :response-time' }),
|
||||
|
||||
// Provides req.cookies
|
||||
express.cookieParser(),
|
||||
|
||||
// Parses x-www-form-urlencoded request bodies (and json)
|
||||
express.bodyParser()
|
||||
);
|
||||
|
||||
app.get('/', function(req, res){
|
||||
if (req.cookies.remember) {
|
||||
res.send('Remembered :). Click to <a href="/forget">forget</a>!.');
|
||||
} else {
|
||||
res.send('<form method="post"><p>Check to <label>'
|
||||
+ '<input type="checkbox" name="remember"/> remember me</label> '
|
||||
+ '<input type="submit" value="Submit"/>.</p></form>');
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/forget', function(req, res){
|
||||
res.clearCookie('remember');
|
||||
res.redirect('back');
|
||||
});
|
||||
|
||||
app.post('/', function(req, res){
|
||||
if (req.body.remember) {
|
||||
res.cookie('remember', '1', { path: '/', expires: new Date(Date.now() + 900000), httpOnly: true });
|
||||
}
|
||||
res.redirect('back');
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
@@ -0,0 +1,47 @@
|
||||
|
||||
// Expose modules in ./support for demo purposes
|
||||
require.paths.unshift(__dirname + '/../../support');
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express');
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.send('<ul>'
|
||||
+ '<li>Download <a href="/files/amazing.txt">amazing.txt</a>.</li>'
|
||||
+ '<li>Download <a href="/files/missing.txt">missing.txt</a>.</li>'
|
||||
+ '</ul>');
|
||||
});
|
||||
|
||||
// /files/* is accessed via req.params[0]
|
||||
// but here we name it :file
|
||||
app.get('/files/:file(*)', function(req, res, next){
|
||||
var file = req.params.file
|
||||
, path = __dirname + '/files/' + file;
|
||||
// either res.download(path) and let
|
||||
// express handle failures, or provide
|
||||
// a callback
|
||||
res.download(path, function(err){
|
||||
if (err) return next(err);
|
||||
// the response has invoked .end()
|
||||
// so you cannnot respond here (of course)
|
||||
// but the callback is handy for statistics etc.
|
||||
console.log('transferred %s', path);
|
||||
});
|
||||
});
|
||||
|
||||
app.error(function(err, req, res, next){
|
||||
if ('ENOENT' == err.code) {
|
||||
res.send('Cant find that file, sorry!');
|
||||
} else {
|
||||
// Not a 404
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express started on port 3000');
|
||||
@@ -0,0 +1 @@
|
||||
what an amazing download
|
||||
@@ -0,0 +1,34 @@
|
||||
|
||||
// Expose modules in ./support for demo purposes
|
||||
require.paths.unshift(__dirname + '/../../support');
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express');
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
// Register ejs as .html
|
||||
|
||||
app.register('.html', require('ejs'));
|
||||
|
||||
// Optional since express defaults to CWD/views
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
app.set('view engine', 'html');
|
||||
|
||||
// Dummy users
|
||||
var users = [
|
||||
{ name: 'tj', email: 'tj@sencha.com' }
|
||||
, { name: 'ciaran', email: 'ciaranj@gmail.com' }
|
||||
, { name: 'aaron', email: 'aaron.heckmann+github@gmail.com' }
|
||||
];
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('users', { users: users });
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
@@ -0,0 +1,6 @@
|
||||
<html>
|
||||
<body>
|
||||
<h1>Users</h1>
|
||||
<%- body %>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,3 @@
|
||||
<ul id="users">
|
||||
<%- partial('user', users) %>
|
||||
</ul>
|
||||
@@ -0,0 +1 @@
|
||||
<li><%= user.name %> <<%= user.email %>></li>
|
||||
@@ -0,0 +1,96 @@
|
||||
|
||||
// Expose modules in ./support for demo purposes
|
||||
require.paths.unshift(__dirname + '/../../support');
|
||||
|
||||
/**
|
||||
* Module dependencies.
|
||||
*/
|
||||
|
||||
var express = require('../../lib/express');
|
||||
|
||||
var app = express.createServer();
|
||||
|
||||
// Serve default connect favicon
|
||||
app.use(express.favicon());
|
||||
|
||||
// Logger is placed below favicon, so favicon.ico
|
||||
// requests will not be logged
|
||||
app.use(express.logger({ format: '":method :url" :status' }));
|
||||
|
||||
// "app.router" positions our routes
|
||||
// specifically above the middleware
|
||||
// assigned below
|
||||
|
||||
app.use(app.router);
|
||||
|
||||
// When no more middleware require execution, aka
|
||||
// our router is finished and did not respond, we
|
||||
// can assume that it is "not found". Instead of
|
||||
// letting Connect deal with this, we define our
|
||||
// custom middleware here to simply pass a NotFound
|
||||
// exception
|
||||
|
||||
app.use(function(req, res, next){
|
||||
next(new NotFound(req.url));
|
||||
});
|
||||
|
||||
app.set('views', __dirname + '/views');
|
||||
|
||||
// Provide our app with the notion of NotFound exceptions
|
||||
|
||||
function NotFound(path){
|
||||
this.name = 'NotFound';
|
||||
if (path) {
|
||||
Error.call(this, 'Cannot find ' + path);
|
||||
this.path = path;
|
||||
} else {
|
||||
Error.call(this, 'Not Found');
|
||||
}
|
||||
Error.captureStackTrace(this, arguments.callee);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inherit from `Error.prototype`.
|
||||
*/
|
||||
|
||||
NotFound.prototype.__proto__ = Error.prototype;
|
||||
|
||||
// We can call app.error() several times as shown below.
|
||||
// Here we check for an instanceof NotFound and show the
|
||||
// 404 page, or we pass on to the next error handler.
|
||||
|
||||
// These handlers could potentially be defined within
|
||||
// configure() blocks to provide introspection when
|
||||
// in the development environment.
|
||||
|
||||
app.error(function(err, req, res, next){
|
||||
if (err instanceof NotFound) {
|
||||
res.render('404.jade', { status: 404, error: err });
|
||||
} else {
|
||||
next(err);
|
||||
}
|
||||
});
|
||||
|
||||
// Here we assume all errors as 500 for the simplicity of
|
||||
// this demo, however you can choose whatever you like
|
||||
|
||||
app.error(function(err, req, res){
|
||||
res.render('500.jade', { status: 500, error: err });
|
||||
});
|
||||
|
||||
// Routes
|
||||
|
||||
app.get('/', function(req, res){
|
||||
res.render('index.jade');
|
||||
});
|
||||
|
||||
app.get('/404', function(req, res){
|
||||
throw new NotFound(req.url);
|
||||
});
|
||||
|
||||
app.get('/500', function(req, res, next){
|
||||
next(new Error('keyboard cat!'));
|
||||
});
|
||||
|
||||
app.listen(3000);
|
||||
console.log('Express app started on port 3000');
|
||||
@@ -0,0 +1,4 @@
|
||||
- if (error.path)
|
||||
h2 Cannot find #{error.path}
|
||||
- else
|
||||
h2 Page Not Found
|
||||