alchemy_cms 4.0.6 → 4.1.0.beta

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 (340) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +1 -0
  3. data/.gitignore +1 -0
  4. data/.localeapp/config.rb +8 -0
  5. data/.rubocop.yml +26 -13
  6. data/.travis.yml +12 -14
  7. data/CHANGELOG.md +5 -24
  8. data/Gemfile +10 -7
  9. data/README.md +16 -14
  10. data/Rakefile +1 -1
  11. data/alchemy_cms.gemspec +6 -7
  12. data/app/assets/images/alchemy/alchemy-logo.png +0 -0
  13. data/app/assets/images/alchemy/alchemy-logo.svg +1 -70
  14. data/app/assets/images/alchemy/favicon.ico +0 -0
  15. data/app/assets/images/alchemy/icon.svg +1 -14
  16. data/app/assets/javascripts/alchemy/admin.js +0 -7
  17. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +2 -2
  18. data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +1 -1
  19. data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +1 -1
  20. data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +1 -0
  21. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +19 -6
  22. data/app/assets/javascripts/alchemy/alchemy.dirty.js.coffee +2 -7
  23. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +36 -26
  24. data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +6 -15
  25. data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +1 -1
  26. data/app/assets/javascripts/alchemy/alchemy.growler.js.coffee +8 -11
  27. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +4 -1
  28. data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +1 -1
  29. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +5 -14
  30. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +54 -75
  31. data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +4 -13
  32. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +1 -0
  33. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +12 -6
  34. data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +0 -158
  35. data/app/assets/stylesheets/alchemy/_defaults.scss +0 -2
  36. data/app/assets/stylesheets/alchemy/_extends.scss +13 -18
  37. data/app/assets/stylesheets/alchemy/_mixins.scss +72 -46
  38. data/app/assets/stylesheets/alchemy/_variables.scss +128 -59
  39. data/app/assets/stylesheets/alchemy/admin.scss +7 -1
  40. data/app/assets/stylesheets/alchemy/archive.scss +23 -27
  41. data/app/assets/stylesheets/alchemy/base.scss +5 -355
  42. data/app/assets/stylesheets/alchemy/buttons.scss +23 -60
  43. data/app/assets/stylesheets/alchemy/clipboard.scss +26 -0
  44. data/app/assets/stylesheets/alchemy/dashboard.scss +7 -40
  45. data/app/assets/stylesheets/alchemy/dialogs.scss +23 -36
  46. data/app/assets/stylesheets/alchemy/elements.scss +80 -156
  47. data/app/assets/stylesheets/alchemy/errors.scss +2 -2
  48. data/app/assets/stylesheets/alchemy/flash.scss +19 -10
  49. data/app/assets/stylesheets/alchemy/fonts.scss +13 -0
  50. data/app/assets/stylesheets/alchemy/forms.scss +6 -1
  51. data/app/assets/stylesheets/alchemy/frame.scss +24 -65
  52. data/app/assets/stylesheets/alchemy/hints.scss +2 -2
  53. data/app/assets/stylesheets/alchemy/icons.scss +3 -337
  54. data/app/assets/stylesheets/alchemy/image_library.scss +9 -10
  55. data/app/assets/stylesheets/alchemy/jquery-ui.scss +21 -839
  56. data/app/assets/stylesheets/alchemy/jquery.datetimepicker.scss +32 -57
  57. data/app/assets/stylesheets/alchemy/lists.scss +4 -8
  58. data/app/assets/stylesheets/alchemy/menubar.scss +26 -29
  59. data/app/assets/stylesheets/alchemy/navigation.scss +23 -25
  60. data/app/assets/stylesheets/alchemy/notices.scss +25 -25
  61. data/app/assets/stylesheets/alchemy/pagination.scss +12 -7
  62. data/app/assets/stylesheets/alchemy/preview_window.scss +20 -0
  63. data/app/assets/stylesheets/alchemy/resource_info.scss +1 -1
  64. data/app/assets/stylesheets/alchemy/search.scss +19 -15
  65. data/app/assets/stylesheets/alchemy/selects.scss +63 -32
  66. data/app/assets/stylesheets/alchemy/sitemap.scss +70 -148
  67. data/app/assets/stylesheets/alchemy/tables.scss +16 -59
  68. data/app/assets/stylesheets/alchemy/toolbar.scss +9 -36
  69. data/app/assets/stylesheets/alchemy/trash.scss +8 -0
  70. data/app/assets/stylesheets/alchemy/upload.scss +5 -6
  71. data/app/assets/stylesheets/tinymce/skins/alchemy/content.min.css.scss +1 -0
  72. data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +78 -43
  73. data/app/controllers/alchemy/admin/attachments_controller.rb +6 -6
  74. data/app/controllers/alchemy/admin/base_controller.rb +9 -9
  75. data/app/controllers/alchemy/admin/contents_controller.rb +0 -17
  76. data/app/controllers/alchemy/admin/elements_controller.rb +1 -4
  77. data/app/controllers/alchemy/admin/essence_files_controller.rb +1 -3
  78. data/app/controllers/alchemy/admin/essence_pictures_controller.rb +1 -3
  79. data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
  80. data/app/controllers/alchemy/admin/pictures_controller.rb +5 -5
  81. data/app/controllers/alchemy/admin/resources_controller.rb +10 -10
  82. data/app/controllers/alchemy/admin/tags_controller.rb +7 -7
  83. data/app/controllers/alchemy/api/contents_controller.rb +6 -1
  84. data/app/controllers/alchemy/api/elements_controller.rb +5 -1
  85. data/app/controllers/alchemy/api/pages_controller.rb +6 -1
  86. data/app/controllers/alchemy/base_controller.rb +5 -3
  87. data/app/controllers/alchemy/pages_controller.rb +1 -1
  88. data/app/helpers/alchemy/admin/base_helper.rb +14 -15
  89. data/app/helpers/alchemy/admin/contents_helper.rb +1 -2
  90. data/app/helpers/alchemy/admin/elements_helper.rb +7 -6
  91. data/app/helpers/alchemy/admin/tags_helper.rb +3 -4
  92. data/app/helpers/alchemy/base_helper.rb +35 -5
  93. data/app/helpers/alchemy/elements_helper.rb +2 -2
  94. data/app/helpers/alchemy/pages_helper.rb +4 -2
  95. data/app/models/alchemy/attachment.rb +14 -23
  96. data/app/models/alchemy/base_record.rb +13 -0
  97. data/app/models/alchemy/cell.rb +1 -1
  98. data/app/models/alchemy/content.rb +1 -2
  99. data/app/models/alchemy/content/factory.rb +1 -1
  100. data/app/models/alchemy/element.rb +10 -12
  101. data/app/models/alchemy/essence_boolean.rb +1 -1
  102. data/app/models/alchemy/essence_date.rb +2 -2
  103. data/app/models/alchemy/essence_file.rb +1 -1
  104. data/app/models/alchemy/essence_html.rb +1 -1
  105. data/app/models/alchemy/essence_link.rb +1 -1
  106. data/app/models/alchemy/essence_picture.rb +1 -1
  107. data/app/models/alchemy/essence_richtext.rb +1 -1
  108. data/app/models/alchemy/essence_select.rb +1 -1
  109. data/app/models/alchemy/essence_text.rb +1 -1
  110. data/app/models/alchemy/folded_page.rb +1 -1
  111. data/app/models/alchemy/language.rb +21 -5
  112. data/app/models/alchemy/page.rb +17 -5
  113. data/app/models/alchemy/page/page_elements.rb +14 -2
  114. data/app/models/alchemy/page/page_naming.rb +17 -4
  115. data/app/models/alchemy/picture.rb +4 -7
  116. data/app/models/alchemy/site.rb +3 -3
  117. data/app/models/alchemy/tag.rb +3 -3
  118. data/app/models/concerns/alchemy/content_touching.rb +23 -0
  119. data/app/serializers/alchemy/element_serializer.rb +2 -0
  120. data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +1 -1
  121. data/app/views/alchemy/admin/attachments/_attachment.html.erb +11 -21
  122. data/app/views/alchemy/admin/attachments/_files_list.html.erb +26 -29
  123. data/app/views/alchemy/admin/attachments/_filter_bar.html.erb +2 -3
  124. data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +3 -4
  125. data/app/views/alchemy/admin/attachments/_replace_button.html.erb +2 -3
  126. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +3 -3
  127. data/app/views/alchemy/admin/attachments/destroy.js.erb +1 -1
  128. data/app/views/alchemy/admin/attachments/edit.html.erb +2 -2
  129. data/app/views/alchemy/admin/attachments/index.html.erb +3 -2
  130. data/app/views/alchemy/admin/attachments/show.html.erb +7 -8
  131. data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
  132. data/app/views/alchemy/admin/clipboard/index.html.erb +23 -7
  133. data/app/views/alchemy/admin/clipboard/insert.js.erb +1 -1
  134. data/app/views/alchemy/admin/clipboard/remove.js.erb +2 -2
  135. data/app/views/alchemy/admin/contents/create.js.erb +1 -1
  136. data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +9 -6
  137. data/app/views/alchemy/admin/dashboard/_recent_pages.html.erb +6 -4
  138. data/app/views/alchemy/admin/dashboard/_sites.html.erb +4 -2
  139. data/app/views/alchemy/admin/dashboard/_users.html.erb +6 -4
  140. data/app/views/alchemy/admin/dashboard/index.html.erb +3 -3
  141. data/app/views/alchemy/admin/dashboard/info.html.erb +6 -7
  142. data/app/views/alchemy/admin/elements/_add_picture.html.erb +1 -1
  143. data/app/views/alchemy/admin/elements/_element.html.erb +1 -1
  144. data/app/views/alchemy/admin/elements/_element_header.html.erb +14 -14
  145. data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +3 -3
  146. data/app/views/alchemy/admin/elements/_new_element_form.html.erb +2 -3
  147. data/app/views/alchemy/admin/elements/index.html.erb +2 -4
  148. data/app/views/alchemy/admin/elements/new.html.erb +1 -2
  149. data/app/views/alchemy/admin/elements/publish.js.erb +5 -5
  150. data/app/views/alchemy/admin/languages/_language.html.erb +4 -9
  151. data/app/views/alchemy/admin/languages/_table.html.erb +1 -1
  152. data/app/views/alchemy/admin/languages/index.html.erb +1 -1
  153. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +5 -5
  154. data/app/views/alchemy/admin/layoutpages/index.html.erb +5 -4
  155. data/app/views/alchemy/admin/leave.html.erb +1 -1
  156. data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +1 -1
  157. data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +1 -1
  158. data/app/views/alchemy/admin/pages/_form.html.erb +1 -1
  159. data/app/views/alchemy/admin/pages/_locked_page.html.erb +1 -1
  160. data/app/views/alchemy/admin/pages/_page.html.erb +31 -23
  161. data/app/views/alchemy/admin/pages/_page_for_links.html.erb +5 -5
  162. data/app/views/alchemy/admin/pages/_page_infos.html.erb +3 -3
  163. data/app/views/alchemy/admin/pages/_publication_fields.html.erb +1 -1
  164. data/app/views/alchemy/admin/pages/edit.html.erb +22 -21
  165. data/app/views/alchemy/admin/pages/index.html.erb +5 -21
  166. data/app/views/alchemy/admin/pages/info.html.erb +5 -5
  167. data/app/views/alchemy/admin/pages/sort.html.erb +1 -1
  168. data/app/views/alchemy/admin/pages/unlock.js.erb +2 -4
  169. data/app/views/alchemy/admin/partials/_flash.html.erb +1 -1
  170. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +7 -3
  171. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +2 -2
  172. data/app/views/alchemy/admin/partials/_search_form.html.erb +3 -3
  173. data/app/views/alchemy/admin/pictures/_archive.html.erb +19 -17
  174. data/app/views/alchemy/admin/pictures/_archive_overlay.html.erb +1 -1
  175. data/app/views/alchemy/admin/pictures/_filter_and_size_bar.html.erb +13 -13
  176. data/app/views/alchemy/admin/pictures/_filter_bar.html.erb +2 -3
  177. data/app/views/alchemy/admin/pictures/_form.html.erb +3 -3
  178. data/app/views/alchemy/admin/pictures/_overlay_picture_list.html.erb +2 -3
  179. data/app/views/alchemy/admin/pictures/_picture.html.erb +7 -7
  180. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +3 -3
  181. data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +6 -7
  182. data/app/views/alchemy/admin/pictures/index.html.erb +12 -12
  183. data/app/views/alchemy/admin/pictures/index.js.erb +0 -1
  184. data/app/views/alchemy/admin/pictures/show.html.erb +9 -9
  185. data/app/views/alchemy/admin/resources/_filter_bar.html.erb +2 -3
  186. data/app/views/alchemy/admin/resources/_form.html.erb +10 -2
  187. data/app/views/alchemy/admin/resources/_resource.html.erb +9 -14
  188. data/app/views/alchemy/admin/resources/_table.html.erb +1 -1
  189. data/app/views/alchemy/admin/resources/_tag_list.html.erb +4 -4
  190. data/app/views/alchemy/admin/resources/index.html.erb +2 -3
  191. data/app/views/alchemy/admin/sites/index.html.erb +1 -1
  192. data/app/views/alchemy/admin/tags/_tag.html.erb +7 -11
  193. data/app/views/alchemy/admin/tags/index.html.erb +4 -4
  194. data/app/views/alchemy/admin/trash/index.html.erb +2 -3
  195. data/app/views/alchemy/admin/uploader/_button.html.erb +1 -2
  196. data/app/views/alchemy/base/500.html.erb +1 -1
  197. data/app/views/alchemy/base/permission_denied.js.erb +1 -1
  198. data/app/views/alchemy/base/redirect.js.erb +1 -2
  199. data/app/views/alchemy/elements/_editor_not_found.html.erb +2 -3
  200. data/app/views/alchemy/essences/_essence_date_editor.html.erb +1 -1
  201. data/app/views/alchemy/essences/_essence_file_editor.html.erb +7 -11
  202. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +9 -7
  203. data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +1 -1
  204. data/app/views/alchemy/pages/_meta_data.html.erb +1 -1
  205. data/app/views/kaminari/alchemy/_first_page.html.erb +7 -3
  206. data/app/views/kaminari/alchemy/_gap.html.erb +1 -1
  207. data/app/views/kaminari/alchemy/_last_page.html.erb +7 -3
  208. data/app/views/kaminari/alchemy/_next_page.html.erb +4 -2
  209. data/app/views/kaminari/alchemy/_page.html.erb +1 -1
  210. data/app/views/kaminari/alchemy/_prev_page.html.erb +4 -2
  211. data/app/views/layouts/alchemy/admin.html.erb +8 -6
  212. data/bin/rails +2 -2
  213. data/bin/rspec +1 -1
  214. data/config/alchemy/config.yml +0 -2
  215. data/config/alchemy/modules.yml +5 -5
  216. data/config/initializers/simple_form.rb +45 -8
  217. data/config/locales/alchemy.en.yml +66 -179
  218. data/config/routes.rb +1 -1
  219. data/db/migrate/20180226123013_alchemy_four_point_zero.rb +392 -0
  220. data/db/migrate/20180227224537_migrate_tags_to_gutentag.rb +41 -0
  221. data/lib/alchemy/config.rb +0 -2
  222. data/lib/alchemy/engine.rb +5 -9
  223. data/lib/alchemy/essence.rb +6 -6
  224. data/lib/alchemy/filetypes.rb +13 -1
  225. data/lib/alchemy/forms/builder.rb +5 -3
  226. data/lib/alchemy/i18n.rb +8 -6
  227. data/lib/alchemy/modules.rb +1 -1
  228. data/lib/alchemy/name_conversions.rb +0 -2
  229. data/lib/alchemy/page_layout.rb +3 -2
  230. data/lib/alchemy/paths.rb +5 -5
  231. data/lib/alchemy/resource.rb +9 -9
  232. data/lib/alchemy/resources_helper.rb +11 -15
  233. data/lib/alchemy/routing_constraints.rb +2 -2
  234. data/lib/alchemy/shell.rb +0 -1
  235. data/lib/alchemy/taggable.rb +40 -0
  236. data/lib/alchemy/tasks/tidy.rb +1 -9
  237. data/lib/alchemy/test_support/factories/content_factory.rb +10 -0
  238. data/lib/alchemy/test_support/factories/element_factory.rb +5 -0
  239. data/lib/alchemy/test_support/shared_contexts.rb +1 -1
  240. data/lib/alchemy/tinymce.rb +2 -2
  241. data/lib/alchemy/upgrader/four_point_one.rb +42 -0
  242. data/lib/alchemy/upgrader/tasks/harden_acts_as_taggable_on_migrations.rb +27 -0
  243. data/lib/alchemy/version.rb +1 -1
  244. data/lib/alchemy_cms.rb +2 -3
  245. data/lib/rails/generators/alchemy/elements/elements_generator.rb +2 -2
  246. data/lib/rails/generators/alchemy/essence/essence_generator.rb +1 -1
  247. data/lib/rails/generators/alchemy/install/install_generator.rb +4 -8
  248. data/lib/rails/generators/alchemy/module/module_generator.rb +1 -1
  249. data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +2 -2
  250. data/lib/rails/generators/alchemy/site_layouts/site_layouts_generator.rb +2 -2
  251. data/lib/rails/generators/alchemy/views/views_generator.rb +1 -1
  252. data/lib/tasks/alchemy/db.rake +2 -1
  253. data/lib/tasks/alchemy/tidy.rake +0 -6
  254. data/lib/tasks/alchemy/upgrade.rake +11 -144
  255. data/vendor/assets/fonts/fa-regular-400.eot +0 -0
  256. data/vendor/assets/fonts/fa-regular-400.svg +363 -0
  257. data/vendor/assets/fonts/fa-regular-400.ttf +0 -0
  258. data/vendor/assets/fonts/fa-regular-400.woff +0 -0
  259. data/vendor/assets/fonts/fa-regular-400.woff2 +0 -0
  260. data/vendor/assets/fonts/fa-solid-900.eot +0 -0
  261. data/vendor/assets/fonts/fa-solid-900.svg +1413 -0
  262. data/vendor/assets/fonts/fa-solid-900.ttf +0 -0
  263. data/vendor/assets/fonts/fa-solid-900.woff +0 -0
  264. data/vendor/assets/fonts/fa-solid-900.woff2 +0 -0
  265. data/vendor/assets/javascripts/tinymce/license.txt +6 -6
  266. data/vendor/assets/javascripts/tinymce/tinymce.min.js +2 -15
  267. data/vendor/assets/stylesheets/fontawesome/_animated.scss +20 -0
  268. data/vendor/assets/stylesheets/fontawesome/_bordered-pulled.scss +20 -0
  269. data/vendor/assets/stylesheets/fontawesome/_core.scss +16 -0
  270. data/vendor/assets/stylesheets/fontawesome/_fixed-width.scss +6 -0
  271. data/vendor/assets/stylesheets/fontawesome/_icons.scss +792 -0
  272. data/vendor/assets/stylesheets/fontawesome/_larger.scss +23 -0
  273. data/vendor/assets/stylesheets/fontawesome/_list.scss +18 -0
  274. data/vendor/assets/stylesheets/fontawesome/_mixins.scss +57 -0
  275. data/vendor/assets/stylesheets/fontawesome/_rotated-flipped.scss +23 -0
  276. data/vendor/assets/stylesheets/fontawesome/_screen-reader.scss +5 -0
  277. data/vendor/assets/stylesheets/fontawesome/_stacked.scss +31 -0
  278. data/vendor/assets/stylesheets/fontawesome/_variables.scss +805 -0
  279. data/vendor/assets/stylesheets/fontawesome/fa-regular.scss +22 -0
  280. data/vendor/assets/stylesheets/fontawesome/fa-solid.scss +23 -0
  281. data/vendor/assets/stylesheets/fontawesome/fontawesome.scss +16 -0
  282. metadata +78 -112
  283. data/app/assets/fonts/alchemy/icons.eot +0 -0
  284. data/app/assets/fonts/alchemy/icons.svg +0 -33
  285. data/app/assets/fonts/alchemy/icons.ttf +0 -0
  286. data/app/assets/fonts/alchemy/icons.woff +0 -0
  287. data/app/assets/images/alchemy/icons.png +0 -0
  288. data/app/assets/images/alchemy/ui-icons_666666_256x240.png +0 -0
  289. data/app/assets/images/sassy-ie-overlay.png +0 -0
  290. data/app/assets/javascripts/alchemy/alchemy.jquery_loader.js +0 -42
  291. data/app/assets/stylesheets/alchemy/icon-font.scss +0 -75
  292. data/app/assets/stylesheets/alchemy/modules.scss +0 -27
  293. data/app/models/alchemy.rb +0 -7
  294. data/app/views/alchemy/admin/contents/destroy.js.erb +0 -4
  295. data/app/views/alchemy/admin/pictures/flush.js.erb +0 -2
  296. data/config/locales/alchemy.de.yml +0 -932
  297. data/config/locales/alchemy.es.yml +0 -960
  298. data/config/locales/alchemy.fr.yml +0 -938
  299. data/config/locales/alchemy.it.yml +0 -938
  300. data/config/locales/alchemy.nl.yml +0 -918
  301. data/config/locales/alchemy.ru.yml +0 -830
  302. data/config/locales/simple_form.de.yml +0 -26
  303. data/config/locales/simple_form.en.yml +0 -25
  304. data/config/locales/simple_form.es.yml +0 -6
  305. data/config/locales/simple_form.fr.yml +0 -26
  306. data/config/locales/simple_form.it.yml +0 -25
  307. data/config/locales/simple_form.nl.yml +0 -25
  308. data/config/locales/simple_form.ru.yml +0 -25
  309. data/db/migrate/20130827094554_alchemy_two_point_six.rb +0 -378
  310. data/db/migrate/20130828121054_remove_do_not_index_from_alchemy_essence_texts.rb +0 -5
  311. data/db/migrate/20130828121120_remove_do_not_index_from_alchemy_essence_richtexts.rb +0 -5
  312. data/db/migrate/20130918201742_add_published_at_to_alchemy_pages.rb +0 -5
  313. data/db/migrate/20150608204610_add_parent_element_id_to_alchemy_elements.rb +0 -6
  314. data/db/migrate/20150729151825_add_link_text_to_alchemy_essence_files.rb +0 -5
  315. data/db/migrate/20150906195818_add_locale_to_alchemy_languages.rb +0 -7
  316. data/db/migrate/20160108174834_add_timebased_publishing_columns_to_pages.rb +0 -32
  317. data/db/migrate/20160422195310_add_image_file_format_to_alchemy_pictures.rb +0 -9
  318. data/db/migrate/20160617224938_change_alchemy_pages_locked_to_locked_at.rb +0 -22
  319. data/db/migrate/20160912223112_add_index_to_alchemy_pages_rgt.rb +0 -9
  320. data/db/migrate/20160927205604_add_foreign_key_indices_and_null_constraints.rb +0 -20
  321. data/db/migrate/20160928080104_add_foreign_keys.rb +0 -27
  322. data/lib/alchemy/touching.rb +0 -42
  323. data/lib/alchemy/upgrader/tasks/available_contents_upgrader.rb +0 -161
  324. data/lib/alchemy/upgrader/tasks/install_asset_manifests.rb +0 -15
  325. data/lib/alchemy/upgrader/tasks/install_dragonfly_config.rb +0 -14
  326. data/lib/alchemy/upgrader/tasks/nestable_elements_migration.rb +0 -71
  327. data/lib/alchemy/upgrader/tasks/three_point_two_task.rb +0 -31
  328. data/lib/alchemy/upgrader/three_point_five.rb +0 -32
  329. data/lib/alchemy/upgrader/three_point_four.rb +0 -52
  330. data/lib/alchemy/upgrader/three_point_one.rb +0 -54
  331. data/lib/alchemy/upgrader/three_point_three.rb +0 -50
  332. data/lib/alchemy/upgrader/three_point_two.rb +0 -40
  333. data/lib/alchemy/upgrader/three_point_zero.rb +0 -92
  334. data/vendor/assets/javascripts/jquery_plugins/jquery.floatThead.min.js +0 -3
  335. data/vendor/assets/javascripts/tinymce/langs/de.js +0 -219
  336. data/vendor/assets/javascripts/tinymce/langs/es.js +0 -219
  337. data/vendor/assets/javascripts/tinymce/langs/fr.js +0 -219
  338. data/vendor/assets/javascripts/tinymce/langs/it.js +0 -219
  339. data/vendor/assets/javascripts/tinymce/langs/nl.js +0 -219
  340. data/vendor/assets/javascripts/tinymce/langs/ru.js +0 -219
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ class MigrateTagsToGutentag < ActiveRecord::Migration[5.0]
4
+ def up
5
+ return if table_exists?(:gutentag_tags)
6
+
7
+ remove_index :taggings, :taggable_id
8
+ remove_column :taggings, :tagger_id, :integer
9
+ remove_index :taggings, :taggable_type
10
+ remove_column :taggings, :tagger_type, :string
11
+ remove_index :taggings, column: [:taggable_id, :taggable_type, :context], name: 'index_taggings_on_taggable_id_and_taggable_type_and_context'
12
+ remove_column :taggings, :context, :string, limit: 128
13
+ if index_exists? :taggings, [:tag_id, :taggable_id, :taggable_type], unique: true, name: 'taggings_idx'
14
+ rename_index :taggings, 'taggings_idx', 'unique_taggings'
15
+ else
16
+ add_index :taggings, [:taggable_type, :taggable_id, :tag_id], unique: true, name: 'unique_taggings'
17
+ end
18
+ if index_exists? :taggings, [:taggable_id, :taggable_type], name: 'taggings_idy'
19
+ rename_index :taggings, 'taggings_idy', 'index_gutentag_taggings_on_taggable_id_and_taggable_type'
20
+ else
21
+ add_index :taggings, [:taggable_type, :taggable_id]
22
+ end
23
+ add_column :taggings, :updated_at, :datetime, precision: 6
24
+ change_column_null :taggings, :tag_id, false
25
+ change_column_null :taggings, :taggable_id, false
26
+ change_column_null :taggings, :taggable_type, false
27
+ change_column_null :taggings, :created_at, false, Time.current
28
+ change_column_null :taggings, :updated_at, false, Time.current
29
+ rename_table :taggings, :gutentag_taggings
30
+
31
+ change_column_null :tags, :name, false
32
+ add_index :tags, :taggings_count
33
+ rename_table :tags, :gutentag_tags
34
+
35
+ %i(alchemy_attachments alchemy_elements alchemy_pages alchemy_pictures).each do |table|
36
+ if column_exists? table, :cached_tag_list
37
+ remove_column table, :cached_tag_list
38
+ end
39
+ end
40
+ end
41
+ end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # encoding: utf-8
4
-
5
3
  module Alchemy
