occams 1.0.0

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 (471) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +4 -0
  3. data/.gitattributes +2 -0
  4. data/.github/issue_template.md +22 -0
  5. data/.github/pull_request_template.md +6 -0
  6. data/.gitignore +21 -0
  7. data/.rubocop.yml +87 -0
  8. data/.travis.yml +44 -0
  9. data/CHANGELOG.md +7 -0
  10. data/CONTRIBUTING.md +35 -0
  11. data/Gemfile +30 -0
  12. data/LICENSE +20 -0
  13. data/LICENSE.comfy +20 -0
  14. data/README.md +121 -0
  15. data/Rakefile +5 -0
  16. data/app/assets/config/manifest.js +0 -0
  17. data/app/assets/fonts/occams/admin/cms/lib/redactor-font.eot +0 -0
  18. data/app/assets/javascripts/occams/admin/cms/application.js +39 -0
  19. data/app/assets/javascripts/occams/admin/cms/base.js +46 -0
  20. data/app/assets/javascripts/occams/admin/cms/categories.js +17 -0
  21. data/app/assets/javascripts/occams/admin/cms/codemirror.js +31 -0
  22. data/app/assets/javascripts/occams/admin/cms/custom.js +1 -0
  23. data/app/assets/javascripts/occams/admin/cms/diff.js +10 -0
  24. data/app/assets/javascripts/occams/admin/cms/file_link.js +67 -0
  25. data/app/assets/javascripts/occams/admin/cms/file_upload.js +194 -0
  26. data/app/assets/javascripts/occams/admin/cms/files_modal.js +40 -0
  27. data/app/assets/javascripts/occams/admin/cms/page_fragments.js +22 -0
  28. data/app/assets/javascripts/occams/admin/cms/slugify.js +34 -0
  29. data/app/assets/javascripts/occams/admin/cms/sortable_list.js +40 -0
  30. data/app/assets/javascripts/occams/admin/cms/timepicker.js +30 -0
  31. data/app/assets/javascripts/occams/admin/cms/wysiwyg.js +72 -0
  32. data/app/assets/javascripts/occams/vendor/Moxie.swf +0 -0
  33. data/app/assets/javascripts/occams/vendor/Moxie.xap +0 -0
  34. data/app/assets/javascripts/occams/vendor/bootstrap.bundle.min.js +7 -0
  35. data/app/assets/javascripts/occams/vendor/bootstrap.bundle.min.js.map +1 -0
  36. data/app/assets/javascripts/occams/vendor/codemirror/addon/edit/closetag.js +169 -0
  37. data/app/assets/javascripts/occams/vendor/codemirror/mode/css/css.js +832 -0
  38. data/app/assets/javascripts/occams/vendor/codemirror/mode/htmlmixed/htmlmixed.js +152 -0
  39. data/app/assets/javascripts/occams/vendor/codemirror/mode/javascript/javascript.js +875 -0
  40. data/app/assets/javascripts/occams/vendor/codemirror/mode/markdown/markdown.js +861 -0
  41. data/app/assets/javascripts/occams/vendor/codemirror/mode/xml/xml.js +394 -0
  42. data/app/assets/javascripts/occams/vendor/codemirror.js +9653 -0
  43. data/app/assets/javascripts/occams/vendor/diff/diff_match_patch.min.js +49 -0
  44. data/app/assets/javascripts/occams/vendor/diff/pretty_text_diff.js +76 -0
  45. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/ar.js +52 -0
  46. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/bg.js +65 -0
  47. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/bn.js +65 -0
  48. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/ca.js +83 -0
  49. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/cs.js +70 -0
  50. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/cy.js +92 -0
  51. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/da.js +71 -0
  52. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/de.js +70 -0
  53. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/default.js +80 -0
  54. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/eo.js +73 -0
  55. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/es.js +69 -0
  56. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/et.js +73 -0
  57. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/fa.js +68 -0
  58. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/fi.js +69 -0
  59. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/fr.js +75 -0
  60. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/gr.js +74 -0
  61. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/he.js +57 -0
  62. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/hi.js +65 -0
  63. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/hr.js +66 -0
  64. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/hu.js +72 -0
  65. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/id.js +61 -0
  66. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/it.js +70 -0
  67. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/ja.js +57 -0
  68. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/ko.js +60 -0
  69. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/lt.js +72 -0
  70. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/lv.js +67 -0
  71. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/mk.js +69 -0
  72. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/mn.js +67 -0
  73. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/ms.js +68 -0
  74. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/my.js +69 -0
  75. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/nl.js +75 -0
  76. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/no.js +73 -0
  77. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/pa.js +65 -0
  78. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/pl.js +68 -0
  79. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/pt-BR.js +66 -0
  80. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/pt.js +66 -0
  81. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/ro.js +69 -0
  82. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/ru.js +66 -0
  83. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/si.js +65 -0
  84. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/sk.js +70 -0
  85. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/sl.js +70 -0
  86. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/sq.js +65 -0
  87. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/sr.js +69 -0
  88. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/sv.js +70 -0
  89. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/th.js +72 -0
  90. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/tr.js +66 -0
  91. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/uk.js +66 -0
  92. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/vn.js +66 -0
  93. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/zh-CN.js +61 -0
  94. data/app/assets/javascripts/occams/vendor/flatpickr/i18n/zh-TW.js +61 -0
  95. data/app/assets/javascripts/occams/vendor/flatpickr.min.js +2 -0
  96. data/app/assets/javascripts/occams/vendor/fontawesome.js +5 -0
  97. data/app/assets/javascripts/occams/vendor/moxie.min.js +16 -0
  98. data/app/assets/javascripts/occams/vendor/plupload.dev.js +2497 -0
  99. data/app/assets/javascripts/occams/vendor/redactor/definedlinks.js +53 -0
  100. data/app/assets/javascripts/occams/vendor/redactor/filemanager.js +64 -0
  101. data/app/assets/javascripts/occams/vendor/redactor/i18n/ar.js +76 -0
  102. data/app/assets/javascripts/occams/vendor/redactor/i18n/az.js +75 -0
  103. data/app/assets/javascripts/occams/vendor/redactor/i18n/ba.js +79 -0
  104. data/app/assets/javascripts/occams/vendor/redactor/i18n/bg.js +77 -0
  105. data/app/assets/javascripts/occams/vendor/redactor/i18n/by.js +77 -0
  106. data/app/assets/javascripts/occams/vendor/redactor/i18n/ca.js +75 -0
  107. data/app/assets/javascripts/occams/vendor/redactor/i18n/cs.js +87 -0
  108. data/app/assets/javascripts/occams/vendor/redactor/i18n/da.js +75 -0
  109. data/app/assets/javascripts/occams/vendor/redactor/i18n/de.js +80 -0
  110. data/app/assets/javascripts/occams/vendor/redactor/i18n/el.js +76 -0
  111. data/app/assets/javascripts/occams/vendor/redactor/i18n/en.js +75 -0
  112. data/app/assets/javascripts/occams/vendor/redactor/i18n/eo.js +76 -0
  113. data/app/assets/javascripts/occams/vendor/redactor/i18n/es.js +75 -0
  114. data/app/assets/javascripts/occams/vendor/redactor/i18n/es_AR.js +76 -0
  115. data/app/assets/javascripts/occams/vendor/redactor/i18n/fa.js +76 -0
  116. data/app/assets/javascripts/occams/vendor/redactor/i18n/fi.js +75 -0
  117. data/app/assets/javascripts/occams/vendor/redactor/i18n/fr.js +75 -0
  118. data/app/assets/javascripts/occams/vendor/redactor/i18n/ge.js +75 -0
  119. data/app/assets/javascripts/occams/vendor/redactor/i18n/gr.js +75 -0
  120. data/app/assets/javascripts/occams/vendor/redactor/i18n/he.js +75 -0
  121. data/app/assets/javascripts/occams/vendor/redactor/i18n/hr.js +76 -0
  122. data/app/assets/javascripts/occams/vendor/redactor/i18n/hu.js +77 -0
  123. data/app/assets/javascripts/occams/vendor/redactor/i18n/id.js +76 -0
  124. data/app/assets/javascripts/occams/vendor/redactor/i18n/it.js +78 -0
  125. data/app/assets/javascripts/occams/vendor/redactor/i18n/ja.js +76 -0
  126. data/app/assets/javascripts/occams/vendor/redactor/i18n/kn.js +75 -0
  127. data/app/assets/javascripts/occams/vendor/redactor/i18n/ko.js +76 -0
  128. data/app/assets/javascripts/occams/vendor/redactor/i18n/lt.js +75 -0
  129. data/app/assets/javascripts/occams/vendor/redactor/i18n/lv.js +75 -0
  130. data/app/assets/javascripts/occams/vendor/redactor/i18n/mk.js +75 -0
  131. data/app/assets/javascripts/occams/vendor/redactor/i18n/nb.js +75 -0
  132. data/app/assets/javascripts/occams/vendor/redactor/i18n/nl.js +80 -0
  133. data/app/assets/javascripts/occams/vendor/redactor/i18n/pl.js +76 -0
  134. data/app/assets/javascripts/occams/vendor/redactor/i18n/pt-BR.js +75 -0
  135. data/app/assets/javascripts/occams/vendor/redactor/i18n/pt.js +75 -0
  136. data/app/assets/javascripts/occams/vendor/redactor/i18n/ro.js +76 -0
  137. data/app/assets/javascripts/occams/vendor/redactor/i18n/ru.js +76 -0
  138. data/app/assets/javascripts/occams/vendor/redactor/i18n/sk.js +76 -0
  139. data/app/assets/javascripts/occams/vendor/redactor/i18n/sl.js +79 -0
  140. data/app/assets/javascripts/occams/vendor/redactor/i18n/sq.js +79 -0
  141. data/app/assets/javascripts/occams/vendor/redactor/i18n/sr-CIR.js +79 -0
  142. data/app/assets/javascripts/occams/vendor/redactor/i18n/sr-LAT.js +79 -0
  143. data/app/assets/javascripts/occams/vendor/redactor/i18n/sv.js +74 -0
  144. data/app/assets/javascripts/occams/vendor/redactor/i18n/th.js +74 -0
  145. data/app/assets/javascripts/occams/vendor/redactor/i18n/tr.js +75 -0
  146. data/app/assets/javascripts/occams/vendor/redactor/i18n/ua.js +77 -0
  147. data/app/assets/javascripts/occams/vendor/redactor/i18n/uk.js +77 -0
  148. data/app/assets/javascripts/occams/vendor/redactor/i18n/vi.js +74 -0
  149. data/app/assets/javascripts/occams/vendor/redactor/i18n/zh-CN.js +75 -0
  150. data/app/assets/javascripts/occams/vendor/redactor/i18n/zh-TW.js +75 -0
  151. data/app/assets/javascripts/occams/vendor/redactor/imagemanager.js +57 -0
  152. data/app/assets/javascripts/occams/vendor/redactor/table.js +337 -0
  153. data/app/assets/javascripts/occams/vendor/redactor/video.js +77 -0
  154. data/app/assets/javascripts/occams/vendor/redactor.js +9561 -0
  155. data/app/assets/javascripts/occams/vendor/sortable.min.js +5 -0
  156. data/app/assets/stylesheets/occams/admin/cms/application.sass +11 -0
  157. data/app/assets/stylesheets/occams/admin/cms/base.sass +256 -0
  158. data/app/assets/stylesheets/occams/admin/cms/codemirror_overrides.sass +19 -0
  159. data/app/assets/stylesheets/occams/admin/cms/custom.sass +1 -0
  160. data/app/assets/stylesheets/occams/admin/cms/redactor_overrides.sass +22 -0
  161. data/app/assets/stylesheets/occams/vendor/bootstrap/_alert.scss +51 -0
  162. data/app/assets/stylesheets/occams/vendor/bootstrap/_badge.scss +54 -0
  163. data/app/assets/stylesheets/occams/vendor/bootstrap/_breadcrumb.scss +41 -0
  164. data/app/assets/stylesheets/occams/vendor/bootstrap/_button-group.scss +163 -0
  165. data/app/assets/stylesheets/occams/vendor/bootstrap/_buttons.scss +137 -0
  166. data/app/assets/stylesheets/occams/vendor/bootstrap/_card.scss +289 -0
  167. data/app/assets/stylesheets/occams/vendor/bootstrap/_carousel.scss +197 -0
  168. data/app/assets/stylesheets/occams/vendor/bootstrap/_close.scss +41 -0
  169. data/app/assets/stylesheets/occams/vendor/bootstrap/_code.scss +48 -0
  170. data/app/assets/stylesheets/occams/vendor/bootstrap/_custom-forms.scss +507 -0
  171. data/app/assets/stylesheets/occams/vendor/bootstrap/_dropdown.scss +191 -0
  172. data/app/assets/stylesheets/occams/vendor/bootstrap/_forms.scss +330 -0
  173. data/app/assets/stylesheets/occams/vendor/bootstrap/_functions.scss +86 -0
  174. data/app/assets/stylesheets/occams/vendor/bootstrap/_grid.scss +52 -0
  175. data/app/assets/stylesheets/occams/vendor/bootstrap/_images.scss +42 -0
  176. data/app/assets/stylesheets/occams/vendor/bootstrap/_input-group.scss +193 -0
  177. data/app/assets/stylesheets/occams/vendor/bootstrap/_jumbotron.scss +17 -0
  178. data/app/assets/stylesheets/occams/vendor/bootstrap/_list-group.scss +149 -0
  179. data/app/assets/stylesheets/occams/vendor/bootstrap/_media.scss +8 -0
  180. data/app/assets/stylesheets/occams/vendor/bootstrap/_mixins.scss +47 -0
  181. data/app/assets/stylesheets/occams/vendor/bootstrap/_modal.scss +229 -0
  182. data/app/assets/stylesheets/occams/vendor/bootstrap/_nav.scss +120 -0
  183. data/app/assets/stylesheets/occams/vendor/bootstrap/_navbar.scss +294 -0
  184. data/app/assets/stylesheets/occams/vendor/bootstrap/_pagination.scss +73 -0
  185. data/app/assets/stylesheets/occams/vendor/bootstrap/_popover.scss +171 -0
  186. data/app/assets/stylesheets/occams/vendor/bootstrap/_print.scss +141 -0
  187. data/app/assets/stylesheets/occams/vendor/bootstrap/_progress.scss +43 -0
  188. data/app/assets/stylesheets/occams/vendor/bootstrap/_reboot.scss +483 -0
  189. data/app/assets/stylesheets/occams/vendor/bootstrap/_root.scss +19 -0
  190. data/app/assets/stylesheets/occams/vendor/bootstrap/_spinners.scss +55 -0
  191. data/app/assets/stylesheets/occams/vendor/bootstrap/_tables.scss +185 -0
  192. data/app/assets/stylesheets/occams/vendor/bootstrap/_toasts.scss +44 -0
  193. data/app/assets/stylesheets/occams/vendor/bootstrap/_tooltip.scss +115 -0
  194. data/app/assets/stylesheets/occams/vendor/bootstrap/_transitions.scss +20 -0
  195. data/app/assets/stylesheets/occams/vendor/bootstrap/_type.scss +125 -0
  196. data/app/assets/stylesheets/occams/vendor/bootstrap/_utilities.scss +17 -0
  197. data/app/assets/stylesheets/occams/vendor/bootstrap/_variables.scss +1123 -0
  198. data/app/assets/stylesheets/occams/vendor/bootstrap/bootstrap-grid.scss +29 -0
  199. data/app/assets/stylesheets/occams/vendor/bootstrap/bootstrap-reboot.scss +12 -0
  200. data/app/assets/stylesheets/occams/vendor/bootstrap/bootstrap.scss +44 -0
  201. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_alert.scss +13 -0
  202. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_background-variant.scss +21 -0
  203. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_badge.scss +17 -0
  204. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_border-radius.scss +63 -0
  205. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_box-shadow.scss +20 -0
  206. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_breakpoints.scss +123 -0
  207. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_buttons.scss +107 -0
  208. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_caret.scss +62 -0
  209. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_clearfix.scss +7 -0
  210. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_deprecate.scss +10 -0
  211. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_float.scss +14 -0
  212. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_forms.scss +192 -0
  213. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_gradients.scss +45 -0
  214. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_grid-framework.scss +66 -0
  215. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_grid.scss +51 -0
  216. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_hover.scss +37 -0
  217. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_image.scss +36 -0
  218. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_list-group.scss +21 -0
  219. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_lists.scss +7 -0
  220. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_nav-divider.scss +10 -0
  221. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_pagination.scss +22 -0
  222. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_reset-text.scss +17 -0
  223. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_resize.scss +6 -0
  224. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_screen-reader.scss +33 -0
  225. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_size.scss +7 -0
  226. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_table-row.scss +39 -0
  227. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_text-emphasis.scss +16 -0
  228. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_text-hide.scss +11 -0
  229. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_text-truncate.scss +8 -0
  230. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_transition.scss +16 -0
  231. data/app/assets/stylesheets/occams/vendor/bootstrap/mixins/_visibility.scss +8 -0
  232. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_align.scss +8 -0
  233. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_background.scss +19 -0
  234. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_borders.scss +75 -0
  235. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_clearfix.scss +3 -0
  236. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_display.scss +26 -0
  237. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_embed.scss +39 -0
  238. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_flex.scss +51 -0
  239. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_float.scss +11 -0
  240. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_overflow.scss +5 -0
  241. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_position.scss +32 -0
  242. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_screenreaders.scss +11 -0
  243. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_shadows.scss +6 -0
  244. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_sizing.scss +20 -0
  245. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_spacing.scss +73 -0
  246. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_stretched-link.scss +19 -0
  247. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_text.scss +72 -0
  248. data/app/assets/stylesheets/occams/vendor/bootstrap/utilities/_visibility.scss +13 -0
  249. data/app/assets/stylesheets/occams/vendor/bootstrap/vendor/_rfs.scss +204 -0
  250. data/app/assets/stylesheets/occams/vendor/codemirror.css +346 -0
  251. data/app/assets/stylesheets/occams/vendor/flatpickr.min.css +13 -0
  252. data/app/assets/stylesheets/occams/vendor/fontawesome.css +343 -0
  253. data/app/assets/stylesheets/occams/vendor/redactor.css +948 -0
  254. data/app/controllers/application_controller.rb +7 -0
  255. data/app/controllers/concerns/occams/paginate.rb +16 -0
  256. data/app/controllers/concerns/occams/reorder_action.rb +19 -0
  257. data/app/controllers/occams/admin/base_controller.rb +22 -0
  258. data/app/controllers/occams/admin/cms/base_controller.rb +55 -0
  259. data/app/controllers/occams/admin/cms/categories_controller.rb +40 -0
  260. data/app/controllers/occams/admin/cms/files_controller.rb +142 -0
  261. data/app/controllers/occams/admin/cms/layouts_controller.rb +69 -0
  262. data/app/controllers/occams/admin/cms/pages_controller.rb +156 -0
  263. data/app/controllers/occams/admin/cms/revisions/base_controller.rb +50 -0
  264. data/app/controllers/occams/admin/cms/revisions/layout_controller.rb +18 -0
  265. data/app/controllers/occams/admin/cms/revisions/page_controller.rb +30 -0
  266. data/app/controllers/occams/admin/cms/revisions/snippet_controller.rb +18 -0
  267. data/app/controllers/occams/admin/cms/revisions/translation_controller.rb +31 -0
  268. data/app/controllers/occams/admin/cms/sites_controller.rb +69 -0
  269. data/app/controllers/occams/admin/cms/snippets_controller.rb +66 -0
  270. data/app/controllers/occams/admin/cms/translations_controller.rb +107 -0
  271. data/app/controllers/occams/cms/assets_controller.rb +40 -0
  272. data/app/controllers/occams/cms/base_controller.rb +33 -0
  273. data/app/controllers/occams/cms/content_controller.rb +87 -0
  274. data/app/helpers/occams/admin/cms_helper.rb +49 -0
  275. data/app/helpers/occams/cms_helper.rb +73 -0
  276. data/app/models/concerns/occams/cms/with_categories.rb +53 -0
  277. data/app/models/concerns/occams/cms/with_fragments.rb +125 -0
  278. data/app/models/occams/cms/categorization.rb +16 -0
  279. data/app/models/occams/cms/category.rb +24 -0
  280. data/app/models/occams/cms/file.rb +70 -0
  281. data/app/models/occams/cms/fragment.rb +63 -0
  282. data/app/models/occams/cms/layout.rb +113 -0
  283. data/app/models/occams/cms/page.rb +170 -0
  284. data/app/models/occams/cms/revision.rb +12 -0
  285. data/app/models/occams/cms/site.rb +94 -0
  286. data/app/models/occams/cms/snippet.rb +45 -0
  287. data/app/models/occams/cms/translation.rb +43 -0
  288. data/app/views/kaminari/occams/_first_page.html.haml +3 -0
  289. data/app/views/kaminari/occams/_gap.html.haml +2 -0
  290. data/app/views/kaminari/occams/_last_page.html.haml +3 -0
  291. data/app/views/kaminari/occams/_next_page.html.haml +2 -0
  292. data/app/views/kaminari/occams/_page.html.haml +2 -0
  293. data/app/views/kaminari/occams/_paginator.html.haml +11 -0
  294. data/app/views/kaminari/occams/_prev_page.html.haml +2 -0
  295. data/app/views/layouts/occams/admin/cms/_body.html.haml +14 -0
  296. data/app/views/layouts/occams/admin/cms/_flash.html.haml +4 -0
  297. data/app/views/layouts/occams/admin/cms/_footer_js.html.haml +6 -0
  298. data/app/views/layouts/occams/admin/cms/_head.html.haml +19 -0
  299. data/app/views/layouts/occams/admin/cms/_left.html.haml +39 -0
  300. data/app/views/layouts/occams/admin/cms/_right.html.haml +5 -0
  301. data/app/views/layouts/occams/admin/cms.html.haml +4 -0
  302. data/app/views/occams/admin/cms/categories/_categories.html.haml +4 -0
  303. data/app/views/occams/admin/cms/categories/_edit.html.haml +7 -0
  304. data/app/views/occams/admin/cms/categories/_form.html.haml +5 -0
  305. data/app/views/occams/admin/cms/categories/_index.html.haml +28 -0
  306. data/app/views/occams/admin/cms/categories/_show.html.haml +15 -0
  307. data/app/views/occams/admin/cms/categories/create.js.erb +7 -0
  308. data/app/views/occams/admin/cms/categories/destroy.js.erb +8 -0
  309. data/app/views/occams/admin/cms/categories/edit.js.erb +3 -0
  310. data/app/views/occams/admin/cms/categories/update.js.erb +6 -0
  311. data/app/views/occams/admin/cms/files/_file.html.haml +31 -0
  312. data/app/views/occams/admin/cms/files/_form.html.haml +26 -0
  313. data/app/views/occams/admin/cms/files/_modal.html.haml +3 -0
  314. data/app/views/occams/admin/cms/files/destroy.js.erb +4 -0
  315. data/app/views/occams/admin/cms/files/edit.html.haml +5 -0
  316. data/app/views/occams/admin/cms/files/index.html.haml +31 -0
  317. data/app/views/occams/admin/cms/files/new.html.haml +5 -0
  318. data/app/views/occams/admin/cms/fragments/_form_fragment_attachments.html.haml +23 -0
  319. data/app/views/occams/admin/cms/fragments/_form_fragments.html.haml +38 -0
  320. data/app/views/occams/admin/cms/layouts/_form.html.haml +20 -0
  321. data/app/views/occams/admin/cms/layouts/_index_branch.html.haml +26 -0
  322. data/app/views/occams/admin/cms/layouts/edit.html.haml +9 -0
  323. data/app/views/occams/admin/cms/layouts/index.html.haml +10 -0
  324. data/app/views/occams/admin/cms/layouts/new.html.haml +5 -0
  325. data/app/views/occams/admin/cms/pages/_form.html.haml +31 -0
  326. data/app/views/occams/admin/cms/pages/_index_branch.html.haml +44 -0
  327. data/app/views/occams/admin/cms/pages/edit.html.haml +10 -0
  328. data/app/views/occams/admin/cms/pages/index.html.haml +13 -0
  329. data/app/views/occams/admin/cms/pages/new.html.haml +5 -0
  330. data/app/views/occams/admin/cms/pages/toggle_branch.js.erb +13 -0
  331. data/app/views/occams/admin/cms/revisions/_sidebar.html.haml +2 -0
  332. data/app/views/occams/admin/cms/revisions/show.html.haml +36 -0
  333. data/app/views/occams/admin/cms/sites/_form.html.haml +15 -0
  334. data/app/views/occams/admin/cms/sites/edit.html.haml +5 -0
  335. data/app/views/occams/admin/cms/sites/index.html.haml +28 -0
  336. data/app/views/occams/admin/cms/sites/new.html.haml +5 -0
  337. data/app/views/occams/admin/cms/snippets/_form.html.haml +18 -0
  338. data/app/views/occams/admin/cms/snippets/edit.html.haml +9 -0
  339. data/app/views/occams/admin/cms/snippets/index.html.haml +33 -0
  340. data/app/views/occams/admin/cms/snippets/new.html.haml +5 -0
  341. data/app/views/occams/admin/cms/translations/_form.html.haml +20 -0
  342. data/app/views/occams/admin/cms/translations/_sidebar.html.haml +19 -0
  343. data/app/views/occams/admin/cms/translations/edit.html.haml +10 -0
  344. data/app/views/occams/admin/cms/translations/new.html.haml +5 -0
  345. data/bin/bundle +3 -0
  346. data/bin/rails +4 -0
  347. data/bin/rake +4 -0
  348. data/bin/setup +36 -0
  349. data/bin/update +31 -0
  350. data/bin/yarn +11 -0
  351. data/config/application.rb +39 -0
  352. data/config/boot.rb +7 -0
  353. data/config/cms_routes.rb +8 -0
  354. data/config/database.yml +11 -0
  355. data/config/environment.rb +7 -0
  356. data/config/environments/development.rb +59 -0
  357. data/config/environments/test.rb +50 -0
  358. data/config/initializers/occams.rb +122 -0
  359. data/config/locales/ar.yml +262 -0
  360. data/config/locales/ca.yml +262 -0
  361. data/config/locales/cs.yml +262 -0
  362. data/config/locales/da.yml +262 -0
  363. data/config/locales/de.yml +262 -0
  364. data/config/locales/en.yml +262 -0
  365. data/config/locales/es.yml +262 -0
  366. data/config/locales/fi.yml +262 -0
  367. data/config/locales/fr.yml +262 -0
  368. data/config/locales/gr.yml +262 -0
  369. data/config/locales/hr.yml +262 -0
  370. data/config/locales/it.yml +262 -0
  371. data/config/locales/ja.yml +262 -0
  372. data/config/locales/nb.yml +262 -0
  373. data/config/locales/nl.yml +262 -0
  374. data/config/locales/pl.yml +262 -0
  375. data/config/locales/pt-BR.yml +262 -0
  376. data/config/locales/ru.yml +262 -0
  377. data/config/locales/sk.yml +262 -0
  378. data/config/locales/sv.yml +262 -0
  379. data/config/locales/tr.yml +262 -0
  380. data/config/locales/uk.yml +262 -0
  381. data/config/locales/zh-CN.yml +262 -0
  382. data/config/locales/zh-TW.yml +262 -0
  383. data/config/storage.yml +35 -0
  384. data/config.ru +6 -0
  385. data/db/cms_seeds/sample-site/files/_default.jpg.yml +5 -0
  386. data/db/cms_seeds/sample-site/files/default.jpg +0 -0
  387. data/db/cms_seeds/sample-site/layouts/default/content.html +16 -0
  388. data/db/cms_seeds/sample-site/layouts/default/nested/content.html +14 -0
  389. data/db/cms_seeds/sample-site/pages/index/child_a/content.html +7 -0
  390. data/db/cms_seeds/sample-site/pages/index/child_b/content.html +6 -0
  391. data/db/cms_seeds/sample-site/pages/index/cms logo.png +0 -0
  392. data/db/cms_seeds/sample-site/pages/index/content.es.html +6 -0
  393. data/db/cms_seeds/sample-site/pages/index/content.fr.html +6 -0
  394. data/db/cms_seeds/sample-site/pages/index/content.html +25 -0
  395. data/db/cms_seeds/sample-site/pages/index/footer.png +0 -0
  396. data/db/cms_seeds/sample-site/pages/index/header.png +0 -0
  397. data/db/cms_seeds/sample-site/snippets/default.html +8 -0
  398. data/db/migrate/00_create_active_storage_tables.rb +34 -0
  399. data/db/migrate/01_create_cms.rb +143 -0
  400. data/lib/generators/occams/cms/README +17 -0
  401. data/lib/generators/occams/cms/assets_generator.rb +18 -0
  402. data/lib/generators/occams/cms/cms_generator.rb +69 -0
  403. data/lib/generators/occams/cms/controllers_generator.rb +17 -0
  404. data/lib/generators/occams/cms/models_generator.rb +17 -0
  405. data/lib/generators/occams/cms/views_generator.rb +17 -0
  406. data/lib/generators/occams/scaffold/scaffold_generator.rb +80 -0
  407. data/lib/generators/occams/scaffold/templates/controller.rb.tt +62 -0
  408. data/lib/generators/occams/scaffold/templates/migration.rb.tt +11 -0
  409. data/lib/generators/occams/scaffold/templates/model.rb.tt +21 -0
  410. data/lib/generators/occams/scaffold/templates/tests/controller.rb.tt +115 -0
  411. data/lib/generators/occams/scaffold/templates/tests/fixture.yml.tt +4 -0
  412. data/lib/generators/occams/scaffold/templates/tests/model.rb.tt +26 -0
  413. data/lib/generators/occams/scaffold/templates/views/_form.haml.tt +7 -0
  414. data/lib/generators/occams/scaffold/templates/views/edit.haml.tt +5 -0
  415. data/lib/generators/occams/scaffold/templates/views/index.haml.tt +21 -0
  416. data/lib/generators/occams/scaffold/templates/views/new.haml.tt +5 -0
  417. data/lib/generators/occams/scaffold/templates/views/show.haml.tt +4 -0
  418. data/lib/occams/access_control/admin_authentication.rb +24 -0
  419. data/lib/occams/access_control/admin_authorization.rb +12 -0
  420. data/lib/occams/access_control/public_authentication.rb +12 -0
  421. data/lib/occams/access_control/public_authorization.rb +12 -0
  422. data/lib/occams/configuration.rb +140 -0
  423. data/lib/occams/content/block.rb +14 -0
  424. data/lib/occams/content/params_parser.rb +151 -0
  425. data/lib/occams/content/renderer.rb +149 -0
  426. data/lib/occams/content/tag.rb +50 -0
  427. data/lib/occams/content/tags/asset.rb +59 -0
  428. data/lib/occams/content/tags/checkbox.rb +29 -0
  429. data/lib/occams/content/tags/date.rb +21 -0
  430. data/lib/occams/content/tags/datetime.rb +44 -0
  431. data/lib/occams/content/tags/file.rb +72 -0
  432. data/lib/occams/content/tags/file_link.rb +63 -0
  433. data/lib/occams/content/tags/files.rb +43 -0
  434. data/lib/occams/content/tags/fragment.rb +66 -0
  435. data/lib/occams/content/tags/helper.rb +55 -0
  436. data/lib/occams/content/tags/markdown.rb +24 -0
  437. data/lib/occams/content/tags/mixins/file_content.rb +43 -0
  438. data/lib/occams/content/tags/number.rb +20 -0
  439. data/lib/occams/content/tags/page_file_link.rb +84 -0
  440. data/lib/occams/content/tags/partial.rb +49 -0
  441. data/lib/occams/content/tags/snippet.rb +38 -0
  442. data/lib/occams/content/tags/template.rb +44 -0
  443. data/lib/occams/content/tags/text.rb +20 -0
  444. data/lib/occams/content/tags/textarea.rb +20 -0
  445. data/lib/occams/content/tags/wysiwyg.rb +21 -0
  446. data/lib/occams/content.rb +31 -0
  447. data/lib/occams/engine.rb +31 -0
  448. data/lib/occams/error.rb +32 -0
  449. data/lib/occams/extensions/acts_as_tree.rb +120 -0
  450. data/lib/occams/extensions/has_revisions.rb +72 -0
  451. data/lib/occams/form_builder.rb +47 -0
  452. data/lib/occams/render_methods.rb +112 -0
  453. data/lib/occams/routes/cms.rb +18 -0
  454. data/lib/occams/routes/cms_admin.rb +58 -0
  455. data/lib/occams/routing.rb +12 -0
  456. data/lib/occams/seeds/file/exporter.rb +43 -0
  457. data/lib/occams/seeds/file/importer.rb +63 -0
  458. data/lib/occams/seeds/layout/exporter.rb +40 -0
  459. data/lib/occams/seeds/layout/importer.rb +62 -0
  460. data/lib/occams/seeds/page/exporter.rb +92 -0
  461. data/lib/occams/seeds/page/importer.rb +219 -0
  462. data/lib/occams/seeds/snippet/exporter.rb +34 -0
  463. data/lib/occams/seeds/snippet/importer.rb +51 -0
  464. data/lib/occams/seeds.rb +118 -0
  465. data/lib/occams/version.rb +7 -0
  466. data/lib/occams/view_hooks.rb +35 -0
  467. data/lib/occams.rb +60 -0
  468. data/lib/tasks/cms_seeds.rake +40 -0
  469. data/occams.gemspec +33 -0
  470. data/public/favicon.ico +0 -0
  471. metadata +666 -0
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationController < ActionController::Base
4
+
5
+ protect_from_forgery
6
+
7
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Occams::Paginate
4
+
5
+ # Wrapper to deal with WillPaginate vs Kaminari nonsense
6
+ def occams_paginate(scope, per_page: 50)
7
+ if defined?(WillPaginate)
8
+ scope.paginate(page: params[:page], per_page: per_page)
9
+ elsif defined?(Kaminari)
10
+ scope.page(params[:page]).per(per_page)
11
+ else
12
+ scope
13
+ end
14
+ end
15
+
16
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Occams::ReorderAction
4
+
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ mattr_accessor :reorder_action_resource
9
+ end
10
+
11
+ def reorder
12
+ resource_class = self.class.reorder_action_resource
13
+ (params.permit(order: [])[:order] || []).each_with_index do |id, index|
14
+ resource_class.where(id: id).update_all(position: index)
15
+ end
16
+ head :ok
17
+ end
18
+
19
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::BaseController < Occams.config.admin_base_controller.to_s.constantize
4
+
5
+ include Occams::Paginate
6
+
7
+ # Authentication module must have `authenticate` method
8
+ include Occams.config.admin_auth.to_s.constantize
9
+
10
+ # Authorization module must have `authorize` method
11
+ include Occams.config.admin_authorization.to_s.constantize
12
+
13
+ helper Occams::Admin::CmsHelper
14
+ helper Occams::CmsHelper
15
+
16
+ protect_from_forgery with: :exception
17
+
18
+ before_action :authenticate
19
+
20
+ layout "occams/admin/cms"
21
+
22
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::BaseController < Occams::Admin::BaseController
4
+
5
+ before_action :load_admin_site,
6
+ :set_locale,
7
+ :load_seeds,
8
+ except: :jump
9
+
10
+ layout :infer_layout
11
+
12
+ if Occams.config.admin_cache_sweeper.present?
13
+ cache_sweeper(*Occams.config.admin_cache_sweeper)
14
+ end
15
+
16
+ def jump
17
+ path = Occams.config.admin_route_redirect
18
+ return redirect_to(path) unless path.blank?
19
+ load_admin_site
20
+ redirect_to occams_admin_cms_site_pages_path(@site) if @site
21
+ end
22
+
23
+ protected
24
+
25
+ def load_admin_site
26
+ id_param = params[:site_id] || session[:site_id]
27
+ if (@site = ::Occams::Cms::Site.find_by(id: id_param) || ::Occams::Cms::Site.first)
28
+ session[:site_id] = @site.id
29
+ else
30
+ I18n.locale = Occams.config.admin_locale || I18n.default_locale
31
+ flash[:danger] = I18n.t("occams.admin.cms.base.site_not_found")
32
+ return redirect_to(new_occams_admin_cms_site_path)
33
+ end
34
+ end
35
+
36
+ def set_locale
37
+ I18n.locale = Occams.config.admin_locale || (@site&.locale)
38
+ true
39
+ end
40
+
41
+ def load_seeds
42
+ return unless Occams.config.enable_seeds
43
+
44
+ controllers = %w[layouts pages snippets files].collect { |c| "occams/admin/cms/" + c }
45
+ if controllers.member?(params[:controller]) && params[:action] == "index"
46
+ Occams::Seeds::Importer.new(@site.identifier).import!
47
+ flash.now[:warning] = I18n.t("occams.admin.cms.base.seeds_enabled")
48
+ end
49
+ end
50
+
51
+ def infer_layout
52
+ false if params[:layout] == "false"
53
+ end
54
+
55
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::CategoriesController < Occams::Admin::Cms::BaseController
4
+
5
+ before_action :load_category, only: %i[edit update destroy]
6
+ before_action :authorize
7
+
8
+ def edit
9
+ render
10
+ end
11
+
12
+ def create
13
+ @category = @site.categories.create!(category_params)
14
+ rescue ActiveRecord::RecordInvalid
15
+ head :ok
16
+ end
17
+
18
+ def update
19
+ @category.update!(category_params)
20
+ rescue ActiveRecord::RecordInvalid
21
+ head :ok
22
+ end
23
+
24
+ def destroy
25
+ @category.destroy
26
+ end
27
+
28
+ protected
29
+
30
+ def load_category
31
+ @category = @site.categories.find(params[:id])
32
+ rescue ActiveRecord::RecordNotFound
33
+ head :ok
34
+ end
35
+
36
+ def category_params
37
+ params.fetch(:category, {}).permit!
38
+ end
39
+
40
+ end
@@ -0,0 +1,142 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::FilesController < Occams::Admin::Cms::BaseController
4
+
5
+ include ::Occams::ReorderAction
6
+ self.reorder_action_resource = ::Occams::Cms::File
7
+
8
+ include ActionView::Helpers::NumberHelper
9
+
10
+ before_action :build_file, only: %i[new create]
11
+ before_action :load_file, only: %i[edit update destroy]
12
+ before_action :authorize
13
+
14
+ def index
15
+ files_scope = @site.files.with_attached_attachment
16
+
17
+ case params[:source]
18
+
19
+ # Integration with Redactor 1.0 Wysiwyg
20
+ when "redactor"
21
+ file_scope = files_scope.limit(100).order(:position)
22
+ file_hashes =
23
+ case params[:type]
24
+ when "image"
25
+ file_scope.with_images.collect do |file|
26
+ { thumb: url_for(file.attachment.variant(combine_options: Occams::Cms::File::VARIANT_SIZE[:redactor])),
27
+ image: url_for(file.attachment),
28
+ title: file.label }
29
+ end
30
+ else
31
+ file_scope.collect do |file|
32
+ { title: file.label,
33
+ name: file.attachment.filename,
34
+ link: url_for(file.attachment),
35
+ size: number_to_human_size(file.attachment.byte_size) }
36
+ end
37
+ end
38
+
39
+ render json: file_hashes
40
+
41
+ else
42
+ files_scope = files_scope
43
+ .includes(:categories)
44
+ .for_category(params[:categories])
45
+ .order("occams_cms_files.position")
46
+ @files = occams_paginate(files_scope, per_page: 50)
47
+ end
48
+ end
49
+
50
+ def new
51
+ render
52
+ end
53
+
54
+ def create
55
+ categories_scope = @site.categories.of_type("Occams::Cms::File")
56
+
57
+ if params[:categories]
58
+ ids = categories_scope.where(label: params[:categories]).pluck(:id)
59
+ @file.category_ids = ids
60
+ end
61
+
62
+ # Automatically tagging upload if it's done through redactor
63
+ if params[:source] == "redactor"
64
+ category = categories_scope.find_or_create_by(label: "wysiwyg")
65
+ @file.category_ids = [category.id]
66
+ end
67
+
68
+ @file.save!
69
+
70
+ case params[:source]
71
+ when "plupload"
72
+ render partial: "file", object: @file
73
+ when "redactor"
74
+ render json: {
75
+ filelink: url_for(@file.attachment),
76
+ filename: @file.attachment.filename
77
+ }
78
+ else
79
+ flash[:success] = I18n.t("occams.admin.cms.files.created")
80
+ redirect_to action: :edit, id: @file
81
+ end
82
+
83
+ rescue ActiveRecord::RecordInvalid
84
+ case params[:source]
85
+ when "plupload"
86
+ render body: @file.errors.full_messages.to_sentence, status: :unprocessable_entity
87
+ when "redactor"
88
+ render body: nil, status: :unprocessable_entity
89
+ else
90
+ flash.now[:danger] = I18n.t("occams.admin.cms.files.creation_failure")
91
+ render action: :new
92
+ end
93
+ end
94
+
95
+ def edit
96
+ render
97
+ end
98
+
99
+ def update
100
+ if @file.update(file_params)
101
+ flash[:success] = I18n.t("occams.admin.cms.files.updated")
102
+ redirect_to action: :edit, id: @file
103
+ else
104
+ flash.now[:danger] = I18n.t("occams.admin.cms.files.update_failure")
105
+ render action: :edit
106
+ end
107
+ end
108
+
109
+ def destroy
110
+ @file.destroy
111
+ respond_to do |format|
112
+ format.js
113
+ format.html do
114
+ flash[:success] = I18n.t("occams.admin.cms.files.deleted")
115
+ redirect_to action: :index
116
+ end
117
+ end
118
+ end
119
+
120
+ protected
121
+
122
+ def build_file
123
+ @file = @site.files.new(file_params)
124
+ end
125
+
126
+ def load_file
127
+ @file = @site.files.find(params[:id])
128
+ rescue ActiveRecord::RecordNotFound
129
+ flash[:danger] = I18n.t("occams.admin.cms.files.not_found")
130
+ redirect_to action: :index
131
+ end
132
+
133
+ def file_params
134
+ file = params[:file]
135
+ unless file.is_a?(Hash) || file.respond_to?(:to_unsafe_hash)
136
+ params[:file] = {}
137
+ params[:file][:file] = file
138
+ end
139
+ params.fetch(:file, {}).permit!
140
+ end
141
+
142
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::LayoutsController < Occams::Admin::Cms::BaseController
4
+
5
+ include ::Occams::ReorderAction
6
+ self.reorder_action_resource = ::Occams::Cms::Layout
7
+
8
+ before_action :build_layout, only: %i[new create]
9
+ before_action :load_layout, only: %i[edit update destroy]
10
+ before_action :authorize
11
+
12
+ def index
13
+ return redirect_to action: :new if @site.layouts.count.zero?
14
+ @layouts = @site.layouts.roots.order(:position)
15
+ end
16
+
17
+ def new
18
+ render
19
+ end
20
+
21
+ def edit
22
+ render
23
+ end
24
+
25
+ def create
26
+ @layout.save!
27
+ flash[:success] = I18n.t("occams.admin.cms.layouts.created")
28
+ redirect_to action: :edit, id: @layout
29
+ rescue ActiveRecord::RecordInvalid
30
+ flash.now[:danger] = I18n.t("occams.admin.cms.layouts.creation_failure")
31
+ render action: :new
32
+ end
33
+
34
+ def update
35
+ @layout.update!(layout_params)
36
+ flash[:success] = I18n.t("occams.admin.cms.layouts.updated")
37
+ redirect_to action: :edit, id: @layout
38
+ rescue ActiveRecord::RecordInvalid
39
+ flash.now[:danger] = I18n.t("occams.admin.cms.layouts.update_failure")
40
+ render action: :edit
41
+ end
42
+
43
+ def destroy
44
+ @layout.destroy
45
+ flash[:success] = I18n.t("occams.admin.cms.layouts.deleted")
46
+ redirect_to action: :index
47
+ end
48
+
49
+ protected
50
+
51
+ def build_layout
52
+ @layout = @site.layouts.new(layout_params)
53
+ @layout.parent ||= ::Occams::Cms::Layout.find_by_id(params[:parent_id])
54
+ @layout.app_layout ||= @layout.parent.try(:app_layout)
55
+ @layout.content ||= "{{ cms:wysiwyg content }}"
56
+ end
57
+
58
+ def load_layout
59
+ @layout = @site.layouts.find(params[:id])
60
+ rescue ActiveRecord::RecordNotFound
61
+ flash[:danger] = I18n.t("occams.admin.cms.layouts.not_found")
62
+ redirect_to action: :index
63
+ end
64
+
65
+ def layout_params
66
+ params.fetch(:layout, {}).permit!
67
+ end
68
+
69
+ end
@@ -0,0 +1,156 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::PagesController < Occams::Admin::Cms::BaseController
4
+
5
+ include ::Occams::ReorderAction
6
+ self.reorder_action_resource = ::Occams::Cms::Page
7
+
8
+ before_action :check_for_layouts, only: %i[new edit]
9
+ before_action :build_page, only: %i[new create]
10
+ before_action :load_page, only: %i[edit update destroy]
11
+
12
+ before_action :authorize
13
+
14
+ before_action :preview_page, only: %i[create update]
15
+
16
+ def index
17
+ return redirect_to action: :new if site_has_no_pages?
18
+
19
+ return index_for_redactor if params[:source] == "redactor"
20
+
21
+ @pages_by_parent = pages_grouped_by_parent
22
+
23
+ @pages =
24
+ if params[:categories].present?
25
+ @site.pages.includes(:categories).for_category(params[:categories]).order(:label)
26
+ else
27
+ [@site.pages.root].compact
28
+ end
29
+ end
30
+
31
+ def new
32
+ render
33
+ end
34
+
35
+ def edit
36
+ render
37
+ end
38
+
39
+ def create
40
+ @page.save!
41
+ flash[:success] = I18n.t("occams.admin.cms.pages.created")
42
+ redirect_to action: :edit, id: @page
43
+ rescue ActiveRecord::RecordInvalid
44
+ flash.now[:danger] = I18n.t("occams.admin.cms.pages.creation_failure")
45
+ render action: :new
46
+ end
47
+
48
+ def update
49
+ @page.save!
50
+ flash[:success] = I18n.t("occams.admin.cms.pages.updated")
51
+ redirect_to action: :edit, id: @page
52
+ rescue ActiveRecord::RecordInvalid
53
+ flash.now[:danger] = I18n.t("occams.admin.cms.pages.update_failure")
54
+ render action: :edit
55
+ end
56
+
57
+ def destroy
58
+ @page.destroy
59
+ flash[:success] = I18n.t("occams.admin.cms.pages.deleted")
60
+ redirect_to action: :index
61
+ end
62
+
63
+ def form_fragments
64
+ @page = @site.pages.find_by(id: params[:id]) || @site.pages.new
65
+ @page.layout = @site.layouts.find_by(id: params[:layout_id])
66
+
67
+ render(
68
+ partial: "occams/admin/cms/fragments/form_fragments",
69
+ locals: { record: @page, scope: :page },
70
+ layout: false
71
+ )
72
+ end
73
+
74
+ def toggle_branch
75
+ @pages_by_parent = pages_grouped_by_parent
76
+ @page = @site.pages.find(params[:id])
77
+ s = (session[:cms_page_tree] ||= [])
78
+ id = @page.id.to_s
79
+ s.member?(id) ? s.delete(id) : s << id
80
+ rescue ActiveRecord::RecordNotFound
81
+ render nothing: true
82
+ end
83
+
84
+ protected
85
+
86
+ def index_for_redactor
87
+ tree_walker = ->(page, list, offset) do
88
+ return unless page.present?
89
+ label = "#{'. . ' * offset}#{page.label}"
90
+ list << { name: label, url: page.url(relative: true) }
91
+ page.children.each do |child_page|
92
+ tree_walker.call(child_page, list, offset + 1)
93
+ end
94
+ list
95
+ end
96
+
97
+ page_select_options = [{
98
+ name: I18n.t("occams.admin.cms.pages.form.choose_link"),
99
+ url: false
100
+ }] + tree_walker.call(@site.pages.root, [], 0)
101
+
102
+ render json: page_select_options
103
+ end
104
+
105
+ def site_has_no_pages?
106
+ @site.pages.count.zero?
107
+ end
108
+
109
+ def pages_grouped_by_parent
110
+ @site.pages.order(:position).includes(:categories).group_by(&:parent_id)
111
+ end
112
+
113
+ def check_for_layouts
114
+ if @site.layouts.count.zero?
115
+ flash[:danger] = I18n.t("occams.admin.cms.pages.layout_not_found")
116
+ redirect_to new_occams_admin_cms_site_layout_path(@site)
117
+ end
118
+ end
119
+
120
+ def build_page
121
+ @page = @site.pages.new(page_params)
122
+ @page.parent ||= (@site.pages.find_by_id(params[:parent_id]) || @site.pages.root)
123
+ @page.layout ||= (@page.parent&.layout || @site.layouts.first)
124
+ end
125
+
126
+ def load_page
127
+ @page = @site.pages.find(params[:id])
128
+ @page.attributes = page_params
129
+ rescue ActiveRecord::RecordNotFound
130
+ flash[:danger] = I18n.t("occams.admin.cms.pages.not_found")
131
+ redirect_to action: :index
132
+ end
133
+
134
+ def preview_page
135
+ if params[:preview]
136
+ layout = @page.layout.app_layout.blank? ? false : @page.layout.app_layout
137
+ @cms_site = @page.site
138
+ @cms_layout = @page.layout
139
+ @cms_page = @page
140
+
141
+ # Make sure to use the site locale to render the preview becaue it might
142
+ # be different from the admin locale.
143
+ I18n.locale = @cms_site.locale
144
+
145
+ # Chrome chokes on content with iframes. Issue #434
146
+ response.headers["X-XSS-Protection"] = "0"
147
+
148
+ render inline: @page.render, layout: layout, content_type: "text/html"
149
+ end
150
+ end
151
+
152
+ def page_params
153
+ params.fetch(:page, {}).permit!
154
+ end
155
+
156
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::Revisions::BaseController < Occams::Admin::Cms::BaseController
4
+
5
+ helper_method :record_path
6
+
7
+ before_action :load_record
8
+ before_action :load_revision, except: :index
9
+ before_action :authorize
10
+
11
+ def index
12
+ revision = @record.revisions.order(created_at: :desc).first
13
+ if revision
14
+ redirect_to action: :show, id: revision.id
15
+ else
16
+ redirect_to record_path
17
+ end
18
+ end
19
+
20
+ def show
21
+ @current_content = @record.revision_fields.each_with_object({}) { |f, c| c[f] = @record.send(f) }
22
+ @versioned_content = @record.revision_fields.each_with_object({}) { |f, c| c[f] = @revision.data[f] }
23
+
24
+ render "occams/admin/cms/revisions/show"
25
+ end
26
+
27
+ def revert
28
+ @record.restore_from_revision(@revision)
29
+ flash[:success] = I18n.t("occams.admin.cms.revisions.reverted")
30
+ redirect_to record_path
31
+ end
32
+
33
+ protected
34
+
35
+ def load_record
36
+ raise "not implemented"
37
+ end
38
+
39
+ def load_revision
40
+ @revision = @record.revisions.find(params[:id])
41
+ rescue ActiveRecord::RecordNotFound
42
+ flash[:danger] = I18n.t("occams.admin.cms.revisions.not_found")
43
+ redirect_to record_path
44
+ end
45
+
46
+ def record_path
47
+ raise "no implemented"
48
+ end
49
+
50
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::Revisions::LayoutController < Occams::Admin::Cms::Revisions::BaseController
4
+
5
+ private
6
+
7
+ def load_record
8
+ @record = @site.layouts.find(params[:layout_id])
9
+ rescue ActiveRecord::RecordNotFound
10
+ flash[:danger] = I18n.t("occams.admin.cms.revisions.record_not_found")
11
+ redirect_to occams_admin_cms_site_layouts_path(@site)
12
+ end
13
+
14
+ def record_path
15
+ edit_occams_admin_cms_site_layout_path(@site, @record)
16
+ end
17
+
18
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::Revisions::PageController < Occams::Admin::Cms::Revisions::BaseController
4
+
5
+ def show
6
+ @current_content = @record.fragments.each_with_object({}) do |b, c|
7
+ c[b.identifier] = b.content
8
+ end
9
+ @versioned_content = @record.fragments.each_with_object({}) do |b, c|
10
+ d = @revision.data["fragments_attributes"].detect { |r| r[:identifier] == b.identifier }
11
+ c[b.identifier] = d.try(:[], :content)
12
+ end
13
+
14
+ render "occams/admin/cms/revisions/show"
15
+ end
16
+
17
+ private
18
+
19
+ def load_record
20
+ @record = @site.pages.find(params[:page_id])
21
+ rescue ActiveRecord::RecordNotFound
22
+ flash[:danger] = I18n.t("occams.admin.cms.revisions.record_not_found")
23
+ redirect_to occams_admin_cms_site_pages_path(@site)
24
+ end
25
+
26
+ def record_path
27
+ edit_occams_admin_cms_site_page_path(@site, @record)
28
+ end
29
+
30
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::Revisions::SnippetController < Occams::Admin::Cms::Revisions::BaseController
4
+
5
+ private
6
+
7
+ def load_record
8
+ @record = @site.snippets.find(params[:snippet_id])
9
+ rescue ActiveRecord::RecordNotFound
10
+ flash[:danger] = I18n.t("occams.admin.cms.revisions.record_not_found")
11
+ redirect_to occams_admin_cms_site_snippets_path(@site)
12
+ end
13
+
14
+ def record_path
15
+ edit_occams_admin_cms_site_snippet_path(@site, @record)
16
+ end
17
+
18
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Occams::Admin::Cms::Revisions::TranslationController < Occams::Admin::Cms::Revisions::BaseController
4
+
5
+ def show
6
+ @current_content = @record.fragments.each_with_object({}) do |b, c|
7
+ c[b.identifier] = b.content
8
+ end
9
+ @versioned_content = @record.fragments.each_with_object({}) do |b, c|
10
+ d = @revision.data["fragments_attributes"].detect { |r| r[:identifier] == b.identifier }
11
+ c[b.identifier] = d.try(:[], :content)
12
+ end
13
+
14
+ render "occams/admin/cms/revisions/show"
15
+ end
16
+
17
+ private
18
+
19
+ def load_record
20
+ @page = @site.pages.find(params[:page_id])
21
+ @record = @page.translations.find(params[:translation_id])
22
+ rescue ActiveRecord::RecordNotFound
23
+ flash[:danger] = I18n.t("occams.admin.cms.revisions.record_not_found")
24
+ redirect_to occams_admin_cms_site_pages_path(@site)
25
+ end
26
+
27
+ def record_path
28
+ edit_occams_admin_cms_site_page_translation_path(@site, @page, @record)
29
+ end
30
+
31
+ end