zen 0.2.8 → 0.3b

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 (422) hide show
  1. data/.gems +20 -0
  2. data/.mailmap +3 -2
  3. data/.rvmrc +1 -1
  4. data/.travis.yml +13 -2
  5. data/.yardopts +13 -0
  6. data/AUTHORS +1 -1
  7. data/README.md +115 -77
  8. data/Rakefile +6 -7
  9. data/bin/zen +12 -5
  10. data/guide/_static/categories/categories.png +0 -0
  11. data/guide/_static/categories/category_groups.png +0 -0
  12. data/guide/_static/categories/new_category.png +0 -0
  13. data/guide/_static/categories/new_category_group.png +0 -0
  14. data/guide/_static/comments/comments.png +0 -0
  15. data/guide/_static/comments/edit_comment.png +0 -0
  16. data/guide/_static/custom_fields/custom_field_groups.png +0 -0
  17. data/guide/_static/custom_fields/custom_field_types.png +0 -0
  18. data/guide/_static/custom_fields/custom_fields.png +0 -0
  19. data/guide/_static/custom_fields/edit_custom_field_general.png +0 -0
  20. data/guide/_static/custom_fields/edit_custom_field_group.png +0 -0
  21. data/guide/_static/custom_fields/edit_custom_field_settings.png +0 -0
  22. data/guide/_static/custom_fields/edit_custom_field_type.png +0 -0
  23. data/guide/_static/menus/edit_menu.png +0 -0
  24. data/guide/_static/menus/edit_menu_item.png +0 -0
  25. data/guide/_static/menus/menu_items.png +0 -0
  26. data/guide/_static/menus/menus.png +0 -0
  27. data/guide/_static/sections/edit_entry.png +0 -0
  28. data/guide/_static/sections/edit_entry_categories.png +0 -0
  29. data/guide/_static/sections/edit_entry_general.png +0 -0
  30. data/guide/_static/sections/edit_entry_meta.png +0 -0
  31. data/guide/_static/sections/edit_section_comments.png +0 -0
  32. data/guide/_static/sections/edit_section_general.png +0 -0
  33. data/guide/_static/sections/edit_section_groups.png +0 -0
  34. data/guide/_static/sections/entries.png +0 -0
  35. data/guide/_static/sections/sections.png +0 -0
  36. data/guide/_static/settings/overview_general.png +0 -0
  37. data/guide/_static/settings/overview_security.png +0 -0
  38. data/guide/_static/settings/overview_user.png +0 -0
  39. data/guide/_static/users/edit_user.png +0 -0
  40. data/guide/_static/users/edit_user_group.png +0 -0
  41. data/guide/_static/users/edit_user_group_permissions.png +0 -0
  42. data/guide/_static/users/edit_user_permissions.png +0 -0
  43. data/guide/_static/users/overview.png +0 -0
  44. data/guide/_static/users/user_groups_overview.png +0 -0
  45. data/guide/asset_management.md +117 -0
  46. data/{CHANGELOG.md → guide/changelog.md} +42 -0
  47. data/guide/css/common.css +20 -0
  48. data/guide/getting_started.md +61 -0
  49. data/guide/hacking.md +52 -0
  50. data/guide/installation.md +44 -0
  51. data/guide/javascript.md +352 -0
  52. data/lib/vendor/sequel_sluggable.rb +137 -0
  53. data/lib/yard/tags.rb +13 -0
  54. data/lib/zen.rb +148 -78
  55. data/lib/zen/asset_groups.rb +85 -0
  56. data/lib/zen/bin/create.rb +267 -56
  57. data/lib/zen/bin/default.rb +84 -0
  58. data/lib/zen/controller/admin_controller.rb +1 -82
  59. data/lib/zen/controller/base_controller.rb +9 -5
  60. data/lib/zen/controller/frontend_controller.rb +0 -1
  61. data/lib/zen/controller/main_controller.rb +30 -42
  62. data/lib/zen/controller/preview.rb +9 -8
  63. data/lib/zen/controller/translations.rb +49 -0
  64. data/lib/zen/error.rb +17 -0
  65. data/lib/zen/event.rb +118 -0
  66. data/lib/zen/helper/asset.rb +63 -0
  67. data/lib/zen/helper/breadcrumb.rb +1 -4
  68. data/lib/zen/helper/controller.rb +73 -0
  69. data/lib/zen/helper/locale.rb +42 -0
  70. data/lib/zen/helper/message.rb +0 -3
  71. data/lib/zen/helper/search.rb +54 -0
  72. data/lib/zen/helper/stacked_aspect.rb +249 -0
  73. data/lib/zen/helper/theme.rb +3 -10
  74. data/lib/zen/language.rb +356 -181
  75. data/lib/zen/language/en/zen_general.rb +52 -0
  76. data/lib/zen/language/en/zen_models.rb +19 -0
  77. data/lib/zen/language/nl/zen_general.rb +57 -0
  78. data/lib/zen/language/nl/zen_models.rb +22 -0
  79. data/lib/zen/language/translation.rb +132 -0
  80. data/lib/zen/languages.rb +9 -0
  81. data/lib/zen/layout/admin.xhtml +3 -3
  82. data/lib/zen/layout/login.xhtml +1 -1
  83. data/lib/zen/markup.rb +189 -0
  84. data/lib/zen/model/helper.rb +65 -0
  85. data/lib/zen/model/init.rb +62 -0
  86. data/lib/zen/model/methods.rb +6 -7
  87. data/lib/zen/package.rb +312 -201
  88. data/lib/zen/package/all.rb +4 -3
  89. data/lib/zen/package/categories/lib/categories.rb +29 -41
  90. data/lib/zen/package/categories/lib/categories/controller/categories.rb +185 -130
  91. data/lib/zen/package/categories/lib/categories/controller/category_groups.rb +172 -102
  92. data/lib/zen/package/categories/lib/categories/helper/category.rb +4 -9
  93. data/lib/zen/package/categories/lib/categories/helper/category_frontend.rb +86 -0
  94. data/lib/zen/package/categories/lib/categories/language/en/categories.rb +40 -0
  95. data/lib/zen/package/categories/lib/categories/language/en/category_groups.rb +39 -0
  96. data/lib/zen/package/categories/lib/categories/language/nl/categories.rb +42 -0
  97. data/lib/zen/package/categories/lib/categories/language/nl/category_groups.rb +42 -0
  98. data/lib/zen/package/categories/lib/categories/model/category.rb +21 -25
  99. data/lib/zen/package/categories/lib/categories/model/category_group.rb +21 -15
  100. data/lib/zen/package/categories/lib/categories/view/admin/categories/form.xhtml +25 -26
  101. data/lib/zen/package/categories/lib/categories/view/admin/categories/index.xhtml +24 -24
  102. data/lib/zen/package/categories/lib/categories/view/admin/category-groups/form.xhtml +18 -20
  103. data/lib/zen/package/categories/lib/categories/view/admin/category-groups/index.xhtml +21 -18
  104. data/lib/zen/package/comments/lib/comments.rb +30 -50
  105. data/lib/zen/package/comments/lib/comments/anti_spam.rb +138 -0
  106. data/lib/zen/package/comments/lib/comments/controller/comments.rb +159 -92
  107. data/lib/zen/package/comments/lib/comments/controller/comments_form.rb +122 -34
  108. data/lib/zen/package/comments/lib/comments/helper/comment.rb +0 -3
  109. data/lib/zen/package/comments/lib/comments/helper/comment_frontend.rb +90 -0
  110. data/lib/zen/package/comments/lib/comments/language/en/comments.rb +57 -0
  111. data/lib/zen/package/comments/lib/comments/language/nl/comments.rb +61 -0
  112. data/lib/zen/package/comments/lib/comments/model/comment.rb +147 -49
  113. data/lib/zen/package/comments/lib/comments/model/comment_status.rb +0 -2
  114. data/lib/zen/package/comments/lib/comments/view/admin/comments/form.xhtml +37 -40
  115. data/lib/zen/package/comments/lib/comments/view/admin/comments/index.xhtml +23 -42
  116. data/lib/zen/package/comments/migrations/1308774099_comment_status.rb +12 -4
  117. data/lib/zen/package/comments/migrations/1313851786_remove_defensio_signature.rb +11 -0
  118. data/lib/zen/package/custom_fields/lib/custom_fields.rb +40 -43
  119. data/lib/zen/package/custom_fields/lib/custom_fields/blue_form_parameters.rb +72 -17
  120. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_groups.rb +154 -118
  121. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_field_types.rb +147 -90
  122. data/lib/zen/package/custom_fields/lib/custom_fields/controller/custom_fields.rb +161 -131
  123. data/lib/zen/package/custom_fields/lib/custom_fields/helper/custom_field.rb +4 -9
  124. data/lib/zen/package/custom_fields/lib/custom_fields/language/en/custom_field_groups.rb +42 -0
  125. data/lib/zen/package/custom_fields/lib/custom_fields/language/en/custom_field_types.rb +51 -0
  126. data/lib/zen/package/custom_fields/lib/custom_fields/language/en/custom_fields.rb +60 -0
  127. data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_field_groups.rb +41 -0
  128. data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_field_types.rb +49 -0
  129. data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_fields.rb +61 -0
  130. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field.rb +18 -23
  131. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_group.rb +20 -19
  132. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_method.rb +1 -3
  133. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_type.rb +19 -9
  134. data/lib/zen/package/custom_fields/lib/custom_fields/model/custom_field_value.rb +18 -15
  135. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-groups/form.xhtml +18 -18
  136. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-groups/index.xhtml +30 -24
  137. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-types/form.xhtml +15 -10
  138. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-field-types/index.xhtml +24 -19
  139. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-fields/form.xhtml +18 -13
  140. data/lib/zen/package/custom_fields/lib/custom_fields/view/admin/custom-fields/index.xhtml +30 -20
  141. data/lib/zen/package/extensions/lib/extensions.rb +20 -0
  142. data/lib/zen/package/extensions/lib/extensions/controller/extensions.rb +41 -0
  143. data/lib/zen/package/extensions/lib/extensions/language/en/extensions.rb +23 -0
  144. data/lib/zen/package/extensions/lib/extensions/language/nl/extensions.rb +25 -0
  145. data/lib/zen/package/extensions/lib/extensions/view/admin/extensions/index.xhtml +86 -0
  146. data/lib/zen/package/menu.rb +109 -0
  147. data/lib/zen/package/menus/lib/menus.rb +25 -34
  148. data/lib/zen/package/menus/lib/menus/controller/menu_items.rb +143 -107
  149. data/lib/zen/package/menus/lib/menus/controller/menus.rb +166 -115
  150. data/lib/zen/package/menus/lib/menus/helper/menu.rb +2 -8
  151. data/lib/zen/package/menus/lib/menus/helper/menu_frontend.rb +114 -0
  152. data/lib/zen/package/menus/lib/menus/language/en/menu_items.rb +48 -0
  153. data/lib/zen/package/menus/lib/menus/language/en/menus.rb +48 -0
  154. data/lib/zen/package/menus/lib/menus/language/nl/menu_items.rb +48 -0
  155. data/lib/zen/package/menus/lib/menus/language/nl/menus.rb +50 -0
  156. data/lib/zen/package/menus/lib/menus/model/menu.rb +24 -17
  157. data/lib/zen/package/menus/lib/menus/model/menu_item.rb +37 -13
  158. data/lib/zen/package/menus/lib/menus/view/admin/menu-items/form.xhtml +32 -25
  159. data/lib/zen/package/menus/lib/menus/view/admin/menu-items/index.xhtml +23 -17
  160. data/lib/zen/package/menus/lib/menus/view/admin/menus/form.xhtml +31 -26
  161. data/lib/zen/package/menus/lib/menus/view/admin/menus/index.xhtml +20 -22
  162. data/lib/zen/package/sections/lib/sections.rb +25 -68
  163. data/lib/zen/package/sections/lib/sections/controller/section_entries.rb +178 -138
  164. data/lib/zen/package/sections/lib/sections/controller/sections.rb +173 -140
  165. data/lib/zen/package/sections/lib/sections/helper/section.rb +3 -6
  166. data/lib/zen/package/sections/lib/sections/helper/section_frontend.rb +146 -0
  167. data/lib/zen/package/sections/lib/sections/language/en/section_entries.rb +50 -0
  168. data/lib/zen/package/sections/lib/sections/language/en/sections.rb +55 -0
  169. data/lib/zen/package/sections/lib/sections/language/nl/section_entries.rb +50 -0
  170. data/lib/zen/package/sections/lib/sections/language/nl/sections.rb +55 -0
  171. data/lib/zen/package/sections/lib/sections/model/section.rb +36 -36
  172. data/lib/zen/package/sections/lib/sections/model/section_entry.rb +52 -59
  173. data/lib/zen/package/sections/lib/sections/model/section_entry_status.rb +2 -2
  174. data/lib/zen/package/sections/lib/sections/view/admin/form.xhtml +24 -21
  175. data/lib/zen/package/sections/lib/sections/view/admin/index.xhtml +24 -26
  176. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/form.xhtml +33 -31
  177. data/lib/zen/package/sections/lib/sections/view/admin/section-entries/index.xhtml +24 -25
  178. data/lib/zen/package/sections/migrations/1308672298_use_id_for_default_section.rb +14 -10
  179. data/lib/zen/package/sections/migrations/1308813320_section_entry_statuses.rb +12 -6
  180. data/lib/zen/package/settings/lib/settings.rb +25 -120
  181. data/lib/zen/package/settings/lib/settings/blue_form_parameters.rb +157 -0
  182. data/lib/zen/package/settings/lib/settings/controller/settings.rb +94 -69
  183. data/lib/zen/package/settings/lib/settings/language/en/settings.rb +41 -0
  184. data/lib/zen/package/settings/lib/settings/language/nl/settings.rb +41 -0
  185. data/lib/zen/package/settings/lib/settings/model/setting.rb +0 -2
  186. data/lib/zen/package/settings/lib/settings/setting.rb +379 -0
  187. data/lib/zen/package/settings/lib/settings/setting_groups.rb +11 -0
  188. data/lib/zen/package/settings/lib/settings/settings.rb +83 -0
  189. data/lib/zen/package/settings/lib/settings/settings_group.rb +84 -0
  190. data/lib/zen/package/settings/lib/settings/singleton_methods.rb +35 -0
  191. data/lib/zen/package/settings/lib/settings/view/admin/settings/index.xhtml +15 -57
  192. data/lib/zen/package/settings/migrations/1321197919_remove_unused_columns.rb +17 -0
  193. data/lib/zen/package/users/lib/users.rb +51 -36
  194. data/lib/zen/package/users/lib/users/controller/user_groups.rb +133 -98
  195. data/lib/zen/package/users/lib/users/controller/users.rb +253 -136
  196. data/lib/zen/package/users/lib/users/helper/access.rb +102 -0
  197. data/lib/zen/package/users/lib/users/helper/acl.rb +113 -0
  198. data/lib/zen/package/users/lib/users/helper/users.rb +41 -24
  199. data/lib/zen/package/users/lib/users/language/en/permissions.rb +16 -0
  200. data/lib/zen/package/users/lib/users/language/en/user_groups.rb +39 -0
  201. data/lib/zen/package/users/lib/users/language/en/users.rb +73 -0
  202. data/lib/zen/package/users/lib/users/language/nl/permissions.rb +16 -0
  203. data/lib/zen/package/users/lib/users/language/nl/user_groups.rb +41 -0
  204. data/lib/zen/package/users/lib/users/language/nl/users.rb +74 -0
  205. data/lib/zen/package/users/lib/users/model/permission.rb +28 -0
  206. data/lib/zen/package/users/lib/users/model/user.rb +104 -65
  207. data/lib/zen/package/users/lib/users/model/user_group.rb +28 -24
  208. data/lib/zen/package/users/lib/users/model/user_status.rb +27 -0
  209. data/lib/zen/package/users/lib/users/public/admin/css/users/permissions.css +22 -0
  210. data/lib/zen/package/users/lib/users/public/admin/js/users/permissions.js +33 -0
  211. data/lib/zen/package/users/lib/users/settings.rb +19 -0
  212. data/lib/zen/package/users/lib/users/view/admin/user-groups/form.xhtml +58 -28
  213. data/lib/zen/package/users/lib/users/view/admin/user-groups/index.xhtml +19 -15
  214. data/lib/zen/package/users/lib/users/view/admin/users/form.xhtml +93 -62
  215. data/lib/zen/package/users/lib/users/view/admin/users/index.xhtml +23 -36
  216. data/lib/zen/package/users/lib/users/view/admin/users/login.xhtml +13 -6
  217. data/lib/zen/package/users/lib/users/view/admin/users/permissions.xhtml +33 -0
  218. data/lib/zen/package/users/lib/users/view/admin/users/register.xhtml +52 -0
  219. data/lib/zen/package/users/migrations/1313786058_update_default_date.rb +41 -0
  220. data/lib/zen/package/users/migrations/1316432327_permissions.rb +36 -0
  221. data/lib/zen/package/users/migrations/1320272365_status_ids.rb +67 -0
  222. data/lib/zen/public/admin/css/zen/buttons.css +3 -11
  223. data/lib/zen/public/admin/css/zen/datepicker.css +23 -13
  224. data/lib/zen/public/admin/css/zen/editor.css +6 -14
  225. data/lib/zen/public/admin/css/zen/forms.css +19 -12
  226. data/lib/zen/public/admin/css/zen/general.css +22 -18
  227. data/lib/zen/public/admin/css/zen/grid.css +1 -20
  228. data/lib/zen/public/admin/css/zen/layout.css +26 -11
  229. data/lib/zen/public/admin/css/zen/messages.css +3 -10
  230. data/lib/zen/public/admin/css/zen/reset.css +13 -15
  231. data/lib/zen/public/admin/css/zen/tables.css +8 -10
  232. data/lib/zen/public/admin/css/zen/tabs.css +2 -10
  233. data/lib/zen/public/admin/css/zen/window.css +2 -8
  234. data/lib/zen/public/admin/js/vendor/datepicker.js +540 -240
  235. data/lib/zen/public/admin/js/vendor/mootools/core.js +273 -283
  236. data/lib/zen/public/admin/js/vendor/mootools/more.js +131 -136
  237. data/lib/zen/public/admin/js/zen/index.js +8 -14
  238. data/lib/zen/public/admin/js/zen/lib/editor.js +36 -33
  239. data/lib/zen/public/admin/js/zen/lib/editor/markdown.js +0 -6
  240. data/lib/zen/public/admin/js/zen/lib/editor/textile.js +0 -6
  241. data/lib/zen/public/admin/js/zen/lib/html_table.js +0 -5
  242. data/lib/zen/public/admin/js/zen/lib/tabs.js +22 -79
  243. data/lib/zen/public/admin/js/zen/lib/window.js +12 -22
  244. data/lib/zen/spec/bacon/color_output.rb +1 -1
  245. data/lib/zen/spec/helper.rb +6 -11
  246. data/lib/zen/spec/simplecov.rb +3 -3
  247. data/lib/zen/task.rb +0 -1
  248. data/lib/zen/task/build.rake +46 -26
  249. data/lib/zen/task/clean.rake +14 -7
  250. data/lib/zen/task/db.rake +31 -29
  251. data/lib/zen/task/package.rake +19 -23
  252. data/lib/zen/task/proto.rake +3 -5
  253. data/lib/zen/task/setup.rake +4 -0
  254. data/lib/zen/task/test.rake +31 -6
  255. data/lib/zen/task/theme.rake +13 -19
  256. data/lib/zen/theme.rb +377 -52
  257. data/lib/zen/validation.rb +22 -30
  258. data/lib/zen/version.rb +1 -2
  259. data/lib/zen/view/bottom.xhtml +9 -1
  260. data/lib/zen/view/head.xhtml +1 -1
  261. data/lib/zen/view/main.xhtml +1 -1
  262. data/lib/zen/view/search.xhtml +9 -0
  263. data/proto/app/Rakefile +0 -1
  264. data/proto/app/app.rb +21 -16
  265. data/proto/app/config/config.rb.erb +41 -0
  266. data/proto/app/config/{database.rb → database.rb.erb} +17 -14
  267. data/proto/app/config/middlewares.rb +1 -1
  268. data/proto/app/theme/default/index.xhtml +25 -0
  269. data/proto/app/theme/theme.rb +19 -0
  270. data/proto/app/{log/database/dev → tmp}/.gitkeep +0 -0
  271. data/proto/migration.rb +3 -5
  272. data/proto/rack/thin.yml +41 -0
  273. data/proto/rack/unicorn.rb +38 -0
  274. data/spec/Rakefile +15 -11
  275. data/spec/fixtures/zen/helper/controller.rb +13 -0
  276. data/spec/fixtures/zen/helper/locale.rb +7 -0
  277. data/spec/fixtures/zen/helper/message.rb +0 -4
  278. data/spec/fixtures/zen/language.rb +31 -0
  279. data/spec/fixtures/zen/language/en/spec.rb +11 -0
  280. data/spec/fixtures/zen/language/nl/spec.rb +11 -0
  281. data/spec/fixtures/zen/package.rb +0 -10
  282. data/spec/fixtures/zen/package/categories/helper/category_frontend.rb +16 -0
  283. data/spec/fixtures/zen/package/comments/helper/comment_frontend.rb +16 -0
  284. data/spec/fixtures/zen/package/sections/helper/section_frontend.rb +16 -0
  285. data/spec/fixtures/zen/package/settings/controller/settings.rb +17 -0
  286. data/spec/fixtures/zen/package/users/helper/access.rb +18 -0
  287. data/spec/fixtures/zen/package/users/helper/acl.rb +23 -0
  288. data/spec/fixtures/zen/theme/{default-section → default}/index.xhtml +0 -0
  289. data/spec/helper.rb +12 -27
  290. data/{proto/app/log/database/live → spec/public}/.gitkeep +0 -0
  291. data/spec/zen/controller/admin_controller.rb +5 -6
  292. data/spec/zen/controller/main_controller.rb +29 -35
  293. data/spec/zen/controller/preview.rb +9 -10
  294. data/spec/zen/event.rb +44 -0
  295. data/spec/zen/helper/breadcrumb.rb +4 -5
  296. data/spec/zen/helper/controller.rb +21 -0
  297. data/spec/zen/helper/locale.rb +25 -0
  298. data/spec/zen/helper/message.rb +4 -11
  299. data/spec/zen/helper/theme.rb +11 -14
  300. data/spec/zen/language.rb +48 -22
  301. data/spec/zen/markup.rb +39 -0
  302. data/spec/zen/package.rb +48 -11
  303. data/spec/zen/package/categories/controller/categories.rb +99 -45
  304. data/spec/zen/package/categories/controller/category_groups.rb +109 -33
  305. data/spec/zen/package/categories/helper/category.rb +19 -32
  306. data/spec/zen/package/categories/helper/category_frontend.rb +61 -0
  307. data/spec/zen/package/comments/anti_spam.rb +50 -0
  308. data/spec/zen/package/comments/controller/comments.rb +121 -61
  309. data/spec/zen/package/comments/controller/comments_form.rb +120 -94
  310. data/spec/zen/package/comments/helper/comment.rb +13 -13
  311. data/spec/zen/package/comments/helper/comment_frontend.rb +92 -0
  312. data/spec/zen/package/custom_fields/blue_form_parameters.rb +50 -50
  313. data/spec/zen/package/custom_fields/controller/custom_field_groups.rb +135 -43
  314. data/spec/zen/package/custom_fields/controller/custom_field_types.rb +153 -48
  315. data/spec/zen/package/custom_fields/controller/custom_fields.rb +130 -51
  316. data/spec/zen/package/custom_fields/helper/custom_field.rb +8 -8
  317. data/spec/zen/package/extensions/controller/extensions.rb +38 -0
  318. data/spec/zen/package/menus/controller/menu_items.rb +121 -42
  319. data/spec/zen/package/menus/controller/menus.rb +125 -38
  320. data/spec/zen/package/menus/helper/menu.rb +26 -26
  321. data/spec/zen/package/menus/helper/menu_frontend.rb +104 -0
  322. data/spec/zen/package/sections/controller/section_entries.rb +145 -89
  323. data/spec/zen/package/sections/controller/sections.rb +130 -35
  324. data/spec/zen/package/sections/helper/section.rb +27 -38
  325. data/spec/zen/package/sections/helper/section_frontend.rb +160 -0
  326. data/spec/zen/package/settings/controller/settings.rb +73 -8
  327. data/spec/zen/package/settings/settings.rb +119 -0
  328. data/spec/zen/package/users/controller/user_groups.rb +134 -34
  329. data/spec/zen/package/users/controller/users.rb +189 -44
  330. data/spec/zen/package/users/helper/access.rb +29 -0
  331. data/spec/zen/package/users/helper/acl.rb +46 -0
  332. data/spec/zen/package/users/helper/users.rb +20 -64
  333. data/spec/zen/theme.rb +7 -9
  334. data/spec/zen/validation.rb +1 -2
  335. data/zen.gemspec +25 -22
  336. metadata +303 -222
  337. data/lib/zen/asset.rb +0 -292
  338. data/lib/zen/bin/runner.rb +0 -118
  339. data/lib/zen/error/language_error.rb +0 -10
  340. data/lib/zen/error/package_error.rb +0 -10
  341. data/lib/zen/error/plugin_error.rb +0 -10
  342. data/lib/zen/error/theme_error.rb +0 -10
  343. data/lib/zen/error/validation_error.rb +0 -10
  344. data/lib/zen/helper/acl.rb +0 -182
  345. data/lib/zen/helper/blue_form_vendor.rb +0 -689
  346. data/lib/zen/language/en/zen_general.yml +0 -25
  347. data/lib/zen/language/en/zen_models.yml +0 -13
  348. data/lib/zen/language/nl/zen_general.yml +0 -25
  349. data/lib/zen/language/nl/zen_models.yml +0 -13
  350. data/lib/zen/model/settings.rb +0 -78
  351. data/lib/zen/package/base.rb +0 -62
  352. data/lib/zen/package/categories/lib/categories/language/en/categories.yml +0 -36
  353. data/lib/zen/package/categories/lib/categories/language/en/category_groups.yml +0 -34
  354. data/lib/zen/package/categories/lib/categories/language/nl/categories.yml +0 -40
  355. data/lib/zen/package/categories/lib/categories/language/nl/category_groups.yml +0 -34
  356. data/lib/zen/package/categories/lib/categories/plugin/categories.rb +0 -141
  357. data/lib/zen/package/comments/lib/comments/language/en/comments.yml +0 -48
  358. data/lib/zen/package/comments/lib/comments/language/nl/comments.yml +0 -50
  359. data/lib/zen/package/comments/lib/comments/plugin/anti_spam.rb +0 -156
  360. data/lib/zen/package/comments/lib/comments/plugin/comments.rb +0 -115
  361. data/lib/zen/package/custom_fields/lib/custom_fields/language/en/custom_field_groups.yml +0 -33
  362. data/lib/zen/package/custom_fields/lib/custom_fields/language/en/custom_field_types.yml +0 -40
  363. data/lib/zen/package/custom_fields/lib/custom_fields/language/en/custom_fields.yml +0 -54
  364. data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_field_groups.yml +0 -33
  365. data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_field_types.yml +0 -40
  366. data/lib/zen/package/custom_fields/lib/custom_fields/language/nl/custom_fields.yml +0 -54
  367. data/lib/zen/package/menus/lib/menus/language/en/menu_items.yml +0 -41
  368. data/lib/zen/package/menus/lib/menus/language/en/menus.yml +0 -40
  369. data/lib/zen/package/menus/lib/menus/language/nl/menu_items.yml +0 -41
  370. data/lib/zen/package/menus/lib/menus/language/nl/menus.yml +0 -40
  371. data/lib/zen/package/menus/lib/menus/plugin/menus.rb +0 -152
  372. data/lib/zen/package/sections/lib/sections/language/en/section_entries.yml +0 -44
  373. data/lib/zen/package/sections/lib/sections/language/en/sections.yml +0 -48
  374. data/lib/zen/package/sections/lib/sections/language/nl/section_entries.yml +0 -44
  375. data/lib/zen/package/sections/lib/sections/language/nl/sections.yml +0 -48
  376. data/lib/zen/package/sections/lib/sections/plugin/section_entries.rb +0 -244
  377. data/lib/zen/package/sections/lib/sections/plugin/sections.rb +0 -87
  378. data/lib/zen/package/settings/lib/settings/language/en/settings.yml +0 -36
  379. data/lib/zen/package/settings/lib/settings/language/nl/settings.yml +0 -37
  380. data/lib/zen/package/settings/lib/settings/plugin/group_base.rb +0 -39
  381. data/lib/zen/package/settings/lib/settings/plugin/setting_base.rb +0 -133
  382. data/lib/zen/package/settings/lib/settings/plugin/settings.rb +0 -251
  383. data/lib/zen/package/users/lib/users/controller/access_rules.rb +0 -284
  384. data/lib/zen/package/users/lib/users/language/en/access_rules.yml +0 -38
  385. data/lib/zen/package/users/lib/users/language/en/user_groups.yml +0 -32
  386. data/lib/zen/package/users/lib/users/language/en/users.yml +0 -57
  387. data/lib/zen/package/users/lib/users/language/nl/access_rules.yml +0 -38
  388. data/lib/zen/package/users/lib/users/language/nl/user_groups.yml +0 -32
  389. data/lib/zen/package/users/lib/users/language/nl/users.yml +0 -57
  390. data/lib/zen/package/users/lib/users/model/access_rule.rb +0 -42
  391. data/lib/zen/package/users/lib/users/public/admin/js/users/access_rules.js +0 -65
  392. data/lib/zen/package/users/lib/users/public/admin/js/users/lib/access_rules.js +0 -49
  393. data/lib/zen/package/users/lib/users/view/admin/access-rules/form.xhtml +0 -120
  394. data/lib/zen/package/users/lib/users/view/admin/access-rules/index.xhtml +0 -102
  395. data/lib/zen/plugin.rb +0 -182
  396. data/lib/zen/plugin/base.rb +0 -46
  397. data/lib/zen/plugin/helper.rb +0 -47
  398. data/lib/zen/plugin/markup/lib/markup.rb +0 -14
  399. data/lib/zen/plugin/markup/lib/markup/language/en/markup.yml +0 -6
  400. data/lib/zen/plugin/markup/lib/markup/markup.rb +0 -165
  401. data/lib/zen/public/admin/js/zen/lib/asset.js +0 -111
  402. data/lib/zen/task/plugin.rake +0 -18
  403. data/lib/zen/theme/base.rb +0 -65
  404. data/proto/app/config/config.rb +0 -18
  405. data/spec/fixtures/zen/language/en/spec.yml +0 -10
  406. data/spec/fixtures/zen/language/nl/spec.yml +0 -7
  407. data/spec/fixtures/zen/package/settings/plugin/settings.rb +0 -20
  408. data/spec/zen/asset.rb +0 -97
  409. data/spec/zen/bin/create.rb +0 -89
  410. data/spec/zen/bin/runner.rb +0 -47
  411. data/spec/zen/helper/acl.rb +0 -149
  412. data/spec/zen/package/categories/plugin/categories.rb +0 -92
  413. data/spec/zen/package/comments/plugin/anti_spam.rb +0 -59
  414. data/spec/zen/package/comments/plugin/comments.rb +0 -107
  415. data/spec/zen/package/menus/plugin/menus.rb +0 -120
  416. data/spec/zen/package/sections/plugin/section_entries.rb +0 -161
  417. data/spec/zen/package/sections/plugin/sections.rb +0 -75
  418. data/spec/zen/package/settings/plugin/settings.rb +0 -33
  419. data/spec/zen/package/users/controller/access_rules.rb +0 -90
  420. data/spec/zen/plugin.rb +0 -64
  421. data/spec/zen/plugin/helper.rb +0 -11
  422. data/spec/zen/plugin/markup.rb +0 -44