6
4
  class Config
7
5
  class << self
@@ -14,15 +14,11 @@ module Alchemy
14
14
  NonStupidDigestAssets.whitelist += [/^tinymce\//]
15
15
  end
16
16
 
17
- # We need to reload each essence class in development mode on every request,
18
- # so it can register itself as essence relation on Page and Element models
19
- #
20
- # @see lib/alchemy/essence.rb:71
21
- config.to_prepare do
22
- unless Rails.configuration.cache_classes
23
- essences = File.join(File.dirname(__FILE__), '../../app/models/alchemy/essence_*.rb')
24
- Dir.glob(essences).each { |essence| load(essence) }
25
- end
17
+ # Gutentag downcases all tgas before save.
18
+ # We support having tags with uppercase characters.
19
+ # The Gutentag search is case insensitive.
20
+ initializer 'alchemy.gutentag_normalizer' do
21
+ Gutentag.normaliser = ->(value) { value.to_s }
26
22
  end
27
23
 
28
24
  config.after_initialize do
@@ -31,15 +31,15 @@ module Alchemy #:nodoc:
31
31
  ingredient_column: 'body'
32
32
  }.update(options)
33
33
 
34
- class_eval <<-EOV
34
+ class_eval <<-RUBY, __FILE__, __LINE__ + 1
35
35
  attr_writer :validation_errors
