middleman-core 3.0.0.alpha.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (571) hide show
  1. data/Rakefile +5 -0
  2. data/bin/middleman +52 -0
  3. data/features/3rd_party_cli.feature +5 -0
  4. data/features/asset_host.feature +7 -0
  5. data/features/auto_layout.feature +36 -0
  6. data/features/automatic_image_sizes.feature +16 -0
  7. data/features/builder.feature +50 -0
  8. data/features/chained_templates.feature +19 -0
  9. data/features/clean_build.feature +31 -0
  10. data/features/cli.feature +120 -0
  11. data/features/content_for.feature +6 -0
  12. data/features/current_page_request_path_backwards.feature +6 -0
  13. data/features/custom_layout_engines.feature +8 -0
  14. data/features/custom_layouts.feature +44 -0
  15. data/features/data.feature +22 -0
  16. data/features/directory_index.feature +36 -0
  17. data/features/dynamic_pages.feature +95 -0
  18. data/features/feature_params.feature +6 -0
  19. data/features/former_padrino_helpers.feature +10 -0
  20. data/features/front-matter.feature +35 -0
  21. data/features/helpers_auto_javascript_include_tag.feature +27 -0
  22. data/features/helpers_auto_stylesheet_link_tag.feature +27 -0
  23. data/features/helpers_external.feature +6 -0
  24. data/features/helpers_lorem.feature +6 -0
  25. data/features/helpers_page_classes.feature +17 -0
  26. data/features/instance_vars.feature +20 -0
  27. data/features/mount_rack.feature +8 -0
  28. data/features/nested_layouts.feature +24 -0
  29. data/features/partials.feature +41 -0
  30. data/features/preview_changes.feature +18 -0
  31. data/features/sitemap_traversal.features +73 -0
  32. data/features/static_server.feature +6 -0
  33. data/features/step_definitions/page_layout_steps.rb +15 -0
  34. data/features/support/env.rb +3 -0
  35. data/features/wildcard_page_helper.feature +19 -0
  36. data/fixtures/3rd-party-command/config.rb +10 -0
  37. data/fixtures/asset-host-app/config.rb +6 -0
  38. data/fixtures/asset-host-app/source/.htaccess +1 -0
  39. data/fixtures/asset-host-app/source/asset_host.html.erb +1 -0
  40. data/fixtures/asset-host-app/source/images/blank.gif +0 -0
  41. data/fixtures/auto-css-app/config.rb +11 -0
  42. data/fixtures/auto-css-app/source/auto-css.html.erb +1 -0
  43. data/fixtures/auto-css-app/source/auto-css/auto-css.html.erb +1 -0
  44. data/fixtures/auto-css-app/source/auto-css/index.html.erb +1 -0
  45. data/fixtures/auto-css-app/source/auto-css/sub/auto-css.html.erb +1 -0
  46. data/fixtures/auto-css-app/source/stylesheets/auto-css.css +3 -0
  47. data/fixtures/auto-css-app/source/stylesheets/auto-css/auto-css.css +3 -0
  48. data/fixtures/auto-css-app/source/stylesheets/auto-css/index.css +0 -0
  49. data/fixtures/auto-css-app/source/stylesheets/auto-css/sub/auto-css.css +3 -0
  50. data/fixtures/auto-js-app/config.rb +11 -0
  51. data/fixtures/auto-js-app/source/auto-js.html.erb +1 -0
  52. data/fixtures/auto-js-app/source/auto-js/auto-js.html.erb +1 -0
  53. data/fixtures/auto-js-app/source/auto-js/index.html.erb +1 -0
  54. data/fixtures/auto-js-app/source/auto-js/sub/auto-js.html.erb +1 -0
  55. data/fixtures/auto-js-app/source/javascripts/auto-js.js +1 -0
  56. data/fixtures/auto-js-app/source/javascripts/auto-js/auto-js.js +1 -0
  57. data/fixtures/auto-js-app/source/javascripts/auto-js/index.js +1 -0
  58. data/fixtures/auto-js-app/source/javascripts/auto-js/sub/auto-js.js +1 -0
  59. data/fixtures/automatic-image-size-app/config.rb +0 -0
  60. data/fixtures/automatic-image-size-app/source/auto-image-sizes.html.erb +1 -0
  61. data/fixtures/automatic-image-size-app/source/images/blank.gif +0 -0
  62. data/fixtures/basic-data-app/config.rb +4 -0
  63. data/fixtures/basic-data-app/data/test.yml +4 -0
  64. data/fixtures/basic-data-app/data/test2.json +4 -0
  65. data/fixtures/basic-data-app/source/data.html.erb +1 -0
  66. data/fixtures/basic-data-app/source/data3.html.erb +1 -0
  67. data/fixtures/build-with-errors-app/config.rb +1 -0
  68. data/fixtures/build-with-errors-app/source/index.html.erb +1 -0
  69. data/fixtures/chained-app/config.rb +0 -0
  70. data/fixtures/chained-app/data/article.yml +2 -0
  71. data/fixtures/chained-app/source/index.html.str.erb +8 -0
  72. data/fixtures/clean-app/config-complications.rb +11 -0
  73. data/fixtures/clean-app/config-empty.rb +0 -0
  74. data/fixtures/clean-app/config.rb +11 -0
  75. data/fixtures/clean-app/source/index.html.erb +1 -0
  76. data/fixtures/clean-app/source/layout.erb +9 -0
  77. data/fixtures/clean-app/source/layouts/custom.erb +8 -0
  78. data/fixtures/clean-app/source/real.html +1 -0
  79. data/fixtures/clean-app/source/real/index.html.erb +5 -0
  80. data/fixtures/clean-app/source/should_be_ignored.html +1 -0
  81. data/fixtures/clean-app/source/should_be_ignored2.html +1 -0
  82. data/fixtures/clean-app/source/should_be_ignored3.html +1 -0
  83. data/fixtures/clean-app/source/static.html +1 -0
  84. data/fixtures/clean-dir-app/config.rb +1 -0
  85. data/fixtures/clean-dir-app/source/about.html +1 -0
  86. data/fixtures/content-for-app/config.rb +3 -0
  87. data/fixtures/content-for-app/source/content_for_erb.html.erb +5 -0
  88. data/fixtures/content-for-app/source/layouts/content_for.erb +4 -0
  89. data/fixtures/current-page-app/config.rb +3 -0
  90. data/fixtures/current-page-app/source/request-path.html.erb +1 -0
  91. data/fixtures/custom-layout-app/config.rb +1 -0
  92. data/fixtures/custom-layout-app/source/index.html.erb +1 -0
  93. data/fixtures/custom-layout-app/source/layout.str +9 -0
  94. data/fixtures/custom-layout-app2/config.rb +0 -0
  95. data/fixtures/custom-layout-app2/source/custom-layout-dir/index.html.erb +1 -0
  96. data/fixtures/custom-layout-app2/source/custom-layout.html.erb +1 -0
  97. data/fixtures/custom-layout-app2/source/layouts/custom.erb +8 -0
  98. data/fixtures/data-app/config.rb +3 -0
  99. data/fixtures/data-app/data/pages.yml +6 -0
  100. data/fixtures/data-app/source/index.html.erb +1 -0
  101. data/fixtures/data-app/source/layout.erb +5 -0
  102. data/fixtures/different-engine-layout/config.rb +0 -0
  103. data/fixtures/different-engine-layout/source/index.html.str +1 -0
  104. data/fixtures/different-engine-layout/source/layout.erb +9 -0
  105. data/fixtures/different-engine-partial/config.rb +0 -0
  106. data/fixtures/different-engine-partial/source/index.html.erb +1 -0
  107. data/fixtures/different-engine-partial/source/layouts/layout.erb +7 -0
  108. data/fixtures/different-engine-partial/source/shared/_footer.str +1 -0
  109. data/fixtures/different-engine-partial/source/shared/_header.erb +1 -0
  110. data/fixtures/dynamic-pages-app/config.rb +29 -0
  111. data/fixtures/dynamic-pages-app/source/real.html +1 -0
  112. data/fixtures/dynamic-pages-app/source/real/index.html.erb +5 -0
  113. data/fixtures/dynamic-pages-app/source/should_be_ignored.html +1 -0
  114. data/fixtures/dynamic-pages-app/source/should_be_ignored2.html +1 -0
  115. data/fixtures/dynamic-pages-app/source/should_be_ignored3.html +1 -0
  116. data/fixtures/dynamic-pages-app/source/should_be_ignored4.html +1 -0
  117. data/fixtures/dynamic-pages-app/source/should_be_ignored5.html +1 -0
  118. data/fixtures/dynamic-pages-app/source/should_be_ignored6.html +1 -0
  119. data/fixtures/dynamic-pages-app/source/should_be_ignored7.html +1 -0
  120. data/fixtures/dynamic-pages-app/source/should_be_ignored8.html +1 -0
  121. data/fixtures/empty-app/not-config.rb +0 -0
  122. data/fixtures/engine-matching-layout/config.rb +0 -0
  123. data/fixtures/engine-matching-layout/source/index.html.erb +1 -0
  124. data/fixtures/engine-matching-layout/source/layout.erb +9 -0
  125. data/fixtures/external-helpers/config.rb +4 -0
  126. data/fixtures/external-helpers/lib/hello_helper.rb +5 -0
  127. data/fixtures/external-helpers/source/index.html.erb +1 -0
  128. data/fixtures/feature-params-app/config.rb +12 -0
  129. data/fixtures/feature-params-app/source/index.html.erb +3 -0
  130. data/fixtures/frontmatter-app/config.rb +0 -0
  131. data/fixtures/frontmatter-app/source/front-matter-2.php.erb +7 -0
  132. data/fixtures/frontmatter-app/source/front-matter-change.html.erb +5 -0
  133. data/fixtures/frontmatter-app/source/front-matter.html.erb +6 -0
  134. data/fixtures/generator-test/config.rb +80 -0
  135. data/fixtures/generator-test/source/index.html.erb +10 -0
  136. data/fixtures/glob-app/config.rb +1 -0
  137. data/fixtures/glob-app/source/index.html.erb +4 -0
  138. data/fixtures/glob-app/source/stylesheets/site.css.str +3 -0
  139. data/fixtures/ignore-app/config.rb +2 -0
  140. data/fixtures/ignore-app/source/articles/template.html.erb +1 -0
  141. data/fixtures/ignore-app/source/template.html.erb +1 -0
  142. data/fixtures/indexable-app/config.rb +2 -0
  143. data/fixtures/indexable-app/source/.htaccess +1 -0
  144. data/fixtures/indexable-app/source/a_folder/needs_index.html +1 -0
  145. data/fixtures/indexable-app/source/leave_me_alone.html +1 -0
  146. data/fixtures/indexable-app/source/needs_index.html +1 -0
  147. data/fixtures/indexable-app/source/regular/index.html +1 -0
  148. data/fixtures/instance-vars-app/config.rb +0 -0
  149. data/fixtures/instance-vars-app/source/_vartial.erb +5 -0
  150. data/fixtures/instance-vars-app/source/instance-var-set.html.erb +2 -0
  151. data/fixtures/instance-vars-app/source/layout.erb +3 -0
  152. data/fixtures/instance-vars-app/source/no-instance-var.html.erb +1 -0
  153. data/fixtures/large-build-app/config.rb +3 -0
  154. data/fixtures/large-build-app/source/.htaccess +1 -0
  155. data/fixtures/large-build-app/source/_partial.erb +1 -0
  156. data/fixtures/large-build-app/source/images/Child folder/regular_file(example).txt +1 -0
  157. data/fixtures/large-build-app/source/images/Read me (example).txt +1 -0
  158. data/fixtures/large-build-app/source/images/blank.gif +0 -0
  159. data/fixtures/large-build-app/source/index.html.erb +1 -0
  160. data/fixtures/large-build-app/source/layout.erb +9 -0
  161. data/fixtures/large-build-app/source/layouts/content_for.erb +4 -0
  162. data/fixtures/large-build-app/source/layouts/custom.erb +8 -0
  163. data/fixtures/large-build-app/source/other_layout.erb +1 -0
  164. data/fixtures/large-build-app/source/services/index.html.erb +1 -0
  165. data/fixtures/large-build-app/source/spaces in file.html.erb +1 -0
  166. data/fixtures/large-build-app/source/static.html +1 -0
  167. data/fixtures/large-build-app/source/stylesheets/static.css +2 -0
  168. data/fixtures/lorem-app/config.rb +0 -0
  169. data/fixtures/lorem-app/source/lorem.html.erb +13 -0
  170. data/fixtures/manual-layout-missing/config.rb +1 -0
  171. data/fixtures/manual-layout-missing/source/index.html.erb +1 -0
  172. data/fixtures/manual-layout-override/config.rb +3 -0
  173. data/fixtures/manual-layout-override/source/index.html.erb +1 -0
  174. data/fixtures/manual-layout-override/source/layouts/another.erb +9 -0
  175. data/fixtures/manual-layout-override/source/layouts/custom.erb +9 -0
  176. data/fixtures/manual-layout/config.rb +1 -0
  177. data/fixtures/manual-layout/source/index.html.erb +1 -0
  178. data/fixtures/manual-layout/source/layouts/custom.erb +9 -0
  179. data/fixtures/multiple-layouts/config.rb +0 -0
  180. data/fixtures/multiple-layouts/source/index.html.erb +1 -0
  181. data/fixtures/multiple-layouts/source/layout.erb +9 -0
  182. data/fixtures/multiple-layouts/source/layout.str +9 -0
  183. data/fixtures/nested-layout-app/config.rb +1 -0
  184. data/fixtures/nested-layout-app/source/data-one.html.erb +5 -0
  185. data/fixtures/nested-layout-app/source/data-two.html.erb +5 -0
  186. data/fixtures/nested-layout-app/source/index.html.erb +1 -0
  187. data/fixtures/nested-layout-app/source/layouts/inner.erb +4 -0
  188. data/fixtures/nested-layout-app/source/layouts/master.erb +3 -0
  189. data/fixtures/nested-layout-app/source/layouts/outer.erb +4 -0
  190. data/fixtures/no-layout/config.rb +0 -0
  191. data/fixtures/no-layout/source/index.html.erb +1 -0
  192. data/fixtures/padrino-helpers-app/config.rb +0 -0
  193. data/fixtures/padrino-helpers-app/source/former_padrino_test.html.erb +4 -0
  194. data/fixtures/page-classes-app/config.rb +4 -0
  195. data/fixtures/page-classes-app/source/page-classes.html.erb +1 -0
  196. data/fixtures/page-classes-app/source/sub1/page-classes.html.erb +1 -0
  197. data/fixtures/page-classes-app/source/sub1/sub2/page-classes.html.erb +1 -0
  198. data/fixtures/partials-app/config.rb +0 -0
  199. data/fixtures/partials-app/source/_locals.erb +1 -0
  200. data/fixtures/partials-app/source/_main.erb +1 -0
  201. data/fixtures/partials-app/source/_main.str +1 -0
  202. data/fixtures/partials-app/source/index.html.erb +3 -0
  203. data/fixtures/partials-app/source/locals.html.erb +1 -0
  204. data/fixtures/partials-app/source/second.html.str +3 -0
  205. data/fixtures/partials-app/source/shared/_footer.erb +1 -0
  206. data/fixtures/partials-app/source/shared/_header.erb +1 -0
  207. data/fixtures/partials-app/source/sub/_local.erb +1 -0
  208. data/fixtures/partials-app/source/sub/index.html.erb +3 -0
  209. data/fixtures/plain-app/index.html +1 -0
  210. data/fixtures/preview-app/config.rb +0 -0
  211. data/fixtures/preview-app/source/content.html.erb +1 -0
  212. data/fixtures/preview-app/source/layout.erb +1 -0
  213. data/fixtures/sinatra-app/config.rb +11 -0
  214. data/fixtures/sinatra-app/source/index.html.erb +5 -0
  215. data/fixtures/traversal-app/config.rb +7 -0
  216. data/fixtures/traversal-app/source/directory-indexed.html.erb +0 -0
  217. data/fixtures/traversal-app/source/directory-indexed/sibling.html.erb +3 -0
  218. data/fixtures/traversal-app/source/directory-indexed/sibling2.html.erb +3 -0
  219. data/fixtures/traversal-app/source/directory-indexed/sub2/index.html.erb +0 -0
  220. data/fixtures/traversal-app/source/directory-indexed/sub3/deep.html.erb +0 -0
  221. data/fixtures/traversal-app/source/index.html.erb +0 -0
  222. data/fixtures/traversal-app/source/layout.erb +19 -0
  223. data/fixtures/traversal-app/source/proxied.html.erb +0 -0
  224. data/fixtures/traversal-app/source/root.html.erb +0 -0
  225. data/fixtures/traversal-app/source/sub/index.html.erb +0 -0
  226. data/fixtures/traversal-app/source/sub/sibling.html.erb +0 -0
  227. data/fixtures/traversal-app/source/sub/sibling2.html.erb +0 -0
  228. data/fixtures/traversal-app/source/sub/sub2/index.html.erb +0 -0
  229. data/fixtures/traversal-app/source/sub/sub3/deep.html.erb +0 -0
  230. data/fixtures/wildcard-app/config.rb +1 -0
  231. data/fixtures/wildcard-app/source/admin/index.html.erb +1 -0
  232. data/fixtures/wildcard-app/source/admin/page.html.erb +1 -0
  233. data/fixtures/wildcard-app/source/index.html.erb +1 -0
  234. data/fixtures/wildcard-app/source/layouts/admin.erb +2 -0
  235. data/fixtures/wildcard-app/source/layouts/layout.erb +2 -0
  236. data/fixtures/wildcard-directory-index-app/config.rb +2 -0
  237. data/fixtures/wildcard-directory-index-app/source/admin/index.html.erb +1 -0
  238. data/fixtures/wildcard-directory-index-app/source/admin/page.html.erb +1 -0
  239. data/fixtures/wildcard-directory-index-app/source/index.html.erb +1 -0
  240. data/fixtures/wildcard-directory-index-app/source/layouts/admin.erb +2 -0
  241. data/fixtures/wildcard-directory-index-app/source/layouts/layout.erb +2 -0
  242. data/lib/middleman-core.rb +259 -0
  243. data/lib/middleman-core/base.rb +494 -0
  244. data/lib/middleman-core/cache.rb +57 -0
  245. data/lib/middleman-core/cli.rb +57 -0
  246. data/lib/middleman-core/cli/build.rb +229 -0
  247. data/lib/middleman-core/cli/init.rb +52 -0
  248. data/lib/middleman-core/cli/server.rb +52 -0
  249. data/lib/middleman-core/core_extensions/assets.rb +30 -0
  250. data/lib/middleman-core/core_extensions/builder.rb +49 -0
  251. data/lib/middleman-core/core_extensions/data.rb +193 -0
  252. data/lib/middleman-core/core_extensions/default_helpers.rb +119 -0
  253. data/lib/middleman-core/core_extensions/extensions.rb +148 -0
  254. data/lib/middleman-core/core_extensions/file_watcher.rb +83 -0
  255. data/lib/middleman-core/core_extensions/front_matter.rb +145 -0
  256. data/lib/middleman-core/core_extensions/rendering.rb +247 -0
  257. data/lib/middleman-core/core_extensions/routing.rb +69 -0
  258. data/lib/middleman-core/core_extensions/show_exceptions.rb +16 -0
  259. data/lib/middleman-core/core_extensions/sitemap.rb +72 -0
  260. data/lib/middleman-core/extensions/asset_host.rb +29 -0
  261. data/lib/middleman-core/extensions/automatic_image_sizes.rb +38 -0
  262. data/lib/middleman-core/extensions/automatic_image_sizes/fastimage.rb +287 -0
  263. data/lib/middleman-core/extensions/directory_indexes.rb +62 -0
  264. data/lib/middleman-core/extensions/lorem.rb +140 -0
  265. data/lib/middleman-core/guard.rb +148 -0
  266. data/lib/middleman-core/renderers/erb.rb +19 -0
  267. data/lib/middleman-core/sitemap/page.rb +186 -0
  268. data/lib/middleman-core/sitemap/store.rb +139 -0
  269. data/lib/middleman-core/sitemap/template.rb +82 -0
  270. data/lib/middleman-core/step_definitions.rb +12 -0
  271. data/lib/middleman-core/step_definitions/builder_steps.rb +42 -0
  272. data/lib/middleman-core/step_definitions/middleman_steps.rb +15 -0
  273. data/lib/middleman-core/step_definitions/server_steps.rb +73 -0
  274. data/lib/middleman-core/templates.rb +82 -0
  275. data/lib/middleman-core/templates/default.rb +29 -0
  276. data/lib/middleman-core/templates/default/source/images/background.png +0 -0
  277. data/lib/middleman-core/templates/default/source/images/middleman.png +0 -0
  278. data/lib/middleman-core/templates/default/source/index.html.erb +10 -0
  279. data/lib/middleman-core/templates/default/source/javascripts/all.js +1 -0
  280. data/lib/middleman-core/templates/default/source/layouts/layout.erb +19 -0
  281. data/lib/middleman-core/templates/default/source/stylesheets/_animate.scss +23 -0
  282. data/lib/middleman-core/templates/default/source/stylesheets/_normalize.scss +431 -0
  283. data/lib/middleman-core/templates/default/source/stylesheets/all.css.scss +40 -0
  284. data/lib/middleman-core/templates/html5.rb +25 -0
  285. data/lib/middleman-core/templates/html5/source/404.html +38 -0
  286. data/lib/middleman-core/templates/html5/source/README.md +388 -0
  287. data/lib/middleman-core/templates/html5/source/apple-touch-icon-114x114-precomposed.png +0 -0
  288. data/lib/middleman-core/templates/html5/source/apple-touch-icon-57x57-precomposed.png +0 -0
  289. data/lib/middleman-core/templates/html5/source/apple-touch-icon-72x72-precomposed.png +0 -0
  290. data/lib/middleman-core/templates/html5/source/apple-touch-icon-precomposed.png +0 -0
  291. data/lib/middleman-core/templates/html5/source/apple-touch-icon.png +0 -0
  292. data/lib/middleman-core/templates/html5/source/crossdomain.xml +25 -0
  293. data/lib/middleman-core/templates/html5/source/css/style.css +293 -0
  294. data/lib/middleman-core/templates/html5/source/favicon.ico +0 -0
  295. data/lib/middleman-core/templates/html5/source/humans.txt +43 -0
  296. data/lib/middleman-core/templates/html5/source/img/.gitignore +2 -0
  297. data/lib/middleman-core/templates/html5/source/index.html +79 -0
  298. data/lib/middleman-core/templates/html5/source/js/libs/jquery-1.6.2.js +8981 -0
  299. data/lib/middleman-core/templates/html5/source/js/libs/jquery-1.6.2.min.js +18 -0
  300. data/lib/middleman-core/templates/html5/source/js/libs/modernizr-2.0.6.min.js +4 -0
  301. data/lib/middleman-core/templates/html5/source/js/mylibs/.gitignore +2 -0
  302. data/lib/middleman-core/templates/html5/source/js/plugins.js +20 -0
  303. data/lib/middleman-core/templates/html5/source/js/script.js +8 -0
  304. data/lib/middleman-core/templates/html5/source/robots.txt +5 -0
  305. data/lib/middleman-core/templates/html5/source/test/index.html +31 -0
  306. data/lib/middleman-core/templates/html5/source/test/qunit/qunit.css +148 -0
  307. data/lib/middleman-core/templates/html5/source/test/qunit/qunit.js +1265 -0
  308. data/lib/middleman-core/templates/html5/source/test/tests.js +24 -0
  309. data/lib/middleman-core/templates/local.rb +21 -0
  310. data/lib/middleman-core/templates/mobile.rb +25 -0
  311. data/lib/middleman-core/templates/mobile/source/404.html +37 -0
  312. data/lib/middleman-core/templates/mobile/source/README.markdown +21 -0
  313. data/lib/middleman-core/templates/mobile/source/crossdomain.xml +25 -0
  314. data/lib/middleman-core/templates/mobile/source/css/style.css +315 -0
  315. data/lib/middleman-core/templates/mobile/source/humans.txt +43 -0
  316. data/lib/middleman-core/templates/mobile/source/img/h/apple-touch-icon.png +0 -0
  317. data/lib/middleman-core/templates/mobile/source/img/h/splash.png +0 -0
  318. data/lib/middleman-core/templates/mobile/source/img/l/apple-touch-icon-precomposed.png +0 -0
  319. data/lib/middleman-core/templates/mobile/source/img/l/apple-touch-icon.png +0 -0
  320. data/lib/middleman-core/templates/mobile/source/img/l/splash.png +0 -0
  321. data/lib/middleman-core/templates/mobile/source/img/m/apple-touch-icon.png +0 -0
  322. data/lib/middleman-core/templates/mobile/source/index.html +92 -0
  323. data/lib/middleman-core/templates/mobile/source/js/libs/modernizr-custom.js +14 -0
  324. data/lib/middleman-core/templates/mobile/source/js/libs/respond.min.js +7 -0
  325. data/lib/middleman-core/templates/mobile/source/js/mylibs/helper.js +171 -0
  326. data/lib/middleman-core/templates/mobile/source/js/plugins.js +20 -0
  327. data/lib/middleman-core/templates/mobile/source/js/script.js +0 -0
  328. data/lib/middleman-core/templates/mobile/source/robots.txt +4 -0
  329. data/lib/middleman-core/templates/mobile/source/sitemap.xml +9 -0
  330. data/lib/middleman-core/templates/mobile/source/test/index.html +31 -0
  331. data/lib/middleman-core/templates/mobile/source/test/qunit/qunit.css +148 -0
  332. data/lib/middleman-core/templates/mobile/source/test/qunit/qunit.js +1265 -0
  333. data/lib/middleman-core/templates/mobile/source/test/tests.js +21 -0
  334. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/Readme.PDF +0 -0
  335. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx1.snippet +31 -0
  336. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/aspx/aspx2.snippet +2 -0
  337. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/aspx/ga.aspx +195 -0
  338. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/aspx/sample.aspx +44 -0
  339. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/jsp/ga.jsp +225 -0
  340. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp1.snippet +35 -0
  341. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/jsp/jsp2.snippet +2 -0
  342. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/jsp/sample.jsp +51 -0
  343. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/php/ga.php +176 -0
  344. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/php/php1.snippet +30 -0
  345. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/php/php2.snippet +4 -0
  346. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/php/sample.php +44 -0
  347. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/pl/ga.pl +195 -0
  348. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/pl/perl1.snippet +27 -0
  349. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/pl/perl2.snippet +1 -0
  350. data/lib/middleman-core/templates/mobile/source/tools/googleanalyticsformobile/pl/sample.pl +38 -0
  351. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/COPYING +202 -0
  352. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/bookmark_bubble.js +559 -0
  353. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/example/example.html +43 -0
  354. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/example/example.js +57 -0
  355. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/images/arrow.png +0 -0
  356. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/images/close.png +0 -0
  357. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/images/generate_base64_images +33 -0
  358. data/lib/middleman-core/templates/mobile/source/tools/mobile-bookmark-bubble/images/icon_calendar.png +0 -0
  359. data/lib/middleman-core/templates/mobile/source/tools/wspl/README +27 -0
  360. data/lib/middleman-core/templates/mobile/source/tools/wspl/databasefactory.js +45 -0
  361. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbworker.js +324 -0
  362. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbworker_test.html +393 -0
  363. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbworkerstarter.js +32 -0
  364. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbwrapper_gears.js +595 -0
  365. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbwrapper_gears_test.html +404 -0
  366. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbwrapper_html5.js +203 -0
  367. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbwrapper_html5_test.html +468 -0
  368. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbwrapperapi.js +202 -0
  369. data/lib/middleman-core/templates/mobile/source/tools/wspl/dbwrapperapi_test.html +51 -0
  370. data/lib/middleman-core/templates/mobile/source/tools/wspl/gears_resultset.js +71 -0
  371. data/lib/middleman-core/templates/mobile/source/tools/wspl/gears_resultset_test.html +86 -0
  372. data/lib/middleman-core/templates/mobile/source/tools/wspl/gears_transaction.js +196 -0
  373. data/lib/middleman-core/templates/mobile/source/tools/wspl/gears_transaction_test.html +221 -0
  374. data/lib/middleman-core/templates/mobile/source/tools/wspl/gearsutils.js +94 -0
  375. data/lib/middleman-core/templates/mobile/source/tools/wspl/gearsutils_test.html +84 -0
  376. data/lib/middleman-core/templates/mobile/source/tools/wspl/global_functions.js +72 -0
  377. data/lib/middleman-core/templates/mobile/source/tools/wspl/simplenotes/index.html +347 -0
  378. data/lib/middleman-core/templates/mobile/source/tools/wspl/simplenotes/simplenotes.js +503 -0
  379. data/lib/middleman-core/templates/mobile/source/tools/wspl/simplenotes/styles.css +66 -0
  380. data/lib/middleman-core/templates/mobile/source/tools/wspl/simplenotes/template.js +75 -0
  381. data/lib/middleman-core/templates/shared/Gemfile.tt +3 -0
  382. data/lib/middleman-core/templates/shared/config.ru +4 -0
  383. data/lib/middleman-core/templates/shared/config.tt +92 -0
  384. data/lib/middleman-core/vendor/hooks-0.2.0/CHANGES.textile +9 -0
  385. data/lib/middleman-core/vendor/hooks-0.2.0/Gemfile +3 -0
  386. data/lib/middleman-core/vendor/hooks-0.2.0/README.rdoc +107 -0
  387. data/lib/middleman-core/vendor/hooks-0.2.0/Rakefile +12 -0
  388. data/lib/middleman-core/vendor/hooks-0.2.0/hooks.gemspec +22 -0
  389. data/lib/middleman-core/vendor/hooks-0.2.0/lib/hooks.rb +109 -0
  390. data/lib/middleman-core/vendor/hooks-0.2.0/lib/hooks/inheritable_attribute.rb +33 -0
  391. data/lib/middleman-core/vendor/hooks-0.2.0/test/hooks_test.rb +141 -0
  392. data/lib/middleman-core/vendor/hooks-0.2.0/test/inheritable_attribute_test.rb +55 -0
  393. data/lib/middleman-core/vendor/hooks-0.2.0/test/test_helper.rb +10 -0
  394. data/lib/middleman-core/vendor/padrino-core-0.10.5/.document +5 -0
  395. data/lib/middleman-core/vendor/padrino-core-0.10.5/.gitignore +22 -0
  396. data/lib/middleman-core/vendor/padrino-core-0.10.5/.yardopts +1 -0
  397. data/lib/middleman-core/vendor/padrino-core-0.10.5/LICENSE.txt +20 -0
  398. data/lib/middleman-core/vendor/padrino-core-0.10.5/README.rdoc +294 -0
  399. data/lib/middleman-core/vendor/padrino-core-0.10.5/Rakefile +5 -0
  400. data/lib/middleman-core/vendor/padrino-core-0.10.5/bin/padrino +9 -0
  401. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core.rb +167 -0
  402. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/application.rb +270 -0
  403. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/application/rendering.rb +292 -0
  404. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/application/routing.rb +934 -0
  405. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/application/showexceptions.rb +20 -0
  406. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/caller.rb +53 -0
  407. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/cli/adapter.rb +24 -0
  408. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/cli/base.rb +151 -0
  409. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/cli/console.rb +20 -0
  410. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake.rb +24 -0
  411. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/cli/rake_tasks.rb +59 -0
  412. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/command.rb +38 -0
  413. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/images/404.png +0 -0
  414. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/images/500.png +0 -0
  415. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/loader.rb +210 -0
  416. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/cs.yml +34 -0
  417. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/da.yml +34 -0
  418. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/de.yml +34 -0
  419. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/en.yml +34 -0
  420. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/es.yml +34 -0
  421. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/fr.yml +34 -0
  422. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/hu.yml +34 -0
  423. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/it.yml +40 -0
  424. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ja.yml +34 -0
  425. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/lv.yml +34 -0
  426. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/nl.yml +34 -0
  427. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/no.yml +35 -0
  428. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pl.yml +34 -0
  429. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/pt_br.yml +40 -0
  430. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/ru.yml +35 -0
  431. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/tr.yml +34 -0
  432. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/uk.yml +34 -0
  433. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_cn.yml +34 -0
  434. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/locale/zh_tw.yml +34 -0
  435. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/logger.rb +345 -0
  436. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/mounter.rb +224 -0
  437. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/reloader.rb +254 -0
  438. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/router.rb +98 -0
  439. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/server.rb +79 -0
  440. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/support_lite.rb +200 -0
  441. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/tasks.rb +21 -0
  442. data/lib/middleman-core/vendor/padrino-core-0.10.5/lib/padrino-core/version.rb +20 -0
  443. data/lib/middleman-core/vendor/padrino-core-0.10.5/padrino-core.gemspec +38 -0
  444. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/apps/.components +6 -0
  445. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/apps/.gitignore +7 -0
  446. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/apps/complex.rb +32 -0
  447. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/apps/simple.rb +33 -0
  448. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/dependencies/a.rb +9 -0
  449. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/dependencies/b.rb +4 -0
  450. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/dependencies/c.rb +1 -0
  451. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/e.rb +13 -0
  452. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/f.rb +2 -0
  453. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/dependencies/circular/g.rb +2 -0
  454. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/fixtures/dependencies/d.rb +4 -0
  455. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/helper.rb +81 -0
  456. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/mini_shoulda.rb +45 -0
  457. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_application.rb +108 -0
  458. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_core.rb +79 -0
  459. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_dependencies.rb +44 -0
  460. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_filters.rb +278 -0
  461. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_locale.rb +21 -0
  462. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_logger.rb +100 -0
  463. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_mounter.rb +177 -0
  464. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_reloader_complex.rb +75 -0
  465. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_reloader_simple.rb +98 -0
  466. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_rendering.rb +461 -0
  467. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_restful_routing.rb +33 -0
  468. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_router.rb +146 -0
  469. data/lib/middleman-core/vendor/padrino-core-0.10.5/test/test_routing.rb +1673 -0
  470. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/.document +5 -0
  471. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/.gitignore +21 -0
  472. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/.yardopts +1 -0
  473. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/LICENSE.txt +20 -0
  474. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/README.rdoc +239 -0
  475. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/Rakefile +5 -0
  476. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers.rb +58 -0
  477. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/asset_tag_helpers.rb +420 -0
  478. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/abstract_form_builder.rb +220 -0
  479. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_builder/standard_form_builder.rb +43 -0
  480. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/form_helpers.rb +602 -0
  481. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/format_helpers.rb +381 -0
  482. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/cs.yml +103 -0
  483. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/da.yml +91 -0
  484. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/de.yml +81 -0
  485. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/en.yml +103 -0
  486. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/es.yml +103 -0
  487. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/fr.yml +80 -0
  488. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/hu.yml +103 -0
  489. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/it.yml +89 -0
  490. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ja.yml +103 -0
  491. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/lv.yml +103 -0
  492. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/nl.yml +82 -0
  493. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/no.yml +91 -0
  494. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pl.yml +95 -0
  495. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/pt_br.yml +103 -0
  496. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/ru.yml +103 -0
  497. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/tr.yml +103 -0
  498. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/uk.yml +103 -0
  499. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_cn.yml +104 -0
  500. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/locale/zh_tw.yml +103 -0
  501. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/number_helpers.rb +288 -0
  502. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers.rb +175 -0
  503. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/abstract_handler.rb +98 -0
  504. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/erb_handler.rb +79 -0
  505. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/haml_handler.rb +63 -0
  506. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/output_helpers/slim_handler.rb +81 -0
  507. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/render_helpers.rb +60 -0
  508. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/tag_helpers.rb +103 -0
  509. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/lib/padrino-helpers/translation_helpers.rb +38 -0
  510. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/padrino-helpers.gemspec +27 -0
  511. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/app.rb +73 -0
  512. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.erb +14 -0
  513. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.haml +12 -0
  514. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/capture_concat.slim +13 -0
  515. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.erb +14 -0
  516. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.haml +12 -0
  517. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_for.slim +12 -0
  518. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.erb +11 -0
  519. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.haml +9 -0
  520. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/content_tag.slim +9 -0
  521. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.erb +5 -0
  522. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.haml +5 -0
  523. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/current_engine.slim +5 -0
  524. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.erb +20 -0
  525. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.haml +15 -0
  526. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/fields_for.slim +15 -0
  527. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.erb +56 -0
  528. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.haml +47 -0
  529. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_for.slim +47 -0
  530. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.erb +56 -0
  531. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.haml +45 -0
  532. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/form_tag.slim +45 -0
  533. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.erb +5 -0
  534. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.haml +4 -0
  535. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/link_to.slim +4 -0
  536. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.erb +3 -0
  537. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.haml +3 -0
  538. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/mail_to.slim +3 -0
  539. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.erb +3 -0
  540. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.haml +3 -0
  541. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/meta_tag.slim +3 -0
  542. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_erb.erb +1 -0
  543. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_haml.haml +1 -0
  544. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/partials/_slim.slim +1 -0
  545. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.erb +1 -0
  546. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.haml +1 -0
  547. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/markup_app/views/simple_partial.slim +1 -0
  548. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/app.rb +50 -0
  549. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engine.haml +5 -0
  550. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_erb.erb +1 -0
  551. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_haml.haml +1 -0
  552. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/current_engines/_slim.slim +1 -0
  553. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/erb/test.erb +1 -0
  554. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/explicit_engine.haml +5 -0
  555. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/haml/test.haml +1 -0
  556. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/_user.haml +7 -0
  557. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/haml_template.haml +1 -0
  558. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/fixtures/render_app/views/template/some_template.haml +2 -0
  559. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/helper.rb +66 -0
  560. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_asset_tag_helpers.rb +320 -0
  561. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_form_builder.rb +996 -0
  562. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_form_helpers.rb +645 -0
  563. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_format_helpers.rb +227 -0
  564. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_locale.rb +20 -0
  565. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_number_helpers.rb +136 -0
  566. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_output_helpers.rb +153 -0
  567. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_render_helpers.rb +76 -0
  568. data/lib/middleman-core/vendor/padrino-helpers-0.10.5/test/test_tag_helpers.rb +105 -0
  569. data/lib/middleman-core/version.rb +13 -0
  570. data/middleman-core.gemspec +41 -0
  571. metadata +974 -0