@@ -1,40 +1,31 @@
1
- Ramaze::HelpersHelper.options.paths.push(__DIR__('menus'))
2
-
3
- require __DIR__('menus/model/menu')
4
- require __DIR__('menus/model/menu_item')
5
- require __DIR__('menus/controller/menus')
6
- require __DIR__('menus/controller/menu_items')
7
- require __DIR__('menus/plugin/menus')
8
-
9
- Zen::Language.options.paths.push(__DIR__('menus'))
10
- Zen::Language.load('menus')
11
- Zen::Language.load('menu_items')
12
-
13
1
  Zen::Package.add do |p|
14
- p.name = 'menus'
15
- p.author = 'Yorick Peterse'
16
- p.url = 'http://zen-cms.com/userguide/menus'
17
- p.about = 'The Menus extension allows you to easily create navigation menus
18
- for the frontend.'
2
+ p.name = :menus
3
+ p.title = 'menus.titles.index'
4
+ p.author = 'Yorick Peterse'
5
+ p.url = 'http://zen-cms.com/'
6
+ p.about = 'menus.description'
7
+ p.root = __DIR__('menus')
8
+ p.migrations = __DIR__('../migrations')
19
9
 
20
- p.directory = __DIR__('menus')
21
- p.migration_dir = __DIR__('../migrations')
10
+ p.menu('menus.titles.index', '/admin/menus', :permission => :show_menu)
22
11
 
