comfortable_mexican_sofa 1.12.11 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (490) hide show
  1. checksums.yaml +5 -5
  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 +3 -0
  7. data/.rubocop.yml +5 -0
  8. data/.rubocop_todo.yml +974 -0
  9. data/.travis.yml +2 -10
  10. data/Gemfile +5 -7
  11. data/README.md +40 -39
  12. data/Rakefile +1 -31
  13. data/app/assets/javascripts/comfy/admin/cms/application.js.coffee +7 -4
  14. data/app/assets/javascripts/comfy/admin/cms/base.js.coffee +23 -33
  15. data/app/assets/javascripts/comfy/admin/cms/lib/diff/pretty_text_diff.js +76 -0
  16. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr.min.js +2 -0
  17. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/ar.js +52 -0
  18. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/bg.js +65 -0
  19. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/bn.js +65 -0
  20. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/cat.js +83 -0
  21. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/cs.js +70 -0
  22. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/cy.js +92 -0
  23. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/da.js +71 -0
  24. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/de.js +70 -0
  25. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/default.js +80 -0
  26. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/eo.js +73 -0
  27. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/es.js +69 -0
  28. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/et.js +73 -0
  29. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/fa.js +68 -0
  30. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/fi.js +69 -0
  31. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/fr.js +75 -0
  32. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/gr.js +74 -0
  33. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/he.js +57 -0
  34. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/hi.js +65 -0
  35. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/hr.js +66 -0
  36. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/hu.js +72 -0
  37. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/id.js +61 -0
  38. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/it.js +70 -0
  39. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/ja.js +57 -0
  40. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/ko.js +60 -0
  41. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/lt.js +72 -0
  42. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/lv.js +67 -0
  43. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/mk.js +69 -0
  44. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/mn.js +67 -0
  45. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/ms.js +68 -0
  46. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/my.js +69 -0
  47. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/nl.js +75 -0
  48. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/no.js +73 -0
  49. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/pa.js +65 -0
  50. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/pl.js +68 -0
  51. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/pt-BR.js +66 -0
  52. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/pt.js +66 -0
  53. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/ro.js +69 -0
  54. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/ru.js +66 -0
  55. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/si.js +65 -0
  56. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/sk.js +70 -0
  57. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/sl.js +70 -0
  58. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/sq.js +65 -0
  59. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/sr.js +69 -0
  60. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/sv.js +70 -0
  61. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/th.js +72 -0
  62. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/tr.js +66 -0
  63. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/uk.js +66 -0
  64. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/vn.js +66 -0
  65. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/zh-CN.js +61 -0
  66. data/app/assets/javascripts/comfy/admin/cms/lib/flatpickr/i18n/zh-TW.js +61 -0
  67. data/app/assets/javascripts/comfy/admin/cms/lib/redactor.js +9 -3
  68. data/app/assets/javascripts/comfy/admin/cms/uploader.js.coffee +9 -10
  69. data/app/assets/stylesheets/comfy/admin/cms/application.sass +4 -4
  70. data/app/assets/stylesheets/comfy/admin/cms/base.sass +215 -338
  71. data/app/assets/stylesheets/comfy/admin/cms/lib/flatpickr.min.css +13 -0
  72. data/app/assets/stylesheets/comfy/admin/cms/redactor_overrides.sass +2 -2
  73. data/app/controllers/comfy/admin/base_controller.rb +20 -0
  74. data/app/controllers/comfy/admin/cms/base_controller.rb +9 -22
  75. data/app/controllers/comfy/admin/cms/categories_controller.rb +2 -3
  76. data/app/controllers/comfy/admin/cms/files_controller.rb +50 -31
  77. data/app/controllers/comfy/admin/cms/layouts_controller.rb +12 -13
  78. data/app/controllers/comfy/admin/cms/pages_controller.rb +28 -28
  79. data/app/controllers/comfy/admin/cms/revisions_controller.rb +23 -14
  80. data/app/controllers/comfy/admin/cms/sites_controller.rb +9 -10
  81. data/app/controllers/comfy/admin/cms/snippets_controller.rb +11 -11
  82. data/app/controllers/comfy/admin/cms/translations_controller.rb +98 -0
  83. data/app/controllers/comfy/cms/assets_controller.rb +9 -10
  84. data/app/controllers/comfy/cms/base_controller.rb +0 -2
  85. data/app/controllers/comfy/cms/content_controller.rb +50 -31
  86. data/app/controllers/concerns/comfy/paginate.rb +2 -2
  87. data/app/helpers/comfy/admin/cms_helper.rb +29 -0
  88. data/app/helpers/comfy/cms_helper.rb +40 -60
  89. data/app/models/comfy/cms/categorization.rb +8 -11
  90. data/app/models/comfy/cms/category.rb +10 -14
  91. data/app/models/comfy/cms/file.rb +31 -47
  92. data/app/models/comfy/cms/fragment.rb +55 -0
  93. data/app/models/comfy/cms/layout.rb +45 -40
  94. data/app/models/comfy/cms/page.rb +47 -36
  95. data/app/models/comfy/cms/revision.rb +5 -8
  96. data/app/models/comfy/cms/site.rb +26 -51
  97. data/app/models/comfy/cms/snippet.rb +20 -24
  98. data/app/models/comfy/cms/translation.rb +37 -0
  99. data/app/models/concerns/comfy/cms/with_categories.rb +38 -0
  100. data/app/models/concerns/comfy/cms/with_fragments.rb +121 -0
  101. data/app/views/comfy/admin/cms/categories/_categories.html.haml +2 -1
  102. data/app/views/comfy/admin/cms/categories/_edit.html.haml +7 -6
  103. data/app/views/comfy/admin/cms/categories/_form.html.haml +8 -5
  104. data/app/views/comfy/admin/cms/categories/_index.html.haml +24 -20
  105. data/app/views/comfy/admin/cms/categories/_show.html.haml +10 -9
  106. data/app/views/comfy/admin/cms/categories/create.js.erb +2 -2
  107. data/app/views/comfy/admin/cms/categories/edit.js.erb +1 -1
  108. data/app/views/comfy/admin/cms/categories/update.js.erb +2 -2
  109. data/app/views/comfy/admin/cms/files/_file.html.haml +31 -25
  110. data/app/views/comfy/admin/cms/files/_form.html.haml +16 -12
  111. data/app/views/comfy/admin/cms/files/edit.html.haml +1 -1
  112. data/app/views/comfy/admin/cms/files/index.html.haml +17 -19
  113. data/app/views/comfy/admin/cms/files/new.html.haml +1 -1
  114. data/app/views/comfy/admin/cms/layouts/_form.html.haml +10 -10
  115. data/app/views/comfy/admin/cms/layouts/_index_branch.html.haml +21 -19
  116. data/app/views/comfy/admin/cms/layouts/edit.html.haml +5 -5
  117. data/app/views/comfy/admin/cms/layouts/index.html.haml +4 -7
  118. data/app/views/comfy/admin/cms/pages/_form.html.haml +15 -21
  119. data/app/views/comfy/admin/cms/pages/_form_fragments.html.haml +40 -0
  120. data/app/views/comfy/admin/cms/pages/_fragment_attachments.html.haml +10 -0
  121. data/app/views/comfy/admin/cms/pages/_index_branch.html.haml +34 -26
  122. data/app/views/comfy/admin/cms/pages/edit.html.haml +19 -5
  123. data/app/views/comfy/admin/cms/pages/form_fragments.js.erb +1 -0
  124. data/app/views/comfy/admin/cms/pages/index.html.haml +5 -8
  125. data/app/views/comfy/admin/cms/pages/new.html.haml +1 -1
  126. data/app/views/comfy/admin/cms/revisions/show.html.haml +29 -27
  127. data/app/views/comfy/admin/cms/sites/_form.html.haml +6 -8
  128. data/app/views/comfy/admin/cms/sites/edit.html.haml +1 -1
  129. data/app/views/comfy/admin/cms/sites/index.html.haml +23 -22
  130. data/app/views/comfy/admin/cms/sites/new.html.haml +1 -1
  131. data/app/views/comfy/admin/cms/snippets/_form.html.haml +9 -9
  132. data/app/views/comfy/admin/cms/snippets/edit.html.haml +6 -5
  133. data/app/views/comfy/admin/cms/snippets/index.html.haml +25 -25
  134. data/app/views/comfy/admin/cms/snippets/new.html.haml +1 -1
  135. data/app/views/comfy/admin/cms/translations/_form.html.haml +21 -0
  136. data/app/views/comfy/admin/cms/translations/edit.html.haml +9 -0
  137. data/app/views/comfy/admin/cms/translations/form_fragments.js.erb +1 -0
  138. data/app/views/comfy/admin/cms/translations/new.html.haml +5 -0
  139. data/app/views/kaminari/comfy/_first_page.html.haml +3 -2
  140. data/app/views/kaminari/comfy/_gap.html.haml +2 -2
  141. data/app/views/kaminari/comfy/_last_page.html.haml +3 -2
  142. data/app/views/kaminari/comfy/_next_page.html.haml +2 -2
  143. data/app/views/kaminari/comfy/_page.html.haml +2 -2
  144. data/app/views/kaminari/comfy/_prev_page.html.haml +1 -1
  145. data/app/views/layouts/comfy/admin/cms/_body.html.haml +13 -15
  146. data/app/views/layouts/comfy/admin/cms/_footer_js.html.haml +10 -3
  147. data/app/views/layouts/comfy/admin/cms/_head.html.haml +7 -10
  148. data/app/views/layouts/comfy/admin/cms/_left.html.haml +33 -15
  149. data/app/views/layouts/comfy/admin/cms/_right.html.haml +2 -2
  150. data/comfortable_mexican_sofa.gemspec +19 -19
  151. data/config/application.rb +14 -8
  152. data/config/boot.rb +2 -2
  153. data/config/cms_routes.rb +3 -3
  154. data/config/environments/development.rb +37 -4
  155. data/config/environments/test.rb +12 -14
  156. data/config/initializers/comfortable_mexican_sofa.rb +5 -12
  157. data/config/locales/cs.yml +33 -7
  158. data/config/locales/da.yml +33 -7
  159. data/config/locales/de.yml +32 -6
  160. data/config/locales/en.yml +33 -7
  161. data/config/locales/es.yml +33 -7
  162. data/config/locales/fr.yml +33 -7
  163. data/config/locales/it.yml +33 -7
  164. data/config/locales/ja.yml +33 -7
  165. data/config/locales/nb.yml +33 -7
  166. data/config/locales/nl.yml +33 -7
  167. data/config/locales/pl.yml +33 -7
  168. data/config/locales/pt-BR.yml +33 -7
  169. data/config/locales/ru.yml +33 -7
  170. data/config/locales/sk.yml +33 -7
  171. data/config/locales/sv.yml +33 -7
  172. data/config/locales/tr.yml +33 -7
  173. data/config/locales/uk.yml +33 -7
  174. data/config/locales/zh-CN.yml +33 -7
  175. data/config/locales/zh-TW.yml +33 -7
  176. data/config/storage.yml +35 -0
  177. data/db/cms_seeds/sample-site/files/_default.jpg.yml +5 -0
  178. data/db/{cms_fixtures/sample-site/files/sample.jpg → cms_seeds/sample-site/files/default.jpg} +0 -0
  179. data/db/cms_seeds/sample-site/layouts/default/content.html +16 -0
  180. data/db/cms_seeds/sample-site/layouts/default/nested/content.html +14 -0
  181. data/db/cms_seeds/sample-site/pages/index/child_a/content.html +7 -0
  182. data/db/cms_seeds/sample-site/pages/index/child_b/content.html +6 -0
  183. data/db/cms_seeds/sample-site/pages/index/content.es.html +6 -0
  184. data/db/cms_seeds/sample-site/pages/index/content.fr.html +6 -0
  185. data/db/cms_seeds/sample-site/pages/index/content.html +24 -0
  186. data/db/{cms_fixtures/sample-site/pages/index/child/thumbnail.png → cms_seeds/sample-site/pages/index/footer.png} +0 -0
  187. data/db/cms_seeds/sample-site/pages/index/header.png +0 -0
  188. data/db/cms_seeds/sample-site/snippets/default.html +8 -0
  189. data/db/migrate/00_create_active_storage_tables.active_storage.rb +26 -0
  190. data/db/migrate/01_create_cms.rb +113 -104
  191. data/doc/preview.jpg +0 -0
  192. data/lib/comfortable_mexican_sofa.rb +10 -14
  193. data/lib/comfortable_mexican_sofa/configuration.rb +9 -13
  194. data/lib/comfortable_mexican_sofa/content.rb +28 -0
  195. data/lib/comfortable_mexican_sofa/content/block.rb +11 -0
  196. data/lib/comfortable_mexican_sofa/content/params_parser.rb +80 -0
  197. data/lib/comfortable_mexican_sofa/content/renderer.rb +125 -0
  198. data/lib/comfortable_mexican_sofa/content/tag.rb +37 -0
  199. data/lib/comfortable_mexican_sofa/content/tags/asset.rb +56 -0
  200. data/lib/comfortable_mexican_sofa/content/tags/checkbox.rb +21 -0
  201. data/lib/comfortable_mexican_sofa/content/tags/date.rb +22 -0
  202. data/lib/comfortable_mexican_sofa/content/tags/datetime.rb +22 -0
  203. data/lib/comfortable_mexican_sofa/content/tags/file.rb +77 -0
  204. data/lib/comfortable_mexican_sofa/content/tags/file_link.rb +66 -0
  205. data/lib/comfortable_mexican_sofa/content/tags/files.rb +39 -0
  206. data/lib/comfortable_mexican_sofa/content/tags/fragment.rb +54 -0
  207. data/lib/comfortable_mexican_sofa/content/tags/helper.rb +52 -0
  208. data/lib/comfortable_mexican_sofa/content/tags/markdown.rb +21 -0
  209. data/lib/comfortable_mexican_sofa/content/tags/number.rb +17 -0
  210. data/lib/comfortable_mexican_sofa/content/tags/partial.rb +42 -0
  211. data/lib/comfortable_mexican_sofa/content/tags/snippet.rb +31 -0
  212. data/lib/comfortable_mexican_sofa/content/tags/template.rb +41 -0
  213. data/lib/comfortable_mexican_sofa/content/tags/text.rb +17 -0
  214. data/lib/comfortable_mexican_sofa/content/tags/textarea.rb +17 -0
  215. data/lib/comfortable_mexican_sofa/content/tags/wysiwyg.rb +18 -0
  216. data/lib/comfortable_mexican_sofa/engine.rb +3 -2
  217. data/lib/comfortable_mexican_sofa/extensions/acts_as_tree.rb +33 -30
  218. data/lib/comfortable_mexican_sofa/extensions/has_revisions.rb +27 -23
  219. data/lib/comfortable_mexican_sofa/form_builder.rb +32 -104
  220. data/lib/comfortable_mexican_sofa/render_methods.rb +24 -21
  221. data/lib/comfortable_mexican_sofa/routes/cms.rb +6 -14
  222. data/lib/comfortable_mexican_sofa/routes/cms_admin.rb +39 -29
  223. data/lib/comfortable_mexican_sofa/routing.rb +1 -1
  224. data/lib/comfortable_mexican_sofa/seeds.rb +102 -0
  225. data/lib/comfortable_mexican_sofa/seeds/file/exporter.rb +40 -0
  226. data/lib/comfortable_mexican_sofa/seeds/file/importer.rb +61 -0
  227. data/lib/comfortable_mexican_sofa/seeds/layout/exporter.rb +37 -0
  228. data/lib/comfortable_mexican_sofa/seeds/layout/importer.rb +59 -0
  229. data/lib/comfortable_mexican_sofa/seeds/page/exporter.rb +88 -0
  230. data/lib/comfortable_mexican_sofa/seeds/page/importer.rb +213 -0
  231. data/lib/comfortable_mexican_sofa/seeds/snippet/exporter.rb +31 -0
  232. data/lib/comfortable_mexican_sofa/seeds/snippet/importer.rb +48 -0
  233. data/lib/comfortable_mexican_sofa/version.rb +1 -1
  234. data/lib/comfortable_mexican_sofa/view_hooks.rb +0 -1
  235. data/lib/generators/comfy/cms/assets_generator.rb +0 -1
  236. data/lib/generators/comfy/cms/cms_generator.rb +15 -5
  237. data/lib/generators/comfy/scaffold/scaffold_generator.rb +26 -20
  238. data/lib/generators/comfy/scaffold/templates/{controller.rb → controller.rb.tt} +10 -10
  239. data/lib/generators/comfy/scaffold/templates/{migration.rb → migration.rb.tt} +2 -3
  240. data/lib/generators/comfy/scaffold/templates/{model.rb → model.rb.tt} +7 -7
  241. data/lib/generators/comfy/scaffold/templates/tests/{controller.rb → controller.rb.tt} +37 -24
  242. data/lib/generators/comfy/scaffold/templates/tests/{fixture.yml → fixture.yml.tt} +0 -0
  243. data/lib/generators/comfy/scaffold/templates/tests/{model.rb → model.rb.tt} +3 -4
  244. data/lib/generators/comfy/scaffold/templates/views/_form.haml.tt +7 -0
  245. data/lib/generators/comfy/scaffold/templates/views/{edit.haml → edit.haml.tt} +1 -1
  246. data/lib/generators/comfy/scaffold/templates/views/index.haml.tt +21 -0
  247. data/lib/generators/comfy/scaffold/templates/views/{new.haml → new.haml.tt} +1 -1
  248. data/lib/generators/comfy/scaffold/templates/views/{show.haml → show.haml.tt} +2 -2
  249. data/lib/tasks/cms_seeds.rake +37 -0
  250. data/test/controllers/comfy/admin/cms/base_controller_test.rb +5 -6
  251. data/test/controllers/comfy/admin/cms/categories_controller_test.rb +27 -24
  252. data/test/controllers/comfy/admin/cms/files_controller_test.rb +97 -97
  253. data/test/controllers/comfy/admin/cms/layouts_controller_test.rb +32 -31
  254. data/test/controllers/comfy/admin/cms/pages_controller_test.rb +317 -263
  255. data/test/controllers/comfy/admin/cms/revisions_controller_test.rb +175 -65
  256. data/test/controllers/comfy/admin/cms/sites_controller_test.rb +27 -29
  257. data/test/controllers/comfy/admin/cms/snippets_controller_test.rb +54 -51
  258. data/test/controllers/comfy/admin/cms/translations_controller_test.rb +181 -0
  259. data/test/controllers/comfy/cms/assets_controller_test.rb +24 -22
  260. data/test/controllers/comfy/cms/content_controller_test.rb +126 -140
  261. data/test/fixtures/active_storage/attachments.yml +9 -0
  262. data/test/fixtures/active_storage/blobs.yml +13 -0
  263. data/test/fixtures/comfy/cms/files.yml +2 -6
  264. data/test/fixtures/comfy/cms/fragments.yml +25 -0
  265. data/test/fixtures/comfy/cms/layouts.yml +7 -13
  266. data/test/fixtures/comfy/cms/pages.yml +2 -17
  267. data/test/fixtures/comfy/cms/revisions.yml +16 -8
  268. data/test/fixtures/comfy/cms/sites.yml +0 -1
  269. data/test/fixtures/comfy/cms/snippets.yml +1 -1
  270. data/test/fixtures/comfy/cms/translations.yml +7 -0
  271. data/test/fixtures/generators/cms/application.rb +7 -0
  272. data/test/fixtures/generators/cms/routes.rb +4 -7
  273. data/test/fixtures/generators/scaffold/controller.rb +10 -10
  274. data/test/fixtures/generators/scaffold/migration.rb +2 -3
  275. data/test/fixtures/generators/scaffold/model.rb +7 -7
  276. data/test/fixtures/generators/scaffold/routes.rb +1 -2
  277. data/test/fixtures/generators/scaffold/tests/controller.rb +37 -24
  278. data/test/fixtures/generators/scaffold/tests/model.rb +3 -4
  279. data/test/fixtures/generators/scaffold/views/_form.haml +3 -2
  280. data/test/fixtures/generators/scaffold/views/edit.haml +1 -1
  281. data/test/fixtures/generators/scaffold/views/index.haml +15 -13
  282. data/test/fixtures/generators/scaffold/views/new.haml +1 -1
  283. data/test/fixtures/generators/scaffold/views/show.haml +2 -2
  284. data/test/gemfiles/Gemfile.rails.5.2 +32 -0
  285. data/test/generators/cms_assets_generator_test.rb +1 -2
  286. data/test/generators/cms_generator_test.rb +3 -1
  287. data/test/generators/cms_views_generator_test.rb +1 -1
  288. data/test/generators/scaffold_generator_test.rb +2 -2
  289. data/test/helpers/cms_helper_test.rb +52 -73
  290. data/test/integration/access_control_test.rb +35 -28
  291. data/test/integration/js_variables_test.rb +1 -2
  292. data/test/integration/render_cms_test.rb +37 -37
  293. data/test/integration/routing_test.rb +4 -5
  294. data/test/integration/seeds_test.rb +76 -0
  295. data/test/integration/sites_test.rb +35 -49
  296. data/test/integration/view_hooks_test.rb +12 -13
  297. data/test/lib/configuration_test.rb +3 -4
  298. data/test/lib/content/block_test.rb +26 -0
  299. data/test/lib/content/params_parser_test.rb +125 -0
  300. data/test/lib/content/renderer_test.rb +240 -0
  301. data/test/lib/content/tag_test.rb +48 -0
  302. data/test/lib/content/tags/asset_test.rb +79 -0
  303. data/test/lib/content/tags/checkbox_test.rb +20 -0
  304. data/test/lib/content/tags/date_test.rb +20 -0
  305. data/test/lib/content/tags/datetime_test.rb +20 -0
  306. data/test/lib/content/tags/file_link_test.rb +78 -0
  307. data/test/lib/content/tags/file_test.rb +60 -0
  308. data/test/lib/content/tags/files_test.rb +49 -0
  309. data/test/lib/content/tags/fragment_test.rb +63 -0
  310. data/test/lib/content/tags/helper_test.rb +52 -0
  311. data/test/lib/content/tags/markdown_test.rb +33 -0
  312. data/test/lib/content/tags/number_test.rb +13 -0
  313. data/test/lib/content/tags/partial_test.rb +43 -0
  314. data/test/lib/content/tags/snippet_test.rb +36 -0
  315. data/test/lib/content/tags/template_test.rb +35 -0
  316. data/test/lib/content/tags/text_test.rb +13 -0
  317. data/test/lib/content/tags/textarea_test.rb +13 -0
  318. data/test/lib/content/tags/wysiwyg_test.rb +13 -0
  319. data/test/lib/revisions_test.rb +146 -111
  320. data/test/lib/seeds/files_test.rb +96 -0
  321. data/test/lib/seeds/layouts_test.rb +155 -0
  322. data/test/lib/seeds/pages_test.rb +227 -0
  323. data/test/lib/seeds/snippets_test.rb +98 -0
  324. data/test/lib/seeds_test.rb +50 -0
  325. data/test/models/categorization_test.rb +37 -38
  326. data/test/models/category_test.rb +14 -14
  327. data/test/models/file_test.rb +23 -96
  328. data/test/models/fragment_test.rb +131 -0
  329. data/test/models/layout_test.rb +105 -74
  330. data/test/models/page_test.rb +352 -97
  331. data/test/models/site_test.rb +101 -90
  332. data/test/models/snippet_test.rb +29 -23
  333. data/test/models/translation_test.rb +60 -0
  334. data/test/tasks/cms_seeds_test.rb +33 -0
  335. data/test/test_helper.rb +49 -32
  336. metadata +235 -210
  337. data/_config.yml +0 -1
  338. data/app/assets/images/comfy/admin/cms/arrow_bottom.gif +0 -0
  339. data/app/assets/images/comfy/admin/cms/arrow_right.gif +0 -0
  340. data/app/assets/images/comfy/admin/cms/checkerboard.gif +0 -0
  341. data/app/assets/images/comfy/admin/cms/icon_draft.gif +0 -0
  342. data/app/assets/images/comfy/admin/cms/icon_file.gif +0 -0
  343. data/app/assets/images/comfy/admin/cms/icon_layout.gif +0 -0
  344. data/app/assets/images/comfy/admin/cms/icon_move.gif +0 -0
  345. data/app/assets/images/comfy/admin/cms/icon_page.gif +0 -0
  346. data/app/assets/images/comfy/admin/cms/icon_site.gif +0 -0
  347. data/app/assets/images/comfy/admin/cms/icon_snippet.gif +0 -0
  348. data/app/assets/javascripts/comfy/admin/cms/lib/bootstrap-datetimepicker.js +0 -29
  349. data/app/assets/javascripts/comfy/admin/cms/lib/diff.js.coffee +0 -9
  350. data/app/assets/javascripts/comfy/admin/cms/lib/diff/pretty_text_diff.min.js +0 -5
  351. data/app/assets/stylesheets/comfy/admin/cms/bootstrap_overrides.sass +0 -32
  352. data/app/assets/stylesheets/comfy/admin/cms/lib/bootstrap-datetimepicker.css +0 -9
  353. data/app/models/comfy/cms/block.rb +0 -63
  354. data/app/views/comfy/admin/cms/files/_page_form.html.haml +0 -10
  355. data/app/views/comfy/admin/cms/pages/_form_blocks.html.haml +0 -32
  356. data/app/views/comfy/admin/cms/pages/form_blocks.js.erb +0 -1
  357. data/app/views/comfy/admin/cms/partials/_body_before.html.haml +0 -3
  358. data/app/views/comfy/admin/cms/partials/_file_form_after.html.haml +0 -3
  359. data/app/views/comfy/admin/cms/partials/_file_form_before.html.haml +0 -3
  360. data/app/views/comfy/admin/cms/partials/_files_after.html.haml +0 -3
  361. data/app/views/comfy/admin/cms/partials/_files_before.html.haml +0 -3
  362. data/app/views/comfy/admin/cms/partials/_html_footer.html.haml +0 -2
  363. data/app/views/comfy/admin/cms/partials/_html_head.html.haml +0 -2
  364. data/app/views/comfy/admin/cms/partials/_layout_form_after.html.haml +0 -3
  365. data/app/views/comfy/admin/cms/partials/_layout_form_before.html.haml +0 -3
  366. data/app/views/comfy/admin/cms/partials/_layouts_after.html.haml +0 -3
  367. data/app/views/comfy/admin/cms/partials/_layouts_before.html.haml +0 -3
  368. data/app/views/comfy/admin/cms/partials/_navigation_after.html.haml +0 -3
  369. data/app/views/comfy/admin/cms/partials/_navigation_before.html.haml +0 -3
  370. data/app/views/comfy/admin/cms/partials/_navigation_inner.html.haml +0 -3
  371. data/app/views/comfy/admin/cms/partials/_page_form_after.html.haml +0 -3
  372. data/app/views/comfy/admin/cms/partials/_page_form_before.html.haml +0 -3
  373. data/app/views/comfy/admin/cms/partials/_page_form_inner.html.haml +0 -3
  374. data/app/views/comfy/admin/cms/partials/_pages_after.html.haml +0 -3
  375. data/app/views/comfy/admin/cms/partials/_pages_before.html.haml +0 -3
  376. data/app/views/comfy/admin/cms/partials/_right_column_after.html.haml +0 -3
  377. data/app/views/comfy/admin/cms/partials/_right_column_before.html.haml +0 -3
  378. data/app/views/comfy/admin/cms/partials/_site_form_after.html.haml +0 -3
  379. data/app/views/comfy/admin/cms/partials/_site_form_before.html.haml +0 -3
  380. data/app/views/comfy/admin/cms/partials/_sites_after.html.haml +0 -3
  381. data/app/views/comfy/admin/cms/partials/_sites_before.html.haml +0 -3
  382. data/app/views/comfy/admin/cms/partials/_snippet_form_after.html.haml +0 -3
  383. data/app/views/comfy/admin/cms/partials/_snippet_form_before.html.haml +0 -3
  384. data/app/views/comfy/admin/cms/partials/_snippets_after.html.haml +0 -3
  385. data/app/views/comfy/admin/cms/partials/_snippets_before.html.haml +0 -3
  386. data/app/views/comfy/admin/cms/sites/_mirrors.html.haml +0 -18
  387. data/app/views/comfy/cms/content/render_sitemap.xml.builder +0 -14
  388. data/app/views/layouts/comfy/admin/cms/_footer.html.haml +0 -3
  389. data/config/initializers/paperclip.rb +0 -3
  390. data/config/initializers/secret_token.rb +0 -15
  391. data/db/cms_fixtures/sample-site/categories/files.yml +0 -1
  392. data/db/cms_fixtures/sample-site/categories/pages.yml +0 -1
  393. data/db/cms_fixtures/sample-site/categories/snippets.yml +0 -1
  394. data/db/cms_fixtures/sample-site/files/_sample.jpg.yml +0 -5
  395. data/db/cms_fixtures/sample-site/layouts/default/attributes.yml +0 -1
  396. data/db/cms_fixtures/sample-site/layouts/default/content.html +0 -5
  397. data/db/cms_fixtures/sample-site/layouts/default/javascript.js +0 -1
  398. data/db/cms_fixtures/sample-site/layouts/default/nested/attributes.yml +0 -2
  399. data/db/cms_fixtures/sample-site/layouts/default/nested/content.haml +0 -3
  400. data/db/cms_fixtures/sample-site/layouts/default/nested/javascript.js +0 -1
  401. data/db/cms_fixtures/sample-site/layouts/default/nested/stylesheet.css +0 -1
  402. data/db/cms_fixtures/sample-site/layouts/default/stylesheet.css +0 -1
  403. data/db/cms_fixtures/sample-site/pages/index/attributes.yml +0 -6
  404. data/db/cms_fixtures/sample-site/pages/index/child/attributes.yml +0 -3
  405. data/db/cms_fixtures/sample-site/pages/index/child/left.haml +0 -1
  406. data/db/cms_fixtures/sample-site/pages/index/child/right.html +0 -1
  407. data/db/cms_fixtures/sample-site/pages/index/content.html +0 -2
  408. data/db/cms_fixtures/sample-site/snippets/default/attributes.yml +0 -4
  409. data/db/cms_fixtures/sample-site/snippets/default/content.html +0 -1
  410. data/db/seeds.rb +0 -7
  411. data/db/upgrade_migrations/02_upgrade_to_1_1_0.rb +0 -19
  412. data/db/upgrade_migrations/03_upgrade_to_1_2_0.rb +0 -15
  413. data/db/upgrade_migrations/04_upgrade_to_1_3_0.rb +0 -23
  414. data/db/upgrade_migrations/05_upgrade_to_1_4_0.rb +0 -33
  415. data/db/upgrade_migrations/06_upgrade_to_1_5_0.rb +0 -21
  416. data/db/upgrade_migrations/07_upgrade_to_1_6_0.rb +0 -25
  417. data/db/upgrade_migrations/08_upgrade_to_1_12_0.rb +0 -83
  418. data/doc/preview.png +0 -0
  419. data/lib/comfortable_mexican_sofa/extensions/cms_manageable.rb +0 -106
  420. data/lib/comfortable_mexican_sofa/extensions/is_categorized.rb +0 -49
  421. data/lib/comfortable_mexican_sofa/extensions/is_mirrored.rb +0 -86
  422. data/lib/comfortable_mexican_sofa/extensions/rails.rb +0 -17
  423. data/lib/comfortable_mexican_sofa/fixture.rb +0 -82
  424. data/lib/comfortable_mexican_sofa/fixture/category.rb +0 -42
  425. data/lib/comfortable_mexican_sofa/fixture/file.rb +0 -85
  426. data/lib/comfortable_mexican_sofa/fixture/layout.rb +0 -95
  427. data/lib/comfortable_mexican_sofa/fixture/page.rb +0 -129
  428. data/lib/comfortable_mexican_sofa/fixture/snippet.rb +0 -75
  429. data/lib/comfortable_mexican_sofa/tag.rb +0 -154
  430. data/lib/comfortable_mexican_sofa/tags/asset.rb +0 -30
  431. data/lib/comfortable_mexican_sofa/tags/collection.rb +0 -64
  432. data/lib/comfortable_mexican_sofa/tags/field_boolean.rb +0 -17
  433. data/lib/comfortable_mexican_sofa/tags/field_datetime.rb +0 -17
  434. data/lib/comfortable_mexican_sofa/tags/field_integer.rb +0 -17
  435. data/lib/comfortable_mexican_sofa/tags/field_rich_text.rb +0 -17
  436. data/lib/comfortable_mexican_sofa/tags/field_string.rb +0 -17
  437. data/lib/comfortable_mexican_sofa/tags/field_text.rb +0 -17
  438. data/lib/comfortable_mexican_sofa/tags/file.rb +0 -29
  439. data/lib/comfortable_mexican_sofa/tags/helper.rb +0 -24
  440. data/lib/comfortable_mexican_sofa/tags/page_datetime.rb +0 -13
  441. data/lib/comfortable_mexican_sofa/tags/page_file.rb +0 -62
  442. data/lib/comfortable_mexican_sofa/tags/page_files.rb +0 -51
  443. data/lib/comfortable_mexican_sofa/tags/page_integer.rb +0 -13
  444. data/lib/comfortable_mexican_sofa/tags/page_markdown.rb +0 -16
  445. data/lib/comfortable_mexican_sofa/tags/page_rich_text.rb +0 -13
  446. data/lib/comfortable_mexican_sofa/tags/page_string.rb +0 -13
  447. data/lib/comfortable_mexican_sofa/tags/page_text.rb +0 -13
  448. data/lib/comfortable_mexican_sofa/tags/partial.rb +0 -23
  449. data/lib/comfortable_mexican_sofa/tags/snippet.rb +0 -19
  450. data/lib/comfortable_mexican_sofa/tags/template.rb +0 -22
  451. data/lib/generators/comfy/scaffold/templates/views/_form.haml +0 -6
  452. data/lib/generators/comfy/scaffold/templates/views/index.haml +0 -23
  453. data/lib/tasks/comfortable_mexican_sofa.rake +0 -37
  454. data/test/fixtures/comfy/cms/blocks.yml +0 -12
  455. data/test/gemfiles/Gemfile.rails.4.1 +0 -22
  456. data/test/gemfiles/Gemfile.rails.4.2 +0 -22
  457. data/test/gemfiles/Gemfile.rails.5.0 +0 -23
  458. data/test/gemfiles/Gemfile.rails.master +0 -23
  459. data/test/integration/fixtures_test.rb +0 -65
  460. data/test/integration/mirrors_test.rb +0 -72
  461. data/test/lib/fixtures/categories_test.rb +0 -36
  462. data/test/lib/fixtures/files_test.rb +0 -109
  463. data/test/lib/fixtures/layouts_test.rb +0 -135
  464. data/test/lib/fixtures/pages_test.rb +0 -168
  465. data/test/lib/fixtures/snippets_test.rb +0 -106
  466. data/test/lib/fixtures_test.rb +0 -43
  467. data/test/lib/mirrors_test.rb +0 -254
  468. data/test/lib/tag_test.rb +0 -309
  469. data/test/lib/tags/asset_test.rb +0 -95
  470. data/test/lib/tags/collection_test.rb +0 -117
  471. data/test/lib/tags/field_boolean_test.rb +0 -49
  472. data/test/lib/tags/field_datetime_test.rb +0 -50
  473. data/test/lib/tags/field_integer_test.rb +0 -49
  474. data/test/lib/tags/field_rich_text_test.rb +0 -49
  475. data/test/lib/tags/field_string_test.rb +0 -52
  476. data/test/lib/tags/field_text_test.rb +0 -48
  477. data/test/lib/tags/file_test.rb +0 -67
  478. data/test/lib/tags/helper_test.rb +0 -86
  479. data/test/lib/tags/page_datetime_test.rb +0 -50
  480. data/test/lib/tags/page_file_test.rb +0 -119
  481. data/test/lib/tags/page_files_test.rb +0 -117
  482. data/test/lib/tags/page_integer_test.rb +0 -49
  483. data/test/lib/tags/page_markdown_test.rb +0 -48
  484. data/test/lib/tags/page_rich_text_test.rb +0 -49
  485. data/test/lib/tags/page_string_test.rb +0 -49
  486. data/test/lib/tags/page_text_test.rb +0 -52
  487. data/test/lib/tags/partial_test.rb +0 -76
  488. data/test/lib/tags/snippet_test.rb +0 -45
  489. data/test/lib/tags/template_test.rb +0 -56
  490. data/test/models/block_test.rb +0 -233
