alchemy_cms 2.0.pre2

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 (489) hide show
  1. data/.gitignore +7 -0
  2. data/.yardopts +6 -0
  3. data/Gemfile +8 -0
  4. data/LICENSE +619 -0
  5. data/README.md +113 -0
  6. data/Rakefile +30 -0
  7. data/TODO.txt +1 -0
  8. data/alchemy.gemspec +36 -0
  9. data/app/controllers/admin/attachments_controller.rb +119 -0
  10. data/app/controllers/admin/clipboard_controller.rb +43 -0
  11. data/app/controllers/admin/contents_controller.rb +69 -0
  12. data/app/controllers/admin/elements_controller.rb +137 -0
  13. data/app/controllers/admin/essence_audios_controller.rb +14 -0
  14. data/app/controllers/admin/essence_files_controller.rb +35 -0
  15. data/app/controllers/admin/essence_flashes_controller.rb +14 -0
  16. data/app/controllers/admin/essence_pictures_controller.rb +89 -0
  17. data/app/controllers/admin/essence_videos_controller.rb +14 -0
  18. data/app/controllers/admin/languages_controller.rb +70 -0
  19. data/app/controllers/admin/layoutpages_controller.rb +11 -0
  20. data/app/controllers/admin/pages_controller.rb +244 -0
  21. data/app/controllers/admin/pictures_controller.rb +132 -0
  22. data/app/controllers/admin/trash_controller.rb +25 -0
  23. data/app/controllers/admin/users_controller.rb +75 -0
  24. data/app/controllers/admin_controller.rb +78 -0
  25. data/app/controllers/alchemy_controller.rb +239 -0
  26. data/app/controllers/attachments_controller.rb +30 -0
  27. data/app/controllers/elements_controller.rb +18 -0
  28. data/app/controllers/messages_controller.rb +98 -0
  29. data/app/controllers/pages_controller.rb +137 -0
  30. data/app/controllers/pictures_controller.rb +68 -0
  31. data/app/helpers/admin/attachments_helper.rb +7 -0
  32. data/app/helpers/admin/elements_helper.rb +28 -0
  33. data/app/helpers/admin/pages_helper.rb +3 -0
  34. data/app/helpers/admin/pictures_helper.rb +26 -0
  35. data/app/helpers/alchemy_helper.rb +1168 -0
  36. data/app/helpers/elements_helper.rb +2 -0
  37. data/app/helpers/errors_helper.rb +37 -0
  38. data/app/helpers/layout_helper.rb +37 -0
  39. data/app/helpers/pages_helper.rb +141 -0
  40. data/app/mailers/messages.rb +15 -0
  41. data/app/mailers/notifications.rb +23 -0
  42. data/app/models/attachment.rb +73 -0
  43. data/app/models/cell.rb +63 -0
  44. data/app/models/content.rb +145 -0
  45. data/app/models/element.rb +423 -0
  46. data/app/models/essence_audio.rb +17 -0
  47. data/app/models/essence_date.rb +20 -0
  48. data/app/models/essence_file.rb +17 -0
  49. data/app/models/essence_flash.rb +15 -0
  50. data/app/models/essence_html.rb +19 -0
  51. data/app/models/essence_picture.rb +27 -0
  52. data/app/models/essence_richtext.rb +50 -0
  53. data/app/models/essence_text.rb +28 -0
  54. data/app/models/essence_video.rb +17 -0
  55. data/app/models/folded_page.rb +3 -0
  56. data/app/models/language.rb +75 -0
  57. data/app/models/message.rb +57 -0
  58. data/app/models/page.rb +501 -0
  59. data/app/models/picture.rb +100 -0
  60. data/app/models/user.rb +72 -0
  61. data/app/models/user_session.rb +10 -0
  62. data/app/sweepers/content_sweeper.rb +20 -0
  63. data/app/sweepers/pages_sweeper.rb +46 -0
  64. data/app/sweepers/pictures_sweeper.rb +20 -0
  65. data/app/views/_contact.html.erb +3 -0
  66. data/app/views/_intro.html.erb +3 -0
  67. data/app/views/_news.html.erb +3 -0
  68. data/app/views/_newsletter_layout.html.erb +1 -0
  69. data/app/views/_search.html.erb +3 -0
  70. data/app/views/_standard.html.erb +1 -0
  71. data/app/views/admin/attachments/_attachment.html.erb +58 -0
  72. data/app/views/admin/attachments/_file_to_assign.html.erb +20 -0
  73. data/app/views/admin/attachments/_files_list.html.erb +24 -0
  74. data/app/views/admin/attachments/archive_overlay.html.erb +8 -0
  75. data/app/views/admin/attachments/create.js.erb +6 -0
  76. data/app/views/admin/attachments/edit.html.erb +12 -0
  77. data/app/views/admin/attachments/index.html.erb +30 -0
  78. data/app/views/admin/attachments/new.html.erb +11 -0
  79. data/app/views/admin/clipboard/clear.js.erb +6 -0
  80. data/app/views/admin/clipboard/index.html.erb +19 -0
  81. data/app/views/admin/clipboard/insert.js.erb +14 -0
  82. data/app/views/admin/clipboard/remove.js.erb +10 -0
  83. data/app/views/admin/contents/_missing.html.erb +20 -0
  84. data/app/views/admin/contents/create.js.erb +93 -0
  85. data/app/views/admin/contents/new.html.erb +15 -0
  86. data/app/views/admin/elements/_add_content.html.erb +16 -0
  87. data/app/views/admin/elements/_element.html.erb +22 -0
  88. data/app/views/admin/elements/_element_foot.html.erb +35 -0
  89. data/app/views/admin/elements/_element_head.html.erb +29 -0
  90. data/app/views/admin/elements/_elements_select.html.erb +8 -0
  91. data/app/views/admin/elements/_new_element_form.html.erb +25 -0
  92. data/app/views/admin/elements/_picture_editor.html.erb +25 -0
  93. data/app/views/admin/elements/create.js.erb +20 -0
  94. data/app/views/admin/elements/destroy.js.erb +6 -0
  95. data/app/views/admin/elements/fold.js.erb +37 -0
  96. data/app/views/admin/elements/index.html.erb +33 -0
  97. data/app/views/admin/elements/list.js.erb +20 -0
  98. data/app/views/admin/elements/new.html.erb +33 -0
  99. data/app/views/admin/elements/order.js.erb +7 -0
  100. data/app/views/admin/elements/trash.js.erb +13 -0
  101. data/app/views/admin/elements/update.js.erb +10 -0
  102. data/app/views/admin/essence_files/edit.html.erb +91 -0
  103. data/app/views/admin/essence_pictures/assign.js.erb +15 -0
  104. data/app/views/admin/essence_pictures/crop.html.erb +36 -0
  105. data/app/views/admin/essence_pictures/destroy.js.erb +17 -0
  106. data/app/views/admin/essence_pictures/edit.html.erb +75 -0
  107. data/app/views/admin/essence_pictures/update.js.erb +16 -0
  108. data/app/views/admin/index.html.erb +92 -0
  109. data/app/views/admin/infos.html.erb +5 -0
  110. data/app/views/admin/languages/_form.html.erb +34 -0
  111. data/app/views/admin/languages/_language.html.erb +35 -0
  112. data/app/views/admin/languages/edit.html.erb +1 -0
  113. data/app/views/admin/languages/index.html.erb +41 -0
  114. data/app/views/admin/languages/new.html.erb +1 -0
  115. data/app/views/admin/layoutpages/_layoutpage.html.erb +80 -0
  116. data/app/views/admin/layoutpages/index.html.erb +75 -0
  117. data/app/views/admin/leave.html.erb +11 -0
  118. data/app/views/admin/login.html.erb +46 -0
  119. data/app/views/admin/logout.html.erb +5 -0
  120. data/app/views/admin/pages/_contactform_links.html.erb +66 -0
  121. data/app/views/admin/pages/_create_language_form.html.erb +42 -0
  122. data/app/views/admin/pages/_external_link.html.erb +54 -0
  123. data/app/views/admin/pages/_file_link.html.erb +52 -0
  124. data/app/views/admin/pages/_internal_link.html.erb +47 -0
  125. data/app/views/admin/pages/_new_page_form.html.erb +29 -0
  126. data/app/views/admin/pages/_page.html.erb +114 -0
  127. data/app/views/admin/pages/_page_for_links.html.erb +43 -0
  128. data/app/views/admin/pages/_page_infos.html.erb +3 -0
  129. data/app/views/admin/pages/_page_status.html.erb +9 -0
  130. data/app/views/admin/pages/_sitemap.html.erb +99 -0
  131. data/app/views/admin/pages/configure.html.erb +71 -0
  132. data/app/views/admin/pages/configure_external.html.erb +40 -0
  133. data/app/views/admin/pages/destroy.js.erb +12 -0
  134. data/app/views/admin/pages/edit.html.erb +185 -0
  135. data/app/views/admin/pages/flush.js.erb +2 -0
  136. data/app/views/admin/pages/fold.js.erb +4 -0
  137. data/app/views/admin/pages/index.html.erb +108 -0
  138. data/app/views/admin/pages/link.html.erb +30 -0
  139. data/app/views/admin/pages/locked.html.erb +3 -0
  140. data/app/views/admin/pages/new.html.erb +50 -0
  141. data/app/views/admin/pages/show.html.erb +1 -0
  142. data/app/views/admin/pages/sort.js.erb +6 -0
  143. data/app/views/admin/pages/unlock.js.erb +8 -0
  144. data/app/views/admin/pages/update.js.erb +19 -0
  145. data/app/views/admin/partials/_flash.html.erb +4 -0
  146. data/app/views/admin/partials/_flash_notices.html.erb +5 -0
  147. data/app/views/admin/partials/_mainnavigation_entry.html.erb +27 -0
  148. data/app/views/admin/partials/_pagination_links.html.erb +7 -0
  149. data/app/views/admin/partials/_per_page_links.html.erb +17 -0
  150. data/app/views/admin/partials/_remote_pagination_links.html.erb +11 -0
  151. data/app/views/admin/partials/_remote_search_form.html.erb +36 -0
  152. data/app/views/admin/partials/_search_form.html.erb +17 -0
  153. data/app/views/admin/partials/_sub_navigation.html.erb +14 -0
  154. data/app/views/admin/partials/_upload_form.html.erb +116 -0
  155. data/app/views/admin/pictures/_archive_overlay_images.html.erb +17 -0
  156. data/app/views/admin/pictures/_filter_and_size_bar.html.erb +88 -0
  157. data/app/views/admin/pictures/_picture.html.erb +36 -0
  158. data/app/views/admin/pictures/_picture_to_assign.html.erb +32 -0
  159. data/app/views/admin/pictures/_pictures_list.html.erb +12 -0
  160. data/app/views/admin/pictures/archive_overlay.html.erb +3 -0
  161. data/app/views/admin/pictures/create.js.erb +12 -0
  162. data/app/views/admin/pictures/index.html.erb +56 -0
  163. data/app/views/admin/pictures/new.html.erb +11 -0
  164. data/app/views/admin/pictures/show_in_window.html.erb +1 -0
  165. data/app/views/admin/pictures/update.js.erb +11 -0
  166. data/app/views/admin/signup.html.erb +16 -0
  167. data/app/views/admin/trash/index.html.erb +25 -0
  168. data/app/views/admin/users/_table.html.erb +54 -0
  169. data/app/views/admin/users/_user.html.erb +36 -0
  170. data/app/views/admin/users/edit.html.erb +6 -0
  171. data/app/views/admin/users/index.html.erb +41 -0
  172. data/app/views/admin/users/new.html.erb +6 -0
  173. data/app/views/attachments/show.html.erb +1 -0
  174. data/app/views/elements/_article_editor.html.erb +4 -0
  175. data/app/views/elements/_article_view.html.erb +25 -0
  176. data/app/views/elements/_bild_editor.html.erb +1 -0
  177. data/app/views/elements/_bild_text_editor.html.erb +2 -0
  178. data/app/views/elements/_bild_text_view.html.erb +9 -0
  179. data/app/views/elements/_bild_view.html.erb +9 -0
  180. data/app/views/elements/_claim_editor.html.erb +1 -0
  181. data/app/views/elements/_claim_view.html.erb +1 -0
  182. data/app/views/elements/_contactform_editor.html.erb +7 -0
  183. data/app/views/elements/_contactform_view.html.erb +92 -0
  184. data/app/views/elements/_editor_not_found.html.erb +5 -0
  185. data/app/views/elements/_footnote_editor.html.erb +1 -0
  186. data/app/views/elements/_footnote_view.html.erb +5 -0
  187. data/app/views/elements/_header_editor.html.erb +1 -0
  188. data/app/views/elements/_header_view.html.erb +1 -0
  189. data/app/views/elements/_headline_editor.html.erb +1 -0
  190. data/app/views/elements/_headline_view.html.erb +1 -0
  191. data/app/views/elements/_image_mosaic_editor.html.erb +2 -0
  192. data/app/views/elements/_image_mosaic_view.html.erb +12 -0
  193. data/app/views/elements/_intro_editor.html.erb +1 -0
  194. data/app/views/elements/_intro_image_text_editor.html.erb +3 -0
  195. data/app/views/elements/_intro_image_text_view.html.erb +16 -0
  196. data/app/views/elements/_intro_view.html.erb +3 -0
  197. data/app/views/elements/_news_editor.html.erb +3 -0
  198. data/app/views/elements/_news_view.html.erb +11 -0
  199. data/app/views/elements/_searchresult_editor.html.erb +1 -0
  200. data/app/views/elements/_searchresult_view.html.erb +42 -0
  201. data/app/views/elements/_sitemap_editor.html.erb +3 -0
  202. data/app/views/elements/_sitemap_view.html.erb +38 -0
  203. data/app/views/elements/_sitename_editor.html.erb +1 -0
  204. data/app/views/elements/_sitename_view.html.erb +1 -0
  205. data/app/views/elements/_subheadline_editor.html.erb +1 -0
  206. data/app/views/elements/_subheadline_view.html.erb +5 -0
  207. data/app/views/elements/_text_editor.html.erb +1 -0
  208. data/app/views/elements/_text_view.html.erb +3 -0
  209. data/app/views/elements/_view_not_found.html.erb +1 -0
  210. data/app/views/elements/show.html.erb +6 -0
  211. data/app/views/elements/show.js.erb +11 -0
  212. data/app/views/essences/_essence_audio_editor.html.erb +1 -0
  213. data/app/views/essences/_essence_audio_view.html.erb +33 -0
  214. data/app/views/essences/_essence_date_editor.html.erb +12 -0
  215. data/app/views/essences/_essence_date_view.html.erb +7 -0
  216. data/app/views/essences/_essence_file_editor.html.erb +63 -0
  217. data/app/views/essences/_essence_file_view.html.erb +6 -0
  218. data/app/views/essences/_essence_flash_editor.html.erb +1 -0
  219. data/app/views/essences/_essence_flash_view.html.erb +26 -0
  220. data/app/views/essences/_essence_html_editor.html.erb +8 -0
  221. data/app/views/essences/_essence_html_view.html.erb +1 -0
  222. data/app/views/essences/_essence_picture_editor.html.erb +70 -0
  223. data/app/views/essences/_essence_picture_tools.html.erb +60 -0
  224. data/app/views/essences/_essence_picture_view.html.erb +42 -0
  225. data/app/views/essences/_essence_richtext_editor.html.erb +9 -0
  226. data/app/views/essences/_essence_richtext_view.html.erb +5 -0
  227. data/app/views/essences/_essence_text_editor.html.erb +82 -0
  228. data/app/views/essences/_essence_text_view.html.erb +11 -0
  229. data/app/views/essences/_essence_video_editor.html.erb +1 -0
  230. data/app/views/essences/_essence_video_view.html.erb +35 -0
  231. data/app/views/layouts/alchemy.html.erb +60 -0
  232. data/app/views/layouts/login.html.erb +60 -0
  233. data/app/views/layouts/pages.html.erb +31 -0
  234. data/app/views/layouts/sitemap.xml.erb +4 -0
  235. data/app/views/messages/mail.text.erb +10 -0
  236. data/app/views/messages/new.html.erb +1 -0
  237. data/app/views/notifications/admin_user_created.text.erb +13 -0
  238. data/app/views/notifications/registered_user_created.text.erb +10 -0
  239. data/app/views/page_layouts/_contact.html.erb +14 -0
  240. data/app/views/page_layouts/_external.html.erb +1 -0
  241. data/app/views/page_layouts/_intro.html.erb +14 -0
  242. data/app/views/page_layouts/_layout_footer.html.erb +14 -0
  243. data/app/views/page_layouts/_layout_header.html.erb +14 -0
  244. data/app/views/page_layouts/_news.html.erb +14 -0
  245. data/app/views/page_layouts/_newsletter_layout.html.erb +1 -0
  246. data/app/views/page_layouts/_search.html.erb +14 -0
  247. data/app/views/page_layouts/_standard.html.erb +14 -0
  248. data/app/views/pages/show.html.erb +1 -0
  249. data/app/views/pages/show.rss.builder +27 -0
  250. data/app/views/pages/sitemap.xml.erb +8 -0
  251. data/app/views/partials/_navigation_image_link.html.erb +14 -0
  252. data/app/views/partials/_navigation_link.html.erb +20 -0
  253. data/app/views/partials/_navigation_renderer.html.erb +23 -0
  254. data/app/views/pictures/show.gif.flexi +19 -0
  255. data/app/views/pictures/show.jpg.flexi +19 -0
  256. data/app/views/pictures/show.png.flexi +19 -0
  257. data/app/views/pictures/thumbnail.png.flexi +13 -0
  258. data/app/views/pictures/zoom.png.flexi +3 -0
  259. data/assets/images/ajax_loader.gif +0 -0
  260. data/assets/images/alchemy-logo.png +0 -0
  261. data/assets/images/flags.png +0 -0
  262. data/assets/images/gui/navi-tab.png +0 -0
  263. data/assets/images/gui/shading.png +0 -0
  264. data/assets/images/gui/shading_90.png +0 -0
  265. data/assets/images/gui/toggle.png +0 -0
  266. data/assets/images/icons.png +0 -0
  267. data/assets/images/jquery-sb/select_arrow.gif +0 -0
  268. data/assets/images/jquery-sb/select_arrow_bg.gif +0 -0
  269. data/assets/images/jquery-sb/select_arrow_bg_hover.gif +0 -0
  270. data/assets/images/jquery-ui/ui-icons_666666_256x240.png +0 -0
  271. data/assets/images/placeholder.png +0 -0
  272. data/assets/images/swfupload/browse_button.png +0 -0
  273. data/assets/javascripts/alchemy.element_editor_selector.js +88 -0
  274. data/assets/javascripts/alchemy.growler.js +44 -0
  275. data/assets/javascripts/alchemy.image_cropper.js +56 -0
  276. data/assets/javascripts/alchemy.js +892 -0
  277. data/assets/javascripts/alchemy.link_overlay.js +221 -0
  278. data/assets/javascripts/alchemy.page_sorter.js +42 -0
  279. data/assets/javascripts/alchemy.preview.js +145 -0
  280. data/assets/javascripts/jquery-ui.js +428 -0
  281. data/assets/javascripts/jquery.Jcrop.min.js +246 -0
  282. data/assets/javascripts/jquery.dialogextend.min.js +8 -0
  283. data/assets/javascripts/jquery.in-place-edit.js +171 -0
  284. data/assets/javascripts/jquery.js +18 -0
  285. data/assets/javascripts/jquery.rails.js +315 -0
  286. data/assets/javascripts/jquery.sb.min.js +14 -0
  287. data/assets/javascripts/jquery.scrollTo-1.4.2-min.js +11 -0
  288. data/assets/javascripts/jquery.ui.nestedSortable.js +291 -0
  289. data/assets/javascripts/jquery.ui.tabspaging.js +281 -0
  290. data/assets/javascripts/swfupload/fileprogress.js +203 -0
  291. data/assets/javascripts/swfupload/handlers.js +171 -0
  292. data/assets/javascripts/swfupload/queue.js +98 -0
  293. data/assets/javascripts/swfupload/swfupload.js +980 -0
  294. data/assets/javascripts/swfupload/swfupload.swf +0 -0
  295. data/assets/javascripts/tiny_mce/jquery.tinymce.js +1 -0
  296. data/assets/javascripts/tiny_mce/langs/de.js +1 -0
  297. data/assets/javascripts/tiny_mce/langs/en.js +223 -0
  298. data/assets/javascripts/tiny_mce/license.txt +504 -0
  299. data/assets/javascripts/tiny_mce/plugins/alchemy_link/editor_plugin.js +43 -0
  300. data/assets/javascripts/tiny_mce/plugins/alchemy_link/langs/de.js +4 -0
  301. data/assets/javascripts/tiny_mce/plugins/alchemy_link/langs/en.js +4 -0
  302. data/assets/javascripts/tiny_mce/plugins/fullscreen/editor_plugin.js +1 -0
  303. data/assets/javascripts/tiny_mce/plugins/fullscreen/fullscreen.htm +109 -0
  304. data/assets/javascripts/tiny_mce/plugins/inlinepopups/editor_plugin.js +1 -0
  305. data/assets/javascripts/tiny_mce/plugins/inlinepopups/skins/alchemy/window.css +402 -0
  306. data/assets/javascripts/tiny_mce/plugins/inlinepopups/template.htm +387 -0
  307. data/assets/javascripts/tiny_mce/plugins/lists/editor_plugin.js +1 -0
  308. data/assets/javascripts/tiny_mce/plugins/paste/editor_plugin.js +1 -0
  309. data/assets/javascripts/tiny_mce/plugins/paste/js/pastetext.js +36 -0
  310. data/assets/javascripts/tiny_mce/plugins/paste/js/pasteword.js +51 -0
  311. data/assets/javascripts/tiny_mce/plugins/paste/langs/de_dlg.js +1 -0
  312. data/assets/javascripts/tiny_mce/plugins/paste/langs/en_dlg.js +5 -0
  313. data/assets/javascripts/tiny_mce/plugins/paste/pastetext.htm +27 -0
  314. data/assets/javascripts/tiny_mce/plugins/paste/pasteword.htm +21 -0
  315. data/assets/javascripts/tiny_mce/plugins/table/cell.htm +180 -0
  316. data/assets/javascripts/tiny_mce/plugins/table/css/cell.css +17 -0
  317. data/assets/javascripts/tiny_mce/plugins/table/css/row.css +25 -0
  318. data/assets/javascripts/tiny_mce/plugins/table/css/table.css +13 -0
  319. data/assets/javascripts/tiny_mce/plugins/table/editor_plugin.js +1 -0
  320. data/assets/javascripts/tiny_mce/plugins/table/js/cell.js +319 -0
  321. data/assets/javascripts/tiny_mce/plugins/table/js/merge_cells.js +27 -0
  322. data/assets/javascripts/tiny_mce/plugins/table/js/row.js +237 -0
  323. data/assets/javascripts/tiny_mce/plugins/table/js/table.js +450 -0
  324. data/assets/javascripts/tiny_mce/plugins/table/langs/de_dlg.js +1 -0
  325. data/assets/javascripts/tiny_mce/plugins/table/langs/en_dlg.js +75 -0
  326. data/assets/javascripts/tiny_mce/plugins/table/merge_cells.htm +32 -0
  327. data/assets/javascripts/tiny_mce/plugins/table/row.htm +158 -0
  328. data/assets/javascripts/tiny_mce/plugins/table/table.htm +188 -0
  329. data/assets/javascripts/tiny_mce/themes/advanced/about.htm +52 -0
  330. data/assets/javascripts/tiny_mce/themes/advanced/anchor.htm +26 -0
  331. data/assets/javascripts/tiny_mce/themes/advanced/charmap.htm +51 -0
  332. data/assets/javascripts/tiny_mce/themes/advanced/color_picker.htm +74 -0
  333. data/assets/javascripts/tiny_mce/themes/advanced/editor_template.js +1 -0
  334. data/assets/javascripts/tiny_mce/themes/advanced/image.htm +80 -0
  335. data/assets/javascripts/tiny_mce/themes/advanced/img/colorpicker.jpg +0 -0
  336. data/assets/javascripts/tiny_mce/themes/advanced/img/flash.gif +0 -0
  337. data/assets/javascripts/tiny_mce/themes/advanced/img/icons.gif +0 -0
  338. data/assets/javascripts/tiny_mce/themes/advanced/img/iframe.gif +0 -0
  339. data/assets/javascripts/tiny_mce/themes/advanced/img/pagebreak.gif +0 -0
  340. data/assets/javascripts/tiny_mce/themes/advanced/img/quicktime.gif +0 -0
  341. data/assets/javascripts/tiny_mce/themes/advanced/img/realmedia.gif +0 -0
  342. data/assets/javascripts/tiny_mce/themes/advanced/img/shockwave.gif +0 -0
  343. data/assets/javascripts/tiny_mce/themes/advanced/img/trans.gif +0 -0
  344. data/assets/javascripts/tiny_mce/themes/advanced/img/video.gif +0 -0
  345. data/assets/javascripts/tiny_mce/themes/advanced/img/windowsmedia.gif +0 -0
  346. data/assets/javascripts/tiny_mce/themes/advanced/js/about.js +73 -0
  347. data/assets/javascripts/tiny_mce/themes/advanced/js/anchor.js +42 -0
  348. data/assets/javascripts/tiny_mce/themes/advanced/js/charmap.js +355 -0
  349. data/assets/javascripts/tiny_mce/themes/advanced/js/color_picker.js +329 -0
  350. data/assets/javascripts/tiny_mce/themes/advanced/js/image.js +247 -0
  351. data/assets/javascripts/tiny_mce/themes/advanced/js/link.js +153 -0
  352. data/assets/javascripts/tiny_mce/themes/advanced/js/source_editor.js +56 -0
  353. data/assets/javascripts/tiny_mce/themes/advanced/langs/de.js +1 -0
  354. data/assets/javascripts/tiny_mce/themes/advanced/langs/de_dlg.js +1 -0
  355. data/assets/javascripts/tiny_mce/themes/advanced/langs/en.js +68 -0
  356. data/assets/javascripts/tiny_mce/themes/advanced/langs/en_dlg.js +54 -0
  357. data/assets/javascripts/tiny_mce/themes/advanced/link.htm +57 -0
  358. data/assets/javascripts/tiny_mce/themes/advanced/shortcuts.htm +47 -0
  359. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/content.css +47 -0
  360. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/dialog.css +117 -0
  361. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/buttons.png +0 -0
  362. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/items.gif +0 -0
  363. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_arrow.gif +0 -0
  364. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/menu_check.gif +0 -0
  365. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/progress.gif +0 -0
  366. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/img/tabs.gif +0 -0
  367. data/assets/javascripts/tiny_mce/themes/advanced/skins/default/ui.css +214 -0
  368. data/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/content.css +23 -0
  369. data/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +105 -0
  370. data/assets/javascripts/tiny_mce/themes/advanced/skins/highcontrast/ui.css +102 -0
  371. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/content.css +46 -0
  372. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/dialog.css +117 -0
  373. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg.png +0 -0
  374. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_black.png +0 -0
  375. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/img/button_bg_silver.png +0 -0
  376. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui.css +217 -0
  377. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_black.css +8 -0
  378. data/assets/javascripts/tiny_mce/themes/advanced/skins/o2k7/ui_silver.css +5 -0
  379. data/assets/javascripts/tiny_mce/themes/advanced/source_editor.htm +25 -0
  380. data/assets/javascripts/tiny_mce/themes/simple/langs/de.js +1 -0
  381. data/assets/javascripts/tiny_mce/tiny_mce.js +1 -0
  382. data/assets/javascripts/tiny_mce/tiny_mce_popup.js +5 -0
  383. data/assets/javascripts/tiny_mce/utils/editable_selects.js +70 -0
  384. data/assets/javascripts/tiny_mce/utils/form_utils.js +210 -0
  385. data/assets/javascripts/tiny_mce/utils/mctabs.js +162 -0
  386. data/assets/javascripts/tiny_mce/utils/validate.js +252 -0
  387. data/assets/stylesheets/Jcrop.gif +0 -0
  388. data/assets/stylesheets/alchemy.css +3629 -0
  389. data/assets/stylesheets/alchemy_tinymce_content.css +94 -0
  390. data/assets/stylesheets/alchemy_tinymce_dialog.css +415 -0
  391. data/assets/stylesheets/default/img/tabs.gif +0 -0
  392. data/assets/stylesheets/elements.css +900 -0
  393. data/assets/stylesheets/flags.css +1 -0
  394. data/assets/stylesheets/ie6.css +18 -0
  395. data/assets/stylesheets/jquery-ui-1.8.7.alchemy.css +2023 -0
  396. data/assets/stylesheets/jquery.Jcrop.css +35 -0
  397. data/assets/stylesheets/jquery.sb.css +244 -0
  398. data/assets/stylesheets/standard_set.css +374 -0
  399. data/bin/alchemy +347 -0
  400. data/config/alchemy/config.yml +199 -0
  401. data/config/alchemy/elements.yml +219 -0
  402. data/config/alchemy/page_layouts.yml +65 -0
  403. data/config/asset_packages.yml +32 -0
  404. data/config/authorization_rules.rb +96 -0
  405. data/config/initializers/authorization.rb +4 -0
  406. data/config/initializers/cache_storage.rb +1 -0
  407. data/config/initializers/fast_gettext.rb +2 -0
  408. data/config/initializers/tiny_mce_hammer.rb +32 -0
  409. data/config/locales/de.yml +370 -0
  410. data/config/locales/en.yml +364 -0
  411. data/config/routes.rb +141 -0
  412. data/db/migrate/20100607143125_create_pages.rb +34 -0
  413. data/db/migrate/20100607144254_create_elements.rb +20 -0
  414. data/db/migrate/20100607145256_create_contents.rb +18 -0
  415. data/db/migrate/20100607145719_create_users.rb +32 -0
  416. data/db/migrate/20100607150611_create_pictures.rb +16 -0
  417. data/db/migrate/20100607150812_create_attachments.rb +16 -0
  418. data/db/migrate/20100607153647_create_folded_pages.rb +13 -0
  419. data/db/migrate/20100607161345_create_essence_texts.rb +19 -0
  420. data/db/migrate/20100607162339_create_elements_pages.rb +12 -0
  421. data/db/migrate/20100607193638_create_essence_pictures.rb +23 -0
  422. data/db/migrate/20100607193646_create_essence_richtexts.rb +16 -0
  423. data/db/migrate/20100607193653_create_essence_htmls.rb +13 -0
  424. data/db/migrate/20100609111653_create_essence_dates.rb +13 -0
  425. data/db/migrate/20100609111809_create_essence_files.rb +15 -0
  426. data/db/migrate/20100609111821_create_essence_flashes.rb +16 -0
  427. data/db/migrate/20100609111837_create_essence_videos.rb +18 -0
  428. data/db/migrate/20100616150753_create_essence_audios.rb +17 -0
  429. data/db/migrate/20100812085225_add_crop_from_and_crop_size_to_essence_pictures.rb +11 -0
  430. data/db/migrate/20100909140701_change_essence_htmls_source_column_type.rb +9 -0
  431. data/db/migrate/20101109150312_alter_pages_visible_column_default.rb +9 -0
  432. data/db/migrate/20101109151812_create_languages.rb +19 -0
  433. data/db/migrate/20101216151419_add_language_id_to_pages.rb +19 -0
  434. data/db/migrate/20101216155216_add_index_to_languages.rb +9 -0
  435. data/db/migrate/20101216173323_add_default_to_languages.rb +9 -0
  436. data/db/migrate/20101218130049_add_urlname_index_to_pages.rb +9 -0
  437. data/db/migrate/20110115123343_remove_css_class_default_from_essence_pictures.rb +11 -0
  438. data/db/migrate/20110224105120_change_pages_visible_default.rb +11 -0
  439. data/db/migrate/20110228182659_remove_default_page_layout_from_pages.rb +11 -0
  440. data/db/migrate/20110414163140_remove_display_name_from_elements.rb +11 -0
  441. data/db/migrate/20110511100516_rename_essence_texts_title_to_link_title.rb +9 -0
  442. data/db/migrate/20110529130429_create_cells.rb +14 -0
  443. data/db/migrate/20110529130500_add_cell_id_to_elements.rb +11 -0
  444. data/db/migrate/20110530102804_change_pages_page_layout_column.rb +11 -0
  445. data/db/migrate/20110707190728_add_render_size_to_essence_pictures.rb +9 -0
  446. data/db/migrate/20110711142057_change_open_link_in_new_window_to_link_target.rb +19 -0
  447. data/lib/alchemy.rb +24 -0
  448. data/lib/alchemy/config.rb +51 -0
  449. data/lib/alchemy/controller.rb +79 -0
  450. data/lib/alchemy/engine.rb +29 -0
  451. data/lib/alchemy/essence.rb +178 -0
  452. data/lib/alchemy/file_utilz.rb +73 -0
  453. data/lib/alchemy/page_layout.rb +66 -0
  454. data/lib/alchemy/remote_pagination_link_renderer.rb +17 -0
  455. data/lib/alchemy/seeder.rb +112 -0
  456. data/lib/alchemy/version.rb +5 -0
  457. data/lib/extensions/action_view.rb +17 -0
  458. data/lib/extensions/array.rb +25 -0
  459. data/lib/extensions/hash.rb +34 -0
  460. data/lib/middleware/flash_session_cookie.rb +22 -0
  461. data/lib/rails/generators/alchemy/elements/elements_generator.rb +35 -0
  462. data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +9 -0
  463. data/lib/rails/generators/alchemy/elements/templates/view.html.erb +21 -0
  464. data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +32 -0
  465. data/lib/rails/generators/alchemy/page_layouts/templates/layout.html.erb +1 -0
  466. data/lib/rails/generators/alchemy/plugin/plugin_generator.rb +29 -0
  467. data/lib/rails/generators/alchemy/plugin/templates/authorization_rules.rb +5 -0
  468. data/lib/rails/generators/alchemy/plugin/templates/config.yml +30 -0
  469. data/lib/rails/generators/alchemy/plugin/templates/init.rb +4 -0
  470. data/lib/rails/generators/alchemy/plugin/templates/routes.rb +4 -0
  471. data/lib/rails/generators/alchemy/scaffold/scaffold_generator.rb +35 -0
  472. data/lib/rails/generators/alchemy/scaffold/templates/elements.yml +91 -0
  473. data/lib/rails/generators/alchemy/scaffold/templates/page_layouts.yml +29 -0
  474. data/lib/rails/templates/alchemy.rb +14 -0
  475. data/lib/tasks/fleximage.rake +154 -0
  476. data/lib/tasks/gettext.rake +75 -0
  477. data/lib/tasks/install.rake +123 -0
  478. data/lib/tasks/upgrade.rake +211 -0
  479. data/lib/translation_extras/alchemy_core_modules.rb +11 -0
  480. data/lib/vendor/i18n_label.rb +23 -0
  481. data/locale/alchemy.pot +1728 -0
  482. data/locale/de/LC_MESSAGES/alchemy.mo +0 -0
  483. data/locale/de/alchemy.po +1774 -0
  484. data/locale/en/LC_MESSAGES/alchemy.mo +0 -0
  485. data/locale/en/alchemy.po +1742 -0
  486. data/locale/missing_translations.rb +4 -0
  487. data/locale/model_attributes.rb +56 -0
  488. data/recipes/alchemy_capistrano_tasks.rb +83 -0
  489. metadata +769 -0