@@ -0,0 +1,292 @@
1
+ require 'padrino-core/support_lite' unless defined?(SupportLite)
2
+
3
+ module Padrino
4
+ ##
5
+ # Padrino enhances the Sinatra 'render' method to have support for
6
+ # automatic template engine detection, enhanced layout functionality,
7
+ # locale enabled rendering, among other features.
8
+ #
9
+ module Rendering
10
+ ##
11
+ # Exception responsible for when an expected template did not exist.
12
+ #
13
+ class TemplateNotFound < RuntimeError
14
+ end
15
+
16
+ ##
17
+ # This is an array of file patterns to ignore. If your editor add a
18
+ # suffix during editing to your files please add it like:
19
+ #
20
+ # @example
21
+ # Padrino::Rendering::IGNORE_FILE_PATTERN << /~$/
22
+ #
23
+ IGNORE_FILE_PATTERN = [
24
+ /~$/ # This is for Gedit
25
+ ] unless defined?(IGNORE_FILE_PATTERN)
26
+
27
+ ##
28
+ # Default rendering options used in the #render-method.
29
+ #
30
+ DEFAULT_RENDERING_OPTIONS = { :strict_format => false, :raise_exceptions => true } unless defined?(DEFAULT_RENDERING_OPTIONS)
31
+
32
+ class << self
33
+ ##
34
+ # Main class that register this extension.
35
+ #
36
+ def registered(app)
37
+ app.send(:include, InstanceMethods)
38
+ app.extend(ClassMethods)
39
+ end
40
+ alias :included :registered
41
+ end
42
+
43
+ ##
44
+ # Class methods responsible for rendering templates as part of a request.
45
+ #
46
+ module ClassMethods
47
+ ##
48
+ # Use layout like rails does or if a block given then like sinatra.
49
+ # If used without a block, sets the current layout for the route.
50
+ #
51
+ # By default, searches in your:
52
+ #
53
+ # +app+/+views+/+layouts+/+application+.(+haml+|+erb+|+xxx+)
54
+ # +app+/+views+/+layout_name+.(+haml+|+erb+|+xxx+)
55
+ #
56
+ # If you define +layout+ :+custom+ then searches for your layouts in
57
+ # +app+/+views+/+layouts+/+custom+.(+haml+|+erb+|+xxx+)
58
+ # +app+/+views+/+custom+.(+haml+|+erb+|+xxx+)
59
+ #
60
+ # @param [Symbol] name (:layout)
61
+ # The layout to use.
62
+ #
63
+ # @yield []
64
+ #
65
+ def layout(name=:layout, &block)
66
+ return super(name, &block) if block_given?
67
+ @layout = name
68
+ end
69
+
70
+ ##
71
+ # Returns the cached template file to render for a given url, content_type and locale.
72
+ #
73
+ # @param [Array<template_path, content_type, locale>] render_options
74
+ #
75
+ def fetch_template_file(render_options)
76
+ (@_cached_templates ||= {})[render_options]
77
+ end
78
+
79
+ ##
80
+ # Caches the template file for the given rendering options
81
+ #
82
+ # @param [String] template_file
83
+ # The path of the template file.
84
+ #
85
+ # @param [Array<template_path, content_type, locale>] render_options
86
+ #
87
+ def cache_template_file!(template_file, render_options)
88
+ (@_cached_templates ||= {})[render_options] = template_file || []
89
+ end
90
+
91
+ ##
92
+ # Returns the cached layout path.
93
+ #
94
+ # @param [Symbol, nil] given_layout
95
+ # The requested layout.
96
+ #
97
+ def fetch_layout_path(given_layout=nil)
98
+ layout_name = given_layout || @layout || :application
99
+ @_cached_layout ||= {}
100
+ cached_layout_path = @_cached_layout[layout_name]
101
+ return cached_layout_path if cached_layout_path
102
+ has_layout_at_root = Dir["#{views}/#{layout_name}.*"].any?
103
+ layout_path = has_layout_at_root ? layout_name.to_sym : File.join('layouts', layout_name.to_s).to_sym
104
+ @_cached_layout[layout_name] = layout_path unless reload_templates?
105
+ layout_path
106
+ end
107
+ end
108
+
109
+ # Instance methods that allow enhanced rendering to function properly in Padrino.
110
+ module InstanceMethods
111
+ attr_reader :current_engine
112
+
113
+ ##
114
+ # Get/Set the content_type
115
+ #
116
+ # @param [String, nil] type
117
+ # The Content-Type to use.
118
+ #
119
+ # @param [Symbol, nil] type.
120
+ # Look and parse the given symbol to the matched Content-Type.
121
+ #
122
+ # @param [Hash] params
123
+ # Additional params to append to the Content-Type.
124
+ #
125
+ # @example
126
+ # case content_type
127
+ # when :js then do_some
128
+ # when :css then do_another
129
+ # end
130
+ #
131
+ # content_type :js
132
+ # # => set the response with 'application/javascript' Content-Type
133
+ # content_type 'text/html'
134
+ #
135
+ # # => set directly the Content-Type to 'text/html'
136
+ #
137
+ def content_type(type=nil, params={})
138
+ unless type.nil?
139
+ super(type, params)
140
+ @_content_type = type
141
+ end
142
+ @_content_type
143
+ end
144
+
145
+ private
146
+ ##
147
+ # Enhancing Sinatra render functionality for:
148
+ #
149
+ # * Using layout similar to rails
150
+ # * Use render 'path/to/my/template' (without symbols)
151
+ # * Use render 'path/to/my/template' (with engine lookup)
152
+ # * Use render 'path/to/template.haml' (with explicit engine lookup)
153
+ # * Use render 'path/to/template', :layout => false
154
+ # * Use render 'path/to/template', :layout => false, :engine => 'haml'
155
+ # * Use render { :a => 1, :b => 2, :c => 3 } # => return a json string
156
+ #
157
+ def render(engine, data=nil, options={}, locals={}, &block)
158
+ # If engine is a hash then render data converted to json
159
+ content_type(:json, :charset => 'utf-8') and return engine.to_json if engine.is_a?(Hash)
160
+
161
+ # If engine is nil, ignore engine parameter and shift up all arguments
162
+ # render nil, "index", { :layout => true }, { :localvar => "foo" }
163
+ engine, data, options = data, options, locals if engine.nil? && data
164
+
165
+ # Data is a hash of options when no engine isn't explicit
166
+ # render "index", { :layout => true }, { :localvar => "foo" }
167
+ # Data is options, and options is locals in this case
168
+ data, options, locals = nil, data, options if data.is_a?(Hash)
169
+
170
+ # If data is unassigned then this is a likely a template to be resolved
171
+ # This means that no engine was explicitly defined
172
+ data, engine = *resolve_template(engine, options.dup) if data.nil?
173
+
174
+ # Setup root
175
+ root = settings.respond_to?(:root) ? settings.root : ""
176
+
177
+ # Use @layout if it exists
178
+ options[:layout] = @layout if options[:layout].nil?
179
+
180
+ # Resolve layouts similar to in Rails
181
+ if (options[:layout].nil? || options[:layout] == true) && !settings.templates.has_key?(:layout)
182
+ layout_path, layout_engine = *resolved_layout
183
+ options[:layout] = layout_path || false # We need to force layout false so sinatra don't try to render it
184
+ options[:layout] = false unless layout_engine == engine # TODO allow different layout engine
185
+ options[:layout_engine] = layout_engine || engine if options[:layout]
186
+ elsif options[:layout].present?
187
+ options[:layout] = settings.fetch_layout_path(options[:layout] || @layout)
188
+ end
189
+
190
+ # Cleanup the template
191
+ @current_engine, engine_was = engine, @current_engine
192
+ @_out_buf, _buf_was = "", @_out_buf
193
+
194
+ # Pass arguments to Sinatra render method
195
+ super(engine, data, options.dup, locals, &block)
196
+ ensure
197
+ @current_engine = engine_was
198
+ @_out_buf = _buf_was
199
+ end
200
+
201
+ ##
202
+ # Returns the located layout tuple to be used for the rendered template
203
+ # (if available).
204
+ #
205
+ # @example
206
+ # resolve_layout
207
+ # # => ["/layouts/custom", :erb]
208
+ # # => [nil, nil]
209
+ #
210
+ def resolved_layout
211
+ located_layout = resolve_template(settings.fetch_layout_path, :raise_exceptions => false, :strict_format => true)
212
+ located_layout ? located_layout : [nil, nil]
213
+ end
214
+
215
+ ##
216
+ # Returns the template path and engine that match content_type (if present),
217
+ # I18n.locale.
218
+ #
219
+ # @param [String] template_path
220
+ # The path of the template.
221
+ #
222
+ # @param [Hash] options
223
+ # Additional options.
224
+ #
225
+ # @option options [Boolean] :strict_format (false)
226
+ # The resolved template must match the content_type of the request.
227
+ #
228
+ # @option options [Boolean] :raise_exceptions (false)
229
+ # Raises a {TemplateNotFound} exception if the template cannot be located.
230
+ #
231
+ # @return [Array<Symbol, Symbol>]
232
+ # The path and format of the template.
233
+ #
234
+ # @raise [TemplateNotFound]
235
+ # The template could not be found.
236
+ #
237
+ # @example
238
+ # get "/foo", :provides => [:html, :js] do; render 'path/to/foo'; end
239
+ # # If you request "/foo.js" with I18n.locale == :ru => [:"/path/to/foo.ru.js", :erb]
240
+ # # If you request "/foo" with I18n.locale == :de => [:"/path/to/foo.de.haml", :haml]
241
+ #
242
+ def resolve_template(template_path, options={})
243
+ began_at = Time.now
244
+ # Fetch cached template for rendering options
245
+ template_path = template_path.to_s[0] == ?/ ? template_path.to_s : "/#{template_path}"
246
+ rendering_options = [template_path, content_type, locale]
247
+ cached_template = settings.fetch_template_file(rendering_options)
248
+ if cached_template
249
+ logger.debug :cached, began_at, cached_template[0] if settings.logging? && defined?(logger)
250
+ return cached_template
251
+ end
252
+
253
+ # Resolve view path and options
254
+ options.reverse_merge!(DEFAULT_RENDERING_OPTIONS)
255
+ view_path = options.delete(:views) || settings.views || "./views"
256
+ target_extension = File.extname(template_path)[1..-1] || "none" # explicit template extension
257
+ template_path = template_path.chomp(".#{target_extension}")
258
+
259
+ # Generate potential template candidates
260
+ templates = Dir[File.join(view_path, template_path) + ".*"].map do |file|
261
+ template_engine = File.extname(file)[1..-1].to_sym # retrieves engine extension
262
+ template_file = file.sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
263
+ [template_file, template_engine] unless IGNORE_FILE_PATTERN.any? { |pattern| template_engine.to_s =~ pattern }
264
+ end
265
+
266
+ # Check if we have a simple content type
267
+ simple_content_type = [:html, :plain].include?(content_type)
268
+
269
+ # Resolve final template to render
270
+ located_template =
271
+ templates.find { |file, e| file.to_s == "#{template_path}.#{locale}.#{content_type}" } ||
272
+ templates.find { |file, e| file.to_s == "#{template_path}.#{locale}" && simple_content_type } ||
273
+ templates.find { |file, e| File.extname(file.to_s) == ".#{target_extension}" or e.to_s == target_extension.to_s } ||
274
+ templates.find { |file, e| file.to_s == "#{template_path}.#{content_type}" } ||
275
+ templates.find { |file, e| file.to_s == "#{template_path}" && simple_content_type } ||
276
+ (!options[:strict_format] && templates.first) # If not strict, fall back to the first located template
277
+
278
+ raise TemplateNotFound, "Template '#{template_path}' not found in '#{view_path}'!" if !located_template && options[:raise_exceptions]
279
+ settings.cache_template_file!(located_template, rendering_options) unless settings.reload_templates?
280
+ logger.debug :template, began_at, located_template[0] if located_template && settings.logging? && defined?(logger)
281
+ located_template
282
+ end
283
+
284
+ ##
285
+ # Return the I18n.locale if I18n is defined.
286
+ #
287
+ def locale
288
+ I18n.locale if defined?(I18n)
289
+ end
290
+ end # InstanceMethods
291
+ end # Rendering
292
+ end # Padrino
@@ -0,0 +1,934 @@
1
+ require 'http_router' unless defined?(HttpRouter)
2
+ require 'padrino-core/support_lite' unless defined?(SupportLite)
3
+
4
+ ##
5
+ # Adds to Sinatra +controller+ informations
6
+ #
7
+ # @private
8
+ class Sinatra::Request
9
+ attr_accessor :route_obj
10
+
11
+ def controller
12
+ route_obj && route_obj.controller
13
+ end
14
+ end
15
+
16
+ ##
17
+ # HttpRouter adapter
18
+ #
19
+ # @private
20
+ class HttpRouter
21
+ def rewrite_partial_path_info(env, request); end
22
+ def rewrite_path_info(env, request); end
23
+
24
+ def process_destination_path(path, env)
25
+ Thread.current['padrino.instance'].instance_eval do
26
+ request.route_obj = path.route
27
+ @_response_buffer = nil
28
+ @route = path.route
29
+ @params ||= {}
30
+ @params.update(env['router.params'])
31
+ @block_params = if path.route.is_a?(HttpRouter::RegexRoute)
32
+ params_list = env['router.request'].extra_env['router.regex_match'].to_a
33
+ params_list.shift
34
+ @params[:captures] = params_list
35
+ params_list
36
+ else
37
+ env['router.request'].params
38
+ end
39
+ # Provide access to the current controller to the request
40
+ # Now we can eval route, but because we have "throw halt" we need to be
41
+ # (en)sure to reset old layout and run controller after filters.
42
+ original_params = @params
43
+ parent_layout = @layout
44
+ successful = false
45
+ begin
46
+ filter! :before
47
+ (@route.before_filters - settings.filters[:before]).each { |block| instance_eval(&block) }
48
+ @layout = path.route.use_layout if path.route.use_layout
49
+ @route.custom_conditions.each { |block| pass if block.bind(self).call == false } if @route.custom_conditions
50
+ @block_params = @block_params[0, @route.dest.arity] if @route.dest.arity > 0
51
+ halt_response = catch(:halt) { route_eval { @route.dest[self, @block_params] } }
52
+ @_response_buffer = halt_response.is_a?(Array) ? halt_response.last : halt_response
53
+ successful = true
54
+ halt halt_response
55
+ ensure
56
+ (@route.after_filters - settings.filters[:after]).each { |block| instance_eval(&block) } if successful
57
+ @layout = parent_layout
58
+ @params = original_params
59
+ end
60
+ end
61
+ end
62
+
63
+ # @private
64
+ class Route
65
+ attr_accessor :use_layout, :controller, :cache, :cache_key, :cache_expires_in
66
+
67
+ def before_filters(&block)
68
+ @_before_filters ||= []
69
+ @_before_filters << block if block_given?
70
+
71
+ @_before_filters
72
+ end
73
+
74
+ def after_filters(&block)
75
+ @_after_filters ||= []
76
+ @_after_filters << block if block_given?
77
+
78
+ @_after_filters
79
+ end
80
+
81
+ def custom_conditions(&block)
82
+ @_custom_conditions ||= []
83
+ @_custom_conditions << block if block_given?
84
+
85
+ @_custom_conditions
86
+ end
87
+ end
88
+ end
89
+
90
+ module Padrino
91
+ class Filter # @private
92
+ attr_reader :block
93
+
94
+ def initialize(mode, scoped_controller, options, args, &block)
95
+ @mode, @scoped_controller, @options, @args, @block = mode, scoped_controller, options, args, block
96
+ end
97
+
98
+ def apply?(request)
99
+ detect = @args.any? do |arg|
100
+ case arg
101
+ when Symbol then request.route_obj && (request.route_obj.named == arg or request.route_obj.named == [@scoped_controller, arg].flatten.join("_").to_sym)
102
+ else arg === request.path_info
103
+ end
104
+ end || @options.any? do |name, val|
105
+ case name
106
+ when :agent then val === request.user_agent
107
+ else val === request.send(name)
108
+ end
109
+ end
110
+ detect ^ !@mode
111
+ end
112
+
113
+ def to_proc
114
+ if @args.empty? && @options.empty?
115
+ block
116
+ else
117
+ filter = self
118
+ proc { instance_eval(&filter.block) if filter.apply?(request) }
119
+ end
120
+ end
121
+ end
122
+
123
+ ##
124
+ # Padrino provides advanced routing definition support to make routes and
125
+ # url generation much easier. This routing system supports named route
126
+ # aliases and easy access to url paths. The benefits of this is that instead
127
+ # of having to hard-code route urls into every area of your application, now
128
+ # we can just define the urls in a single spot and then attach an alias
129
+ # which can be used to refer to the url throughout the application.
130
+ #
131
+ module Routing
132
+ # Defines common content-type alias mappings
133
+ CONTENT_TYPE_ALIASES = { :htm => :html } unless defined?(CONTENT_TYPE_ALIASES)
134
+ # Defines the available route priorities supporting route deferrals.
135
+ ROUTE_PRIORITY = {:high => 0, :normal => 1, :low => 2} unless defined?(ROUTE_PRIORITY)
136
+
137
+ # Raised when a route was invalid or cannot be processed.
138
+ class UnrecognizedException < RuntimeError; end
139
+
140
+ class Parent < String # @private
141
+ attr_reader :map
142
+ attr_reader :optional
143
+ attr_reader :options
144
+
145
+ alias_method :optional?, :optional
146
+
147
+ def initialize(value, options={})
148
+ super(value.to_s)
149
+ @map = options.delete(:map)
150
+ @optional = options.delete(:optional)
151
+ @options = options
152
+ end
153
+ end
154
+
155
+ class << self
156
+ ##
157
+ # Main class that register this extension.
158
+ #
159
+ def registered(app)
160
+ app.send(:include, InstanceMethods)
161
+ app.extend(ClassMethods)
162
+ end
163
+ alias :included :registered
164
+ end
165
+
166
+ # Class methods responsible for enhanced routing for controllers.
167
+ module ClassMethods
168
+ ##
169
+ # Method for organize in a better way our routes.
170
+ #
171
+ # @param [Array] args
172
+ # Controller arguments.
173
+ #
174
+ # @yield []
175
+ # The given block will be used to define the routes within the
176
+ # Controller.
177
+ #
178
+ # @example
179
+ # controller :admin do
180
+ # get :index do; ...; end
181
+ # get :show, :with => :id do; ...; end
182
+ # end
183
+ #
184
+ # url(:admin_index) # => "/admin"
185
+ # url(:admin_show, :id => 1) # "/admin/show/1"
186
+ #
187
+ # @example Using named routes follow the sinatra way:
188
+ # controller "/admin" do
189
+ # get "/index" do; ...; end
190
+ # get "/show/:id" do; ...; end
191
+ # end
192
+ #
193
+ # @example Supply +:provides+ to all controller routes:
194
+ # controller :provides => [:html, :xml, :json] do
195
+ # get :index do; "respond to html, xml and json"; end
196
+ # post :index do; "respond to html, xml and json"; end
197
+ # get :foo do; "respond to html, xml and json"; end
198
+ # end
199
+ #
200
+ # @example Specify parent resources in padrino with the +:parent+ option on the controller:
201
+ # controllers :product, :parent => :user do
202
+ # get :index do
203
+ # # url is generated as "/user/#{params[:user_id]}/product"
204
+ # # url_for(:product, :index, :user_id => 5) => "/user/5/product"
205
+ # end
206
+ # get :show, :with => :id do
207
+ # # url is generated as "/user/#{params[:user_id]}/product/show/#{params[:id]}"
208
+ # # url_for(:product, :show, :user_id => 5, :id => 10) => "/user/5/product/show/10"
209
+ # end
210
+ # end
211
+ #
212
+ # @example Specify conditions to run for all routes:
213
+ # controller :conditions => {:protect => true} do
214
+ # def self.protect(protected)
215
+ # condition do
216
+ # halt 403, "No secrets for you!" unless params[:key] == "s3cr3t"
217
+ # end if protected
218
+ # end
219
+ #
220
+ # # This route will only return "secret stuff" if the user goes to
221
+ # # `/private?key=s3cr3t`.
222
+ # get("/private") { "secret stuff" }
223
+ #
224
+ # # And this one, too!
225
+ # get("/also-private") { "secret stuff" }
226
+ #
227
+ # # But you can override the conditions for each route as needed.
228
+ # # This route will be publicly accessible without providing the
229
+ # # secret key.
230
+ # get :index, :protect => false do
231
+ # "Welcome!"
232
+ # end
233
+ # end
234
+ #
235
+ # @example Supply default values:
236
+ # controller :lang => :de do
237
+ # get :index, :map => "/:lang" do; "params[:lang] == :de"; end
238
+ # end
239
+ #
240
+ # In a controller before and after filters are scoped and didn't affect other controllers or main app.
241
+ # In a controller layout are scoped and didn't affect others controllers and main app.
242
+ #
243
+ # @example
244
+ # controller :posts do
245
+ # layout :post
246
+ # before { foo }
247
+ # after { bar }
248
+ # end
249
+ #
250
+ def controller(*args, &block)
251
+ if block_given?
252
+ options = args.extract_options!
253
+
254
+ # Controller defaults
255
+ @_controller, original_controller = args, @_controller
256
+ @_parents, original_parent = options.delete(:parent), @_parents
257
+ @_provides, original_provides = options.delete(:provides), @_provides
258
+ @_use_format, original_use_format = options.delete(:use_format), @_use_format
259
+ @_cache, original_cache = options.delete(:cache), @_cache
260
+ @_map, original_map = options.delete(:map), @_map
261
+ @_conditions, original_conditions = options.delete(:conditions), @_conditions
262
+ @_defaults, original_defaults = options, @_defaults
263
+
264
+ # Application defaults
265
+ @filters, original_filters = { :before => @filters[:before].dup, :after => @filters[:after].dup }, @filters
266
+ @layout, original_layout = nil, @layout
267
+
268
+ instance_eval(&block)
269
+
270
+ # Application defaults
271
+ @filters = original_filters
272
+ @layout = original_layout
273
+
274
+ # Controller defaults
275
+ @_controller, @_parents, @_cache = original_controller, original_parent, original_cache
276
+ @_defaults, @_provides, @_map = original_defaults, original_provides, original_map
277
+ @_conditions, @_use_format = original_conditions, original_use_format
278
+ else
279
+ include(*args) if extensions.any?
280
+ end
281
+ end
282
+ alias :controllers :controller
283
+
284
+ ##
285
+ # Add a before filter hook
286
+ #
287
+ # @see #construct_filter
288
+ #
289
+ def before(*args, &block)
290
+ add_filter :before, &(args.empty? ? block : construct_filter(*args, &block))
291
+ end
292
+
293
+ ##
294
+ # Add an after filter hook
295
+ #
296
+ # @see #construct_filter
297
+ #
298
+ def after(*args, &block)
299
+ add_filter :after, &(args.empty? ? block : construct_filter(*args, &block))
300
+ end
301
+
302
+ ##
303
+ # Adds a filter hook to a request.
304
+ #
305
+ def add_filter(type, &block)
306
+ filters[type] << block
307
+ end
308
+
309
+ ##
310
+ # Creates a filter to process before/after the matching route.
311
+ #
312
+ # @param [Array] args
313
+ #
314
+ # @example We are be able to filter with String path
315
+ # before('/') { 'only to :index' }
316
+ # get(:index} { 'foo' } # => filter match only before this.
317
+ # get(:main) { 'bar' }
318
+ #
319
+ # @example is the same of
320
+ # before(:index) { 'only to :index' }
321
+ # get(:index} { 'foo' } # => filter match only before this.
322
+ # get(:main) { 'bar' }
323
+ #
324
+ # @example it works only for the given controller
325
+ # controller :foo do
326
+ # before(:index) { 'only to for :foo_index' }
327
+ # get(:index} { 'foo' } # => filter match only before this.
328
+ # get(:main) { 'bar' }
329
+ # end
330
+ #
331
+ # controller :bar do
332
+ # before(:index) { 'only to for :bar_index' }
333
+ # get(:index} { 'foo' } # => filter match only before this.
334
+ # get(:main) { 'bar' }
335
+ # end
336
+ #
337
+ # @example if filters based on a symbol or regexp
338
+ # before :index, /main/ do; ... end
339
+ # # => match oly path that are +/+ or contains +main+
340
+ #
341
+ # @example filtering everything except an occurency
342
+ # before :except => :index do; ...; end
343
+ #
344
+ # @example you can also filter using a request param
345
+ # before :agent => /IE/ do; ...; end
346
+ # # => match +HTTP_USER_AGENT+ containing +IE+
347
+ #
348
+ # @see http://www.padrinorb.com/guides/controllers#route-filters
349
+ #
350
+ def construct_filter(*args, &block)
351
+ options = args.last.is_a?(Hash) ? args.pop : {}
352
+ except = options.key?(:except) && Array(options.delete(:except))
353
+ raise("You cannot use except with other options specified") if except && (!args.empty? || !options.empty?)
354
+ options = except.last.is_a?(Hash) ? except.pop : {} if except
355
+ Filter.new(!except, @_controller, options, Array(except || args), &block)
356
+ end
357
+
358
+ ##
359
+ # Provides many parents with shallowing.
360
+ #
361
+ # @param [Symbol] name
362
+ # The parent name.
363
+ #
364
+ # @param [Hash] options
365
+ # Additional options.
366
+ #
367
+ # @example
368
+ # controllers :product do
369
+ # parent :shop, :optional => true, :map => "/my/stand"
370
+ # parent :category, :optional => true
371
+ # get :show, :with => :id do
372
+ # # generated urls:
373
+ # # "/product/show/#{params[:id]}"
374
+ # # "/my/stand/#{params[:shop_id]}/product/show/#{params[:id]}"
375
+ # # "/my/stand/#{params[:shop_id]}/category/#{params[:category_id]}/product/show/#{params[:id]}"
376
+ # # url_for(:product, :show, :id => 10) => "/product/show/10"
377
+ # # url_for(:product, :show, :shop_id => 5, :id => 10) => "/my/stand/5/product/show/10"
378
+ # # url_for(:product, :show, :shop_id => 5, :category_id => 1, :id => 10) => "/my/stand/5/category/1/product/show/10"
379
+ # end
380
+ # end
381
+ #
382
+ def parent(name, options={})
383
+ defaults = { :optional => false, :map => name.to_s }
384
+ options = defaults.merge(options)
385
+ @_parents = Array(@_parents) unless @_parents.is_a?(Array)
386
+ @_parents << Parent.new(name, options)
387
+ end
388
+
389
+ ##
390
+ # Using {HttpRouter}, for features and configurations.
391
+ #
392
+ # @example
393
+ # router.add('/greedy/:greed')
394
+ # router.recognize('/simple')
395
+ #
396
+ # @see http://github.com/joshbuddy/http_router
397
+ #
398
+ def router
399
+ @router ||= HttpRouter.new
400
+ block_given? ? yield(@router) : @router
401
+ end
402
+ alias :urls :router
403
+
404
+ # Compiles the routes including deferred routes.
405
+ def compiled_router
406
+ if deferred_routes.empty?
407
+ router
408
+ else
409
+ deferred_routes.each { |_, routes| routes.each { |(route, dest)| route.to(dest) } }
410
+ @deferred_routes = nil
411
+ router
412
+ end
413
+ end
414
+
415
+ # Returns all routes that were deferred based on their priority.
416
+ def deferred_routes
417
+ @deferred_routes ||= Hash[ROUTE_PRIORITY.values.sort.map{|p| [p, []]}]
418
+ end
419
+
420
+ ##
421
+ # Resets the http router and all deferred routes.
422
+ #
423
+ def reset_router!
424
+ @deferred_routes = nil
425
+ router.reset!
426
+ end
427
+
428
+ ##
429
+ # Recognize a given path
430
+ #
431
+ # @param [String] path
432
+ # Path+Query to parse
433
+ #
434
+ # @return [Symbol, Hash]
435
+ # Returns controller and query params.
436
+ #
437
+ # @example Giving a controller like:
438
+ # controller :foo do
439
+ # get :bar, :map => 'foo-bar-:id'; ...; end
440
+ # end
441
+ #
442
+ # @example You should be able to reverse:
443
+ # MyApp.url(:foo_bar, :id => :mine)
444
+ # # => /foo-bar-mine
445
+ #
446
+ # @example Into this:
447
+ # MyApp.recognize_path('foo-bar-mine')
448
+ # # => [:foo_bar, :id => :mine]
449
+ #
450
+ def recognize_path(path)
451
+ responses = @router.recognize(Rack::MockRequest.env_for(path))
452
+ [responses[0].path.route.named, responses[0].params]
453
+ end
454
+
455
+ ##
456
+ # Instance method for url generation.
457
+ #
458
+ # @example
459
+ # url(:show, :id => 1)
460
+ # url(:show, :name => 'test', :id => 24)
461
+ # url(:show, 1)
462
+ # url(:controller_name, :show, :id => 21)
463
+ # url(:controller_show, :id => 29)
464
+ #
465
+ def url(*args)
466
+ params = args.extract_options! # parameters is hash at end
467
+ names, params_array = args.partition{|a| a.is_a?(Symbol)}
468
+ name = names.join("_").to_sym # route name is concatenated with underscores
469
+ if params.is_a?(Hash)
470
+ params[:format] = params[:format].to_s unless params[:format].nil?
471
+ params = value_to_param(params)
472
+ end
473
+ url = if params_array.empty?
474
+ compiled_router.url(name, params)
475
+ else
476
+ compiled_router.url(name, *(params_array << params))
477
+ end
478
+ url[0,0] = conform_uri(uri_root) if defined?(uri_root)
479
+ url[0,0] = conform_uri(ENV['RACK_BASE_URI']) if ENV['RACK_BASE_URI']
480
+ url = "/" if url.blank?
481
+ url
482
+ rescue HttpRouter::InvalidRouteException
483
+ route_error = "route mapping for url(#{name.inspect}) could not be found!"
484
+ raise Padrino::Routing::UnrecognizedException.new(route_error)
485
+ end
486
+ alias :url_for :url
487
+
488
+ def get(path, *args, &block) # @private
489
+ conditions = @conditions.dup
490
+ route('GET', path, *args, &block)
491
+
492
+ @conditions = conditions
493
+ route('HEAD', path, *args, &block)
494
+ end
495
+
496
+ private
497
+ # Parse params from the url method
498
+ def value_to_param(value)
499
+ case value
500
+ when Array
501
+ value.map { |v| value_to_param(v) }.compact
502
+ when Hash
503
+ value.inject({}) do |memo, (k,v)|
504
+ v = value_to_param(v)
505
+ memo[k] = v unless v.nil?
506
+ memo
507
+ end
508
+ when nil then nil
509
+ else value.respond_to?(:to_param) ? value.to_param : value
510
+ end
511
+ end
512
+
513
+ # Add prefix slash if its not present and remove trailing slashes.
514
+ def conform_uri(uri_string)
515
+ uri_string.gsub(/^(?!\/)(.*)/, '/\1').gsub(/[\/]+$/, '')
516
+ end
517
+
518
+ ##
519
+ # Rewrite default routes.
520
+ #
521
+ # @example
522
+ # get :index # => "/"
523
+ # get :index, "/" # => "/"
524
+ # get :index, :map => "/" # => "/"
525
+ # get :show, "/show-me" # => "/show-me"
526
+ # get :show, :map => "/show-me" # => "/show-me"
527
+ # get "/foo/bar" # => "/show"
528
+ # get :index, :parent => :user # => "/user/:user_id/index"
529
+ # get :show, :with => :id, :parent => :user # => "/user/:user_id/show/:id"
530
+ # get :show, :with => :id # => "/show/:id"
531
+ # get [:show, :id] # => "/show/:id"
532
+ # get :show, :with => [:id, :name] # => "/show/:id/:name"
533
+ # get [:show, :id, :name] # => "/show/:id/:name"
534
+ # get :list, :provides => :js # => "/list.{:format,js)"
535
+ # get :list, :provides => :any # => "/list(.:format)"
536
+ # get :list, :provides => [:js, :json] # => "/list.{!format,js|json}"
537
+ # get :list, :provides => [:html, :js, :json] # => "/list(.{!format,js|json})"
538
+ # get :list, :priority => :low # Defers route to be last
539
+ #
540
+ def route(verb, path, *args, &block)
541
+ options = case args.size
542
+ when 2
543
+ args.last.merge(:map => args.first)
544
+ when 1
545
+ map = args.shift if args.first.is_a?(String)
546
+ if args.first.is_a?(Hash)
547
+ map ? args.first.merge(:map => map) : args.first
548
+ else
549
+ {:map => map || args.first}
550
+ end
551
+ when 0
552
+ {}
553
+ else raise
554
+ end
555
+
556
+ # Do padrino parsing. We dup options so we can build HEAD request correctly
557
+ route_options = options.dup
558
+ route_options[:provides] = @_provides if @_provides
559
+ path, *route_options[:with] = path if path.is_a?(Array)
560
+ path, name, options = *parse_route(path, route_options, verb)
561
+ options.reverse_merge!(@_conditions) if @_conditions
562
+
563
+ # Sinatra defaults
564
+ method_name = "#{verb} #{path}"
565
+ unbound_method = generate_method(method_name, &block)
566
+
567
+ block = block.arity != 0 ?
568
+ proc { |a,p| unbound_method.bind(a).call(*p) } :
569
+ proc { |a,p| unbound_method.bind(a).call }
570
+
571
+ invoke_hook(:route_added, verb, path, block)
572
+
573
+ # HTTPRouter route construction
574
+ route = router.add(path)
575
+ route.name(name) if name
576
+ priority_name = options.delete(:priority) || :normal
577
+ priority = ROUTE_PRIORITY[priority_name] or raise("Priority #{priority_name} not recognized, try #{ROUTE_PRIORITY.keys.join(', ')}")
578
+ route.cache = options.key?(:cache) ? options.delete(:cache) : @_cache
579
+ route.send(verb.downcase.to_sym)
580
+ route.host(options.delete(:host)) if options.key?(:host)
581
+ route.user_agent(options.delete(:agent)) if options.key?(:agent)
582
+ if options.key?(:default_values)
583
+ defaults = options.delete(:default_values)
584
+ route.default(defaults) if defaults
585
+ end
586
+ options.delete_if do |option, args|
587
+ if route.send(:significant_variable_names).include?(option)
588
+ route.matching(option => Array(args).first)
589
+ true
590
+ end
591
+ end
592
+
593
+ # Add Sinatra conditions
594
+ options.each { |o, a| route.respond_to?(o) ? route.send(o, *a) : send(o, *a) }
595
+ conditions, @conditions = @conditions, []
596
+ route.custom_conditions.concat(conditions)
597
+
598
+ invoke_hook(:padrino_route_added, route, verb, path, args, options, block)
599
+
600
+ # Add Application defaults
601
+ route.before_filters.concat(@filters[:before])
602
+ route.after_filters.concat(@filters[:after])
603
+ if @_controller
604
+ route.use_layout = @layout
605
+ route.controller = Array(@_controller)[0].to_s
606
+ end
607
+
608
+ deferred_routes[priority] << [route, block]
609
+
610
+ route
611
+ end
612
+
613
+ ##
614
+ # Returns the final parsed route details (modified to reflect all
615
+ # Padrino options) given the raw route. Raw route passed in could be
616
+ # a named alias or a string and is parsed to reflect provides formats,
617
+ # controllers, parents, 'with' parameters, and other options.
618
+ #
619
+ def parse_route(path, options, verb)
620
+ # We need save our originals path/options so we can perform correctly cache.
621
+ original = [path, options.dup]
622
+
623
+ # We need check if path is a symbol, if that it's a named route
624
+ map = options.delete(:map)
625
+
626
+ if path.kind_of?(Symbol) # path i.e :index or :show
627
+ name = path # The route name
628
+ path = map ? map.dup : (path == :index ? '/' : path.to_s) # The route path
629
+ end
630
+
631
+ if path.kind_of?(String) # path i.e "/index" or "/show"
632
+ # Now we need to parse our 'with' params
633
+ if with_params = options.delete(:with)
634
+ path = process_path_for_with_params(path, with_params)
635
+ end
636
+
637
+ # Now we need to parse our provides
638
+ options.delete(:provides) if options[:provides].nil?
639
+
640
+ if @_use_format or format_params = options[:provides]
641
+ process_path_for_provides(path, format_params)
642
+ options[:matching] ||= {}
643
+ options[:matching][:format] = /[^\.]+/
644
+ end
645
+
646
+ # Build our controller
647
+ controller = Array(@_controller).map { |c| c.to_s }
648
+
649
+ absolute_map = map && map[0] == ?/
650
+
651
+ unless controller.empty?
652
+ # Now we need to add our controller path only if not mapped directly
653
+ if map.blank? and !absolute_map
654
+ controller_path = controller.join("/")
655
+ path.gsub!(%r{^\(/\)|/\?}, "")
656
+ path = File.join(controller_path, path)
657
+ end
658
+ # Here we build the correct name route
659
+ if name
660
+ controller_name = controller.join("_")
661
+ name = "#{controller_name}_#{name}".to_sym unless controller_name.blank?
662
+ end
663
+ end
664
+
665
+ # Now we need to parse our 'parent' params and parent scope
666
+ if !absolute_map and parent_params = options.delete(:parent) || @_parents
667
+ parent_params = Array(@_parents) + Array(parent_params)
668
+ path = process_path_for_parent_params(path, parent_params)
669
+ end
670
+
671
+ # Add any controller level map to the front of the path
672
+ path = "#{@_map}/#{path}".squeeze('/') unless absolute_map or @_map.blank?
673
+
674
+ # Small reformats
675
+ path.gsub!(%r{/\?$}, '(/)') # Remove index path
676
+ path.gsub!(%r{//$}, '/') # Remove index path
677
+ path[0,0] = "/" if path !~ %r{^\(?/} # Paths must start with a /
678
+ path.sub!(%r{/(\))?$}, '\\1') if path != "/" # Remove latest trailing delimiter
679
+ path.gsub!(/\/(\(\.|$)/, '\\1') # Remove trailing slashes
680
+ path.squeeze!('/')
681
+ end
682
+
683
+ # Merge in option defaults
684
+ options.reverse_merge!(:default_values => @_defaults)
685
+
686
+ [path, name, options]
687
+ end
688
+
689
+ ##
690
+ # Processes the existing path and appends the 'with' parameters onto the route
691
+ # Used for calculating path in route method.
692
+ #
693
+ def process_path_for_with_params(path, with_params)
694
+ File.join(path, Array(with_params).map(&:inspect).join("/"))
695
+ end
696
+
697
+ ##
698
+ # Processes the existing path and prepends the 'parent' parameters onto the route
699
+ # Used for calculating path in route method.
700
+ #
701
+ def process_path_for_parent_params(path, parent_params)
702
+ parent_prefix = parent_params.flatten.compact.uniq.map do |param|
703
+ map = (param.respond_to?(:map) && param.map ? param.map : param.to_s)
704
+ part = "#{map}/:#{param.to_s.singularize}_id/"
705
+ part = "(#{part})" if param.respond_to?(:optional) && param.optional?
706
+ part
707
+ end
708
+
709
+ [parent_prefix, path].flatten.join("")
710
+ end
711
+
712
+ ##
713
+ # Processes the existing path and appends the 'format' suffix onto the route
714
+ # Used for calculating path in route method.
715
+ #
716
+ def process_path_for_provides(path, format_params)
717
+ path << "(.:format)" unless path[-10, 10] == '(.:format)'
718
+ end
719
+
720
+ ##
721
+ # Allows routing by MIME-types specified in the URL or ACCEPT header.
722
+ #
723
+ # By default, if a non-provided mime-type is specified in a URL, the
724
+ # route will not match an thus return a 404.
725
+ #
726
+ # Setting the :treat_format_as_accept option to true allows treating
727
+ # missing mime types specified in the URL as if they were specified
728
+ # in the ACCEPT header and thus return 406.
729
+ #
730
+ # If no type is specified, the first in the provides-list will be
731
+ # returned.
732
+ #
733
+ # @example
734
+ # get "/a", :provides => [:html, :js]
735
+ # # => GET /a => :html
736
+ # # => GET /a.js => :js
737
+ # # => GET /a.xml => 404
738
+ #
739
+ # get "/b", :provides => [:html]
740
+ # # => GET /b; ACCEPT: html => html
741
+ # # => GET /b; ACCEPT: js => 406
742
+ #
743
+ # enable :treat_format_as_accept
744
+ # get "/c", :provides => [:html, :js]
745
+ # # => GET /c.xml => 406
746
+ #
747
+ def provides(*types)
748
+ @_use_format = true
749
+ condition do
750
+ mime_types = types.map { |t| mime_type(t) }
751
+ url_format = params[:format].to_sym if params[:format]
752
+ accepts = request.accept.map { |a| a.split(";")[0].strip }
753
+
754
+ # per rfc2616-sec14:
755
+ # Assume */* if no ACCEPT header is given.
756
+ catch_all = (accepts.delete "*/*" || accepts.empty?)
757
+ matching_types = accepts.empty? ? mime_types.slice(0,1) : (accepts & mime_types)
758
+
759
+ if !url_format && matching_types.first
760
+ type = ::Rack::Mime::MIME_TYPES.find { |k, v| v == matching_types.first }[0].sub(/\./,'').to_sym
761
+ accept_format = CONTENT_TYPE_ALIASES[type] || type
762
+ elsif catch_all
763
+ type = types.first
764
+ accept_format = CONTENT_TYPE_ALIASES[type] || type
765
+ end
766
+
767
+ matched_format = types.include?(:any) ||
768
+ types.include?(accept_format) ||
769
+ types.include?(url_format) ||
770
+ ((!url_format) && request.accept.empty? && types.include?(:html))
771
+
772
+ # per rfc2616-sec14:
773
+ # answer with 406 if accept is given but types to not match any
774
+ # provided type
775
+ halt 406 if
776
+ (!url_format && !accepts.empty? && !matched_format) ||
777
+ (settings.respond_to?(:treat_format_as_accept) && settings.treat_format_as_accept && url_format && !matched_format)
778
+
779
+ if matched_format
780
+ @_content_type = url_format || accept_format || :html
781
+ content_type(@_content_type, :charset => 'utf-8')
782
+ end
783
+
784
+ matched_format
785
+ end
786
+ end
787
+ end
788
+
789
+ ##
790
+ # Instance methods related to recognizing and processing routes and serving static files.
791
+ #
792
+ module InstanceMethods
793
+ ##
794
+ # Instance method for url generation.
795
+ #
796
+ # @example
797
+ # url(:show, :id => 1)
798
+ # url(:show, :name => :test)
799
+ # url(:show, 1)
800
+ # url("/foo")
801
+ #
802
+ # @see Padrino::Routing::ClassMethods#url
803
+ #
804
+ def url(*args)
805
+ # Delegate to Sinatra 1.2 for simple url("/foo")
806
+ # http://www.sinatrarb.com/intro#Generating%20URLs
807
+ return super if args.first.is_a?(String) && !args[1].is_a?(Hash)
808
+
809
+ # Delegate to Padrino named route url generation
810
+ settings.url(*args)
811
+ end
812
+ alias :url_for :url
813
+
814
+ ##
815
+ # Returns the recognized path for a route.
816
+ #
817
+ def recognize_path(path)
818
+ settings.recognize_path(path)
819
+ end
820
+
821
+ ##
822
+ # Returns the current path within a route from specified +path_params+.
823
+ #
824
+ def current_path(*path_params)
825
+ if path_params.last.is_a?(Hash)
826
+ path_params[-1] = params.merge(path_params[-1])
827
+ else
828
+ path_params << params
829
+ end
830
+ @route.url(*path_params)
831
+ end
832
+
833
+ ##
834
+ # Returns the current route
835
+ #
836
+ # @example
837
+ # -if route.controller == :press
838
+ # %li=show_article
839
+ #
840
+ def route
841
+ @route
842
+ end
843
+
844
+ ##
845
+ # This is mostly just a helper so request.path_info isn't changed when
846
+ # serving files from the public directory.
847
+ #
848
+ def static_file?(path_info)
849
+ return if (public_dir = settings.public_folder).nil?
850
+ public_dir = File.expand_path(public_dir)
851
+ path = File.expand_path(public_dir + unescape(path_info))
852
+ return if path[0, public_dir.length] != public_dir
853
+ return unless File.file?(path)
854
+ return path
855
+ end
856
+
857
+ #
858
+ # Method for deliver static files.
859
+ #
860
+ def static!
861
+ if path = static_file?(request.path_info)
862
+ env['sinatra.static_file'] = path
863
+ cache_control *settings.static_cache_control if settings.static_cache_control?
864
+ send_file(path, :disposition => nil)
865
+ end
866
+ end
867
+
868
+ ##
869
+ # Return the request format, this is useful when we need to respond to
870
+ # a given Content-Type.
871
+ #
872
+ # @param [Symbol, nil] type
873
+ #
874
+ # @param [Hash] params
875
+ #
876
+ # @example
877
+ # get :index, :provides => :any do
878
+ # case content_type
879
+ # when :js then ...
880
+ # when :json then ...
881
+ # when :html then ...
882
+ # end
883
+ # end
884
+ #
885
+ def content_type(type=nil, params={})
886
+ unless type.nil?
887
+ super(type, params)
888
+ @_content_type = type
889
+ end
890
+ @_content_type
891
+ end
892
+
893
+ private
894
+ def filter!(type, base=settings)
895
+ base.filters[type].each { |block| instance_eval(&block) }
896
+ end
897
+
898
+ def dispatch!
899
+ static! if settings.static? && (request.get? || request.head?)
900
+ route!
901
+ rescue ::Exception => boom
902
+ filter! :before
903
+ handle_exception!(boom)
904
+ ensure
905
+ filter! :after unless env['sinatra.static_file']
906
+ end
907
+
908
+ def route!(base=settings, pass_block=nil)
909
+ Thread.current['padrino.instance'] = self
910
+ if base.compiled_router and match = base.compiled_router.call(@request.env)
911
+ if match.respond_to?(:each)
912
+ route_eval do
913
+ match[1].each {|k,v| response[k] = v}
914
+ status match[0]
915
+ route_missing if match[0] == 404
916
+ end
917
+ end
918
+ else
919
+ filter! :before
920
+ end
921
+
922
+ # Run routes defined in superclass.
923
+ if base.superclass.respond_to?(:router)
924
+ route!(base.superclass, pass_block)
925
+ return
926
+ end
927
+
928
+ route_eval(&pass_block) if pass_block
929
+
930
+ route_missing
931
+ end
932
+ end # InstanceMethods
933
+ end # Routing
934
+ end # Padrino