23
- p.menu = [{
24
- :title => lang('menus.titles.index'),
25
- :url => "/admin/menus"
26
- }]
12
+ p.permission :show_menu , 'menus.permissions.show'
13
+ p.permission :edit_menu , 'menus.permissions.edit'
14
+ p.permission :new_menu , 'menus.permissions.new'
15
+ p.permission :delete_menu, 'menus.permissions.delete'
27
16
 
28
- p.controllers = {
29
- lang('menus.titles.index') => Menus::Controller::Menus,
30
- lang('menu_items.titles.index') => Menus::Controller::MenuItems
31
- }
17
+ p.permission :show_menu_item , 'menu_items.permissions.show'
18
+ p.permission :edit_menu_item , 'menu_items.permissions.edit'
19
+ p.permission :new_menu_item , 'menu_items.permissions.new'
20
+ p.permission :delete_menu_item, 'menu_items.permissions.delete'
32
21
  end
33
22
 
34
- Zen::Plugin.add do |p|
35
- p.name = 'menus'
36
- p.author = 'Yorick Peterse'
37
- p.url = 'http://yorickpeterse.com/'
38
- p.about = 'Plugin that can be used to display a navigation menu.'
39
- p.plugin = Menus::Plugin::Menus
40
- end
23
+ Zen::Language.load('menus')
24
+ Zen::Language.load('menu_items')
25
+
26
+ require __DIR__('menus/model/menu')
27
+ require __DIR__('menus/model/menu_item')
28
+ require __DIR__('menus/controller/menus')
29
+ require __DIR__('menus/controller/menu_items')
30
+
31
+ Zen::Controller::FrontendController.helper(:menu_frontend)
@@ -1,62 +1,82 @@
1
- #:nodoc:
2
1
  module Menus