36
36
  include Alchemy::Essence::InstanceMethods
37
37
  stampable stamper_class_name: Alchemy.user_class_name
38
- validate :validate_ingredient, :on => :update, :if => 'validations.any?'
38
+ validate :validate_ingredient, on: :update, if: -> { validations.any? }
39
39
 
40
- has_one :content, :as => :essence, class_name: "Alchemy::Content"
41
- has_one :element, :through => :content, class_name: "Alchemy::Element"
42
- has_one :page, :through => :element, class_name: "Alchemy::Page"
40
+ has_one :content, as: :essence, class_name: "Alchemy::Content"
41
+ has_one :element, through: :content, class_name: "Alchemy::Element"
42
+ has_one :page, through: :element, class_name: "Alchemy::Page"
43
43
 
44
44
  scope :available, -> { joins(:element).merge(Alchemy::Element.available) }
45
45
  scope :from_element, ->(name) { joins(:element).where(Element.table_name => { name: name }) }
@@ -65,7 +65,7 @@ module Alchemy #:nodoc:
65
65
  def preview_text_column
66
66
  '#{configuration[:preview_text_column] || configuration[:ingredient_column]}'
67
67
  end
68
- EOV
68
+ RUBY
69
69
  end
70
70
 
71
71
  # Register the current class as has_many association on +Alchemy::Page+ and +Alchemy::Element+ models