@@ -1,21 +1,22 @@
1
- # encoding: utf-8
2
-
3
1
  class Comfy::Cms::Page < ActiveRecord::Base
4
2
  self.table_name = 'comfy_cms_pages'
5
3
 
6
- cms_acts_as_tree :counter_cache => :children_count
7
- cms_is_categorized
8
- cms_is_mirrored
9
- cms_manageable
10
- cms_has_revisions_for :blocks_attributes
4
+ include Comfy::Cms::WithFragments
5
+ include Comfy::Cms::WithCategories
6
+
7
+ cms_acts_as_tree counter_cache: :children_count
8
+ cms_has_revisions_for :fragments_attributes
11
9
 
12
- # -- Relationships --------------------------------------------------------
10
+ # -- Relationships -----------------------------------------------------------
13
11
  belongs_to :site
14
- belongs_to :layout
15
12
  belongs_to :target_page,
16
- :class_name => 'Comfy::Cms::Page'
13
+ class_name: 'Comfy::Cms::Page',
14
+ optional: true
17
15
 
18
- # -- Callbacks ------------------------------------------------------------
16
+ has_many :translations,
17
+ dependent: :destroy
18
+
19
+ # -- Callbacks ---------------------------------------------------------------
19
20
  before_validation :assigns_label,
