spontaneous 0.1.0.alpha1

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 (556) hide show
  1. data/Gemfile +49 -0
  2. data/Gemfile.lock +146 -0
  3. data/LICENSE +0 -0
  4. data/README +0 -0
  5. data/Rakefile +284 -0
  6. data/Readme.markdown +7 -0
  7. data/application/css/add_alias_dialogue.scss +27 -0
  8. data/application/css/definitions.scss +249 -0
  9. data/application/css/developer.scss +9 -0
  10. data/application/css/editing.scss +649 -0
  11. data/application/css/login.scss +91 -0
  12. data/application/css/min/54ee0ed3c7fac7632bd5c020d69e9a2503e0c88c.css +1 -0
  13. data/application/css/min/c256adc144e2bdd0b0539356b04eb62db01e1dc3.css +1 -0
  14. data/application/css/popover.scss +335 -0
  15. data/application/css/schema_error.scss +90 -0
  16. data/application/css/spontaneous.scss +111 -0
  17. data/application/css/unsupported.scss +16 -0
  18. data/application/css/v2.scss +1606 -0
  19. data/application/css/variables.scss +80 -0
  20. data/application/js/add_alias_dialogue.js +59 -0
  21. data/application/js/add_home_dialogue.js +59 -0
  22. data/application/js/ajax.js +99 -0
  23. data/application/js/authentication.js +22 -0
  24. data/application/js/box.js +104 -0
  25. data/application/js/box_container.js +82 -0
  26. data/application/js/compatibility.js +132 -0
  27. data/application/js/conflicted_field_dialogue.js +92 -0
  28. data/application/js/content.js +224 -0
  29. data/application/js/content_area.js +44 -0
  30. data/application/js/dialogue.js +196 -0
  31. data/application/js/dom.js +71 -0
  32. data/application/js/edit_dialogue.js +137 -0
  33. data/application/js/edit_panel.js +232 -0
  34. data/application/js/editing.js +42 -0
  35. data/application/js/entry.js +13 -0
  36. data/application/js/extensions.js +104 -0
  37. data/application/js/field.js +4 -0
  38. data/application/js/field_preview.js +55 -0
  39. data/application/js/field_types/date_field.js +16 -0
  40. data/application/js/field_types/file_field.js +71 -0
  41. data/application/js/field_types/image_field.js +358 -0
  42. data/application/js/field_types/markdown_field.js +656 -0
  43. data/application/js/field_types/string_field.js +185 -0
  44. data/application/js/image.js +72 -0
  45. data/application/js/init.js +34 -0
  46. data/application/js/load.js +4 -0
  47. data/application/js/location.js +157 -0
  48. data/application/js/login.js +53 -0
  49. data/application/js/min/492a209de8ee955fa9c729a765377495001e11b1.js +17 -0
  50. data/application/js/min/80f684d77c940887a1d4a63e3a96102e993baa98.js +88 -0
  51. data/application/js/min/b8abf302a824c35385ff517b34111e1710ff3b37.js +2 -0
  52. data/application/js/min/c7140ec9475e5bf868b901e0621338d7d162358b.js +3 -0
  53. data/application/js/min/f07f2bd6630ee31e1c2288ec223383d8f0658ba6.js +2 -0
  54. data/application/js/page.js +43 -0
  55. data/application/js/page_browser.js +147 -0
  56. data/application/js/page_entry.js +47 -0
  57. data/application/js/popover.js +99 -0
  58. data/application/js/popover_view.js +56 -0
  59. data/application/js/preview.js +64 -0
  60. data/application/js/progress.js +358 -0
  61. data/application/js/properties.js +90 -0
  62. data/application/js/publish.js +187 -0
  63. data/application/js/require.js +129 -0
  64. data/application/js/sharded_upload.js +206 -0
  65. data/application/js/side_bar.js +30 -0
  66. data/application/js/spontaneous.js +6 -0
  67. data/application/js/state.js +64 -0
  68. data/application/js/status_bar.js +47 -0
  69. data/application/js/top_bar.js +368 -0
  70. data/application/js/types.js +98 -0
  71. data/application/js/upload.js +88 -0
  72. data/application/js/upload_manager.js +319 -0
  73. data/application/js/user.js +37 -0
  74. data/application/js/vendor/.DS_Store +0 -0
  75. data/application/js/vendor/JS.Class-2.1.5/CHANGELOG +283 -0
  76. data/application/js/vendor/JS.Class-2.1.5/MIT-LICENSE +30 -0
  77. data/application/js/vendor/JS.Class-2.1.5/README +30 -0
  78. data/application/js/vendor/JS.Class-2.1.5/min/command.js +1 -0
  79. data/application/js/vendor/JS.Class-2.1.5/min/comparable.js +1 -0
  80. data/application/js/vendor/JS.Class-2.1.5/min/constant_scope.js +1 -0
  81. data/application/js/vendor/JS.Class-2.1.5/min/core.js +1 -0
  82. data/application/js/vendor/JS.Class-2.1.5/min/decorator.js +1 -0
  83. data/application/js/vendor/JS.Class-2.1.5/min/enumerable.js +1 -0
  84. data/application/js/vendor/JS.Class-2.1.5/min/forwardable.js +1 -0
  85. data/application/js/vendor/JS.Class-2.1.5/min/hash.js +1 -0
  86. data/application/js/vendor/JS.Class-2.1.5/min/linked_list.js +1 -0
  87. data/application/js/vendor/JS.Class-2.1.5/min/loader.js +1 -0
  88. data/application/js/vendor/JS.Class-2.1.5/min/method_chain.js +1 -0
  89. data/application/js/vendor/JS.Class-2.1.5/min/observable.js +1 -0
  90. data/application/js/vendor/JS.Class-2.1.5/min/package.js +1 -0
  91. data/application/js/vendor/JS.Class-2.1.5/min/proxy.js +1 -0
  92. data/application/js/vendor/JS.Class-2.1.5/min/ruby.js +1 -0
  93. data/application/js/vendor/JS.Class-2.1.5/min/set.js +1 -0
  94. data/application/js/vendor/JS.Class-2.1.5/min/stack_trace.js +1 -0
  95. data/application/js/vendor/JS.Class-2.1.5/min/state.js +1 -0
  96. data/application/js/vendor/JS.Class-2.1.5/min/stdlib.js +16 -0
  97. data/application/js/vendor/JS.Class-2.1.5/src/command.js +93 -0
  98. data/application/js/vendor/JS.Class-2.1.5/src/comparable.js +37 -0
  99. data/application/js/vendor/JS.Class-2.1.5/src/constant_scope.js +48 -0
  100. data/application/js/vendor/JS.Class-2.1.5/src/core.js +1060 -0
  101. data/application/js/vendor/JS.Class-2.1.5/src/decorator.js +50 -0
  102. data/application/js/vendor/JS.Class-2.1.5/src/enumerable.js +505 -0
  103. data/application/js/vendor/JS.Class-2.1.5/src/forwardable.js +22 -0
  104. data/application/js/vendor/JS.Class-2.1.5/src/hash.js +334 -0
  105. data/application/js/vendor/JS.Class-2.1.5/src/linked_list.js +114 -0
  106. data/application/js/vendor/JS.Class-2.1.5/src/loader.js +553 -0
  107. data/application/js/vendor/JS.Class-2.1.5/src/method_chain.js +172 -0
  108. data/application/js/vendor/JS.Class-2.1.5/src/observable.js +55 -0
  109. data/application/js/vendor/JS.Class-2.1.5/src/package.js +472 -0
  110. data/application/js/vendor/JS.Class-2.1.5/src/proxy.js +58 -0
  111. data/application/js/vendor/JS.Class-2.1.5/src/ruby.js +44 -0
  112. data/application/js/vendor/JS.Class-2.1.5/src/set.js +332 -0
  113. data/application/js/vendor/JS.Class-2.1.5/src/stack_trace.js +151 -0
  114. data/application/js/vendor/JS.Class-2.1.5/src/state.js +95 -0
  115. data/application/js/vendor/JS.Class-2.1.5/src/stdlib.js +2612 -0
  116. data/application/js/vendor/crypto-2.3.0-crypto.js +160 -0
  117. data/application/js/vendor/crypto-2.3.0-sha1.js +91 -0
  118. data/application/js/vendor/diff_match_patch.js +2153 -0
  119. data/application/js/vendor/jquery-1.4.2.min.js +154 -0
  120. data/application/js/vendor/jquery-1.4.3.min.js +166 -0
  121. data/application/js/vendor/jquery-1.5.1.min.js +16 -0
  122. data/application/js/vendor/jquery-1.5.1rc1.min.js +24 -0
  123. data/application/js/vendor/jquery-1.6.2.min.js +18 -0
  124. data/application/js/vendor/jquery-ui-1.8.6.custom.min.js +265 -0
  125. data/application/js/vendor/jquery-ui-1.8.9.custom.min.js +415 -0
  126. data/application/js/vendor/jquery-ui-1.8.custom.min.js +106 -0
  127. data/application/js/vendor/jquery.hotkeys-0.7.9.js +248 -0
  128. data/application/js/vendor/jquery.hotkeys-0.7.9.min.js +19 -0
  129. data/application/js/vendor/jsdiff.js +169 -0
  130. data/application/js/views/box_view.js +229 -0
  131. data/application/js/views/page_piece_view.js +45 -0
  132. data/application/js/views/page_view.js +238 -0
  133. data/application/js/views/piece_view.js +178 -0
  134. data/application/js/views.js +110 -0
  135. data/application/static/editing-0-noise.png +0 -0
  136. data/application/static/editing-1-noise.png +0 -0
  137. data/application/static/editing-texture-1.png +0 -0
  138. data/application/static/editing-texture.png +0 -0
  139. data/application/static/editing-toolbar-shadow-bottom.png +0 -0
  140. data/application/static/editing-toolbar-shadow-top.png +0 -0
  141. data/application/static/favicon.ico +0 -0
  142. data/application/static/inner-glow.png +0 -0
  143. data/application/static/item-buttons.png +0 -0
  144. data/application/static/location-arrow.png +0 -0
  145. data/application/static/logo-400px-transparent.png +0 -0
  146. data/application/static/missing.png +0 -0
  147. data/application/static/orange-down-arrow.png +0 -0
  148. data/application/static/page-browser-next.png +0 -0
  149. data/application/static/paper-texture-dark.png +0 -0
  150. data/application/static/px.gif +0 -0
  151. data/application/static/select-arrow-root.png +0 -0
  152. data/application/static/select-arrow.png +0 -0
  153. data/application/static/slot-down-arrow.png +0 -0
  154. data/application/static/splash.png +0 -0
  155. data/application/static/spontaneous.png +0 -0
  156. data/application/static/spot.png +0 -0
  157. data/application/static/spot.svg +40 -0
  158. data/application/static/texture.png +0 -0
  159. data/application/views/index.erubis +46 -0
  160. data/application/views/login.erubis +69 -0
  161. data/application/views/schema_modification_error.html.erb +61 -0
  162. data/application/views/unsupported.erubis +23 -0
  163. data/bin/limit-upload +5 -0
  164. data/bin/spot +10 -0
  165. data/bin/unlimit-upload +3 -0
  166. data/config/nginx.conf +60 -0
  167. data/db/migrations/20100610142136_init.rb +66 -0
  168. data/db/migrations/20101130104334_timestamps.rb +44 -0
  169. data/db/migrations/20101202113205_site_publishing_flags.rb +12 -0
  170. data/db/migrations/20101206124543_aliases.rb +16 -0
  171. data/db/migrations/20110201133550_visibility.rb +27 -0
  172. data/db/migrations/20110209152710_users_and_groups.rb +58 -0
  173. data/db/migrations/20110215133910_boxes.rb +25 -0
  174. data/db/migrations/20110521114145_remove_slots_and_entries.rb +21 -0
  175. data/db/migrations/20110604192145_rename_schema_id_columns.rb +22 -0
  176. data/db/migrations/20110805141925_rename_site_to_state.rb +11 -0
  177. data/lib/cutaneous/context_helper.rb +82 -0
  178. data/lib/cutaneous/first_pass_parser.rb +23 -0
  179. data/lib/cutaneous/first_pass_renderer.rb +18 -0
  180. data/lib/cutaneous/parser_core.rb +18 -0
  181. data/lib/cutaneous/preview_context.rb +31 -0
  182. data/lib/cutaneous/preview_renderer.rb +15 -0
  183. data/lib/cutaneous/publish_context.rb +9 -0
  184. data/lib/cutaneous/renderer.rb +122 -0
  185. data/lib/cutaneous/request_context.rb +8 -0
  186. data/lib/cutaneous/second_pass_parser.rb +23 -0
  187. data/lib/cutaneous/second_pass_renderer.rb +18 -0
  188. data/lib/cutaneous.rb +47 -0
  189. data/lib/sequel/plugins/content_table_inheritance.rb +196 -0
  190. data/lib/sequel/plugins/yajl_serialization.rb +154 -0
  191. data/lib/spontaneous/application/feature.rb +9 -0
  192. data/lib/spontaneous/application/plugin.rb +13 -0
  193. data/lib/spontaneous/application.rb +8 -0
  194. data/lib/spontaneous/box.rb +232 -0
  195. data/lib/spontaneous/box_style.rb +64 -0
  196. data/lib/spontaneous/change.rb +107 -0
  197. data/lib/spontaneous/cli/adapter.rb +13 -0
  198. data/lib/spontaneous/cli/base.rb +184 -0
  199. data/lib/spontaneous/cli/console.rb +0 -0
  200. data/lib/spontaneous/cli/media.rb +13 -0
  201. data/lib/spontaneous/cli/server.rb +50 -0
  202. data/lib/spontaneous/cli/site.rb +46 -0
  203. data/lib/spontaneous/cli/sync.rb +42 -0
  204. data/lib/spontaneous/cli/tasks.rb +9 -0
  205. data/lib/spontaneous/cli.rb +83 -0
  206. data/lib/spontaneous/collections/box_set.rb +56 -0
  207. data/lib/spontaneous/collections/change_set.rb +43 -0
  208. data/lib/spontaneous/collections/entry_set.rb +83 -0
  209. data/lib/spontaneous/collections/field_set.rb +53 -0
  210. data/lib/spontaneous/collections/prototype_set.rb +131 -0
  211. data/lib/spontaneous/collections/style_set.rb +13 -0
  212. data/lib/spontaneous/config.rb +156 -0
  213. data/lib/spontaneous/constants.rb +24 -0
  214. data/lib/spontaneous/content.rb +113 -0
  215. data/lib/spontaneous/content_query.rb +17 -0
  216. data/lib/spontaneous/errors.rb +48 -0
  217. data/lib/spontaneous/extensions/array.rb +18 -0
  218. data/lib/spontaneous/extensions/class.rb +17 -0
  219. data/lib/spontaneous/extensions/hash.rb +18 -0
  220. data/lib/spontaneous/extensions/json.rb +26 -0
  221. data/lib/spontaneous/extensions/kernel.rb +7 -0
  222. data/lib/spontaneous/extensions/object.rb +30 -0
  223. data/lib/spontaneous/extensions/object_space.rb +12 -0
  224. data/lib/spontaneous/extensions/string.rb +44 -0
  225. data/lib/spontaneous/facet.rb +47 -0
  226. data/lib/spontaneous/field_types/date_field.rb +12 -0
  227. data/lib/spontaneous/field_types/field.rb +252 -0
  228. data/lib/spontaneous/field_types/image_field.rb +329 -0
  229. data/lib/spontaneous/field_types/markdown_field.rb +37 -0
  230. data/lib/spontaneous/field_types/string_field.rb +14 -0
  231. data/lib/spontaneous/field_types.rb +40 -0
  232. data/lib/spontaneous/generators/page/inline.html.cut +1 -0
  233. data/lib/spontaneous/generators/page/page.html.cut.tt +4 -0
  234. data/lib/spontaneous/generators/page/page.rb.tt +9 -0
  235. data/lib/spontaneous/generators/page.rb +38 -0
  236. data/lib/spontaneous/generators/site/.gitignore +4 -0
  237. data/lib/spontaneous/generators/site/Gemfile.tt +31 -0
  238. data/lib/spontaneous/generators/site/Rakefile.tt +6 -0
  239. data/lib/spontaneous/generators/site/config/back.ru +7 -0
  240. data/lib/spontaneous/generators/site/config/boot.rb +19 -0
  241. data/lib/spontaneous/generators/site/config/database.yml.tt +21 -0
  242. data/lib/spontaneous/generators/site/config/deploy.rb.tt +0 -0
  243. data/lib/spontaneous/generators/site/config/environment.rb.tt +8 -0
  244. data/lib/spontaneous/generators/site/config/environments/development.rb.tt +15 -0
  245. data/lib/spontaneous/generators/site/config/environments/production.rb.tt +5 -0
  246. data/lib/spontaneous/generators/site/config/front.ru +8 -0
  247. data/lib/spontaneous/generators/site/config/user_levels.yml +22 -0
  248. data/lib/spontaneous/generators/site/lib/site.rb.tt +4 -0
  249. data/lib/spontaneous/generators/site/lib/tasks/site.rake.tt +8 -0
  250. data/lib/spontaneous/generators/site/public/css/site.css +0 -0
  251. data/lib/spontaneous/generators/site/public/favicon.ico +0 -0
  252. data/lib/spontaneous/generators/site/public/js/.empty_directory +0 -0
  253. data/lib/spontaneous/generators/site/public/js/site.js +0 -0
  254. data/lib/spontaneous/generators/site/public/robots.txt +0 -0
  255. data/lib/spontaneous/generators/site/schema/.map +1 -0
  256. data/lib/spontaneous/generators/site/schema/page.rb.tt +8 -0
  257. data/lib/spontaneous/generators/site/schema/piece.rb.tt +4 -0
  258. data/lib/spontaneous/generators/site/templates/layouts/standard.html.cut.tt +13 -0
  259. data/lib/spontaneous/generators/site.rb +77 -0
  260. data/lib/spontaneous/generators.rb +23 -0
  261. data/lib/spontaneous/image_size.rb +117 -0
  262. data/lib/spontaneous/json.rb +33 -0
  263. data/lib/spontaneous/layout.rb +15 -0
  264. data/lib/spontaneous/loader.rb +280 -0
  265. data/lib/spontaneous/logger.rb +369 -0
  266. data/lib/spontaneous/media.rb +84 -0
  267. data/lib/spontaneous/page.rb +92 -0
  268. data/lib/spontaneous/page_controller.rb +18 -0
  269. data/lib/spontaneous/page_piece.rb +77 -0
  270. data/lib/spontaneous/paths.rb +30 -0
  271. data/lib/spontaneous/permissions/access_group.rb +50 -0
  272. data/lib/spontaneous/permissions/access_key.rb +35 -0
  273. data/lib/spontaneous/permissions/user.rb +167 -0
  274. data/lib/spontaneous/permissions/user_level.rb +177 -0
  275. data/lib/spontaneous/permissions.rb +55 -0
  276. data/lib/spontaneous/piece.rb +30 -0
  277. data/lib/spontaneous/plugins/aliases.rb +128 -0
  278. data/lib/spontaneous/plugins/allowed_types.rb +173 -0
  279. data/lib/spontaneous/plugins/application/facets.rb +25 -0
  280. data/lib/spontaneous/plugins/application/paths.rb +137 -0
  281. data/lib/spontaneous/plugins/application/render.rb +29 -0
  282. data/lib/spontaneous/plugins/application/serialisation.rb +16 -0
  283. data/lib/spontaneous/plugins/application/state.rb +86 -0
  284. data/lib/spontaneous/plugins/boxes.rb +84 -0
  285. data/lib/spontaneous/plugins/controllers.rb +52 -0
  286. data/lib/spontaneous/plugins/entries.rb +193 -0
  287. data/lib/spontaneous/plugins/entry.rb +51 -0
  288. data/lib/spontaneous/plugins/fields.rb +103 -0
  289. data/lib/spontaneous/plugins/instance_code.rb +18 -0
  290. data/lib/spontaneous/plugins/layouts.rb +87 -0
  291. data/lib/spontaneous/plugins/media.rb +41 -0
  292. data/lib/spontaneous/plugins/page/formats.rb +67 -0
  293. data/lib/spontaneous/plugins/page/request.rb +89 -0
  294. data/lib/spontaneous/plugins/page_search.rb +64 -0
  295. data/lib/spontaneous/plugins/page_tree.rb +25 -0
  296. data/lib/spontaneous/plugins/paths.rb +125 -0
  297. data/lib/spontaneous/plugins/permissions.rb +63 -0
  298. data/lib/spontaneous/plugins/prototypes.rb +84 -0
  299. data/lib/spontaneous/plugins/publishing.rb +255 -0
  300. data/lib/spontaneous/plugins/render.rb +24 -0
  301. data/lib/spontaneous/plugins/schema_hierarchy.rb +76 -0
  302. data/lib/spontaneous/plugins/schema_id.rb +60 -0
  303. data/lib/spontaneous/plugins/schema_title.rb +33 -0
  304. data/lib/spontaneous/plugins/serialisation.rb +67 -0
  305. data/lib/spontaneous/plugins/site/instance.rb +22 -0
  306. data/lib/spontaneous/plugins/site/map.rb +19 -0
  307. data/lib/spontaneous/plugins/site/publishing.rb +74 -0
  308. data/lib/spontaneous/plugins/site/revisions.rb +28 -0
  309. data/lib/spontaneous/plugins/site/selectors.rb +41 -0
  310. data/lib/spontaneous/plugins/site_map.rb +34 -0
  311. data/lib/spontaneous/plugins/styles.rb +119 -0
  312. data/lib/spontaneous/plugins/supertype.rb +11 -0
  313. data/lib/spontaneous/plugins/visibility.rb +151 -0
  314. data/lib/spontaneous/plugins.rb +20 -0
  315. data/lib/spontaneous/prototypes/box_prototype.rb +168 -0
  316. data/lib/spontaneous/prototypes/field_prototype.rb +112 -0
  317. data/lib/spontaneous/prototypes/layout_prototype.rb +17 -0
  318. data/lib/spontaneous/prototypes/style_prototype.rb +42 -0
  319. data/lib/spontaneous/proxy_object.rb +12 -0
  320. data/lib/spontaneous/publishing/fire_and_forget.rb +57 -0
  321. data/lib/spontaneous/publishing/immediate.rb +197 -0
  322. data/lib/spontaneous/publishing/threaded.rb +25 -0
  323. data/lib/spontaneous/publishing.rb +10 -0
  324. data/lib/spontaneous/rack/around_back.rb +44 -0
  325. data/lib/spontaneous/rack/around_front.rb +29 -0
  326. data/lib/spontaneous/rack/around_preview.rb +26 -0
  327. data/lib/spontaneous/rack/assets.rb +98 -0
  328. data/lib/spontaneous/rack/back.rb +729 -0
  329. data/lib/spontaneous/rack/front.rb +41 -0
  330. data/lib/spontaneous/rack/http.rb +18 -0
  331. data/lib/spontaneous/rack/media.rb +29 -0
  332. data/lib/spontaneous/rack/public.rb +232 -0
  333. data/lib/spontaneous/rack/reloader.rb +42 -0
  334. data/lib/spontaneous/rack/static.rb +25 -0
  335. data/lib/spontaneous/rack.rb +55 -0
  336. data/lib/spontaneous/render/context.rb +100 -0
  337. data/lib/spontaneous/render/development_renderer.rb +14 -0
  338. data/lib/spontaneous/render/engine.rb +19 -0
  339. data/lib/spontaneous/render/format/html.rb +5 -0
  340. data/lib/spontaneous/render/format.rb +70 -0
  341. data/lib/spontaneous/render/preview_renderer.rb +18 -0
  342. data/lib/spontaneous/render/published_renderer.rb +54 -0
  343. data/lib/spontaneous/render/publishing_renderer.rb +13 -0
  344. data/lib/spontaneous/render/renderer.rb +46 -0
  345. data/lib/spontaneous/render.rb +173 -0
  346. data/lib/spontaneous/revision.rb +7 -0
  347. data/lib/spontaneous/schema/schema_modification.rb +260 -0
  348. data/lib/spontaneous/schema/uid.rb +221 -0
  349. data/lib/spontaneous/schema.rb +295 -0
  350. data/lib/spontaneous/server.rb +65 -0
  351. data/lib/spontaneous/site.rb +87 -0
  352. data/lib/spontaneous/state.rb +53 -0
  353. data/lib/spontaneous/style.rb +144 -0
  354. data/lib/spontaneous/tasks/database.rake +9 -0
  355. data/lib/spontaneous/tasks.rb +5 -0
  356. data/lib/spontaneous/version.rb +6 -0
  357. data/lib/spontaneous.rb +179 -0
  358. data/spontaneous.gemspec.tmpl +66 -0
  359. data/test/disabled/test_slots.rb +287 -0
  360. data/test/experimental/test_formats.rb +92 -0
  361. data/test/experimental/test_plugins.rb +64 -0
  362. data/test/fixtures/application/css/test.less +5 -0
  363. data/test/fixtures/application/js/test.js +1 -0
  364. data/test/fixtures/application/static/favicon.ico +1 -0
  365. data/test/fixtures/application/static/test.html +1 -0
  366. data/test/fixtures/application/views/index.erubis +1 -0
  367. data/test/fixtures/back/public/test.html +1 -0
  368. data/test/fixtures/back/templates/layouts/standard.html.cut +1 -0
  369. data/test/fixtures/config/config/environment.rb +4 -0
  370. data/test/fixtures/config/config/environments/development.rb +13 -0
  371. data/test/fixtures/config/config/environments/production.rb +22 -0
  372. data/test/fixtures/config/config/environments/staging.rb +2 -0
  373. data/test/fixtures/example_application/Gemfile +6 -0
  374. data/test/fixtures/example_application/Gemfile.lock +76 -0
  375. data/test/fixtures/example_application/Rakefile +6 -0
  376. data/test/fixtures/example_application/config/back.rb +15 -0
  377. data/test/fixtures/example_application/config/back.ru +8 -0
  378. data/test/fixtures/example_application/config/back.yml +8 -0
  379. data/test/fixtures/example_application/config/boot.rb +16 -0
  380. data/test/fixtures/example_application/config/database.yml +24 -0
  381. data/test/fixtures/example_application/config/environment.rb +4 -0
  382. data/test/fixtures/example_application/config/environments/development.rb +16 -0
  383. data/test/fixtures/example_application/config/environments/production.rb +21 -0
  384. data/test/fixtures/example_application/config/environments/staging.rb +1 -0
  385. data/test/fixtures/example_application/config/front.rb +8 -0
  386. data/test/fixtures/example_application/config/front.ru +8 -0
  387. data/test/fixtures/example_application/config/front.yml +8 -0
  388. data/test/fixtures/example_application/config/schema.yml +48 -0
  389. data/test/fixtures/example_application/config/unicorn.rb +1 -0
  390. data/test/fixtures/example_application/config/user_levels.yml +19 -0
  391. data/test/fixtures/example_application/public/css/test.css +0 -0
  392. data/test/fixtures/example_application/public/favicon.ico +1 -0
  393. data/test/fixtures/example_application/public/js/test.js +0 -0
  394. data/test/fixtures/example_application/public/test.html +1 -0
  395. data/test/fixtures/example_application/schema/client_project.rb +18 -0
  396. data/test/fixtures/example_application/schema/client_projects.rb +8 -0
  397. data/test/fixtures/example_application/schema/home_page.rb +22 -0
  398. data/test/fixtures/example_application/schema/info_page.rb +13 -0
  399. data/test/fixtures/example_application/schema/inline_image.rb +11 -0
  400. data/test/fixtures/example_application/schema/page.rb +4 -0
  401. data/test/fixtures/example_application/schema/piece.rb +3 -0
  402. data/test/fixtures/example_application/schema/project.rb +21 -0
  403. data/test/fixtures/example_application/schema/project_image.rb +18 -0
  404. data/test/fixtures/example_application/schema/projects_page.rb +12 -0
  405. data/test/fixtures/example_application/schema/text.rb +8 -0
  406. data/test/fixtures/example_application/templates/client_project/images.html.cut +1 -0
  407. data/test/fixtures/example_application/templates/client_project.html.cut +4 -0
  408. data/test/fixtures/example_application/templates/client_projects.html.cut +6 -0
  409. data/test/fixtures/example_application/templates/info_page/inline.html.cut +0 -0
  410. data/test/fixtures/example_application/templates/inline_image.html.cut +1 -0
  411. data/test/fixtures/example_application/templates/layouts/home.html.cut +15 -0
  412. data/test/fixtures/example_application/templates/layouts/info.html.cut +3 -0
  413. data/test/fixtures/example_application/templates/layouts/project.html.cut +13 -0
  414. data/test/fixtures/example_application/templates/layouts/projects.html.cut +11 -0
  415. data/test/fixtures/example_application/templates/layouts/standard.html.cut +0 -0
  416. data/test/fixtures/example_application/templates/project/inline.html.cut +5 -0
  417. data/test/fixtures/example_application/templates/project.html.cut +5 -0
  418. data/test/fixtures/example_application/templates/project_image.html.cut +1 -0
  419. data/test/fixtures/example_application/templates/text.html.cut +1 -0
  420. data/test/fixtures/images/rose.greyscale.jpg +0 -0
  421. data/test/fixtures/images/rose.jpg +0 -0
  422. data/test/fixtures/images/size.gif +0 -0
  423. data/test/fixtures/images/size.jpg +0 -0
  424. data/test/fixtures/images/size.png24 +0 -0
  425. data/test/fixtures/images/size.png8 +0 -0
  426. data/test/fixtures/layouts/layouts/custom1.html.cut +1 -0
  427. data/test/fixtures/layouts/layouts/custom1.pdf.cut +0 -0
  428. data/test/fixtures/layouts/layouts/custom1.xml.cut +0 -0
  429. data/test/fixtures/layouts/layouts/custom2.html.cut +1 -0
  430. data/test/fixtures/layouts/layouts/custom3.html.cut +0 -0
  431. data/test/fixtures/layouts/layouts/standard.html.cut +1 -0
  432. data/test/fixtures/media/101/003/rose.jpg +0 -0
  433. data/test/fixtures/permissions/config/user_levels.yml +9 -0
  434. data/test/fixtures/permissions/media/image.jpg +0 -0
  435. data/test/fixtures/plugins/schema_plugin/init.rb +1 -0
  436. data/test/fixtures/plugins/schema_plugin/schema/external.rb +5 -0
  437. data/test/fixtures/plugins/schema_plugin/templates/external.html.cut +1 -0
  438. data/test/fixtures/plugins/schema_plugin/templates/from_plugin.html.cut +0 -0
  439. data/test/fixtures/plugins/schema_plugin/templates/layouts/from_plugin.html.cut +0 -0
  440. data/test/fixtures/public/templates/layouts/default.html.cut +1 -0
  441. data/test/fixtures/public/templates/layouts/default.pdf.cut +1 -0
  442. data/test/fixtures/public/templates/layouts/default.rss.cut +1 -0
  443. data/test/fixtures/public/templates/layouts/dynamic.html.cut +1 -0
  444. data/test/fixtures/public/templates/layouts/standard.html.cut +0 -0
  445. data/test/fixtures/schema/before.yml +24 -0
  446. data/test/fixtures/schema/resolvable.yml +12 -0
  447. data/test/fixtures/schema/schema.yml +7 -0
  448. data/test/fixtures/serialisation/class_hash.yaml.erb +53 -0
  449. data/test/fixtures/serialisation/root_hash.yaml.erb +184 -0
  450. data/test/fixtures/sharding/rose.jpg +0 -0
  451. data/test/fixtures/sharding/xaa +0 -0
  452. data/test/fixtures/sharding/xab +0 -0
  453. data/test/fixtures/sharding/xac +0 -0
  454. data/test/fixtures/sharding/xad +0 -0
  455. data/test/fixtures/sharding/xae +0 -0
  456. data/test/fixtures/sharding/xaf +0 -0
  457. data/test/fixtures/sharding/xag +0 -0
  458. data/test/fixtures/styles/box_a/runny.html.cut +0 -0
  459. data/test/fixtures/styles/box_a.html.cut +1 -0
  460. data/test/fixtures/styles/named2.html.cut +1 -0
  461. data/test/fixtures/styles/orange/apple.html.cut +1 -0
  462. data/test/fixtures/styles/template_class/named1.html.cut +1 -0
  463. data/test/fixtures/styles/template_class/results.html.cut +1 -0
  464. data/test/fixtures/styles/template_class/walky.html.cut +0 -0
  465. data/test/fixtures/styles/template_class.epub.cut +0 -0
  466. data/test/fixtures/styles/template_class.html.cut +1 -0
  467. data/test/fixtures/styles/template_class.pdf.cut +0 -0
  468. data/test/fixtures/styles/template_sub_class1.html.cut +1 -0
  469. data/test/fixtures/templates/aliases/a/a_style.html.cut +0 -0
  470. data/test/fixtures/templates/aliases/a/page.html.cut +0 -0
  471. data/test/fixtures/templates/aliases/a_alias/a_alias_style.html.cut +0 -0
  472. data/test/fixtures/templates/aliases/layouts/b.html.cut +1 -0
  473. data/test/fixtures/templates/aliases/layouts/b_alias.html.cut +1 -0
  474. data/test/fixtures/templates/aliases/layouts/c_alias.html.cut +1 -0
  475. data/test/fixtures/templates/boxes/blank_content/things.html.cut +1 -0
  476. data/test/fixtures/templates/boxes/my_box_class/christy.html.cut +1 -0
  477. data/test/fixtures/templates/boxes/thangs.html.cut +1 -0
  478. data/test/fixtures/templates/boxes/with_template_box.html.cut +1 -0
  479. data/test/fixtures/templates/content/include.html.cut +1 -0
  480. data/test/fixtures/templates/content/include_dir.html.cut +1 -0
  481. data/test/fixtures/templates/content/included.epub.cut +1 -0
  482. data/test/fixtures/templates/content/included.html.cut +1 -0
  483. data/test/fixtures/templates/content/partial/included.html.cut +1 -0
  484. data/test/fixtures/templates/content/preprocess.html.cut +1 -0
  485. data/test/fixtures/templates/content/second.html.cut +1 -0
  486. data/test/fixtures/templates/content/template.epub.cut +1 -0
  487. data/test/fixtures/templates/content/template.html.cut +1 -0
  488. data/test/fixtures/templates/default_style_class.html.cut +1 -0
  489. data/test/fixtures/templates/direct.html.cut +1 -0
  490. data/test/fixtures/templates/extended/grandparent.html.cut +10 -0
  491. data/test/fixtures/templates/extended/main.html.cut +6 -0
  492. data/test/fixtures/templates/extended/parent.html.cut +10 -0
  493. data/test/fixtures/templates/layouts/entries.html.cut +7 -0
  494. data/test/fixtures/templates/layouts/page_style.html.cut +1 -0
  495. data/test/fixtures/templates/layouts/params.html.cut +1 -0
  496. data/test/fixtures/templates/layouts/preview_render.html.cut +2 -0
  497. data/test/fixtures/templates/layouts/standard_page.html.cut +1 -0
  498. data/test/fixtures/templates/layouts/subdir_style.html.cut +1 -0
  499. data/test/fixtures/templates/layouts/template_params.html.cut +1 -0
  500. data/test/fixtures/templates/page_class/inline_style.html.cut +1 -0
  501. data/test/fixtures/templates/preview_render/inline.html.cut +0 -0
  502. data/test/fixtures/templates/publishing/layouts/dynamic.html.cut +1 -0
  503. data/test/fixtures/templates/publishing/layouts/static.html.cut +1 -0
  504. data/test/fixtures/templates/template_class/anonymous_style.html.cut +4 -0
  505. data/test/fixtures/templates/template_class/another_template.html.cut +0 -0
  506. data/test/fixtures/templates/template_class/complex_template.html.cut +6 -0
  507. data/test/fixtures/templates/template_class/complex_template.pdf.cut +6 -0
  508. data/test/fixtures/templates/template_class/default_template_style.html.cut +4 -0
  509. data/test/fixtures/templates/template_class/images_with_template.html.cut +5 -0
  510. data/test/fixtures/templates/template_class/slots_template.html.cut +5 -0
  511. data/test/fixtures/templates/template_class/slots_template.pdf.cut +5 -0
  512. data/test/fixtures/templates/template_class/this_template.epub.cut +1 -0
  513. data/test/fixtures/templates/template_class/this_template.html.cut +1 -0
  514. data/test/fixtures/templates/template_class/this_template.pdf.cut +1 -0
  515. data/test/fixtures/templates/with_default_style_class.html.cut +1 -0
  516. data/test/functional/test_application.rb +176 -0
  517. data/test/functional/test_back.rb +902 -0
  518. data/test/functional/test_front.rb +571 -0
  519. data/test/javascript/test_dom.rb +94 -0
  520. data/test/javascript/test_markdown.rb +97 -0
  521. data/test/slow/test_publishing.rb +987 -0
  522. data/test/slow/test_visibility.rb +250 -0
  523. data/test/support/custom_matchers.rb +77 -0
  524. data/test/support/timing.rb +23 -0
  525. data/test/test_helper.rb +164 -0
  526. data/test/test_javascript.rb +34 -0
  527. data/test/ui/test_page_editing.rb +167 -0
  528. data/test/ui_helper.rb +114 -0
  529. data/test/unit/test_alias.rb +254 -0
  530. data/test/unit/test_authentication.rb +510 -0
  531. data/test/unit/test_boxes.rb +497 -0
  532. data/test/unit/test_config.rb +156 -0
  533. data/test/unit/test_content.rb +221 -0
  534. data/test/unit/test_content_inheritance.rb +103 -0
  535. data/test/unit/test_extensions.rb +14 -0
  536. data/test/unit/test_fields.rb +392 -0
  537. data/test/unit/test_generators.rb +97 -0
  538. data/test/unit/test_image_size.rb +25 -0
  539. data/test/unit/test_images.rb +265 -0
  540. data/test/unit/test_layouts.rb +111 -0
  541. data/test/unit/test_logger.rb +80 -0
  542. data/test/unit/test_media.rb +70 -0
  543. data/test/unit/test_page.rb +244 -0
  544. data/test/unit/test_permissions.rb +834 -0
  545. data/test/unit/test_piece.rb +80 -0
  546. data/test/unit/test_prototype_set.rb +192 -0
  547. data/test/unit/test_prototypes.rb +102 -0
  548. data/test/unit/test_render.rb +359 -0
  549. data/test/unit/test_schema.rb +1009 -0
  550. data/test/unit/test_serialisation.rb +215 -0
  551. data/test/unit/test_site.rb +145 -0
  552. data/test/unit/test_structure.rb +85 -0
  553. data/test/unit/test_styles.rb +417 -0
  554. data/test/unit/test_templates.rb +224 -0
  555. data/test/unit/test_type_hierarchy.rb +28 -0
  556. metadata +1017 -0