3
2
  #:nodoc:
4
3
  module Controller
5
4
  ##
6
- # Controller for managing individual navigation items that belong to a menu.
5
+ # The MenuItems controller allows users to manage menu items of a menu
6
+ # group. In order to manage menu items you must first navigate to a menu
7
+ # group and click the link "Manage menu items" (see
8
+ # {Menus::Controller::Menus} for more information). Once you've reached this
9
+ # page you'll see an overview that looks like the image below.
10
+ #
11
+ # ![Menu Items](../../_static/menus/menu_items.png)
12
+ #
13
+ # Editing or creating a menu item can be done by either clicking the name of
14
+ # a menu item or by clicking the "Add menu item" button. In both cases
15
+ # you'll end up with a form looking like the one in the following image:
16
+ #
17
+ # ![Edit Menu Item](../../_static/menus/edit_menu_item.png)
18
+ #
19
+ # In this form you can specify the following fields:
20
+ #
21
+ # * **Name**: the name of the menu item.
22
+ # * **URL**: the URL of the menu item.
23
+ # * **Order**: a number that indicates the sort order when the menu is
24
+ # built.
25
+ # * **Parent**: a parent menu item. This allows you to easily create sub
26
+ # menus.
27
+ # * **HTML class**: a space separated list of classes to apply to the HTML
28
+ # element.
29
+ # * **HTML ID**: a single ID to apply to the HTML element.
30
+ #
31
+ # Note that the name, URL, HTML class and HTML ID fields have a maximum
32
+ # length of 255 characters.
33
+ #
34
+ # ## Used Permissions
35
+ #
36
+ # * show_menu_item
37
+ # * new_menu_item
38
+ # * edit_menu_item
39
+ # * delete_menu_item
40
+ #
41
+ # ## Events
42
+ #
43
+ # All events in this controller receive an instance of
44
+ # {Menus::Model::MenuItem}. Just like other packages the event
45
+ # ``delete_menu_item`` receives an instance that has already been destroyed.
46
+ #
47
+ # @example Automatically prefix URLs with http
48
+ # Zen::Event.listen(:new_menu_item) do |item|
49
+ # unless item.url =~ /^http/
50
+ # item.url = 'http://' + item.url
51
+ # item.save
52
+ # end
53
+ # end
7
54
  #