20
21
  :assign_parent,
21
22
  :escape_slug,
@@ -24,25 +25,22 @@ class Comfy::Cms::Page < ActiveRecord::Base
24
25
  after_save :sync_child_full_paths!
25
26
  after_find :unescape_slug_and_path
26
27
 
27
- # -- Validations ----------------------------------------------------------
28
- validates :site_id,
29
- :presence => true
28
+ # -- Validations -------------------------------------------------------------
30
29
  validates :label,
31
- :presence => true
30
+ presence: true
32
31
  validates :slug,
33
- :presence => true,
34
- :uniqueness => { :scope => :parent_id },
35
- :unless => lambda{ |p| p.site && (p.site.pages.count == 0 || p.site.pages.root == self) }
36
- validates :layout,
37
- :presence => true
32
+ presence: true,
33
+ uniqueness: {scope: :parent_id},
34
+ unless: -> (p) {
35
+ p.site && (p.site.pages.count == 0 || p.site.pages.root == self)
36
+ }
38
37
  validate :validate_target_page
39
38
  validate :validate_format_of_unescaped_slug
40
39
 
41
- # -- Scopes ---------------------------------------------------------------
42
- default_scope -> { order('comfy_cms_pages.position') }
43
- scope :published, -> { where(:is_published => true) }
40
+ # -- Scopes ------------------------------------------------------------------
41
+ scope :published, -> { where(is_published: true) }
44
42
 
