zen 0.3 → 0.4

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 (373) hide show
  1. data/.gems +3 -2
  2. data/.rvmrc +1 -1
  3. data/.travis.yml +5 -0
  4. data/.yardopts +2 -1
  5. data/LICENSE +1 -1
  6. data/README.md +28 -24
  7. data/Rakefile +5 -2
  8. data/guide/asset_management.md +6 -6
  9. data/guide/autosaving_forms.md +42 -0
  10. data/guide/changelog.md +41 -0
  11. data/guide/faq.md +49 -0
  12. data/guide/getting_started.md +24 -13
  13. data/guide/hacking.md +40 -9
  14. data/guide/images/categories/categories.png +0 -0
  15. data/guide/images/categories/category_groups.png +0 -0
  16. data/guide/images/categories/new_category.png +0 -0
  17. data/guide/images/categories/new_category_group.png +0 -0
  18. data/guide/images/comments/comments.png +0 -0
  19. data/guide/images/comments/edit_comment.png +0 -0
  20. data/guide/images/custom_fields/custom_field_groups.png +0 -0
  21. data/guide/images/custom_fields/custom_field_types.png +0 -0
  22. data/guide/images/custom_fields/custom_fields.png +0 -0
  23. data/guide/images/custom_fields/edit_custom_field_general.png +0 -0
  24. data/guide/images/custom_fields/edit_custom_field_group.png +0 -0
  25. data/guide/images/custom_fields/edit_custom_field_settings.png +0 -0
  26. data/guide/images/custom_fields/edit_custom_field_type.png +0 -0
  27. data/guide/images/dashboard/added.png +0 -0
  28. data/guide/images/dashboard/columns.png +0 -0
  29. data/guide/images/dashboard/dashboard.png +0 -0
  30. data/guide/images/dashboard/options.png +0 -0
  31. data/guide/images/menus/edit_menu.png +0 -0
  32. data/guide/images/menus/edit_menu_item.png +0 -0
  33. data/guide/images/menus/menu_item_hierarchy.png +0 -0
  34. data/guide/images/menus/menu_items.png +0 -0
  35. data/guide/images/menus/menus.png +0 -0
  36. data/guide/images/sections/edit_entry.png +0 -0
  37. data/guide/images/sections/edit_entry_categories.png +0 -0
  38. data/guide/images/sections/edit_entry_general.png +0 -0
  39. data/guide/images/sections/edit_entry_meta.png +0 -0
  40. data/guide/images/sections/edit_section_comments.png +0 -0
  41. data/guide/images/sections/edit_section_general.png +0 -0
  42. data/guide/images/sections/edit_section_groups.png +0 -0
  43. data/guide/images/sections/entries.png +0 -0
  44. data/guide/images/sections/sections.png +0 -0
  45. data/guide/images/settings/overview_general.png +0 -0
  46. data/guide/images/settings/overview_security.png +0 -0
  47. data/guide/images/settings/overview_user.png +0 -0
  48. data/guide/images/users/edit_user.png +0 -0
  49. data/guide/images/users/edit_user_group.png +0 -0
  50. data/guide/images/users/edit_user_group_permissions.png +0 -0
  51. data/guide/images/users/edit_user_permissions.png +0 -0
  52. data/guide/images/users/overview.png +0 -0
  53. data/guide/images/users/user_groups_overview.png +0 -0
  54. data/guide/installation.md +7 -1
  55. data/guide/javascript.md +36 -273
  56. data/guide/javascript/zen_autosave.md +26 -0
  57. data/guide/javascript/zen_editor.md +83 -0
  58. data/guide/javascript/zen_hash.md +34 -0
  59. data/guide/javascript/zen_htmltable.md +78 -0
  60. data/guide/javascript/zen_tabs.md +44 -0
  61. data/guide/javascript/zen_window.md +49 -0
  62. data/guide/zen_compared.md +201 -0
  63. data/lib/vendor/sequel_sluggable.rb +1 -1
  64. data/lib/zen.rb +64 -44
  65. data/lib/zen/asset_groups.rb +10 -10
  66. data/lib/zen/bin/create.rb +8 -1
  67. data/lib/zen/helper/breadcrumb.rb +4 -12
  68. data/lib/zen/helper/controller.rb +209 -6
  69. data/lib/zen/helper/locale.rb +19 -0
  70. data/lib/zen/helper/search.rb +1 -1
  71. data/lib/zen/helper/stacked_aspect.rb +7 -43
  72. data/lib/zen/helper/theme.rb +3 -3
  73. data/lib/zen/language.rb +5 -10
  74. data/lib/zen/language/translation.rb +1 -1
  75. data/lib/zen/layout/admin.xhtml +41 -25
  76. data/lib/zen/layout/login.xhtml +8 -3
  77. data/lib/zen/migrator.rb +54 -0
  78. data/lib/zen/model/helper.rb +20 -1
  79. data/lib/zen/model/init.rb +2 -0
  80. data/lib/zen/model/plugin/events.rb +158 -0
  81. data/lib/zen/package.rb +32 -6
  82. data/lib/zen/package/all.rb +1 -0
  83. data/lib/zen/package/categories/lib/categories.rb +6 -6
  84. data/lib/zen/package/categories/lib/categories/controller/categories.rb +20 -83
  85. data/lib/zen/package/categories/lib/categories/controller/category_groups.rb +23 -74
  86. data/lib/zen/package/categories/lib/categories/model/category.rb +58 -1
  87. data/lib/zen/package/categories/lib/categories/model/category_group.rb +62 -2
  88. data/lib/zen/package/categories/lib/categories/view/admin/categories/form.xhtml +46 -40
  89. data/lib/zen/package/categories/lib/categories/view/admin/categories/index.xhtml +74 -75
  90. data/lib/zen/package/categories/lib/categories/view/admin/category-groups/form.xhtml +27 -24
  91. data/lib/zen/package/categories/lib/categories/view/admin/category-groups/index.xhtml +83 -86
  92. data/lib/zen/package/comments/lib/comments.rb +5 -5
  93. data/lib/zen/package/comments/lib/comments/controller/comments.rb +12 -64
  94. data/lib/zen/package/comments/lib/comments/controller/comments_form.rb +4 -22
  95. data/lib/zen/package/comments/lib/comments/model/comment.rb +65 -16
  96. data/lib/zen/package/comments/lib/comments/view/admin/comments/form.xhtml +52 -49
  97. data/lib/zen/package/comments/lib/comments/view/admin/comments/index.xhtml +52 -60
  98. data/lib/zen/package/comments/migrations/1308774099_comment_status.rb +1 -1
  99. data/lib/zen/package/custom_fields/lib/custom_fields.rb +11 -13
  100. data/lib/zen/package/custom_fields/lib/custom_fields/blue_form_parameters.rb +29 -13
  101. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_groups.rb +21 -50
  102. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_types.rb +27 -71
  103. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_fields.rb +25 -78
  104. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field.rb +48 -1
  105. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_group.rb +35 -1
  106. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_method.rb +3 -0
  107. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_type.rb +40 -1
  108. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_value.rb +1 -0
  109. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-groups/form.xhtml +29 -26
  110. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-groups/index.xhtml +96 -100
  111. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-types/form.xhtml +56 -53
  112. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-types/index.xhtml +82 -82
  113. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-fields/form.xhtml +88 -85
  114. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-fields/index.xhtml +83 -80
  115. data/lib/zen/package/dashboard/lib/dashboard.rb +28 -0
  116. data/lib/zen/package/dashboard/lib/dashboard/controller/dashboard.rb +154 -0
  117. data/lib/zen/package/dashboard/lib/dashboard/language/en/dashboard.rb +35 -0
  118. data/lib/zen/package/dashboard/lib/dashboard/language/nl/dashboard.rb +36 -0
  119. data/lib/zen/package/dashboard/lib/dashboard/model/widget.rb +45 -0
  120. data/lib/zen/package/dashboard/lib/dashboard/public/admin/dashboard/css/dashboard.css +74 -0
  121. data/lib/zen/package/dashboard/lib/dashboard/public/admin/dashboard/js/dashboard.js +102 -0
  122. data/lib/zen/package/dashboard/lib/dashboard/view/admin/index.xhtml +29 -0
  123. data/lib/zen/package/dashboard/lib/dashboard/view/admin/widget/welcome.xhtml +28 -0
  124. data/lib/zen/package/dashboard/lib/dashboard/widget.rb +292 -0
  125. data/lib/zen/package/dashboard/lib/dashboard/widget/welcome.rb +9 -0
  126. data/lib/zen/package/dashboard/migrations/1326411254_create_schema.rb +28 -0
  127. data/lib/zen/package/extensions/lib/extensions.rb +5 -5
  128. data/lib/zen/package/extensions/lib/extensions/view/admin/extensions/index.xhtml +72 -67
  129. data/lib/zen/package/menu.rb +6 -1
  130. data/lib/zen/package/menus/lib/menus.rb +6 -4
  131. data/lib/zen/package/menus/lib/menus/controller/menu_items.rb +69 -104
  132. data/lib/zen/package/menus/lib/menus/controller/menus.rb +19 -76
  133. data/lib/zen/package/menus/lib/menus/helper/menu.rb +54 -38
  134. data/lib/zen/package/menus/lib/menus/helper/menu_frontend.rb +7 -13
  135. data/lib/zen/package/menus/lib/menus/model/menu.rb +158 -2
  136. data/lib/zen/package/menus/lib/menus/model/menu_item.rb +73 -10
  137. data/lib/zen/package/menus/lib/menus/public/admin/menus/css/menus.css +47 -0
  138. data/lib/zen/package/menus/lib/menus/public/admin/menus/js/lib/nested_sortables.js +549 -0
  139. data/lib/zen/package/menus/lib/menus/public/admin/menus/js/menu_items.js +38 -0
  140. data/lib/zen/package/menus/lib/menus/view/admin/menu-items/form.xhtml +51 -61
  141. data/lib/zen/package/menus/lib/menus/view/admin/menu-items/index.xhtml +18 -81
  142. data/lib/zen/package/menus/lib/menus/view/admin/menus/form.xhtml +49 -44
  143. data/lib/zen/package/menus/lib/menus/view/admin/menus/index.xhtml +81 -83
  144. data/lib/zen/package/sections/lib/sections.rb +9 -4
  145. data/lib/zen/package/sections/lib/sections/controller/section_entries.rb +80 -132
  146. data/lib/zen/package/sections/lib/sections/controller/sections.rb +27 -73
  147. data/lib/zen/package/sections/lib/sections/helper/section.rb +44 -1
  148. data/lib/zen/package/sections/lib/sections/language/en/section_entries.rb +2 -0
  149. data/lib/zen/package/sections/lib/sections/language/nl/section_entries.rb +2 -0
  150. data/lib/zen/package/sections/lib/sections/model/section.rb +48 -1
  151. data/lib/zen/package/sections/lib/sections/model/section_entry.rb +55 -5
  152. data/lib/zen/package/sections/lib/sections/model/section_entry_status.rb +2 -0
  153. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/form.xhtml +76 -67
  154. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/index.xhtml +74 -79
  155. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/recent_entries.xhtml +45 -0
  156. data/lib/zen/package/sections/lib/sections/view/admin/sections/form.xhtml +119 -0
  157. data/lib/zen/package/sections/lib/sections/view/admin/sections/index.xhtml +96 -0
  158. data/lib/zen/package/sections/lib/sections/widget/recent_entries.rb +14 -0
  159. data/lib/zen/package/sections/migrations/1308813320_section_entry_statuses.rb +1 -1
  160. data/lib/zen/package/settings/lib/settings.rb +14 -5
  161. data/lib/zen/package/settings/lib/settings/controller/settings.rb +4 -4
  162. data/lib/zen/package/settings/lib/settings/language/nl/settings.rb +1 -1
  163. data/lib/zen/package/settings/lib/settings/setting.rb +1 -1
  164. data/lib/zen/package/settings/lib/settings/view/admin/settings/index.xhtml +21 -17
  165. data/lib/zen/package/users/lib/users.rb +18 -19
  166. data/lib/zen/package/users/lib/users/controller/user_groups.rb +23 -50
  167. data/lib/zen/package/users/lib/users/controller/users.rb +57 -89
  168. data/lib/zen/package/users/lib/users/helper/acl.rb +1 -0
  169. data/lib/zen/package/users/lib/users/language/en/user_groups.rb +1 -0
  170. data/lib/zen/package/users/lib/users/language/en/users.rb +2 -1
  171. data/lib/zen/package/users/lib/users/language/nl/user_groups.rb +1 -0
  172. data/lib/zen/package/users/lib/users/language/nl/users.rb +2 -1
  173. data/lib/zen/package/users/lib/users/model/permission.rb +13 -0
  174. data/lib/zen/package/users/lib/users/model/user.rb +57 -4
  175. data/lib/zen/package/users/lib/users/model/user_group.rb +37 -3
  176. data/lib/zen/package/users/lib/users/model/user_status.rb +4 -0
  177. data/lib/zen/package/users/lib/users/public/admin/{css/users/permissions.css → users/css/users.css} +0 -0
  178. data/lib/zen/package/users/lib/users/public/admin/{js/users/permissions.js → users/js/users.js} +4 -2
  179. data/lib/zen/package/users/lib/users/view/admin/user-groups/form.xhtml +51 -47
  180. data/lib/zen/package/users/lib/users/view/admin/user-groups/index.xhtml +62 -69
  181. data/lib/zen/package/users/lib/users/view/admin/users/form.xhtml +92 -82
  182. data/lib/zen/package/users/lib/users/view/admin/users/index.xhtml +68 -66
  183. data/lib/zen/package/users/lib/users/view/admin/users/login.xhtml +36 -28
  184. data/lib/zen/package/users/lib/users/view/admin/users/permissions.xhtml +5 -7
  185. data/lib/zen/package/users/lib/users/view/admin/users/register.xhtml +47 -41
  186. data/lib/zen/package/users/migrations/1320272365_status_ids.rb +1 -1
  187. data/lib/zen/public/admin/{js/vendor/mootools → mootools/js}/core.js +113 -108
  188. data/lib/zen/public/admin/{js/vendor/mootools → mootools/js}/more.js +99 -6
  189. data/lib/zen/public/admin/zen/css/buttons.css +106 -0
  190. data/lib/zen/public/admin/{css/zen → zen/css}/datepicker.css +45 -30
  191. data/lib/zen/public/admin/zen/css/editor.css +69 -0
  192. data/lib/zen/public/admin/{css/zen → zen/css}/forms.css +28 -30
  193. data/lib/zen/public/admin/zen/css/general.css +183 -0
  194. data/lib/zen/public/admin/zen/css/layout.css +224 -0
  195. data/lib/zen/public/admin/zen/css/messages.css +34 -0
  196. data/lib/zen/public/admin/{css/zen → zen/css}/reset.css +4 -9
  197. data/lib/zen/public/admin/zen/css/tables.css +57 -0
  198. data/lib/zen/public/admin/zen/css/tabs.css +84 -0
  199. data/lib/zen/public/admin/zen/css/window.css +74 -0
  200. data/lib/zen/public/admin/{images/zen → zen/images}/icons/asc.png +0 -0
  201. data/lib/zen/public/admin/{images/zen → zen/images}/icons/bold.png +0 -0
  202. data/lib/zen/public/admin/zen/images/icons/box.png +0 -0
  203. data/lib/zen/public/admin/zen/images/icons/categories.png +0 -0
  204. data/lib/zen/public/admin/{images/zen → zen/images}/icons/close.png +0 -0
  205. data/lib/zen/public/admin/zen/images/icons/comment.png +0 -0
  206. data/lib/zen/public/admin/{images/zen → zen/images}/icons/desc.png +0 -0
  207. data/lib/zen/public/admin/{images/zen → zen/images}/icons/edit.png +0 -0
  208. data/lib/zen/public/admin/{images/zen → zen/images}/icons/error.png +0 -0
  209. data/lib/zen/public/admin/zen/images/icons/external.png +0 -0
  210. data/lib/zen/public/admin/zen/images/icons/globe.png +0 -0
  211. data/lib/zen/public/admin/{images/zen → zen/images}/icons/italic.png +0 -0
  212. data/lib/zen/public/admin/{images/zen → zen/images}/icons/link.png +0 -0
  213. data/lib/zen/public/admin/zen/images/icons/lock.png +0 -0
  214. data/lib/zen/public/admin/{images/zen → zen/images}/icons/ol.png +0 -0
  215. data/lib/zen/public/admin/zen/images/icons/pages.png +0 -0
  216. data/lib/zen/public/admin/{images/zen → zen/images}/icons/preview.png +0 -0
  217. data/lib/zen/public/admin/zen/images/icons/relation.png +0 -0
  218. data/lib/zen/public/admin/zen/images/icons/settings.png +0 -0
  219. data/lib/zen/public/admin/zen/images/icons/template.png +0 -0
  220. data/lib/zen/public/admin/{images/zen → zen/images}/icons/ul.png +0 -0
  221. data/lib/zen/public/admin/{images/zen → zen/images}/icons/user.png +0 -0
  222. data/lib/zen/public/admin/zen/images/icons/user_group.png +0 -0
  223. data/lib/zen/public/admin/{js/zen → zen/js}/index.js +21 -9
  224. data/lib/zen/public/admin/zen/js/lib/autosave.js +185 -0
  225. data/lib/zen/public/admin/zen/js/lib/base.js +60 -0
  226. data/lib/zen/public/admin/{js/vendor → zen/js/lib}/datepicker.js +52 -28
  227. data/lib/zen/public/admin/{js/zen → zen/js}/lib/editor.js +23 -34
  228. data/lib/zen/public/admin/{js/zen → zen/js}/lib/editor/markdown.js +5 -1
  229. data/lib/zen/public/admin/{js/zen → zen/js}/lib/editor/textile.js +4 -0
  230. data/lib/zen/public/admin/zen/js/lib/hash.js +218 -0
  231. data/lib/zen/public/admin/{js/zen → zen/js}/lib/html_table.js +5 -0
  232. data/lib/zen/public/admin/zen/js/lib/tabs.js +194 -0
  233. data/lib/zen/public/admin/{js/zen → zen/js}/lib/window.js +54 -29
  234. data/lib/zen/security.rb +50 -0
  235. data/lib/zen/spec/helper.rb +5 -120
  236. data/lib/zen/spec/helper/capybara.rb +75 -0
  237. data/lib/zen/spec/helper/general.rb +75 -0
  238. data/lib/zen/spec/simplecov.rb +1 -0
  239. data/lib/zen/task/build.rake +2 -21
  240. data/lib/zen/task/clean.rake +1 -10
  241. data/lib/zen/task/db.rake +4 -10
  242. data/lib/zen/task/package.rake +2 -5
  243. data/lib/zen/task/setup.rake +1 -1
  244. data/lib/zen/task/test.rake +6 -6
  245. data/lib/zen/task/theme.rake +2 -5
  246. data/lib/zen/theme.rb +26 -22
  247. data/lib/zen/version.rb +1 -1
  248. data/lib/zen/view/bottom.xhtml +2 -3
  249. data/lib/zen/view/search.xhtml +3 -5
  250. data/proto/app/config/config.rb.erb +1 -1
  251. data/proto/app/theme/default/index.xhtml +116 -20
  252. data/proto/app/theme/partials/head.xhtml +9 -0
  253. data/proto/app/theme/partials/sidebar.xhtml +40 -0
  254. data/proto/app/theme/theme.rb +3 -0
  255. data/spec/Rakefile +1 -2
  256. data/spec/fixtures/zen/helper/stacked_aspect.rb +54 -0
  257. data/spec/fixtures/zen/package/dashboard/controller/widget.rb +15 -0
  258. data/spec/fixtures/zen/package/dashboard/widget.rb +5 -0
  259. data/spec/fixtures/zen/theme/theme.rb +2 -2
  260. data/spec/helper.rb +19 -10
  261. data/spec/zen/controller/admin_controller.rb +3 -3
  262. data/spec/zen/controller/main_controller.rb +7 -7
  263. data/spec/zen/controller/preview.rb +3 -3
  264. data/spec/zen/event.rb +4 -4
  265. data/spec/zen/helper/breadcrumb.rb +4 -8
  266. data/spec/zen/helper/controller.rb +47 -4
  267. data/spec/zen/helper/locale.rb +3 -3
  268. data/spec/zen/helper/message.rb +4 -4
  269. data/spec/zen/helper/stacked_aspect.rb +40 -0
  270. data/spec/zen/helper/theme.rb +9 -9
  271. data/spec/zen/language.rb +8 -8
  272. data/spec/zen/markup.rb +6 -6
  273. data/spec/zen/package.rb +11 -9
  274. data/spec/zen/package/categories/controller/categories.rb +56 -24
  275. data/spec/zen/package/categories/controller/category_groups.rb +55 -23
  276. data/spec/zen/package/categories/helper/category.rb +5 -5
  277. data/spec/zen/package/categories/helper/category_frontend.rb +5 -5
  278. data/spec/zen/package/comments/anti_spam.rb +4 -4
  279. data/spec/zen/package/comments/controller/comments.rb +95 -24
  280. data/spec/zen/package/comments/controller/comments_form.rb +31 -26
  281. data/spec/zen/package/comments/helper/comment.rb +3 -3
  282. data/spec/zen/package/comments/helper/comment_frontend.rb +6 -6
  283. data/spec/zen/package/custom_fields/blue_form_parameters.rb +8 -8
  284. data/spec/zen/package/custom_fields/controller/custom_field_groups.rb +58 -27
  285. data/spec/zen/package/custom_fields/controller/custom_field_types.rb +57 -27
  286. data/spec/zen/package/custom_fields/controller/custom_fields.rb +58 -27
  287. data/spec/zen/package/custom_fields/helper/custom_field.rb +7 -7
  288. data/spec/zen/package/dashboard/controller/dashboard.rb +147 -0
  289. data/spec/zen/package/dashboard/widget.rb +56 -0
  290. data/spec/zen/package/extensions/controller/extensions.rb +4 -4
  291. data/spec/zen/package/menus/controller/menu_items.rb +48 -39
  292. data/spec/zen/package/menus/controller/menus.rb +55 -24
  293. data/spec/zen/package/menus/helper/menu.rb +6 -14
  294. data/spec/zen/package/menus/helper/menu_frontend.rb +7 -7
  295. data/spec/zen/package/menus/model/menu.rb +121 -0
  296. data/spec/zen/package/menus/model/menu_item.rb +34 -0
  297. data/spec/zen/package/sections/controller/section_entries.rb +104 -39
  298. data/spec/zen/package/sections/controller/sections.rb +60 -27
  299. data/spec/zen/package/sections/helper/section.rb +5 -5
  300. data/spec/zen/package/sections/helper/section_frontend.rb +9 -9
  301. data/spec/zen/package/sections/widget.rb +44 -0
  302. data/spec/zen/package/settings/controller/settings.rb +18 -16
  303. data/spec/zen/package/settings/settings.rb +12 -12
  304. data/spec/zen/package/users/controller/user_groups.rb +61 -29
  305. data/spec/zen/package/users/controller/users.rb +118 -39
  306. data/spec/zen/package/users/helper/access.rb +3 -3
  307. data/spec/zen/package/users/helper/acl.rb +4 -4
  308. data/spec/zen/package/users/helper/users.rb +5 -5
  309. data/spec/zen/security.rb +25 -0
  310. data/spec/zen/theme.rb +20 -18
  311. data/spec/zen/validation.rb +5 -5
  312. data/spec/zen/vendor/sequel_sluggable.rb +12 -0
  313. data/zen.gemspec +27 -4
  314. metadata +182 -124
  315. data/AUTHORS +0 -4
  316. data/guide/_static/categories/categories.png +0 -0
  317. data/guide/_static/categories/category_groups.png +0 -0
  318. data/guide/_static/categories/new_category.png +0 -0
  319. data/guide/_static/categories/new_category_group.png +0 -0
  320. data/guide/_static/comments/comments.png +0 -0
  321. data/guide/_static/comments/edit_comment.png +0 -0
  322. data/guide/_static/custom_fields/custom_field_groups.png +0 -0
  323. data/guide/_static/custom_fields/custom_field_types.png +0 -0
  324. data/guide/_static/custom_fields/custom_fields.png +0 -0
  325. data/guide/_static/custom_fields/edit_custom_field_general.png +0 -0
  326. data/guide/_static/custom_fields/edit_custom_field_group.png +0 -0
  327. data/guide/_static/custom_fields/edit_custom_field_settings.png +0 -0
  328. data/guide/_static/custom_fields/edit_custom_field_type.png +0 -0
  329. data/guide/_static/menus/edit_menu.png +0 -0
  330. data/guide/_static/menus/edit_menu_item.png +0 -0
  331. data/guide/_static/menus/menu_items.png +0 -0
  332. data/guide/_static/menus/menus.png +0 -0
  333. data/guide/_static/sections/edit_entry.png +0 -0
  334. data/guide/_static/sections/edit_entry_categories.png +0 -0
  335. data/guide/_static/sections/edit_entry_general.png +0 -0
  336. data/guide/_static/sections/edit_entry_meta.png +0 -0
  337. data/guide/_static/sections/edit_section_comments.png +0 -0
  338. data/guide/_static/sections/edit_section_general.png +0 -0
  339. data/guide/_static/sections/edit_section_groups.png +0 -0
  340. data/guide/_static/sections/entries.png +0 -0
  341. data/guide/_static/sections/sections.png +0 -0
  342. data/guide/_static/settings/overview_general.png +0 -0
  343. data/guide/_static/settings/overview_security.png +0 -0
  344. data/guide/_static/settings/overview_user.png +0 -0
  345. data/guide/_static/users/edit_user.png +0 -0
  346. data/guide/_static/users/edit_user_group.png +0 -0
  347. data/guide/_static/users/edit_user_group_permissions.png +0 -0
  348. data/guide/_static/users/edit_user_permissions.png +0 -0
  349. data/guide/_static/users/overview.png +0 -0
  350. data/guide/_static/users/user_groups_overview.png +0 -0
  351. data/lib/zen/controller/translations.rb +0 -49
  352. data/lib/zen/package/sections/lib/sections/view/admin/form.xhtml +0 -113
  353. data/lib/zen/package/sections/lib/sections/view/admin/index.xhtml +0 -97
  354. data/lib/zen/public/admin/css/zen/buttons.css +0 -46
  355. data/lib/zen/public/admin/css/zen/editor.css +0 -88
  356. data/lib/zen/public/admin/css/zen/general.css +0 -109
  357. data/lib/zen/public/admin/css/zen/grid.css +0 -100
  358. data/lib/zen/public/admin/css/zen/layout.css +0 -184
  359. data/lib/zen/public/admin/css/zen/messages.css +0 -54
  360. data/lib/zen/public/admin/css/zen/tables.css +0 -97
  361. data/lib/zen/public/admin/css/zen/tabs.css +0 -47
  362. data/lib/zen/public/admin/css/zen/window.css +0 -73
  363. data/lib/zen/public/admin/images/zen/icons/accept.png +0 -0
  364. data/lib/zen/public/admin/images/zen/icons/add.png +0 -0
  365. data/lib/zen/public/admin/images/zen/icons/back.png +0 -0
  366. data/lib/zen/public/admin/images/zen/icons/delete.png +0 -0
  367. data/lib/zen/public/admin/images/zen/icons/help.png +0 -0
  368. data/lib/zen/public/admin/images/zen/icons/info.png +0 -0
  369. data/lib/zen/public/admin/images/zen/icons/logout.png +0 -0
  370. data/lib/zen/public/admin/images/zen/icons/pdf.png +0 -0
  371. data/lib/zen/public/admin/images/zen/icons/view.png +0 -0
  372. data/lib/zen/public/admin/js/zen/lib/tabs.js +0 -207
  373. data/lib/zen/view/main.xhtml +0 -19