@@ -16,7 +16,8 @@ module Alchemy
16
16
  "image/jpeg",
17
17
  "image/png",
18
18
  "image/svg+xml",
19
- "image/tiff"
19
+ "image/tiff",
20
+ "image/x-psd"
20
21
  ]
21
22
 
22
23
  VCARD_FILE_TYPES = ["text/x-vcard", "application/vcard"]
@@ -30,5 +31,16 @@ module Alchemy
30
31
  "video/x-msvideo",
31
32
  "video/x-ms-wmv"
32
33
  ]
34
+
35
+ TEXT_FILE_TYPES = [
36
+ "application/rtf",
37
+ "text/plain"
38
+ ]
39
+
40
+ EXCEL_FILE_TYPES = [
41
+ "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
42
+ "application/vnd.ms-excel",
43
+ "text/csv"
44
+ ]
33
45
  end
34
46
  end
@@ -21,9 +21,11 @@ module Alchemy
21
21
  # Renders a button tag wrapped in a div with 'submit' class.
22
22
  #
23
23
  def submit(label, options = {})
24
- options = {class: 'submit'}.update(options[:wrapper_html] || {})
25
- template.content_tag('div', options) do
26
- template.content_tag('button', label, options[:input_html])
24
+ options = {
25
+ wrapper_html: {class: 'submit'}
26
+ }.update(options)
27
+ template.content_tag('div', options.delete(:wrapper_html)) do
28
+ template.content_tag('button', label, options.delete(:input_html))
27
29
  end