45
- # -- Class Methods --------------------------------------------------------
43
+ # -- Class Methods -----------------------------------------------------------
46
44
  # Tree-like structure for pages
47
45
  def self.options_for_select(site, page = nil, current_page = nil, depth = 0, exclude_self = true, spacer = '. . ')
48
46
  return [] if (current_page ||= site.pages.root) == page && exclude_self || !current_page
@@ -54,7 +52,7 @@ class Comfy::Cms::Page < ActiveRecord::Base
54
52
  return out.compact
55
53
  end
56
54
 
57
- # -- Instance Methods -----------------------------------------------------
55
+ # -- Instance Methods --------------------------------------------------------
58
56
  # For previewing purposes sometimes we need to have full_path set. This
59
57
  # full path take care of the pages and its childs but not of the site path
60
58
  def full_path
@@ -63,17 +61,29 @@ class Comfy::Cms::Page < ActiveRecord::Base
63
61
 
64
62
  # Somewhat unique method of identifying a page that is not a full_path
65
63
  def identifier
66
- self.parent_id.blank?? 'index' : self.full_path[1..-1].slugify
64
+ self.parent_id.blank?? 'index' : self.full_path[1..-1].parameterize
67
65
  end
68
66
 
69
67
  # Full url for a page
70
- def url(relative = false)
71
- public_cms_path = ComfortableMexicanSofa.config.public_cms_path || '/'
72
- if relative
73
- [public_cms_path, self.site.path, self.full_path].join('/').squeeze('/')
74
- else
75
- '//' + [self.site.hostname, public_cms_path, self.site.path, self.full_path].join('/').squeeze('/')
76
- end
68
+ def url(relative: false)
69
+ [self.site.url(relative: relative), self.full_path].compact.join
70
+ end
71
+
72
+ # This method will mutate page object by transfering attributes from translation
73
+ # for a given locale.
74
+ def translate!(locale)
75
+ translation = self.translations.published.find_by!(locale: locale)
76
+ self.layout = translation.layout
77
+ self.label = translation.label
78
+ self.content_cache = translation.content_cache
79
+
80
+ # We can't just assign fragments as it's a relation and will write to DB
81
+ # This has odd side-effect of preserving page's fragments and just replacing
82
+ # them from the translation. Not an issue if all fragments match.
83
+ self.fragments_attributes = translation.fragments_attributes
84
+ self.readonly!
85
+
86
+ return self
77
87
  end