8
- # @author Yorick Peterse
9
55
  # @since 0.2a
56
+ # @map /admin/menu-items
57
+ # @event before_new_menu_item
58
+ # @event after_new_menu_item
59
+ # @event before_edit_menu_item
60
+ # @event after_edit_menu_item
61
+ # @event before_delete_menu_item
62
+ # @event after_delete_menu_item
10
63
  #
11
- class MenuItems < ::Zen::Controller::AdminController
12
- include ::Menus::Model
13
-
14
- map '/admin/menu-items'
64
+ class MenuItems < Zen::Controller::AdminController
65
+ map '/admin/menu-items'
15
66
  helper :menu
67
+ title 'menu_items.titles.%s'
16
68
 
17
- before_all do
18
- csrf_protection(:save, :delete) do
19
- respond(lang('zen_general.errors.csrf'), 403)
20
- end
21
- end
22
-
23
- ##
24
- # Initializes the class, loads all language packs and sets the form URLs.
25
- #
26
- # This method loads the following language files:
27
- #
28
- # * menus
29
- # * menu_items
30
- #
31
- # @author Yorick Peterse
32
- # @since 0.2a
33
- #
34
- def initialize
35
- super
36
-
37
- Zen::Language.load('menu_items')
38
- Zen::Language.load('menus')
39
-
40
- # Set the page title based on the current method
41
- if !action.method.nil?
42
- method = action.method.to_sym
43
- @page_title = lang("menu_items.titles.#{method}") rescue nil
44
- end
45
- end
69
+ csrf_protection :save, :delete
46
70
 