@@ -49,58 +49,74 @@ module Ramaze
49
49
  end
50
50
 
51
51
  ##
52
- # Builds a hierarchy of navigation items and all their sub items. The
53
- # generated structure looks like the following:
52
+ # Builds the menu item tree that can be used by the user to edit the sort
53
+ # order, create the menu item tree and edit individual menu items.
54
54
  #
55
- # Root
56
- # |
57
- # |_ Sub
58
- # | |
59
- # | |_ Sub sub
60
- # |
61
- # |_ Sub 1
55
+ # @since 11-02-2012
56
+ # @param [Array] tree The menu item tree to process. This array should be
57
+ # in the format as returned by {Menus::Model::Menu#menu_items_tree}.
58
+ # @return [String]
62
59
  #
63
- # @since 0.2a
64
- # @param [Fixnum] menu_id The ID of the current menu group.
65
- # @return [Hash]
66
- #
67
- def menu_item_tree(menu_id)
68
- menu_items = ::Menus::Model::MenuItem.filter(
69
- :menu_id => menu_id,
70
- :parent_id => nil
71
- )
60
+ def menu_items_tree(tree)
61
+ gestalt = Ramaze::Gestalt.new
62
+ params = {:id => 'menu_items'}
72
63
 
73
- @menu_items_hash = {nil => '--'}
74
-
75
- menu_items.each do |item|
76
- @menu_items_hash[item.id] = item.name
64
+ unless user_authorized?(:edit_menu_item)
65
+ params[:'data-editable'] = false
66
+ end
77
67
 