78
88
 
79
89
  protected
@@ -104,7 +114,9 @@ protected
104
114
  return unless self.target_page
105
115
  p = self
106
116
  while p.target_page do
107
- return self.errors.add(:target_page_id, 'Invalid Redirect') if (p = p.target_page) == self
117
+ if (p = p.target_page) == self
118
+ return self.errors.add(:target_page_id, 'Invalid Redirect')
119
+ end
108
120
  end
109
121
  end
110
122
 
@@ -116,7 +128,7 @@ protected
116
128
 
117
129
  # Forcing re-saves for child pages so they can update full_paths
118
130
  def sync_child_full_paths!
119
- return unless full_path_changed?
131
+ return unless self.full_path_previously_changed?
120
132
  children.each do |p|
121
133
  p.update_attribute(:full_path, p.send(:assign_full_path))
122
134
  end
@@ -132,5 +144,4 @@ protected
132
144
  self.slug = CGI::unescape(self.slug) unless self.slug.nil?
133
145
  self.full_path = CGI::unescape(self.full_path) unless self.full_path.nil?
134
146
  end
135
-
136
147
  end
@@ -1,12 +1,9 @@
1
1
  class Comfy::Cms::Revision < ActiveRecord::Base
2
2
  self.table_name = 'comfy_cms_revisions'