28
30
  end
29
31
  end
data/lib/alchemy/i18n.rb CHANGED
@@ -18,6 +18,8 @@ module Alchemy
18
18
  end
19
19
 
20
20
  module I18n
21
+ LOCALE_FILE_PATTERN = /alchemy\.(\S{2,5})\.yml/
22
+
21
23
  class << self
22
24
  # Alchemy translation methods
23
25
  #
@@ -54,9 +56,9 @@ module Alchemy
54
56
 
55
57
  def available_locales
56
58
  @@available_locales ||= nil
57
- @@available_locales || translation_files.collect do |f|
58
- f.match(/.{2}\.yml$/).to_s.gsub(/\.yml/, '').to_sym
59
- end
59
+ @@available_locales || translation_files.collect { |f|
60
+ f.match(LOCALE_FILE_PATTERN)[1].to_sym
61
+ }.uniq.sort
60
62
  end
61
63
 
62
64
  def available_locales=(locales)
@@ -64,12 +66,12 @@ module Alchemy
64
66
  @@available_locales = nil if @@available_locales.empty?
65
67
  end
66
68
 
69
+ private
70
+
67
71
  def translation_files
68
- Dir.glob(File.join(File.dirname(__FILE__), '../../config/locales/alchemy.*.yml'))
72
+ ::I18n.load_path.select { |path| path.match(LOCALE_FILE_PATTERN) }
69
73
  end