78
- item.descendants.each do |i|
79
- descendant_items(i, 2)
68
+ gestalt.ul(params) do
69
+ tree.each do |item|
70
+ menu_item(item, gestalt)
80
71
  end
81
72
  end
82
73
 
83
- return @menu_items_hash
74
+ return gestalt.to_s
84
75
  end
85
76
 
77
+ private
78
+
86
79
  ##
87
- # Helper method for retrieving descendant navigation items.
80
+ # Builds the HTML for a single menu item and recursively calls itself for
81
+ # any sub menu items.
88
82
  #
89
- # @since 0.2a
90
- # @param [Menus::Model::MenuItem] item A MenuItem instance
91
- # @param [Fixnum] spaces The amount of unbreakable spaces to use.
83
+ # @since 11-02-2012
84
+ # @param [Hash] item A single menu item to process.
85
+ # @param [Ramaze::Gestalt] gestalt An instance of Ramaze::Gestalt to use
86
+ # for building the HTML.
92
87
  #
93
- def descendant_items(item, spaces)
94
- return if @menu_items_hash.key?(item.id)
88
+ def menu_item(item, gestalt)
89
+ gestalt.li(:id => "menu_item_#{item[:node].id}") do
90
+ gestalt.div(:class => 'menu_item') do
95
91
 