@@ -0,0 +1,193 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins
4
+ module Entries
5
+
6
+ def self.configure(base)
7
+ base.__send__(:alias_method, :<<, :push)
8
+ end
9
+
10
+ module InstanceMethods
11
+ CONTENT_PATH_SEP = ".".freeze
12
+
13
+ # because it's possible to build content out of order
14
+ # some relations don't necessarily get created straight away
15
+ def before_save
16
+ if container
17
+ self.page = container.page if page.nil?
18
+ if page?
19
+ self.depth = parent ? ((parent.depth || 0) + 1) : 0
20
+ else
21
+ self.depth = (container.content_depth || 0) + 1
22
+ end
23
+ end
24
+ super
25
+ end
26
+
27
+ def after_save
28
+ pieces.each do |entry|
29
+ entry.save if entry.modified?
30
+ end
31
+ super
32
+ end
33
+
34
+ def destroy(remove_container_entry=true, container=nil)
35
+ container ||= self.container
36
+ if container && remove_container_entry
37
+ container.destroy_entry!(self)
38
+ end
39
+ super()
40
+ end
41
+
42
+ def before_destroy
43
+ recursive_destroy
44
+ super
45
+ end
46
+
47
+ def recursive_destroy
48
+ all_pieces.destroy
49
+ end
50
+
51
+ def destroy_entry!(entry)
52
+ pieces.remove(entry)
53
+ # save the container because it won't be obvious to the caller
54
+ # that content other than the destroyed object will have been
55
+ # modified
56
+ self.save
57
+ end
58
+
59
+ def content_depth
60
+ depth
61
+ end
62
+
63
+ def entry_modified!(modified_entry)
64
+ self.entry_store = all_pieces.serialize_db
65
+ end
66
+
67
+ def pieces
68
+ if Spontaneous::Content.visible_only?
69
+ visible_pieces
70
+ else
71
+ all_pieces
72
+ end
73
+ end
74
+
75
+ # ensure that all access to pieces is through their corresponding entry
76
+ # alias_method :pieces, :entries
77
+
78
+ def all_pieces
79
+ @all_pieces ||= Spontaneous::Collections::EntrySet.new(self, entry_store)
80
+ end
81
+
82
+ def visible_pieces
83
+ @visible_pieces ||= all_pieces.visible!
84
+ end
85
+
86
+ protected(:all_pieces, :visible_pieces)
87
+
88
+ def reload
89
+ @all_pieces = @visible_pieces = nil
90
+ super
91
+ end
92
+
93
+
94
+ def first
95
+ pieces.first
96
+ end
97
+
98
+ def last
99
+ pieces.last
100
+ end
101
+
102
+ def push(page_or_piece)
103
+ insert(-1, page_or_piece)
104
+ end
105
+
106
+ def insert(index, page_or_piece, box = nil)
107
+ save if new?
108
+ if page_or_piece.page?
109
+ insert_page(index, page_or_piece, box)
110
+ else
111
+ insert_piece(index, page_or_piece, box)
112
+ end
113
+ end
114
+
115
+
116
+ def insert_page(index, child_page, box = nil)
117
+ child_page.container = self
118
+ if page
119
+ child_page.depth = page.depth + 1
120
+ page.children << child_page
121
+ child_page.parent = page
122
+ child_page.update_path
123
+ end
124
+ insert_with_style(:page, index, child_page, box)
125
+ end
126
+
127
+ def insert_piece(index, piece, box = nil)
128
+ piece.container = self
129
+ piece.page = page if page
130
+ piece.depth = (content_depth || 0) + 1
131
+ insert_with_style(:piece, index, piece, box)
132
+ end
133
+
134
+ def insert_with_style(type, index, content, box = nil)
135
+ self._pieces << content
136
+ entry_style = style_for_content(content, box)
137
+ content.box_sid = box.schema_id if box
138
+ content._prototype = box.prototype_for_content(content) if box
139
+ content.save if content.new?
140
+ entry = \
141
+ case type
142
+ when :page
143
+ Spontaneous::PagePiece.new(self, content, entry_style ? entry_style.schema_id : nil)
144
+ when :piece
145
+ content.style = entry_style
146
+ content
147
+ end
148
+ begin
149
+ pieces.insert(index, entry)
150
+ rescue TypeError, RuntimeError => e
151
+ # TODO: raise a custom more helpful error here
152
+ logger.error { "Attempting to modify visible only pieces" }
153
+ raise e
154
+ end
155
+
156
+ entry
157
+ end
158
+
159
+ def update_position(position)
160
+ entry.set_position(position)
161
+ container.save
162
+ end
163
+
164
+ def set_position(new_position)
165
+ if box
166
+ box.set_position(self, new_position)
167
+ else
168
+ container.pieces.set_position(self, new_position)
169
+ end
170
+ end
171
+
172
+ def style_for_content(content, box = nil)
173
+ if box
174
+ box.style_for_content(content)
175
+
176
+ else
177
+ content.default_style
178
+ end
179
+ end
180
+
181
+ def available_styles(content)
182
+ content.class.styles
183
+ end
184
+
185
+ def container=(container)
186
+ super
187
+ self[:content_path] = [container.content_path, container.id].compact.join(CONTENT_PATH_SEP)
188
+ end
189
+
190
+ end # InstanceMethods
191
+ end # Entries
192
+ end # Spontaneous::Plugins
193
+
@@ -0,0 +1,51 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins
4
+ module Entry
5
+ module InstanceMethods
6
+
7
+ # kept to allow access to pages & pieces as they would be seen when
8
+ # accessed as an entry in a box
9
+ def entry
10
+ self
11
+ end
12
+
13
+ def box_sid
14
+ @box_sid ||= Spot::Schema::UID[self[:box_sid]]
15
+ end
16
+
17
+ def box_sid=(sid)
18
+ self[:box_sid] = sid.to_s
19
+ end
20
+
21
+ def box
22
+ container.boxes.sid(box_sid) if container
23
+ end
24
+
25
+ def first?
26
+ container.pieces.first == self
27
+ end
28
+
29
+ def last?
30
+ container.pieces.last == self
31
+ end
32
+
33
+ def set_position(new_position)
34
+ if box
35
+ box.set_position(self, new_position)
36
+ else
37
+ container.pieces.set_position(self, new_position)
38
+ end
39
+ end
40
+
41
+ def position
42
+ container.pieces.index(self)
43
+ end
44
+
45
+ def serialize_db
46
+ [self.id]
47
+ end
48
+ end # InstanceMethods
49
+ end # Entry
50
+ end # Spontaneous::Plugins
51
+
@@ -0,0 +1,103 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins
4
+ module Fields
5
+ module ClassMethods
6
+ def field(name, type=nil, options={}, &block)
7
+ if type.is_a?(Hash)
8
+ options = type
9
+ type = nil
10
+ end
11
+
12
+ prototype = Spontaneous::Prototypes::FieldPrototype.new(self, name, type, options, &block)
13
+ field_prototypes[name] = prototype
14
+ unless method_defined?(name)
15
+ define_method(name) do |*args|
16
+ fields[name].tap { |f| f.template_params = args }
17
+ end
18
+ else
19
+ # raise "Must give warning when field name clashes with method name #{name}"
20
+ end
21
+
22
+ setter = "#{name}=".to_sym
23
+ unless method_defined?(setter)
24
+ define_method(setter) { |value| fields[name].value = value }
25
+ else
26
+ # raise "Must give warning when field name clashes with method name"
27
+ end
28
+ prototype
29
+ end
30
+
31
+ def field_prototypes
32
+ @field_prototypes ||= Spontaneous::Collections::PrototypeSet.new(supertype, :field_prototypes)
33
+ end
34
+
35
+ def field_names
36
+ field_prototypes.order
37
+ end
38
+
39
+ def fields
40
+ field_prototypes
41
+ end
42
+
43
+ def field_order(*new_order)
44
+ field_prototypes.order = new_order.flatten if new_order and !new_order.empty?
45
+ end
46
+
47
+ def field?(field_name)
48
+ field_prototypes.key?(field_name)
49
+ end
50
+
51
+ def field_for_mime_type(mime_type)
52
+ fields.find do |prototype|
53
+ prototype.field_class.accepts?(mime_type)
54
+ end
55
+ end
56
+
57
+ def readable_fields
58
+ field_prototypes.keys.select { |name| field_readable?(name) }
59
+ end
60
+ end
61
+
62
+ module InstanceMethods
63
+ def after_save
64
+ super
65
+ fields.saved
66
+ end
67
+
68
+ def reload
69
+ @field_set = nil
70
+ super
71
+ end
72
+
73
+ def field_prototypes
74
+ self.class.field_prototypes
75
+ end
76
+
77
+ def fields
78
+ @field_set ||= Spontaneous::Collections::FieldSet.new(self, field_store)
79
+ end
80
+
81
+ def field?(field_name)
82
+ self.class.field?(field_name)
83
+ end
84
+
85
+ # TODO: unify the update mechanism for these two stores
86
+ def field_modified!(modified_field)
87
+ self.field_store = @field_set.serialize_db
88
+ end
89
+
90
+ def type_for_mime_type(mime_type)
91
+ self.class.allowed_types.find do |t|
92
+ t.field_for_mime_type(mime_type)
93
+ end
94
+ end
95
+
96
+ def field_for_mime_type(mime_type)
97
+ prototype = self.class.field_for_mime_type(mime_type)
98
+ self.fields[prototype.name]
99
+ end
100
+ end
101
+ end
102
+ end
103
+
@@ -0,0 +1,18 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins
4
+ module InstanceCode
5
+
6
+ module InstanceMethods
7
+ def after_initialize
8
+ super
9
+ mixin_instance_code
10
+ end
11
+
12
+ def mixin_instance_code
13
+ self.instance_eval(self.instance_code) unless self.instance_code.nil?
14
+ end
15
+ end
16
+ end
17
+ end
18
+
@@ -0,0 +1,87 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins
4
+ module Layouts
5
+ module ClassMethods
6
+ def layout(name, options={})
7
+ layout_prototypes[name] = Spontaneous::Prototypes::LayoutPrototype.new(self, name, options)
8
+ end
9
+
10
+ def layout_prototypes
11
+ @layout_prototypes ||= Spontaneous::Collections::PrototypeSet.new(supertype, :layout_prototypes)
12
+ end
13
+
14
+ alias_method :layouts, :layout_prototypes
15
+
16
+ def resolve_layout(layout_sid)
17
+ if layout_sid.nil? #layout_name.blank?
18
+ default_layout
19
+ else
20
+ find_layout(layout_sid)
21
+ end
22
+ end
23
+
24
+ def default_layout
25
+ if prototype = (layouts.detect { |prototype| prototype.default? } || layouts.first)
26
+ prototype.layout(self)
27
+ else
28
+ Spontaneous::Layout::Default.new(self)
29
+ end
30
+ end
31
+
32
+ def find_layout(layout_sid)
33
+ if prototype = layout_prototypes.sid(layout_sid)
34
+ prototype.layout(self)
35
+ end
36
+ end
37
+
38
+ def find_named_layout(layout_name)
39
+ layout_prototypes[layout_name.to_sym]
40
+ end
41
+ end # ClassMethods
42
+
43
+ module InstanceMethods
44
+ def layout
45
+ resolve_layout(self.style_sid)
46
+ end
47
+
48
+ def resolve_layout(style_sid)
49
+ self.class.resolve_layout(style_sid)
50
+ end
51
+
52
+ def layout=(layout)
53
+ self.style_sid = layout_to_schema_id(layout)
54
+ end
55
+
56
+ def layout_to_schema_id(layout)
57
+ sid = nil
58
+ if layout.respond_to?(:schema_id)
59
+ sid = layout.schema_id
60
+ else
61
+ if Spontaneous::Schema::UID === layout
62
+ sid = layout
63
+ else
64
+ if s = self.find_named_layout(layout)
65
+ sid = s.schema_id
66
+ end
67
+ end
68
+ end
69
+ sid
70
+ end
71
+
72
+ def find_named_layout(layout_name)
73
+ self.class.find_named_layout(layout_name)
74
+ end
75
+
76
+ def template(format = :html)
77
+ layout.template(format)
78
+ end
79
+
80
+ # def provides_format?(format)
81
+ # format = (format || :html).to_sym
82
+ # self.formats.include?(format)
83
+ # end
84
+ end # InstanceMethods
85
+ end # Layouts
86
+ end # Spontaneous::Plugins
87
+
@@ -0,0 +1,41 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins
4
+ module Media
5
+ module ClassMethods
6
+ end
7
+
8
+ module InstanceMethods
9
+ def media_filepath(*args)
10
+ File.join(Spontaneous.media_dir, padded_id, padded_revision, *args)
11
+ end
12
+
13
+ def media_urlpath(*args)
14
+ File.join("/media", padded_id, padded_revision, *args)
15
+ end
16
+
17
+ def padded_id
18
+ save if media_id.nil?
19
+ media_id.to_s.rjust(5, "0")
20
+ end
21
+
22
+ def media_id
23
+ id
24
+ end
25
+
26
+ def padded_revision
27
+ Spontaneous::Site.working_revision.to_s.rjust(4, "0")
28
+ end
29
+
30
+ def make_media_file(src_file, filename = nil)
31
+ filename ||= File.basename(src_file)
32
+ filename = Spontaneous::Media.to_filename(filename)
33
+ media_filepath = media_filepath(filename)
34
+ FileUtils.mkdir_p(File.dirname(media_filepath))
35
+ FileUtils.cp(src_file, media_filepath)
36
+ media_filepath
37
+ end
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,67 @@
1
+ # encoding: UTF-8
2
+
3
+
4
+ module Spontaneous::Plugins::Page
5
+ module Formats
6
+ module ClassMethods
7
+ def formats(*formats)
8
+ @formats ||= [:html]
9
+ return @formats if formats.nil? or formats.empty?
10
+ set_formats(formats)
11
+ end
12
+
13
+ def set_formats(formats)
14
+ @mime_types = {}
15
+ formats = formats.flatten
16
+ mime_type = nil
17
+ @formats = formats.map do |format|
18
+ if format.is_a?(Hash)
19
+ mime_type = format.values.first
20
+ format = format.keys.first
21
+ @mime_types[format.to_sym] = mime_type
22
+ else
23
+ mime_type = ::Rack::Mime.mime_type("#{Spontaneous::DOT}#{format}", nil)
24
+ end
25
+ raise Spontaneous::UnknownFormatException.new(format) unless mime_type
26
+ format.to_sym
27
+ end
28
+ end
29
+
30
+ def default_format
31
+ formats.first
32
+ end
33
+
34
+ def provides_format?(format)
35
+ format = (format || :html).to_sym
36
+ formats.include?(format)
37
+ end
38
+
39
+ def mime_type(format)
40
+ if @mime_types && @mime_types.key?(format)
41
+ @mime_types[format]
42
+ else
43
+ ::Rack::Mime.mime_type("#{Spontaneous::DOT}#{format}")
44
+ end
45
+ end
46
+ end
47
+
48
+ module InstanceMethods
49
+ def formats
50
+ self.class.formats
51
+ end
52
+
53
+ def default_format
54
+ self.class.default_format
55
+ end
56
+
57
+ def provides_format?(format)
58
+ self.class.provides_format?(format)
59
+ end
60
+
61
+ def mime_type(format)
62
+ self.class.mime_type(format)
63
+ end
64
+ end
65
+ end # Formats
66
+ end # Spontaneous::Plugins::Page
67
+
@@ -0,0 +1,89 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins::Page
4
+ module Request
5
+ # liked this but it didn't work particularly well so wasn't used in the end
6
+ # perhaps, when I re-write the bloody Public handler i can use it
7
+ class PageResponse
8
+ attr_reader :page, :format, :request, :response
9
+
10
+ def initialize(page, request, response, format)
11
+ @page, @request, @response, @format = page, request, response, format
12
+ end
13
+
14
+ def headers(hash=nil)
15
+ response.headers.merge! hash if hash
16
+ response.headers
17
+ end
18
+
19
+ def session; request.session; end
20
+ def params; request.params; end
21
+
22
+
23
+
24
+ def call(&block)
25
+ response = catch(:halt) { instance_eval(&block) }
26
+ case response
27
+ when String
28
+ [200, Spontaneous::Site[response]]
29
+ when (100..599) === response
30
+ [response, page]
31
+ else
32
+ response
33
+ end
34
+ end
35
+
36
+ REDIRECTS = {
37
+ :permanent => 301,
38
+ :temporary => 302
39
+ }
40
+
41
+ def redirect(redirection, redirect_code=:temporary)
42
+ redirection = Spontaneous::Site[redirection] if String === redirection
43
+ redirect_code = REDIRECTS[redirect_code] if Symbol === redirect_code
44
+ redirect_code ||= REDIRECTS[:temporary]
45
+ throw(:halt, [redirect_code, redirection])
46
+ end
47
+
48
+ def show(page, status_code = 200)
49
+ page = Spontaneous::Site[page] if String === page
50
+ throw(:halt, [status_code, page])
51
+ end
52
+ end
53
+
54
+
55
+ module ClassMethods
56
+ def request(method = :get, &block)
57
+ request_blocks[method.to_sym] = block
58
+ end
59
+
60
+ def request_blocks
61
+ @request_blocks ||= {}
62
+ end
63
+
64
+ # unused at present
65
+ def _request_response(instance, request, response, format)
66
+ method = request.request_method.downcase.to_sym
67
+ if (block = request_blocks[method])
68
+ app = PageResponse.new(instance, request, response, format)
69
+ app.call(&block)
70
+ else
71
+ nil
72
+ end
73
+ end
74
+ end # ClassMethods
75
+
76
+
77
+ module InstanceMethods
78
+ def request_block(request)
79
+ method = request.request_method.downcase.to_sym
80
+ self.class.request_blocks[method]
81
+ end
82
+
83
+ def is_dynamic?
84
+ self.class.request_blocks.key?(:get)
85
+ end
86
+ end
87
+ end # Request
88
+ end
89
+
@@ -0,0 +1,64 @@
1
+ # encoding: UTF-8
2
+
3
+ module Spontaneous::Plugins
4
+ module PageSearch
5
+ module ClassMethods
6
+ def root
7
+ first_visible(:path => Spontaneous::SLASH)
8
+ end
9
+
10
+ def uid(uid)
11
+ first_visible(:uid => uid)
12
+ end
13
+
14
+ def path(path)
15
+ page = first_visible(:path => path)
16
+ page = aliased_path(path) if page.nil?
17
+ page
18
+ end
19
+
20
+ def first_visible(params)
21
+ page = Spontaneous::Content.first(params)
22
+ # don't want to return nil if a page matching the params exists but is hidden
23
+ # if we return blank we force searches via other routes (such as aliased pages)
24
+ if page and Spontaneous::Content.visible_only? and page.hidden?
25
+ return false
26
+ end
27
+ page
28
+ end
29
+
30
+ def aliased_path(path)
31
+ @_ps ||= Hash.new { |h, k| h[k] = prepare_aliased_path_query(k) }
32
+ p = path.split(S::SLASH)
33
+ root = p[0..-2].join(S::SLASH)
34
+ visible = Spontaneous::Content.visible_only?
35
+ @_ps[visible].call(:root => root, :slug => p.last)
36
+ end
37
+
38
+ protected
39
+
40
+ def prepare_aliased_path_query(visible_only=false)
41
+ # select c2.*
42
+ # from content as c1, content as c2, content as c3 \
43
+ # where c1.path = '/aliases'
44
+ # and c2.parent_id = c1.id
45
+ # and c2.target_id = c3.id
46
+ # and c3.slug = 'b';
47
+ params = {
48
+ :c1__path => :$root,
49
+ :c2__parent_id => :c1__id,
50
+ :c2__target_id => :c3__id,
51
+ :c3__slug => :$slug
52
+ }
53
+ params.merge!(:c3__hidden => false) if visible_only
54
+
55
+ query = S::Content._unfiltered_dataset.select(Sequel::LiteralString.new("c2.*")).from(:content___c1, :content___c2, :content___c3).where(params)
56
+ query.prepare(:first)
57
+ end
58
+ end
59
+
60
+ # module InstanceMethods
61
+ # end
62
+ end
63
+ end
64
+