70
74
 
71
- private
72
-
73
75
  def humanize_default_string!(msg, options)
74
76
  return if options[:default].present?
75
77
  options[:default] = msg.is_a?(Symbol) ? msg.to_s.humanize : msg
@@ -4,7 +4,7 @@ module Alchemy
4
4
  module Modules
5
5
  mattr_accessor :alchemy_modules
6
6
 
7
- @@alchemy_modules = YAML.load_file(File.expand_path('../../../config/alchemy/modules.yml', __FILE__))
7
+ @@alchemy_modules = YAML.load_file(File.expand_path('../../config/alchemy/modules.yml', __dir__))
8
8
 
9
9
  def self.included(base)
10
10
  base.send :helper_method, :alchemy_modules, :module_definition_for
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # encoding: utf-8
4
-
5
3
  module Alchemy
6
4
  # Provides methods for converting names into urlnames and vice versa.
7
5
  #
@@ -138,7 +138,7 @@ module Alchemy
138
138
  # Returns true if one page already has the given layout
139
139
  #
140
140
  def page_with_layout_existing?(layout)
141
- Page.where(page_layout: layout, language_id: @language_id).pluck(:id).any?
141
+ Alchemy::Page.where(page_layout: layout, language_id: @language_id).pluck(:id).any?
142
142
  end