47
71
  ##
48
- # Show an overview of all navigation items for the current navigation menu.
72
+ # Shows an overview of all the menu items for a menu group.
49
73
  #
50
- # This method requires the following permissions:
51
- #
52
- # * read
53
- #
54
- # @author Yorick Peterse
55
- # @since 0.2a
56
- # @param [Integer] menu_id The ID of the current navigation menu.
74
+ # @since 0.2a
75
+ # @param [Fixnum] menu_id The ID of the current navigation menu.
76
+ # @permission show_menu_item
57
77
  #
58
78
  def index(menu_id)
59
- require_permissions(:read)
79
+ authorize_user!(:show_menu_item)
60
80
 
61
81
  menu = validate_menu(menu_id)
62
82
 
@@ -66,32 +86,35 @@ module Menus
66
86
  )
67
87
 
68
88
  @menu_id = menu_id
69
- @menu_items = MenuItem.filter(:menu_id => menu_id)
89
+ @menu_items = search do |query|
90
+ ::Menus::Model::MenuItem.search(query) \
91
+ .filter(:menu_id => menu_id) \
92
+ .order(:id.asc)
93
+ end
94
+
95
+ @menu_items ||= ::Menus::Model::MenuItem \
96
+ .filter(:menu_id => menu_id) \
97
+ .order(:id.asc)
98
+
70
99
  @menu_items = paginate(@menu_items)
71
100
  end
72
101
 
73
102
  ##
74
- # Allow the user to edit an existing navigation item.
75
- #
76
- # This method requires the following permissions:
77
- #
78
- # * read
79
- # * update
103
+ # Allow the user to create a new menu item for the current menu.
80
104
  #
81
- # @author Yorick Peterse
82
- # @since 0.2a
83
- # @param [Integer] menu_id The ID of the current navigation menu.
84
- # @param [Integer] id The ID of the menu item to edit.
105
+ # @since 0.2a
106
+ # @param [Fixnum] menu_id The ID of the current navigation menu.
107
+ # @permission new_menu_item
85
108
  #
86
- def edit(menu_id, id)
87
- require_permissions(:read, :update)
109
+ def new(menu_id)
110
+ authorize_user!(:new_menu_item)
88
111
 
89
112
  validate_menu(menu_id)
90
113
 
91
114
  set_breadcrumbs(
92
115
  Menus.a(lang('menus.titles.index'), :index),
93
116
  MenuItems.a(lang('menu_items.titles.index'), :index, menu_id),
94
- lang('menu_items.titles.edit')
117
+ lang('menu_items.titles.new')
95
118
  )
96
119
 
97
120
  @menu_id = menu_id
@@ -99,37 +122,38 @@ module Menus
99
122
  if flash[:form_data]
100
123
  @menu_item = flash[:form_data]
101
124
  else
102
- @menu_item = validate_menu_item(id, menu_id)
125
+ @menu_item = ::Menus::Model::MenuItem.new
103
126
  end
104
127
 
105
128
  render_view(:form)
106
129
  end
107
130
 
108
131
  ##
109
- # Allow the user to create a new menu item for the current menu.
110
- #
111
- # This method requires the following permissions:
112
- #
113
- # * read
114
- # * create
132
+ # Allow the user to edit an existing navigation item.
115
133
  #
116
- # @author Yorick Peterse
117
- # @since 0.2a
118
- # @param [Integer] menu_id The ID of the current navigation menu.
134
+ # @since 0.2a
135
+ # @param [Fixnum] menu_id The ID of the current navigation menu.
136
+ # @param [Fixnum] id The ID of the menu item to edit.
137
+ # @permission edit_menu_item
119
138
  #
120
- def new(menu_id)
121
- require_permissions(:create, :read)
139
+ def edit(menu_id, id)
140
+ authorize_user!(:edit_menu_item)
122
141
 
123
142
  validate_menu(menu_id)
124
143
 
125
144
  set_breadcrumbs(
126
145
  Menus.a(lang('menus.titles.index'), :index),
127
146
  MenuItems.a(lang('menu_items.titles.index'), :index, menu_id),
128
- lang('menu_items.titles.new')
147
+ lang('menu_items.titles.edit')
129
148
  )
130
149
 
131
- @menu_id = menu_id
132
- @menu_item = MenuItem.new
150
+ @menu_id = menu_id
151
+
152
+ if flash[:form_data]
153
+ @menu_item = flash[:form_data]
154
+ else
155
+ @menu_item = validate_menu_item(id, menu_id)
156
+ end
133
157
 
134
158
  render_view(:form)
135
159
  end
@@ -138,13 +162,13 @@ module Menus
138
162
  # Saves an existing menu iten or creates a new one using the supplied
139
163
  # POST data.
140
164
  #
141
- # This method requires the following permissions:
142
- #
143
- # * create
144
- # * update
145
- #
146
- # @author Yorick Peterse
147
- # @since 0.2a
165
+ # @since 0.2a
166
+ # @permission edit_menu_item (when editing an item)
167
+ # @permission new_menu_item (when creating an item)
168
+ # @event before_edit_menu_item
169
+ # @event after_edit_menu_item
170
+ # @event before_new_menu_item
171
+ # @event after_new_menu_item
148
172
  #
149
173
  def save
150
174
  post = request.subset(
@@ -158,62 +182,67 @@ module Menus
158
182
  :menu_id
159
183
  )
160
184
 
161
- if post['parent_id'].empty? or post['parent_id'] === post['id']
185
+ if post['parent_id'].empty? or post['parent_id'] == post['id']
162
186
  post['parent_id'] = nil
163
187
  end
164
188
 
165
189
  # Determine if we're saving changes made to an existing menu item or
166
190
  # if we're going to create a new one.
167
191
  if post.key?('id') and !post['id'].empty?
168
- require_permissions(:update)
192
+ authorize_user!(:edit_menu_item)
169
193
 
170
- @menu_item = validate_menu_item(post['id'], post['menu_id'])
171
- save_action = :save
194
+ menu_item = validate_menu_item(post['id'], post['menu_id'])
195
+ save_action = :save
196
+ before_event = :before_edit_menu_item
197
+ after_event = :after_edit_menu_item
172
198
  else
173
- require_permissions(:create)
199
+ authorize_user!(:new_menu_item)
174
200
 
175
- @menu_item = MenuItem.new
176
- save_action = :new
201
+ menu_item = ::Menus::Model::MenuItem.new
202
+ save_action = :new
203
+ before_event = :before_new_menu_item
204
+ after_event = :after_new_menu_item
177
205
  end
178
206
 
179
207
  post.delete('id')
180
208
 
181
209
  # Set our notifications
182
- flash_success = lang("menu_items.success.#{save_action}")
183
- flash_error = lang("menu_items.errors.#{save_action}")
210
+ success = lang("menu_items.success.#{save_action}")
211
+ error = lang("menu_items.errors.#{save_action}")
184
212
 
185
213
  # Time to save the data
186
214
  begin
187
- @menu_item.update(post)
188
- message(:success, flash_success)
215
+ post.each { |k, v| menu_item.send("#{k}=", v) }
216
+ Zen::Event.call(before_event, menu_item)
217
+
218
+ menu_item.save
189
219
  rescue => e