@@ -0,0 +1,17 @@
1
+ class EssenceFile < ActiveRecord::Base
2
+
3
+ acts_as_essence(
4
+ :ingredient_column => :attachment,
5
+ :preview_text_method => :name
6
+ )
7
+
8
+ belongs_to :attachment
9
+
10
+ # Saves the ingredient
11
+ def save_ingredient(params, options = {})
12
+ return true if params.blank?
13
+ self.attachment_id = params["attachment_id"].to_s
14
+ self.save
15
+ end
16
+
17
+ end
@@ -0,0 +1,15 @@
1
+ class EssenceFlash < ActiveRecord::Base
2
+
3
+ acts_as_essence(
4
+ :ingredient_column => :attachment,
5
+ :preview_text_method => :name
6
+ )
7
+
8
+ # Saves the ingredient
9
+ def save_ingredient(params, options = {})
10
+ return true if params.blank?
11
+ self.attachment_id = params["attachment_id"].to_s
12
+ self.save
13
+ end
14
+
15
+ end
@@ -0,0 +1,19 @@
1
+ class EssenceHtml < ActiveRecord::Base
2
+
3
+ acts_as_essence(
4
+ :ingredient_column => :source
5
+ )
6
+
7
+ # Returns the first x (default = 30) (HTML escaped) characters from self.source for the Element#preview_text method.
8
+ def preview_text(maxlength = 30)
9
+ CGI.escapeHTML(source.to_s)[0..maxlength]
10
+ end
11
+
12
+ # Saves the ingredient
13
+ def save_ingredient(params, options = {})
14
+ return true if params.blank?
15
+ self.source = params["source"].to_s
16
+ self.save
17
+ end
18
+
19
+ end
@@ -0,0 +1,27 @@
1
+ class EssencePicture < ActiveRecord::Base
2
+
3
+ acts_as_essence(
4
+ :ingredient_column => :picture,
5
+ :preview_text_method => :name
6
+ )
7
+
8
+ belongs_to :picture
9
+ before_save :replace_newlines
10
+
11
+ def replace_newlines
12
+ return nil if caption.nil?
13
+ caption.gsub!(/(\r\n|\r|\n)/, "<br/>")
14
+ end
15
+
16
+ # Saves the ingredient
17
+ def save_ingredient(params, options = {})
18
+ return true if params.blank?
19
+ self.link_class_name = params['link_class_name']
20
+ self.link_target = params['link_target']
21
+ self.link = params['link']
22
+ self.link_title = params['link_title']
23
+ self.picture_id = params['picture_id']
24
+ self.save
25
+ end
26
+
27
+ end
@@ -0,0 +1,50 @@
1
+ class EssenceRichtext < ActiveRecord::Base
2
+
3
+ acts_as_essence(
4
+ :preview_text_column => :stripped_body
5
+ )
6
+
7
+ acts_as_ferret(:fields => {:stripped_body => {:store => :yes}}, :remote => false) if Alchemy::Config.get(:ferret) == true
8
+ before_save :strip_content
9
+ before_save :check_ferret_indexing if Alchemy::Config.get(:ferret) == true
10
+
11
+ # Saves the ingredient
12
+ def save_ingredient(params, options = {})
13
+ return true if params.blank?
14
+ self.body = params['body'].to_s
15
+ self.public = options[:public]
16
+ self.save
17
+ end
18
+
19
+ private
20
+
21
+ def strip_content
22
+ self.stripped_body = strip_tags(self.body)
23
+ end
24
+
25
+ def check_ferret_indexing
26
+ if self.do_not_index
27
+ self.disable_ferret(:always)
28
+ end
29
+ end
30
+
31
+ # Stripping HTML Tags and only returns plain text.
32
+ def strip_tags(html)
33
+ return html if html.blank?
34
+ if html.index("<")
35
+ text = ""
36
+ tokenizer = HTML::Tokenizer.new(html)
37
+ while token = tokenizer.next
38
+ node = HTML::Node.parse(nil, 0, 0, token, false)
39
+ # result is only the content of any Text nodes
40
+ text << node.to_s if node.class == HTML::Text
41
+ end
42
+ # strip any comments, and if they have a newline at the end (ie. line with
43
+ # only a comment) strip that too
44
+ text.gsub(/<!--(.*?)-->[\n]?/m, "")
45
+ else
46
+ html # already plain text
47
+ end
48
+ end
49
+
50
+ end
@@ -0,0 +1,28 @@
1
+ class EssenceText < ActiveRecord::Base
2
+
3
+ acts_as_essence
4
+ acts_as_ferret(:fields => {:body => {:store => :yes}}, :remote => false) if Alchemy::Config.get(:ferret) == true
5
+
6
+ before_save :check_ferret_indexing if Alchemy::Config.get(:ferret) == true
7
+
8
+ # Saves the content from params
9
+ def save_ingredient(params, options = {})
10
+ return true if params.blank?
11
+ self.body = params["body"]
12
+ self.link = params["link"]
13
+ self.link_title = params["link_title"]
14
+ self.link_class_name = params["link_class_name"]
15
+ self.link_target = params["link_target"]
16
+ self.public = options[:public]
17
+ self.save
18
+ end
19
+
20
+ private
21
+
22
+ def check_ferret_indexing
23
+ if self.do_not_index
24
+ self.disable_ferret(:always)
25
+ end
26
+ end
27
+
28
+ end
@@ -0,0 +1,17 @@
1
+ class EssenceVideo < ActiveRecord::Base
2
+
3
+ acts_as_essence(
4
+ :ingredient_column => :attachment,
5
+ :preview_text_method => :name
6
+ )
7
+
8
+ belongs_to :attachment
9
+
10
+ # Saves the ingredient
11
+ def save_ingredient(params, options = {})
12
+ return true if params.blank?
13
+ self.attachment_id = params["attachment_id"].to_s
14
+ self.save
15
+ end
16
+
17
+ end
@@ -0,0 +1,3 @@
1
+ class FoldedPage < ActiveRecord::Base
2
+ belongs_to :page
3
+ end
@@ -0,0 +1,75 @@
1
+ class Language < ActiveRecord::Base
2
+
3
+ validates_presence_of :name
4
+ validates_presence_of :code
5
+ validates_presence_of :page_layout
6
+ validates_presence_of :frontpage_name
7
+ validates_uniqueness_of :code
8
+ validate :presence_of_default_language
9
+ validate :publicity_of_default_language
10
+ has_many :pages
11
+ after_destroy :delete_language_root_page
12
+ validates_format_of :code, :with => /^[a-z]{2}$/
13
+ before_destroy :check_for_default
14
+ after_update :set_pages_language, :if => proc { |m| m.code_changed? }
15
+ before_update :remove_old_default, :if => proc { |m| m.default_changed? && m != Language.get_default }
16
+
17
+ scope :published, where(:public => true)
18
+
19
+ def self.all_for_created_language_trees
20
+ find(Page.language_roots.collect(&:language_id))
21
+ end
22
+
23
+ def self.all_codes_for_published
24
+ self.published.collect(&:code)
25
+ rescue
26
+ []
27
+ end
28
+
29
+ def self.get_default
30
+ self.find_by_default(true)
31
+ end
32
+
33
+ private
34
+
35
+ def publicity_of_default_language
36
+ if self.default? && !self.public?
37
+ errors.add_to_base(N_("Defaut language has to be public"))
38
+ return false
39
+ else
40
+ return true
41
+ end
42
+ end
43
+
44
+ def presence_of_default_language
45
+ if Language.get_default == self && self.default_changed?
46
+ errors.add_to_base(N_("we_need_at_least_one_default"))
47
+ return false
48
+ else
49
+ return true
50
+ end
51
+ end
52
+
53
+ def remove_old_default
54
+ lang = Language.get_default
55
+ return true if lang.nil?
56
+ lang.default = false
57
+ lang.save(false)
58
+ end
59
+
60
+ def set_pages_language
61
+ pages.map { |page| page.language_code = self.code; page.save(false) }
62
+ end
63
+
64
+ def check_for_default
65
+ raise "Default language not deletable" if self.default?
66
+ end
67
+
68
+ def delete_language_root_page
69
+ page = Page.language_root_for(id)
70
+ page.destroy if page
71
+ layoutroot = Page.layout_root_for(id)
72
+ layoutroot.destroy if layoutroot
73
+ end
74
+
75
+ end
@@ -0,0 +1,57 @@
1
+ # This is a tableless model only used for validating Contactform Fields.
2
+ # You can specify the fields for your contactform in the config/alchemy/config.yml file in the :mailer options
3
+ #
4
+ # === Options:
5
+ #
6
+ # - form_layout_name: A Alchemy::PageLayout name (String). Used to render the contactform on a page with this layout.
7
+ #
8
+ # === Validating fields:
9
+ #
10
+ # Pass the field name as symbol and a message_id (will be translated) to :validate_fields:
11
+ #
12
+ # === Translating the validation messages:
13
+ #
14
+ # Validationmessages will be send to +I18n.t+ method with the scope +"alchemy.contactform.validations.#{field[1][:message].to_s}"+.
15
+ # So a +name+ field with the validation message_id +blank_name+ will be available for translation in your locale files like:
16
+ #
17
+ # de:
18
+ # contactform:
19
+ # validations:
20
+ # blank_name: 'Bitte geben Sie Ihren Namen an'
21
+ #
22
+ # === Example Contactform Configuration:
23
+ #
24
+ # :mailer:
25
+ # :form_layout_name: contact
26
+ # :fields: [subject, name, email, message, info]
27
+ # :validate_fields:
28
+ # :name:
29
+ # :message: blank_name
30
+ # :email:
31
+ # :message: blank_email
32
+
33
+ class Message
34
+
35
+ include ActiveModel::Validations
36
+
37
+ attr_accessor :contact_form_id, :ip
38
+
39
+ Alchemy::Config.get(:mailer)[:fields].each do |field|
40
+ attr_accessor field.keys.first.to_sym
41
+ end
42
+
43
+ validate_fields = Alchemy::Config.get(:mailer)[:validate_fields]
44
+ validate_fields.each do |field|
45
+ validates_presence_of field[0], :message => I18n.t("alchemy.contactform.validations.#{field[1][:message].to_s}")
46
+ if field[0].to_s.include?('email')
47
+ validates_format_of field[0], :with => Authlogic::Regex.email, :message => I18n.t('alchemy.contactform.validations.wrong_email_format'), :if => :email_is_filled
48
+ end
49
+ end
50
+
51
+ private
52
+
53
+ def email_is_filled #:nodoc:
54
+ !email.blank?
55
+ end
56
+
57
+ end
@@ -0,0 +1,501 @@
1
+ # encoding: UTF-8
2
+
3
+ require 'awesome_nested_set'
4
+
5
+ class Page < ActiveRecord::Base
6
+
7
+ acts_as_nested_set
8
+ stampable
9
+
10
+ has_many :folded_pages
11
+ has_many :cells, :dependent => :destroy
12
+ has_many :elements, :dependent => :destroy, :order => :position
13
+ has_and_belongs_to_many :to_be_sweeped_elements, :class_name => 'Element', :uniq => true
14
+ belongs_to :language
15
+
16
+ validates_presence_of :name, :message => N_("please enter a name")
17
+ validates_presence_of :page_layout, :message => N_("Please choose a page layout.")
18
+ validates_length_of :urlname, :minimum => 3, :too_short => N_("urlname_to_short"), :if => :urlname_entered?
19
+ validates_uniqueness_of :urlname, :message => N_("URL-Name already token"), :scope => 'language_id', :if => :urlname_entered?
20
+
21
+ attr_accessor :do_not_autogenerate
22
+ attr_accessor :do_not_sweep
23
+ attr_accessor :do_not_validate_language
24
+
25
+ before_save :set_url_name, :unless => Proc.new { |page| page.redirects_to_external? }
26
+ before_save :set_title, :unless => Proc.new { |page| page.redirects_to_external? }
27
+ before_save :set_language_code
28
+ after_create :autogenerate_elements, :unless => Proc.new { |page| page.do_not_autogenerate }
29
+ after_create :create_cells
30
+ after_save :set_restrictions_to_child_pages
31
+
32
+ scope :language_roots, where(:language_root => true)
33
+ scope :layoutpages, where(:layoutpage => true)
34
+ scope :all_locked, where(:locked => true)
35
+ scope :visible, where(:visible => true)
36
+ scope :public, where(:public => true)
37
+ scope :accessable, where(:restricted => false)
38
+ scope :restricted, where(:restricted => true)
39
+ scope :public_language_roots, lambda {
40
+ where("language_root = 1 AND language_code IN ('#{Language.all_codes_for_published.join('\',\'')}') AND public = 1")
41
+ }
42
+ scope :all_last_edited_from, lambda { |user| where(:updater_id => user.id).order('updated_at DESC').limit(5) }
43
+
44
+ # Returns all pages for langugae that are not locked and public.
45
+ # Used for flushing all page caches at once.
46
+ scope :flushables, lambda { |language_id| where({:public => true, :locked => false, :language_id => language_id}) }
47
+
48
+ scope :contentpages, where("pages.layoutpage = 0 AND pages.parent_id IS NOT NULL")
49
+
50
+ # Finds selected elements from page either except a passed collection or only the passed collection
51
+ # Collection is an array of strings from element names. E.g.: ['text', 'headline']
52
+ # Returns only public ones
53
+ def find_selected_elements(options, show_non_public = false)
54
+ public_condition = show_non_public ? nil : ' AND elements.public = 1'
55
+ if !options[:except].blank?
56
+ condition = ["elements.name NOT IN (?)#{public_condition}", options[:except]]
57
+ elsif !options[:only].blank?
58
+ condition = ["elements.name IN (?)#{public_condition}", options[:only]]
59
+ else
60
+ condition = show_non_public.nil? ? nil : {:public => true}
61
+ end
62
+ elements = self.elements.where(condition).limit(options[:count]).offset(options[:offset])
63
+ elements.order("RAND()") unless options[:random].blank?
64
+ elements
65
+ end
66
+
67
+ def find_elements(options, show_non_public = false)
68
+ if !options[:collection].blank? && options[:collection].is_a?(Array)
69
+ all_elements = options[:collection]
70
+ else
71
+ all_elements = find_selected_elements(options, show_non_public)
72
+ end
73
+ all_elements
74
+ end
75
+
76
+ def elements_grouped_by_cells
77
+ group = ActiveSupport::OrderedHash.new
78
+ cells.each { |cell| group[cell] = cell.elements }
79
+ group[Cell.new({:name => 'for_other_elements'})] = elements.find_all_by_cell_id(nil)
80
+ return group
81
+ end
82
+
83
+ # Finds the previous page on the same structure level. Otherwise it returns nil.
84
+ # Options:
85
+ # => :restricted => boolean (standard: nil) - next restricted page (true), skip restricted pages (false), ignore restriction (nil)
86
+ # => :public => boolean (standard: true) - next public page (true), skip public pages (false)
87
+ def previous_page(options = {})
88
+ default_options = {
89
+ :restricted => nil,
90
+ :public => true
91
+ }
92
+ options = default_options.merge(options)
93
+ find_next_or_previous_page("previous", options)
94
+ end
95
+
96
+ # Finds the next page on the same structure level. Otherwise it returns nil.
97
+ # Options:
98
+ # => :restricted => boolean (standard: nil) - next restricted page (true), skip restricted pages (false), ignore restriction (nil)
99
+ # => :public => boolean (standard: true) - next public page (true), skip public pages (false)
100
+ def next_page(options = {})
101
+ default_options = {
102
+ :restricted => nil,
103
+ :public => true
104
+ }
105
+ options = default_options.merge(options)
106
+ find_next_or_previous_page("next", options)
107
+ end
108
+
109
+ def find_first_public(page)
110
+ if(page.public == true)
111
+ return page
112
+ end
113
+ page.children.each do |child|
114
+ result = find_first_public(child)
115
+ if(result!=nil)
116
+ return result
117
+ end
118
+ end
119
+ return nil
120
+ end
121
+
122
+ def name_entered?
123
+ !self.name.blank?
124
+ end
125
+
126
+ def urlname_entered?
127
+ !self.urlname.blank?
128
+ end
129
+
130
+ def set_url_name
131
+ self.urlname = generate_url_name((self.urlname.blank? ? self.name : self.urlname))
132
+ end
133
+
134
+ def set_title
135
+ self.title = self.name
136
+ end
137
+
138
+ def show_in_navigation?
139
+ if visible?
140
+ return true
141
+ end
142
+ return false
143
+ end
144
+
145
+ def lock(user)
146
+ self.locked = true
147
+ self.locked_by = user.id
148
+ self.save(false)
149
+ end
150
+
151
+ def unlock
152
+ self.locked = false
153
+ self.locked_by = nil
154
+ self.do_not_sweep = true
155
+ self.save
156
+ end
157
+
158
+ def public_elements
159
+ self.elements.select{ |m| m.public? }
160
+ end
161
+
162
+ # Returns the name of the creator of this page.
163
+ def creator
164
+ @page_creator ||= User.find_by_id(creator_id)
165
+ return _('unknown') if @page_creator.nil?
166
+ @page_creator.name
167
+ end
168
+
169
+ # Returns the name of the last updater of this page.
170
+ def updater
171
+ @page_updater = User.find_by_id(updater_id)
172
+ return _('unknown') if @page_updater.nil?
173
+ @page_updater.name
174
+ end
175
+
176
+ # Returns the name of the user currently editing this page.
177
+ def current_editor
178
+ @current_editor = User.find_by_id(locked_by)
179
+ return _('unknown') if @current_editor.nil?
180
+ @current_editor.name
181
+ end
182
+
183
+ def locker
184
+ User.find_by_id(self.locked_by)
185
+ end
186
+
187
+ def fold(user_id, status)
188
+ folded_page = FoldedPage.find_or_create_by_user_id_and_page_id(user_id, self.id)
189
+ folded_page.update_attributes(:folded => status)
190
+ folded_page.save
191
+ end
192
+
193
+ def folded?(user_id)
194
+ folded_page = FoldedPage.find_by_user_id_and_page_id(user_id, self.id)
195
+ return false if folded_page.nil?
196
+ folded_page.folded
197
+ end
198
+
199
+ def elements_by_type type
200
+ elements.select{|m| type.include? m.name}
201
+ end
202
+
203
+ # Returns the translated explanation of seven the page stati.
204
+ def humanized_status
205
+ case self.status
206
+ when 0
207
+ then
208
+ return _('page_status_visible_public_locked')
209
+ when 1
210
+ then
211
+ return _('page_status_visible_unpublic_locked')
212
+ when 2
213
+ then
214
+ return _('page_status_invisible_public_locked')
215
+ when 3
216
+ then
217
+ return _('page_status_invisible_unpublic_locked')
218
+ when 4
219
+ then
220
+ return _('page_status_visible_public')
221
+ when 5
222
+ then
223
+ return _('page_status_visible_unpublic')
224
+ when 6
225
+ then
226
+ return _('page_status_invisible_public')
227
+ when 7
228
+ then
229
+ return _('page_status_invisible_unpublic')
230
+ end
231
+ end
232
+
233
+ # Returns the status code. Used by humanized_status and the page status icon inside the sitemap rendered by Pages.index.
234
+ def status
235
+ if self.locked
236
+ if self.public? && self.visible?
237
+ return 0
238
+ elsif !self.public? && self.visible?
239
+ return 1
240
+ elsif self.public? && !self.visible?
241
+ return 2
242
+ elsif !self.public? && !self.visible?
243
+ return 3
244
+ end
245
+ else
246
+ if self.public? && self.visible?
247
+ return 4
248
+ elsif !self.public? && self.visible?
249
+ return 5
250
+ elsif self.public? && !self.visible?
251
+ return 6
252
+ elsif !self.public? && !self.visible?
253
+ return 7
254
+ end
255
+ end
256
+ end
257
+
258
+ def has_controller?
259
+ !Alchemy::PageLayout.get(self.page_layout).nil? && !Alchemy::PageLayout.get(self.page_layout)["controller"].blank?
260
+ end
261
+
262
+ def controller_and_action
263
+ if self.has_controller?
264
+ {:controller => self.layout_description["controller"], :action => self.layout_description["action"]}
265
+ end
266
+ end
267
+
268
+ # Returns the self#page_layout description from config/alchemy/page_layouts.yml file.
269
+ def layout_description
270
+ page_layout = Alchemy::PageLayout.get(self.page_layout)
271
+ if page_layout.nil?
272
+ logger.warn("\n+++++++++++ Warning! Alchemy::PageLayout description not found for layout: #{self.page_layout}\n")
273
+ return nil
274
+ else
275
+ return page_layout
276
+ end
277
+ end
278
+ alias_method :definition, :layout_description
279
+
280
+ # Returns translated name of the pages page_layout value.
281
+ # Page layout names are defined inside the config/alchemy/page_layouts.yml file.
282
+ # Translate the name in your config/locales language yml file.
283
+ def layout_display_name
284
+ I18n.t("alchemy.page_layout_names.#{page_layout}", :default => page_layout.camelize)
285
+ end
286
+
287
+ def renamed?
288
+ self.name_was != self.name || self.urlname_was != self.urlname
289
+ end
290
+
291
+ def changed_publicity?
292
+ self.public_was != self.public
293
+ end
294
+
295
+ def set_restrictions_to_child_pages
296
+ return nil if self.restricted_was == self.restricted
297
+ descendants.each do |child|
298
+ child.restricted = restricted
299
+ child.save
300
+ end
301
+ end
302
+
303
+ def contains_feed?
304
+ desc = self.layout_description
305
+ return false if desc.blank?
306
+ desc["feed"]
307
+ end
308
+
309
+ # Returns true or false if the pages layout_description for config/alchemy/page_layouts.yml contains redirects_to_external: true
310
+ def redirects_to_external?
311
+ desc = self.layout_description
312
+ return false if desc.blank?
313
+ desc["redirects_to_external"]
314
+ end
315
+
316
+ # Returns an array of all pages currently locked by user
317
+ def self.all_locked_by(user)
318
+ find_all_by_locked_and_locked_by(true, user.id)
319
+ end
320
+
321
+ def first_public_child
322
+ self.children.where(:public => true).limit(1)
323
+ end
324
+
325
+ def self.language_root_for(language_id)
326
+ self.language_roots.find_by_language_id(language_id)
327
+ end
328
+
329
+ # Creates a copy of source (an Page object) and does a copy of all elements depending to source.
330
+ # You can pass any kind of Page#attributes as a difference to source.
331
+ # Notice: It prevents the element auto_generator from running.
332
+ def self.copy(source, differences = {})
333
+ attributes = source.attributes.symbolize_keys.merge(differences)
334
+ attributes.merge!(
335
+ :do_not_autogenerate => true,
336
+ :do_not_sweep => true,
337
+ :visible => false,
338
+ :public => false,
339
+ :locked => false,
340
+ :locked_by => nil
341
+ )
342
+ page = self.new(attributes.except(["id", "updated_at", "created_at", "created_id", "updater_id"]))
343
+ if page.save
344
+ source.elements.each do |element|
345
+ new_element = Element.copy(element, :page_id => page.id)
346
+ new_element.move_to_bottom
347
+ end
348
+ return page
349
+ else
350
+ raise page.errors.full_messages
351
+ end
352
+ end
353
+
354
+ # Gets the language_root page for page
355
+ def get_language_root
356
+ return self if self.language_root
357
+ page = self
358
+ while page.parent do
359
+ page = page.parent
360
+ break if page.language_root?
361
+ end
362
+ return page
363
+ end
364
+
365
+ def self.layout_root_for(language_id)
366
+ where({:parent_id => Page.root.id, :layoutpage => true, :language_id => language_id}).limit(1).first
367
+ end
368
+
369
+ def self.find_or_create_layout_root_for(language_id)
370
+ layoutroot = layout_root_for(language_id)
371
+ return layoutroot if layoutroot
372
+ language = Language.find(language_id)
373
+ layoutroot = Page.new({
374
+ :name => "Layoutroot for #{language.name}",
375
+ :layoutpage => true,
376
+ :language => language,
377
+ :do_not_autogenerate => true
378
+ })
379
+ if layoutroot.save(false)
380
+ layoutroot.move_to_child_of(Page.root)
381
+ return layoutroot
382
+ else
383
+ raise "Layout root for #{language.name} could not be created"
384
+ end
385
+ end
386
+
387
+ def self.all_from_clipboard(clipboard)
388
+ return [] if clipboard.blank?
389
+ self.find_all_by_id(clipboard)
390
+ end
391
+
392
+ def self.all_from_clipboard_for_select(clipboard, language_id, layoutpage = false)
393
+ return [] if clipboard.blank?
394
+ clipboard_pages = self.all_from_clipboard(clipboard)
395
+ allowed_page_layouts = Alchemy::PageLayout.selectable_layouts(language_id, layoutpage)
396
+ allowed_page_layout_names = allowed_page_layouts.collect{ |p| p['name'] }
397
+ clipboard_pages.select { |cp| allowed_page_layout_names.include?(cp.page_layout) }
398
+ end
399
+
400
+ def copy_children_to(new_parent)
401
+ self.children.each do |child|
402
+ next if child == new_parent
403
+ new_child = Page.copy(child, {
404
+ :language_id => new_parent.language_id,
405
+ :language_code => new_parent.language_code,
406
+ :name => child.name + ' (' + _('Copy') + ')',
407
+ :urlname => '',
408
+ :title => ''
409
+ })
410
+ new_child.move_to_child_of(new_parent)
411
+ child.copy_children_to(new_child) unless child.children.blank?
412
+ end
413
+ end
414
+
415
+ # Returns true or false if the page has a page_layout that has cells.
416
+ def has_cells?
417
+ pagelayout = Alchemy::PageLayout.get(self.page_layout)
418
+ return false if pagelayout.blank?
419
+ !pagelayout['cells'].blank?
420
+ end
421
+
422
+ def self.link_target_options
423
+ options = [
424
+ [I18n.t('default', :scope => 'alchemy.link_target_options'), '']
425
+ ]
426
+ link_target_options = Alchemy::Config.get(:link_target_options)
427
+ link_target_options.each do |option|
428
+ options << [I18n.t(option, :scope => 'alchemy.link_target_options'), option]
429
+ end
430
+ options
431
+ end
432
+
433
+ def locker_name
434
+ return N_('unknown') if self.locker.nil?
435
+ self.locker.name
436
+ end
437
+
438
+ private
439
+
440
+ def find_next_or_previous_page(direction = "next", options = {})
441
+ if direction == "previous"
442
+ step_direction = ["pages.lft < ?", self.lft]
443
+ order_direction = "lft DESC"
444
+ else
445
+ step_direction = ["pages.lft > ?", self.lft]
446
+ order_direction = "lft"
447
+ end
448
+ conditions = Page.merge_conditions(
449
+ {:parent_id => self.parent_id},
450
+ {:public => options[:public]},
451
+ step_direction
452
+ )
453
+ if !options[:restricted].nil?
454
+ conditions = Page.merge_conditions(conditions, {:restricted => options[:restricted]})
455
+ end
456
+ return Page.where(conditions).order(order_direction).limit(1)
457
+ end
458
+
459
+ def generate_url_name(url_name)
460
+ new_url_name = url_name.to_s.downcase
461
+ new_url_name = new_url_name.gsub(/[ä]/, 'ae')
462
+ new_url_name = new_url_name.gsub(/[ü]/, 'ue')
463
+ new_url_name = new_url_name.gsub(/[ö]/, 'oe')
464
+ new_url_name = new_url_name.gsub(/[Ä]/, 'AE')
465
+ new_url_name = new_url_name.gsub(/[Ü]/, 'UE')
466
+ new_url_name = new_url_name.gsub(/[Ö]/, 'OE')
467
+ new_url_name = new_url_name.gsub(/[ß]/, 'ss')
468
+ new_url_name = new_url_name.gsub(/[^a-zA-Z0-9_]+/, '-')
469
+ if(new_url_name.length < 3)
470
+ new_url_name = "-#{new_url_name}-"
471
+ else
472
+ new_url_name.gsub(/-+$/, '')
473
+ end
474
+ end
475
+
476
+ # Looks in the layout_descripion, if there are elements to autogenerate.
477
+ # If so, it generates them.
478
+ def autogenerate_elements
479
+ return true if self.layout_description.blank?
480
+ elements = self.layout_description["autogenerate"]
481
+ unless (elements.blank?)
482
+ elements.each do |element|
483
+ element = Element.create_from_scratch({'page_id' => self.id, 'name' => element})
484
+ element.move_to_bottom if element
485
+ end
486
+ end
487
+ end
488
+
489
+ def set_language_code
490
+ return false if self.language.blank?
491
+ self.language_code = self.language.code
492
+ end
493
+
494
+ def create_cells
495
+ return true if !has_cells?
496
+ definition['cells'].each do |cellname|
497
+ cells.create({:name => cellname})
498
+ end
499
+ end
500
+
501
+ end