143
143
 
144
144
  # Returns true if given layout is available for current site.
@@ -152,7 +152,8 @@ module Alchemy
152
152
  # page_layouts: [default_intro]
153
153
  #
154
154
  def available_on_site?(layout)
155
- Site.current.definition.blank? || Site.current.definition.fetch('page_layouts', []).include?(layout['name'])
155
+ Alchemy::Site.current.definition.blank? ||
156
+ Alchemy::Site.current.definition.fetch('page_layouts', []).include?(layout['name'])
156
157
  end
157
158
 
158
159
  # Reads the layout definitions from +config/alchemy/page_layouts.yml+.
data/lib/alchemy/paths.rb CHANGED
@@ -4,7 +4,7 @@
4
4
  #
5
5
  # Alchemy has some defaults for admin path and admin constraints:
6
6
  #
7
- # +Alchemy.admin_path defaults to +'/admin'+
7
+ # +Alchemy.admin_path defaults to +'admin'+
8
8
  # +Alchemy.admin_constraints defaults to +{}+
9
9
  #
10
10
  # Anyway, you can tell Alchemy about your routing configuration:
@@ -17,11 +17,11 @@
17
17
  #
18
18
  # == Example
19
19
  #
20
- # If you do not wish to use the default admin interface routing ('example.com/admin/')
21
- # and prefer e.g. 'hidden.example.com/backend/', those are the settings you need:
20
+ # If you do not wish to use the default admin interface routing ('example.com/admin')
21
+ # and prefer e.g. 'hidden.example.com/backend', those are the settings you need:
22
22
  #
23
23
  # # config/initializers/alchemy.rb
24
- # Alchemy.admin_path = '/backend'
24
+ # Alchemy.admin_path = 'backend'
25
25
  # Alchemy.admin_constraints = {subdomain: 'hidden'}
26
26
  #
27
27
  module Alchemy
@@ -29,6 +29,6 @@ module Alchemy
29
29
 
30
30
  # Defaults
31
31
  #
32
- @@admin_path = '/admin'
32
+ @@admin_path = 'admin'
33
33
  @@admin_constraints = {}
34
34
  end
@@ -95,7 +95,7 @@ module Alchemy
95
95
  # If you don't want to stick with these conventions you can separate model and controller by providing
96
96
  # a model class (for example used by Alchemy's Tags admin interface):
97
97
  #
98
- # resource = Resource.new('/admin/tags', {"engine_name"=>"alchemy"}, ActsAsTaggableOn::Tag)
98
+ # resource = Resource.new('/admin/tags', {"engine_name"=>"alchemy"}, Gutentag::Tag)
99
99
  #
100
100
  class Resource
101
101
  attr_accessor :resource_relations, :model_associations
@@ -238,23 +238,23 @@ module Alchemy
238
238
 
239
239
  private
240
240
 
241
- def searchable_attribute?(a)
242
- SEARCHABLE_COLUMN_TYPES.include?(a[:type].to_sym) && !a.key?(:relation)
241
+ def searchable_attribute?(attribute)
242
+ SEARCHABLE_COLUMN_TYPES.include?(attribute[:type].to_sym) && !attribute.key?(:relation)
243
243
  end
244
244
 
245
- def searchable_attribute_on_relation?(a)
246
- a.key?(:relation) &&
247
- SEARCHABLE_COLUMN_TYPES.include?(a[:relation][:attr_type].to_sym)
245
+ def searchable_attribute_on_relation?(attribute)
246
+ attribute.key?(:relation) &&
247
+ SEARCHABLE_COLUMN_TYPES.include?(attribute[:relation][:attr_type].to_sym)
248
248
  end
249
249
 
250
250
  def searchable_relation_attributes(attrs)
251
251
  attrs.select { |a| searchable_attribute_on_relation?(a) }.map { |a| searchable_relation_attribute(a) }
252
252
  end
253
253
 
254
- def searchable_relation_attribute(a)
254
+ def searchable_relation_attribute(attribute)
255
255
  {
256
- name: "#{a[:relation][:model_association].name}_#{a[:relation][:attr_method]}",
257
- type: a[:relation][:attr_type]
256
+ name: "#{attribute[:relation][:model_association].name}_#{attribute[:relation][:attr_method]}",
257
+ type: attribute[:relation][:attr_type]
258
258
  }
259
259
  end
260
260
 
@@ -68,17 +68,25 @@ module Alchemy
68
68
  # @param [Alchemy::Resource] resource