190
220
  Ramaze::Log.error(e.inspect)
191
- message(:error, flash_error)
221
+ message(:error, error)
192
222
 
193
- flash[:form_data] = @menu_item
194
- flash[:form_errors] = @menu_item.errors
223
+ flash[:form_data] = menu_item
224
+ flash[:form_errors] = menu_item.errors
195
225
 
196
226
  redirect_referrer
197
227
  end
198
228
 
199
- if @menu_item.id
200
- redirect(MenuItems.r(:edit, @menu_item.menu_id, @menu_item.id))
201
- else
202
- redirect_referrer
203
- end
229
+ Zen::Event.call(after_event, menu_item)
230
+
231
+ message(:success, success)
232
+ redirect(MenuItems.r(:edit, menu_item.menu_id, menu_item.id))
204
233
  end
205
234
 
206
235
  ##
207
236
  # Delete all specified menu items based on the values in the POST array
208
- # "menu_item_ids". This method requires the following permissions:
237
+ # "menu_item_ids".
209
238
  #
210
- # * delete
211
- #
212
- # @author Yorick Peterse
213
- # @since 0.2a
239
+ # @since 0.2a
240
+ # @permission delete_menu_item
241
+ # @event before_delete_menu_item
242
+ # @event after_delete_menu_item
214
243
  #
215
244
  def delete
216
- require_permissions(:delete)
245
+ authorize_user!(:delete_menu_item)
217
246
 
218
247
  post = request.subset(:menu_item_ids)
219
248
 
@@ -223,14 +252,21 @@ module Menus
223
252
  end
224
253
 
225
254
  post['menu_item_ids'].each do |id|
255
+ menu = ::Menus::Model::MenuItem[id]
256
+
257
+ next if menu.nil?
258
+ Zen::Event.call(:before_delete_menu_item, menu)
259
+
226
260
  begin
227
- MenuItem[id].destroy
261
+ menu.destroy
228
262
  rescue => e
229
263
  Ramaze::Log.error(e.inspect)
230
264
  message(:error, lang('menu_items.errors.delete') % id)
231
265
 
232
266
  redirect_referrer
233
267
  end
268
+
269
+ Zen::Event.call(:after_delete_menu_item, menu)
234
270
  end
235
271
 
236
272
  message(:success, lang('menu_items.success.delete'))
@@ -1,137 +1,183 @@
1
- #:nodoc:
1
+ ##
2
+ # Package for managing menus and menu items.
3
+ #
4
+ # ## Controllers
5
+ #
6
+ # * {Menus::Controller::Menus}
7
+ # * {Menus::Controller::MenuItems}
8
+ #
9
+ # ## Helpers
10
+ #
11
+ # * {Ramaze::Helper::Menu}
12
+ # * {Ramaze::Helper::MenuFrontend}
13
+ #
14
+ # ## Models
15
+ #
16
+ # * {Menus::Model::Menu}
17
+ # * {Menus::Model::MenuItem}
18
+ #
2
19
  module Menus
3
20
  #:nodoc:
4
21
  module Controller
5
22
  ##
6
- # Controller for managing menu groups. Individual navigation items are
7
- # managed using the menu items controller, simply named "menu_items".
23
+ # The Menus controller allows you to create custom menu groups. You can
24
+ # create large menu structures without having to write a single line of
25
+ # code. In order to start managing your menus you must first navigate to
26
+ # ``/admin/menus`` (there's a navigation item called "Menus" that you can
27
+ # also use). Once you've reached this page you'll see an overview of all
28
+ # your existing menus or a message telling you that no menus were found (if
29
+ # this is the case). An example of such an overview can be seen in the image
30
+ # below.
31
+ #
32
+ # ![Menus Overview](../../_static/menus/menus.png)
33
+ #
34
+ # This overview allows you to edit, create or remove menu groups as well as
35
+ # managing the menu items of a group. Editing a group can be done by
36
+ # clicking the name of the group, creating a new one can be done by clicking
37
+ # the button "Add menu". In both cases you'll end up with the form shown in
38
+ # the image below.
39
+ #
40
+ # ![Edit Menu](../../_static/menus/edit_menu.png)
41
+ #
42
+ # In this form you can use the following fields:
43
+ #
44
+ # * **Name** (required): the name of the menu.
45
+ # * **Slug**: a URL friendly version of the name. If none is specified it
46
+ # will be generated automatically based on the name of the menu.
47
+ # * **HTML class**: a space separated list of classes to apply to the HTML
48
+ # element. The format of this field should match the regular exresspion
49
+ # ``^[a-zA-Z\-_0-9\s]*$``
50
+ # * **HTML ID**: an ID to apply to the HTML element. This value should match
51
+ # the regular expression ``^[a-zA-Z\-_0-9]*$``.
52
+ # * **Description**: the description of the menu.
53
+ #
54
+ # Note that all fields except the description field have a maximum length of
55
+ # 255 characters.
56
+ #
57
+ # ## Used Permissions
58
+ #
59
+ # * show_menu
60
+ # * new_menu
61
+ # * edit_menu
62
+ # * delete_menu
63
+ #
64
+ # ## Events
65
+ #
66
+ # All events in this controller receive an instance of {Menus::Model::Menu}.
67
+ # Just like other packages the event ``delete_menu`` receives an instance
68
+ # that has already been destroyed.
69
+ #
70
+ # @example Automatically add a menu item
71
+ # Zen::Event.listen(:new_menu) do |menu|
72
+ # menu.add_menu_item(:name => 'Home', :url => '/', :html_id => 'home')
73
+ # end
74
+ #
75
+ # @example Remove duplicate menu items when editing a menu
76
+ # Zen::Event.listen(:edit_menu) do |menu|
77
+ # urls = []
78
+ #
79
+ # menu.items.each do |item|
80
+ # if urls.include?(item.url)
81
+ # item.destroy
82
+ # else
83
+ # urls << item.url
84
+ # end
85
+ # end
86
+ # end
8
87
  #
9
- # @author Yorick Peterse
10
88
  # @since 0.2a
89
+ # @map /admin/menus
90
+ # @event before_new_menu
91
+ # @event after_new_menu
92
+ # @event before_edit_menu
93
+ # @event after_edit_menu
94
+ # @event before_delete_menu
95
+ # @event after_delete_menu
11
96
  #
12
97
  class Menus < Zen::Controller::AdminController
13
- include ::Menus::Model
14
-
15
- map '/admin/menus'
98
+ map '/admin/menus'
16
99
  helper :menu
100
+ title 'menus.titles.%s'
17
101
 
18
- before_all do
19
- csrf_protection(:save, :delete) do
20
- respond(lang('zen_general.errors.csrf'), 403)
21
- end
22
- end
23
-
24
- ##
25
- # Initializes the class and loads all required language packs.
26
- #
27
- # This method loads the following language files:
28
- #
29
- # * menus
30
- #
31
- # @author Yorick Peterse
32
- # @since 0.2a
33
- #
34
- def initialize
35
- super
36
-
37
- Zen::Language.load('menus')
38
-
39
- # Set the page title
40
- if !action.method.nil?
41
- method = action.method.to_sym
42
- @page_title = lang("menus.titles.#{method}") rescue nil
43
- end
44
- end
102
+ csrf_protection :save, :delete
45
103
 
46
104
  ##
47
105
  # Shows an overview of all exisitng menus and a few properties of these
48
106
  # groups such as the name, slug and the amount of items in that group.
49
107
  #
50
- # This method requires the following permissions:
51
- #
52
- # * read
53
- #
54
- # @author Yorick Peterse
55
- # @since 0.2a
108
+ # @since 0.2a
109
+ # @permission show_menu
56
110
  #
57
111
  def index