96
- nbsps = ''
97
- spaces.times { nbsps += " " }
98
- @menu_items_hash[item.id] = nbsps + item.name
99
- descendants = item.descendants
92
+ if user_authorized?(:delete_menu_item)
93
+ gestalt.input(
94
+ :type => 'checkbox',
95
+ :name => 'menu_item_ids[]',
96
+ :value => item[:node].id
97
+ )
98
+ end
99
+
100
+ if user_authorized?(:edit_menu_item)
101
+ edit_link(
102
+ Menus::Controller::MenuItems.r(
103
+ :edit,
104
+ item[:node].menu_id,
105
+ item[:node].id
106
+ ),
107
+ item[:node].name
108
+ )
109
+ else
110
+ item[:node].name
111
+ end
112
+ end
100
113
 
101
- if !descendants.empty?
102
- descendants.each do |i|
103
- self.descendant_items(i, spaces + 2)
114
+ unless item[:children].empty?
115
+ gestalt.ul do
116
+ item[:children].each do |child|
117
+ menu_item(child, gestalt)
118
+ end
119
+ end
104
120
  end
105
121
  end
106
122
  end
@@ -40,13 +40,6 @@ module Ramaze
40
40
  }.merge(options)
41
41
 
42
42
  menu = Menus::Model::Menu.find_by_pk_or_slug(menu)