3
-
3
+
4
4
  serialize :data
5
-
5
+
6
6
  # -- Relationships --------------------------------------------------------
7
- belongs_to :record, :polymorphic => true
8
-
9
- # -- Scopes ---------------------------------------------------------------
10
- default_scope -> { order('created_at DESC') }
11
-
12
- end
7
+ belongs_to :record, polymorphic: true
8
+
9
+ end
@@ -1,8 +1,8 @@
1
1
  class Comfy::Cms::Site < ActiveRecord::Base
2
2
  self.table_name = 'comfy_cms_sites'
3
3
 
4
- # -- Relationships --------------------------------------------------------
5
- with_options :dependent => :destroy do |site|
4
+ # -- Relationships -----------------------------------------------------------
5
+ with_options dependent: :destroy do |site|
6
6
  site.has_many :layouts
7
7
  site.has_many :pages
8
8
  site.has_many :snippets
@@ -10,43 +10,38 @@ class Comfy::Cms::Site < ActiveRecord::Base
10
10
  site.has_many :categories
11
11
  end
12
12
 
13
- # -- Callbacks ------------------------------------------------------------
13
+ # -- Callbacks ---------------------------------------------------------------
14
14
  before_validation :assign_identifier,
15
15
  :assign_hostname,
16
- :assign_label
17
- before_save :clean_path
18
- after_save :sync_mirrors
16
+ :assign_label,
17
+ :clean_path
19
18
 