58
- require_permissions(:read)
112
+ authorize_user!(:show_menu)
59
113
 
60
114
  set_breadcrumbs(lang('menus.titles.index'))
61
115
 
62
- @menus = paginate(Menu)
116
+ @menus = search do |query|
117
+ ::Menus::Model::Menu.search(query).order(:id.asc)
118
+ end
119
+
120
+ @menus ||= ::Menus::Model::Menu.order(:id.asc)
121
+ @menus = paginate(@menus)
63
122
  end
64
123
 
65
124
  ##
66
- # Show a form that allows the user to edit the details (such as the name
67
- # and slug) of a menu group. This method can not be used to manage all
68
- # menu items for this group.
69
- #
70
- # This method requires the following permissions:
71
- #
72
- # * read
73
- # * update
125
+ # Show a form that can be used to create a new menu group. Once a menu
126
+ # group has been created users can start adding navigation items to the
127
+ # group.
74
128
  #
75
- # @author Yorick Peterse
76
- # @since 0.2a
129
+ # @since 0.2a
130
+ # @permission new_menu
77
131
  #
78
- def edit(id)
79
- require_permissions(:read, :update)
132
+ def new
133
+ authorize_user!(:new_menu)
80
134
 
81
135
  set_breadcrumbs(
82
136
  Menus.a(lang('menus.titles.index'), :index),
83
137
  @page_title
84
138
  )
85
139
 
86
- if flash[:form_data]
87
- @menu = flash[:form_data]
88
- else
89
- @menu = validate_menu(id)
90
- end
140
+ @menu = ::Menus::Model::Menu.new
91
141
 
92
142
  render_view(:form)
93
143
  end
94
144
 
95
145
  ##
96
- # Show a form that can be used to create a new menu group. Once a menu
97
- # group has been created users can start adding navigation items to the
98
- # group.
99
- #
100
- # This method requires the following permissions:
101
- #
102
- # * create
103
- # * read
146
+ # Show a form that allows the user to edit the details (such as the name
147
+ # and slug) of a menu group. This method can not be used to manage all
148
+ # menu items for this group.
104
149
  #
105
- # @author Yorick Peterse
106
- # @since 0.2a
150
+ # @since 0.2a
151
+ # @param [Fixnum] id The ID of the menu to edit.
152
+ # @permission edit_menu
107
153
  #
108
- def new
109
- require_permissions(:create, :read)
154
+ def edit(id)
155
+ authorize_user!(:edit_menu)
110
156
 
111
157
  set_breadcrumbs(
112
158
  Menus.a(lang('menus.titles.index'), :index),
113
159
  @page_title
114
160
  )
115
161
 
116
- @menu = Menu.new
162
+ if flash[:form_data]
163
+ @menu = flash[:form_data]
164
+ else
165
+ @menu = validate_menu(id)
166
+ end
117
167
 
118
168
  render_view(:form)
119
169
  end
120
170
 
121
171
  ##
122
- # Saves the changes made to an existing menu group or creates a new group
123
- # using the supplied POST data. In order to detect this forms that contain
124
- # data of an existing group should have a hidden field named "id", the
125
- # value of this field is the primary value of the menu group of which the
126
- # changes should be saved.
172
+ # Saves any changes made to an existing menu or creates a new menu.
127
173
  #
128
- # This method requires the following permissions:
129
- #
130
- # * create
131
- # * update
132
- #
133
- # @author Yorick Peterse
134
- # @since 0.2a
174
+ # @since 0.2a
175
+ # @event before_edit_menu
176
+ # @event after_edit_menu
177
+ # @event before_new_menu
178
+ # @event after_new_menu
179
+ # @permission edit_menu (when editing an existing menu)
180
+ # @permission new_menu (when creating a new menu)
135
181
  #
136
182
  def save
137
183
  post = request.subset(
@@ -145,45 +191,46 @@ module Menus
145
191
 
146
192
  # Determine if we're creating a new group or modifying an existing one.
147
193
  if post.key?('id') and !post['id'].empty?
148
- require_permissions(:update)
194
+ authorize_user!(:edit_menu)
149
195
 
150
- @menu = validate_menu(post['id'])
151
- save_action = :save
196
+ menu = validate_menu(post['id'])
197
+ save_action = :save
198
+ before_event = :before_edit_menu
199
+ after_event = :after_edit_menu
152
200
  else
153
- require_permissions(:create)
201
+ authorize_user!(:new_menu)
154
202
 
155
- @menu = Menu.new
156
- save_action = :new
157
-
158
- # Delete the slug if it's empty
159
- post.delete('slug') if post['slug'].empty?
203
+ menu = ::Menus::Model::Menu.new
204
+ save_action = :new
205
+ before_event = :before_new_menu
206
+ after_event = :after_new_menu
160
207
  end
161
208
 
162
209
  post.delete('id')
163
210
 
164
- flash_success = lang("menus.success.#{save_action}")
165
- flash_error = lang("menus.errors.#{save_action}")
211
+ success = lang("menus.success.#{save_action}")
212
+ error = lang("menus.errors.#{save_action}")
166
213
 
167
214
  # Let's see if we can insert/update the data
168
215
  begin
169
- @menu.update(post)
170
- message(:success, flash_success)
216
+ post.each { |k, v| menu.send("#{k}=", v) }
217
+ Zen::Event.call(before_event, menu)
218
+
219
+ menu.save
171
220
  rescue => e
172
221
  Ramaze::Log.error(e.inspect)
173
- message(:error, flash_error)
222
+ message(:error, error)
174
223
 
175
- flash[:form_data] = @menu
176
- flash[:form_errors] = @menu.errors
224
+ flash[:form_data] = menu
225
+ flash[:form_errors] = menu.errors
177
226
 
178
227
  redirect_referrer
179
228
  end
180
229
 
181
- # Redrect the user to the proper page
182
- if @menu.id
183
- redirect(Menus.r(:edit, @menu.id))
184
- else
185
- redirect_referrer
186
- end
230
+ Zen::Event.call(after_event, menu)
231
+
232
+ message(:success, success)
233
+ redirect(Menus.r(:edit, menu.id))
187
234
  end
188
235
 
189
236
  ##
@@ -191,19 +238,16 @@ module Menus
191
238
  # values. These primary values should be stored in a POST array called
192
239
  # "menu_ids".
193
240
  #
194
- # This method requires the following permissions:
195
- #
196
- # * delete
197
- #
198
- # @author Yorick Peterse
199
- # @since 0.2a
241
+ # @since 0.2a
242
+ # @event before_delete_menu
243
+ # @event after_delete_menu
244
+ # @permission delete_menu
200
245
  #
201
246
  def delete
202
- require_permissions(:delete)
247
+ authorize_user!(:delete_menu)
203
248
 
204
249
  post = request.params.dup
205
250
 
206
- # We always require a set of IDs
207
251
  if !post['menu_ids'] or post['menu_ids'].empty?
208
252
  message(:error, lang('menus.errors.no_delete'))
209
253
  redirect_referrer
@@ -211,14 +255,21 @@ module Menus
211
255
 
212
256
  # Time to delete all menus
213
257
  post['menu_ids'].each do |id|
258
+ menu = ::Menus::Model::Menu[id]
259
+
260
+ next if menu.nil?
261
+ Zen::Event.call(:before_delete_menu, menu)
262
+
214
263
  begin
215
- Menu[id].destroy
264
+ menu.destroy
216
265
  rescue => e
217
266
  Ramaze::Log.error(e.inspect)
218
267
  message(:error, lang('menus.errors.delete') % id)
219
268
 
220
269
  redirect_referrer
221
270
  end
271
+
272
+ Zen::Event.call(:after_delete_menu, menu)
222
273
  end
223
274
 
224
275
  message(:success, lang('menus.success.delete'))