43
- items = Menus::Model::MenuItem \
44
- .filter(:parent_id => nil, :menu_id => menu.id) \
45
- .limit(options[:limit]) \
46
- .order(:sort_order.send(options[:order])) \
47
- .eager(:parent) \
48
- .all
49
-
50
43
  g = Ramaze::Gestalt.new
51
44
  attrs = {}
52
45
  tree = {}
@@ -61,8 +54,8 @@ module Ramaze
61
54
 
62
55
  # Build the HTML
63
56
  g.ul(attrs) do
64
- items.each do |item|
65
- if item.parent_id.nil?
57
+ menu.menu_items_tree(options[:order], options[:limit]).each do |item|
58
+ if item[:node].parent_id.nil?
66
59
  render_menu_item(item, g, options)
67
60
  end
68
61
  end
@@ -77,14 +70,15 @@ module Ramaze
77
70
  # Generates the HTML for a single menu item.
78
71
  #
79
72
  # @since 0.3
80
- # @param [Menus::Model::MenuItem] item The menu item to render.
73
+ # @param [Hash] node A single node containing a :node and :children key.
81
74
  # @param [Ramaze::Gestalt] g An instance of ``Ramaze::Gestalt`` to use
82
75
  # for building the HTML.
83
76
  # @param [Hash] options A hash of options, see the options hash for