20
- # -- Validations ----------------------------------------------------------
19
+ # -- Validations -------------------------------------------------------------
21
20
  validates :identifier,
22
- :presence => true,
23
- :uniqueness => true,
24
- :format => { :with => /\A\w[a-z0-9_-]*\z/i }
21
+ presence: true,
22
+ uniqueness: true,
23
+ format: {with: /\A\w[a-z0-9_-]*\z/i}
25
24
  validates :label,
26
- :presence => true
25
+ presence: true
27
26
  validates :hostname,
28
- :presence => true,
29
- :uniqueness => { :scope => :path },
30
- :format => { :with => /\A[\w\.\-]+(?:\:\d+)?\z/ }
27
+ presence: true,
28
+ uniqueness: {scope: :path},
29
+ format: {with: /\A[\w\.\-]+(?:\:\d+)?\z/}
31
30
 
32
- # -- Scopes ---------------------------------------------------------------
33
- scope :mirrored, -> { where(:is_mirrored => true) }
34
-
35
- # -- Class Methods --------------------------------------------------------
31
+ # -- Class Methods -----------------------------------------------------------
36
32
  # returning the Comfy::Cms::Site instance based on host and path
37
33
  def self.find_site(host, path = nil)
38
34
  return Comfy::Cms::Site.first if Comfy::Cms::Site.count == 1
39
35
  cms_site = nil
40
36
 
37
+
41
38
  public_cms_path = ComfortableMexicanSofa.configuration.public_cms_path