69
69
  # @param [Hash] attribute
70
70
  # @option options [Hash] :truncate (50) The length of the value returned.
71
+ # @option options [Hash] :datetime_format (alchemy.default) The format of timestamps.
72
+ # @option options [Hash] :time_format (alchemy.time) The format of time values.
71
73
  #
72
74
  # @return [String]
73
75
  #
74
76
  def render_attribute(resource, attribute, options = {})
77
+ attribute_value = resource.send(attribute[:name])
75
78
  if attribute[:relation]
76
79
  record = resource.send(attribute[:relation][:name])
77
80
  value = record.present? ? record.send(attribute[:relation][:attr_method]) : Alchemy.t(:not_found)
78
- elsif attribute[:type] == :datetime
79
- value = l(resource.send(attribute[:name]))
81
+ elsif attribute_value && (attribute[:type] == :datetime || attribute[:type] == :time)
82
+ localization_format = if attribute[:type] == :datetime
83
+ options[:datetime_format] || :'alchemy.default'
84
+ else
85
+ options[:time_format] || :'alchemy.time'
86
+ end
87
+ value = l(attribute_value, format: localization_format)
80
88
  else
81
- value = resource.send(attribute[:name])
89
+ value = attribute_value
82
90
  end
83
91
 
84
92
  options.reverse_merge!(truncate: 50)
@@ -163,18 +171,6 @@ module Alchemy
163
171
  render partial: 'resource', collection: resources_instance_variable
164
172
  end
165
173
 
166
- # Returns all the params necessary to get you back from where you where
167
- # before: the Ransack query and the current page.
168
- #
169
- def current_location_params
170
- {
171
- q: params[:q],
172
- page: params[:page],
173
- tagged_with: params[:tagged_with],
174
- filter: params[:filter]
175
- }
176
- end
177
-
178
174
  def resource_has_tags
179
175
  resource_model.respond_to?(:tag_counts) && resource_model.tag_counts.any?
180
176
  end
@@ -39,8 +39,8 @@ module Alchemy
39
39
  end
40
40
 
41
41
  # Handle invalid byte sequence in UTF-8 errors with 400 status.
42
- def handle_invalid_byte_sequence(e)
43
- if e.message =~ /invalid byte sequence/
42
+ def handle_invalid_byte_sequence(error)
43
+ if error.message =~ /invalid byte sequence/
44
44
  raise ActionController::BadRequest
45
45
  else
46
46
  raise
data/lib/alchemy/shell.rb CHANGED
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  require 'thor/shell/color'
3
2
 
4
3
  module Alchemy
@@ -0,0 +1,40 @@
1
+ module Alchemy
2
+ # ActsAsTaggableOn to Gutentag interface compatibility module
3
+ # Include this module to add tagging support to your model.
4
+ module Taggable
5
+ def self.included(base)
6
+ Gutentag::ActiveRecord.call base
7
+ base.extend ClassMethods
8
+ base.send(:alias_method, :tag_list, :tag_names)
9
+ end
10
+
11
+ # Set a list of tags
12
+ # Pass a String with comma separated tag names or
13
+ # an Array of tag names
14
+ def tag_list=(tags)
15
+ case tags
16
+ when String
17
+ self.tag_names = tags.split(/,\s*/)
18
+ when Array
19
+ self.tag_names = tags
20
+ end
21
+ end
22
+
23
+ module ClassMethods
24
+ # Find all records matching all of the given tags.
25
+ # Separate multiple tags by comma.
26
+ def tagged_with(names)
27
+ if names.is_a? String
28
+ names = names.split(/,\s*/)
29
+ end
30
+ super(names: names, match: :all)
31
+ end
32
+
33
+ # Returns all unique tags
34
+ def tag_counts
35
+ Gutentag::Tag.distinct.joins(:taggings)
36
+ .where(gutentag_taggings: {taggable_type: name})
37
+ end
38
+ end
39
+ end
40
+ end
@@ -117,20 +117,12 @@ module Alchemy
117
117
  end
118
118
  end
119
119
 
120
- def remove_duplicate_folded_pages
121
- Alchemy::FoldedPage.select(:page_id, :user_id).group(:page_id, :user_id).having("count(*) > 1").each do |duplicate_page|
122
- duplicate_page_ids = Alchemy::FoldedPage.where(duplicate_page.attributes.except("id")).pluck(:id)
123
- duplicate_page_ids_except_oldest = duplicate_page_ids.reject { |i| i == duplicate_page_ids.min }
124
- Alchemy::FoldedPage.where(id: duplicate_page_ids_except_oldest).delete_all
125
- end
126
- end
127
-
128
120
  private
129
121
 
130
122
  def destroy_orphaned_records(records, class_name)
131
123
  records.each do |record|
132
124
  log "Destroy orphaned #{class_name}: #{record.inspect}"
133
- record.reload.try(:destroy)
125
+ record.destroy
134
126
  end
135
127
  end
136
128
  end
@@ -7,5 +7,15 @@ FactoryBot.define do
7
7
  essence_type "Alchemy::EssenceText"
8
8
  association :essence, factory: :alchemy_essence_text
9
9
  association :element, factory: :alchemy_element
10
+
11
+ trait :essence_file do
12
+ essence_type "Alchemy::EssenceFile"
13
+ association :essence, factory: :alchemy_essence_file
14
+ end
15
+
16
+ trait :essence_picture do
17
+ essence_type "Alchemy::EssencePicture"
18
+ association :essence, factory: :alchemy_essence_picture
19
+ end
10
20
  end
11
21
  end