84
77
  # {Ramaze::Helper::MenuFrontend#render_menu} for more information.
85
78
  #
86
- def render_menu_item(item, g, options = {})
79
+ def render_menu_item(node, g, options = {})
87
80
  attrs = {}
81
+ item = node[:node]
88
82
 
89
83
  if !item.html_class.nil? and !item.html_class.empty?
90
84
  attrs[:class] = item.html_class
@@ -99,9 +93,9 @@ module Ramaze
99
93
 
100
94
  # Render any sub menu items
101
95
  if options[:sub] == true
102
- children = item.children
96
+ children = node[:children]
103
97
 
104
- if !children.empty?
98
+ unless children.empty?
105
99
  g.ul(:class => :children) do
106
100
  children.each { |child| render_menu_item(child, g, options) }
107
101
  end
@@ -4,15 +4,56 @@ module Menus
4
4
  ##
5
5
  # Model used for managing groups of menu items.
6
6
  #
7
- # @since 0.2a
7
+ # @example Automatically add a menu item
8
+ # Zen::Event.listen(:new_menu) do |menu|
9
+ # menu.add_menu_item(:name => 'Home', :url => '/', :html_id => 'home')
10
+ # end
11
+ #
12
+ # @example Remove duplicate menu items when editing a menu
13
+ # Zen::Event.listen(:edit_menu) do |menu|
14
+ # urls = []
15
+ #
16
+ # menu.items.each do |item|
17
+ # if urls.include?(item.url)
18
+ # item.destroy
19
+ # else
20
+ # urls << item.url
21
+ # end
22
+ # end
23
+ # end
24
+ #
25
+ # @since 0.2a
26
+ # @event before_new_menu
27
+ # @event after_new_menu
28
+ # @event before_edit_menu
29
+ # @event after_edit_menu
30
+ # @event before_delete_menu
31
+ # @event after_delete_menu
8
32
  #