42
- if path && public_cms_path != "/"
43
- path = path.sub(%r{\A#{public_cms_path}}, "")
44
- end
39
+ path.gsub!(/\A#{public_cms_path}/, '') unless path.nil? || public_cms_path == '/'
45
40
 
46
- Comfy::Cms::Site.where(:hostname => real_host_from_aliases(host)).each do |site|
41
+ Comfy::Cms::Site.where(hostname: real_host_from_aliases(host)).each do |site|
47
42
  if site.path.blank?
48
43
  cms_site = site
49
- elsif "#{path.to_s.split('?')[0]}/" =~ %r{^/#{Regexp.escape(site.path.to_s)}/}
44
+ elsif "#{path.to_s.split('?')[0]}/".match /^\/#{Regexp.escape(site.path.to_s)}\//
50
45
  cms_site = site
51
46
  break
52
47
  end
@@ -54,17 +49,12 @@ class Comfy::Cms::Site < ActiveRecord::Base
54
49
  return cms_site
55
50
  end
56
51
 
57
- # -- Instance Methods -----------------------------------------------------
58
- def url
52
+ # -- Instance Methods --------------------------------------------------------
53
+ def url(relative: false)
59
54
  public_cms_path = ComfortableMexicanSofa.config.public_cms_path || '/'
60
- '//' + [self.hostname, public_cms_path, self.path].join('/').squeeze('/')
61
- end
62
-
63
- # When removing entire site, let's not destroy content from other sites
64
- # Since before_destroy doesn't really work, this does the trick
65
- def destroy
66
- self.update_attributes(:is_mirrored => false) if self.is_mirrored?
67
- super
55
+ host = "//#{self.hostname}"
56
+ path = ['/', public_cms_path, self.path].compact.join('/').squeeze('/').chomp('/')
57
+ relative ? path.presence : [host, path].join
68
58
  end
69
59
 
70
60
  protected
@@ -79,7 +69,7 @@ protected
79
69
  end
80
70
 
81
71
  def assign_identifier
82
- self.identifier = self.identifier.blank?? self.hostname.try(:slugify) : self.identifier
72
+ self.identifier = self.identifier.blank?? self.hostname.try(:parameterize) : self.identifier
83
73
  end
84
74
 
85
75
  def assign_hostname
@@ -94,21 +84,6 @@ protected
94
84
  self.path ||= ''
95
85
  self.path.squeeze!('/')
96
86
  self.path.gsub!(/\/$/, '')
87
+ self.path = nil if self.path.blank?
97
88
  end
98
-
99
- # When site is marked as a mirror we need to sync its structure
100
- # with other mirrors.
101
- def sync_mirrors
102
- return unless is_mirrored_changed? && is_mirrored?
103
-
104
- [self, Comfy::Cms::Site.mirrored.where("id != #{id}").first].compact.each do |site|
105
- site.layouts.reload
106
- site.pages.reload
107
- site.snippets.reload
108
- (site.layouts.roots + site.layouts.roots.map(&:descendants)).flatten.map(&:sync_mirror)
109
- (site.pages.roots + site.pages.roots.map(&:descendants)).flatten.map(&:sync_mirror)
110
- site.snippets.map(&:sync_mirror)
111
- end
112
- end
113
-
114
- end
89
+ end
@@ -1,45 +1,41 @@
1
1
  class Comfy::Cms::Snippet < ActiveRecord::Base
2
2
  self.table_name = 'comfy_cms_snippets'
3
-
4
- cms_is_categorized
5
- cms_is_mirrored
3
+
4
+ include Comfy::Cms::WithCategories
5
+
6
6
  cms_has_revisions_for :content
7
-
8
- # -- Relationships --------------------------------------------------------
7
+
8
+ # -- Relationships -----------------------------------------------------------
9
9
  belongs_to :site
10
-
11
- # -- Callbacks ------------------------------------------------------------
10
+
11
+ # -- Callbacks ---------------------------------------------------------------
12
12
  before_validation :assign_label
13
13
  before_create :assign_position
14
14
  after_save :clear_page_content_cache
15
15
  after_destroy :clear_page_content_cache
16
-
17
- # -- Validations ----------------------------------------------------------
18
- validates :site_id,
19
- :presence => true
16
+
17
+ # -- Validations -------------------------------------------------------------
20
18
  validates :label,
21
- :presence => true
19
+ presence: true
22
20
  validates :identifier,
23
- :presence => true,
24
- :uniqueness => { :scope => :site_id },
25
- :format => { :with => /\A\w[a-z0-9_-]*\z/i }
26
-
27
- # -- Scopes ---------------------------------------------------------------
28
- default_scope -> { order('comfy_cms_snippets.position') }
29
-
21
+ presence: true,
22
+ uniqueness: {scope: :site_id},
23
+ format: {with: /\A\w[a-z0-9_-]*\z/i}
24
+
30
25
  protected
31
-
26
+
32
27
  def assign_label
33
28
  self.label = self.label.blank?? self.identifier.try(:titleize) : self.label
34
29
  end
35
-
30
+
31
+ # When snippet is changed or removed we need to blow away all page caches as
32
+ # we don't know where it was used.
36
33
  def clear_page_content_cache
37
- Comfy::Cms::Page.where(:id => site.pages.pluck(:id)).update_all(:content_cache => nil)
34
+ Comfy::Cms::Page.where(id: site.pages.pluck(:id)).update_all(content_cache: nil)
38
35
  end
39
-
36
+
40
37
  def assign_position
41
38
  max = self.site.snippets.maximum(:position)
42
39
  self.position = max ? max + 1 : 0
43
40
  end
44
-
45
41
  end
@@ -0,0 +1,37 @@
1
+ class Comfy::Cms::Translation < ActiveRecord::Base
2
+ self.table_name = "comfy_cms_translations"
3
+
4
+ include Comfy::Cms::WithFragments
5
+
6
+ cms_has_revisions_for :fragments_attributes
7
+
8
+ # -- Relationships -----------------------------------------------------------
9
+ belongs_to :page
10
+
11
+ # -- Callbacks ---------------------------------------------------------------
12
+ before_validation :assign_layout
13
+
14
+ # -- Scopes ------------------------------------------------------------------
15
+ scope :published, -> { where(is_published: true) }
16
+
17
+ # -- Validations -------------------------------------------------------------
18
+ validates :label,
19
+ presence: true
20
+
21
+ validates :locale,
22
+ presence: true,
23
+ uniqueness: {scope: :page_id}
24
+
25
+ validate :validate_locale
26
+
27
+ private
28
+
29
+ def validate_locale
30
+ return unless self.page
31
+ errors.add(:locale) if self.locale == self.page.site.locale
32
+ end
33
+
34
+ def assign_layout
35
+ self.layout ||= self.page.layout if self.page.present?
36
+ end
37
+ end
@@ -0,0 +1,38 @@
1
+ module Comfy::Cms::WithCategories
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ has_many :categorizations,
6
+ as: :categorized,
7
+ class_name: "Comfy::Cms::Categorization",
8
+ dependent: :destroy
9
+ has_many :categories,
10
+ through: :categorizations,
11
+ class_name: "Comfy::Cms::Category"
12
+
13
+ attr_accessor :category_ids
14
+
15
+ after_save :sync_categories
16
+
17
+ scope :for_category, -> (*categories) {
18
+ if (categories = [categories].flatten.compact).present?
19
+ self.distinct.
20
+ joins(categorizations: :category).
21
+ where("comfy_cms_categories.label" => categories)
22
+ end
23
+ }
24
+ end
25
+
26
+ def sync_categories
27
+ (self.category_ids || {}).each do |category_id, flag|
28
+ case flag.to_i
29
+ when 1
30
+ if category = Comfy::Cms::Category.find_by_id(category_id)
31
+ category.categorizations.create(categorized: self)
32
+ end
33
+ when 0
34
+ self.categorizations.where(category_id: category_id).destroy_all
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,121 @@
1
+ module Comfy::Cms::WithFragments
2
+ extend ActiveSupport::Concern
3
+
4
+ included do
5
+ attr_accessor :fragments_attributes_changed
6
+
7
+ belongs_to :layout,
8
+ class_name: 'Comfy::Cms::Layout'
9
+
10
+ has_many :fragments,
11
+ class_name: 'Comfy::Cms::Fragment',
12
+ as: :record,
13
+ autosave: true,
14
+ dependent: :destroy
15
+
16
+ before_save :clear_content_cache
17
+
18
+ validates :layout,
19
+ presence: true
20
+ end
21
+
22
+ # Array of fragment hashes in the following format:
23
+ # [
24
+ # {identifier: "frag_a", format: "text", content: "fragment a content"},
25
+ # {identifier: "frag_b", format: "file", files: [{file_a}, {file_b}]}
26
+ # ]
27
+ # It also handles when frag hashes come in as a hash:
28
+ # {
29
+ # "0" => {identifer: "foo", content: "bar"},
30
+ # "1" => {identifier: "bar", content: "foo"}
31
+ # }
32
+ def fragments_attributes=(frag_hashes = [])
33
+ frag_hashes = frag_hashes.values if frag_hashes.is_a?(Hash)
34
+
35
+ frag_hashes.each do |frag_attrs|
36
+ unless frag_attrs.is_a?(HashWithIndifferentAccess)
37
+ frag_attrs.symbolize_keys!
38
+ end
39
+
40
+ identifier = frag_attrs.delete(:identifier)
41
+
42
+ fragment =
43
+ self.fragments.detect{|f| f.identifier == identifier} ||
44
+ self.fragments.build(identifier: identifier)
45
+
46
+ fragment.attributes = frag_attrs
47
+
48
+ # tracking dirty
49
+ self.fragments_attributes_changed ||= fragment.changed?
50
+ end
51
+ end
52
+
53
+ # Snapshop of page fragments data used primarily for saving revisions
54
+ def fragments_attributes(was = false)
55
+ self.fragments.collect do |frag|
56
+ attrs = {}
57
+ %i(identifier tag content datetime boolean).each do |column|
58
+ attrs[column] = frag.send(was ? "#{column}_was" : column)
59
+ end
60
+ # TODO: save files against revision (not on db though)
61
+ # attrs[:files] = frag.attachments.collect do |a|
62
+ # {io: a.download, filename: a.filename.to_s, content_type: a.content_type}
63
+ # end
64
+ attrs
65
+ end
66
+ end
67
+
68
+ # Method to collect prevous state of blocks for revisions
69
+ def fragments_attributes_was
70
+ fragments_attributes(:previous_values)
71
+ end
72
+
73
+ # Grabbing nodes that we need to render form elements in the admin area
74
+ # Rejecting duplicates as we'd need to render only one form field. Don't declare
75
+ # duplicate tags on the layout. That's wierd (but still works).
76
+ def fragment_nodes
77
+ nodes
78
+ .select{|n| n.is_a?(ComfortableMexicanSofa::Content::Tag::Fragment)}
79
+ .uniq{|n| n.identifier}
80
+ end
81
+
82
+ # Rendered content of the page. We grab whatever layout is associated with the
83
+ # page and feed its content tokens to the renderer while passing this page as
84
+ # context.
85
+ def render(n = nodes)
86
+ renderer.render(n)
87
+ end
88
+
89
+ # If content_cache column is populated we don't need to call render for this
90
+ # page.
91
+ def content_cache
92
+ if (cache = read_attribute(:content_cache)).nil?
93
+ cache = self.render
94
+ update_column(:content_cache, cache) unless self.new_record?
95
+ end
96
+ cache
97
+ end
98
+
99
+ # Nuking content cache so it can be regenerated.
100
+ def clear_content_cache!
101
+ self.update_column(:content_cache, nil)
102
+ end
103
+
104
+ # Blanking cache on page saves so it can be regenerated on access
105
+ def clear_content_cache
106
+ write_attribute(:content_cache, nil)
107
+ end
108
+
109
+ protected
110
+
111
+ def renderer
112
+ ComfortableMexicanSofa::Content::Renderer.new(self)
113
+ end
114
+
115
+ def nodes
116
+ return [] unless self.layout.present?
117
+
118
+ tokens = self.layout.content_tokens
119
+ renderer.nodes(tokens)
120
+ end
121
+ end