9
33
  class Menu < Sequel::Model
10
34
  include Zen::Model::Helper
11
35
 
12
- plugin :sluggable, :source => :name, :freeze => false
36
+ ##
37
+ # Array containing all the columns that can be set by the user.
38
+ #
39
+ # @since 17-02-2012
40
+ #
41
+ COLUMNS = [:name, :slug, :description, :html_class, :html_id]
13
42
 
14
43
  one_to_many :menu_items, :class => 'Menus::Model::MenuItem'
15
44
 
45
+ plugin :sluggable, :source => :name, :freeze => false
46
+
47
+ plugin :association_dependencies, :menu_items => :delete
48
+
49
+ plugin :events,
50
+ :before_create => :before_new_menu,
51
+ :after_create => :after_new_menu,
52
+ :before_update => :before_edit_menu,
53
+ :after_update => :after_edit_menu,
54
+ :before_destroy => :before_delete_menu,
55
+ :after_destroy => :after_delete_menu
56
+
16
57
  ##
17
58
  # Searches for a set of menus.
18
59
  #
@@ -28,6 +69,81 @@ module Menus
28
69
  )
29
70
  end
30
71
 
72
+ ##
73
+ # Creates an array containing a hierarchy of menu items based on the
74
+ # values of the "id" and "parent_id" columns. The advantage of this method
75
+ # over the "tree" plugin that comes with Sequel is that it's capable of
76
+ # building this structure using only a single query, the downside is that
77
+ # it probably uses a bit more memory.
78
+ #
79
+ # The return value is an array of hashes. Each hash has the following
80
+ # format:
81
+ #
82
+ # {:node => #<Menus::Model::MenuItem>, :children => [...]}
83
+ #
84
+ # The :node key contains the menu item, the :children key contains an
85
+ # array which in turn contains all the sub nodes (and so on).
86
+ #
87
+ # On average this method is about 2.5 times faster than using the tree
88
+ # plugin's ``#children()`` method, see https://gist.github.com/1713481 for
89
+ # a small benchmark.
90
+ #
91
+ # @example
92
+ # def loop_nodes(node)
93
+ # puts node[:node].id
94
+ #
95
+ # node[:children].each do |child|
96
+ # loop_nodes(child)
97
+ # end
98
+ # end
99
+ #
100
+ # loop_nodes(Menus::Model::Menu[1].menu_items_tree)
101
+ #
102
+ # @since 30-01-2012
103
+ # @param [Symbol] order The sort order to apply to menu items, set to
104
+ # :asc by default.
105
+ # @param [Fixnum|NilClass] limit The maximum amount of menu items to
106
+ # retrieve. Set to unlimited by default.
107
+ # @return [Hash]
108
+ #
109
+ def menu_items_tree(order = :asc, limit = nil)
110
+ nodes = []
111
+ indexes = {}
112
+ rows = MenuItem.filter(:menu_id => id).limit(limit).all
113
+
114
+ rows.sort! do |left, right|
115
+ (left.parent_id || 0) <=> (right.parent_id || 0)
116
+ end
117
+
118
+ # Create the basic structure for each node and index said node.
119
+ rows.each do |item|
120
+ node = {:node => item, :children => []}
121
+ nodes << node
122
+
123
+ indexes[item.id] = nodes.rindex(node)
124
+ end
125
+
126
+ # Sort the nodes by their parent ID in descending order.
127
+ nodes.sort! do |left, right|
128
+ (left[:node].parent_id || 0) <=> (right[:node].parent_id || 0)
129
+ end
130
+
131
+ # Process the list of nodes in reverse order so that the child items can
132
+ # be assigned properly.
133
+ nodes.reverse.each do |node|
134
+ # If there's a matching parent node the current node should be
135
+ # assigned to that node and removed from the list. If there's no
136
+ # parent item then the node is un-modified.
137
+ if indexes[node[:node].parent_id]
138
+ index = indexes[node[:node].parent_id]
139
+
140
+ nodes[index][:children] << nodes.delete(node) if nodes[index]
141
+ end
142
+ end
143
+
144
+ return sort_menu_items(nodes, order)
145
+ end
146
+
31
147
  ##
32
148
  # Specifies all validates rules used when creating or updating a menu.
33
149
  #
@@ -40,6 +156,46 @@ module Menus
40
156
  validates_format(/^[a-zA-Z\-_0-9\s]*$/, :html_class)
41
157
  validates_format(/^[a-zA-Z\-_0-9]*$/ , :html_id)
42
158
  end
159
+
160
+ ##
161
+ # Hook that is executed before creating or saving an object.
162
+ #
163
+ # @since 03-01-2012
164
+ #
165
+ def before_save
166
+ sanitize_fields([:name, :slug, :description, :html_class, :html_id])
167
+
168
+ super
169
+ end
170
+
171
+ private
172
+
173
+ ##
174
+ # Sorts a set of sub nodes as returned by
175
+ # {Menus::Model::Menu#menu_item_tree}.
176
+ #
177
+ # @since 01-02-2012
178
+ # @param [Array] nodes An array of nodes to sort.
179
+ # @param [Symbol] order The sort order to apply.
180
+ # @return [Array]
181
+ #
182
+ def sort_menu_items(nodes, order = :asc)
183
+ return nodes if nodes.empty?
184
+
185
+ nodes.sort! do |left, right|
186
+ if order == :asc
187
+ left[:node].sort_order <=> right[:node].sort_order
188
+ else
189
+ right[:node].sort_order <=> left[:node].sort_order
190
+ end
191
+ end
192
+
193
+ nodes.each do |node|
194
+ node[:children] = sort_menu_items(node[:children])
195
+ end
196
+
197
+ return nodes
198
+ end
43
199
  end # Menu
44
200
  end # Model
45
201
  end # Menus
@@ -4,13 +4,44 @@ module Menus
4
4
  ##
5
5
  # Model used for managing individual menu items in a group.
6
6
  #
7
- # @since 0.2a
7
+ # @example Automatically prefix URLs with http
8
+ # Zen::Event.listen(:new_menu_item) do |item|
9
+ # unless item.url =~ /^http/
10
+ # item.url = 'http://' + item.url
11
+ # item.save
12
+ # end
13
+ # end
14
+ #
15
+ # @since 0.2a
16
+ # @event before_new_menu_item
17
+ # @event after_new_menu_item
18
+ # @event before_edit_menu_item
19
+ # @event after_edit_menu_item
20
+ # @event before_delete_menu_item
21
+ # @event after_delete_menu_item
8
22
  #
9
23
  class MenuItem < Sequel::Model
10
24
  include Zen::Model::Helper
11
25
 
26
+ ##
27
+ # Array containing the columns that can be set by the user.
28
+ #
29
+ # @since 17-02-2012
30
+ #
31
+ COLUMNS = [
32
+ :parent_id, :name, :url, :sort_order, :html_class, :html_id, :menu_id
33
+ ]
34
+
12
35
  plugin :tree, :order => :sort_order
13
36
 
37
+ plugin :events,
38
+ :before_create => :before_new_menu_item,
39
+ :after_create => :after_new_menu_item,
40
+ :before_update => :before_edit_menu_item,
41
+ :after_update => :after_edit_menu_item,
42
+ :before_destroy => :before_delete_menu_item,
43
+ :after_destroy => :after_delete_menu_item
44
+
14
45
  many_to_one :menu , :class => 'Menus::Model::Menu'
15
46
  many_to_one :parent, :class => self
16
47
 
@@ -29,6 +60,18 @@ module Menus
29
60
  )
30
61
  end
31
62
 
63
+ ##
64
+ # Sets the ID of the parent navigation item but *only* if it's not empty
65
+ # and not the same as the current ID.
66
+ #
67
+ # @since 0.3
68
+ # @param [Fixnum] parent_id The ID of the parent navigation item.
69
+ #
70
+ def parent_id=(parent_id)
71
+ return if parent_id == id
72
+ return super(parent_id)
73
+ end
74
+
32
75
  ##
33
76
  # Specifies all validation rules that will be used when creating or
34
77
  # updating a menu item.
@@ -36,7 +79,7 @@ module Menus
36
79
  # @since 0.2a
37
80
  #
38
81
  def validate
39
- validates_presence([:name, :url])
82
+ validates_presence([:name, :url, :menu_id])
40
83
  validates_max_length(255, [:name, :url, :html_class, :html_id])
41
84
  validates_integer([:sort_order, :parent_id])
42
85
  validates_format(/^[a-zA-Z\-_0-9\s]*$/, :html_class)
@@ -44,17 +87,37 @@ module Menus
44
87
  end
45
88
 
46
89
  ##
47
- # Sets the ID of the parent navigation item but *only* if it's not empty
48
- # and not the same as the current ID.
90
+ # Hook that is called before creating a new object.
49
91
  #
50
- # @since 0.3
51
- # @param [Fixnum] parent_id The ID of the parent navigation item.
92
+ # @since 28-02-2012
52
93
  #
53
- def parent_id=(parent_id)
54
- if !(parent_id.respond_to?(:empty?) and !parent_id.empty?) \
55
- and parent_id != self.id
56
- super(parent_id)
94
+ def before_create
95
+ # Set the sort order based on the order of the last item.
96
+ if self.sort_order.nil?
97
+ last = Zen.database[MenuItem.table_name] \
98
+ .select(:sort_order + 1 => :sort_order) \
99
+ .filter(:menu_id => self.menu_id) \
100
+ .order(:sort_order.desc) \
101
+ .limit(1) \
102
+ .first
103
+
104
+ unless last.nil?
105
+ self.sort_order = last[:sort_order]
106
+ end
57
107
  end
108
+
109
+ super
110
+ end
111
+
112
+ ##
113
+ # Hook that is executed before creating or saving an object.
114
+ #
115
+ # @since 03-01-2012
116
+ #
117
+ def before_save
118
+ sanitize_fields([:name, :url, :html_class, :html_id])
119
+
120
+ super
58
121
  end
59
122
  end # MenuItem
60
123
  end # Model