alchemy_cms 4.3.2 → 4.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +92 -0
  3. data/.gitignore +1 -0
  4. data/CHANGELOG.md +59 -2
  5. data/Gemfile +6 -5
  6. data/README.md +7 -6
  7. data/alchemy_cms.gemspec +4 -2
  8. data/app/assets/config/alchemy_manifest.js +15 -0
  9. data/app/assets/javascripts/alchemy/admin.js +1 -0
  10. data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +1 -13
  11. data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +1 -1
  12. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +84 -87
  13. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +0 -4
  14. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +1 -1
  15. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +2 -2
  16. data/app/assets/javascripts/alchemy/page_select.js +41 -0
  17. data/app/assets/javascripts/alchemy/templates/index.js +1 -0
  18. data/app/assets/javascripts/alchemy/templates/page.hbs +9 -0
  19. data/app/assets/stylesheets/alchemy/_mixins.scss +11 -1
  20. data/app/assets/stylesheets/alchemy/admin.scss +3 -0
  21. data/app/assets/stylesheets/alchemy/elements.scss +1 -0
  22. data/app/assets/stylesheets/alchemy/forms.scss +6 -5
  23. data/app/assets/stylesheets/alchemy/labels.scss +6 -0
  24. data/app/assets/stylesheets/alchemy/nodes.scss +154 -0
  25. data/app/assets/stylesheets/alchemy/page-select.scss +30 -0
  26. data/app/assets/stylesheets/alchemy/selects.scss +39 -22
  27. data/app/assets/stylesheets/alchemy/sitemap.scss +0 -33
  28. data/app/assets/stylesheets/alchemy/tags.scss +0 -3
  29. data/app/controllers/alchemy/admin/base_controller.rb +1 -0
  30. data/app/controllers/alchemy/admin/elements_controller.rb +24 -11
  31. data/app/controllers/alchemy/admin/languages_controller.rb +5 -0
  32. data/app/controllers/alchemy/admin/nodes_controller.rb +43 -0
  33. data/app/controllers/alchemy/admin/pages_controller.rb +1 -21
  34. data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
  35. data/app/controllers/alchemy/admin/tags_controller.rb +1 -2
  36. data/app/controllers/alchemy/api/contents_controller.rb +17 -2
  37. data/app/controllers/alchemy/api/elements_controller.rb +26 -1
  38. data/app/controllers/alchemy/api/pages_controller.rb +78 -7
  39. data/app/controllers/alchemy/messages_controller.rb +23 -8
  40. data/app/helpers/alchemy/admin/contents_helper.rb +1 -1
  41. data/app/helpers/alchemy/admin/elements_helper.rb +6 -0
  42. data/app/helpers/alchemy/admin/essences_helper.rb +23 -4
  43. data/app/helpers/alchemy/elements_block_helper.rb +11 -3
  44. data/app/helpers/alchemy/elements_helper.rb +3 -3
  45. data/app/helpers/alchemy/essences_helper.rb +36 -9
  46. data/app/helpers/alchemy/pages_helper.rb +29 -0
  47. data/app/models/alchemy/content.rb +1 -1
  48. data/app/models/alchemy/element.rb +20 -8
  49. data/app/models/alchemy/element/element_contents.rb +6 -4
  50. data/app/models/alchemy/element/presenters.rb +2 -2
  51. data/app/models/alchemy/essence_page.rb +29 -0
  52. data/app/models/alchemy/essence_picture.rb +8 -3
  53. data/app/models/alchemy/language.rb +10 -2
  54. data/app/models/alchemy/node.rb +48 -0
  55. data/app/models/alchemy/page.rb +74 -3
  56. data/app/models/alchemy/page/page_elements.rb +12 -4
  57. data/app/models/alchemy/page/page_natures.rb +6 -0
  58. data/app/models/alchemy/page/page_scopes.rb +1 -1
  59. data/app/models/alchemy/picture.rb +5 -1
  60. data/app/models/concerns/alchemy/content_touching.rb +1 -1
  61. data/app/serializers/alchemy/element_serializer.rb +7 -1
  62. data/app/serializers/alchemy/page_serializer.rb +0 -4
  63. data/app/views/alchemy/_menubar.html.erb +1 -1
  64. data/app/views/alchemy/admin/elements/_element.html.erb +18 -2
  65. data/app/views/alchemy/admin/leave.html.erb +1 -1
  66. data/app/views/alchemy/admin/nodes/_form.html.erb +39 -0
  67. data/app/views/alchemy/admin/nodes/_node.html.erb +87 -0
  68. data/app/views/alchemy/admin/nodes/edit.html.erb +1 -0
  69. data/app/views/alchemy/admin/nodes/index.html.erb +58 -0
  70. data/app/views/alchemy/admin/nodes/new.html.erb +1 -0
  71. data/app/views/alchemy/admin/pages/_anchor_link.html.erb +22 -0
  72. data/app/views/alchemy/admin/pages/_form.html.erb +1 -1
  73. data/app/views/alchemy/admin/pages/_internal_link.html.erb +7 -11
  74. data/app/views/alchemy/admin/pages/_menu_fields.html.erb +33 -0
  75. data/app/views/alchemy/admin/pages/_sitemap.html.erb +0 -7
  76. data/app/views/alchemy/admin/pages/link.html.erb +4 -0
  77. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +7 -3
  78. data/app/views/alchemy/admin/partials/_routes.html.erb +3 -3
  79. data/app/views/alchemy/essences/_essence_boolean_view.html.erb +1 -0
  80. data/app/views/alchemy/essences/_essence_date_view.html.erb +1 -0
  81. data/app/views/alchemy/essences/_essence_file_view.html.erb +1 -0
  82. data/app/views/alchemy/essences/_essence_html_view.html.erb +1 -0
  83. data/app/views/alchemy/essences/_essence_link_view.html.erb +1 -0
  84. data/app/views/alchemy/essences/_essence_page_editor.html.erb +23 -0
  85. data/app/views/alchemy/essences/_essence_page_view.html.erb +5 -0
  86. data/app/views/alchemy/essences/_essence_picture_editor.html.erb +2 -0
  87. data/app/views/alchemy/essences/_essence_picture_view.html.erb +1 -0
  88. data/app/views/alchemy/essences/_essence_richtext_view.html.erb +1 -0
  89. data/app/views/alchemy/essences/_essence_select_editor.html.erb +1 -0
  90. data/app/views/alchemy/essences/_essence_select_view.html.erb +1 -0
  91. data/app/views/alchemy/essences/_essence_text_editor.html.erb +3 -0
  92. data/app/views/alchemy/essences/_essence_text_view.html.erb +1 -0
  93. data/config/alchemy/modules.yml +13 -4
  94. data/config/initializers/assets.rb +1 -13
  95. data/config/locales/alchemy.en.yml +27 -9
  96. data/config/routes.rb +11 -3
  97. data/db/migrate/20191016073858_create_alchemy_essence_pages.rb +8 -0
  98. data/db/migrate/20191029212236_create_alchemy_nodes.rb +24 -0
  99. data/lib/alchemy/admin/locale.rb +1 -1
  100. data/lib/alchemy/auth_accessors.rb +8 -2
  101. data/lib/alchemy/cache_digests/template_tracker.rb +8 -5
  102. data/lib/alchemy/elements_finder.rb +17 -14
  103. data/lib/alchemy/engine.rb +4 -0
  104. data/lib/alchemy/essence.rb +40 -2
  105. data/lib/alchemy/permissions.rb +2 -0
  106. data/lib/alchemy/tasks/tidy.rb +1 -1
  107. data/lib/alchemy/test_support/essence_shared_examples.rb +25 -8
  108. data/lib/alchemy/test_support/factories/essence_page_factory.rb +10 -0
  109. data/lib/alchemy/test_support/factories/essence_picture_factory.rb +5 -0
  110. data/lib/alchemy/test_support/factories/node_factory.rb +21 -0
  111. data/lib/alchemy/version.rb +1 -1
  112. data/lib/rails/generators/alchemy/elements/elements_generator.rb +0 -1
  113. data/lib/rails/generators/alchemy/elements/templates/view.html.erb +3 -3
  114. data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -3
  115. data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -3
  116. data/lib/rails/generators/alchemy/install/files/{_article_view.html.erb → _article.html.erb} +2 -2
  117. data/lib/rails/generators/alchemy/install/files/application.html.erb +13 -10
  118. data/lib/rails/generators/alchemy/install/install_generator.rb +2 -11
  119. data/lib/rails/generators/alchemy/menus/menus_generator.rb +24 -0
  120. data/lib/rails/generators/alchemy/menus/templates/node.html.erb +19 -0
  121. data/lib/rails/generators/alchemy/menus/templates/node.html.haml +16 -0
  122. data/lib/rails/generators/alchemy/menus/templates/node.html.slim +16 -0
  123. data/lib/rails/generators/alchemy/menus/templates/wrapper.html.erb +8 -0
  124. data/lib/rails/generators/alchemy/menus/templates/wrapper.html.haml +6 -0
  125. data/lib/rails/generators/alchemy/menus/templates/wrapper.html.slim +6 -0
  126. data/lib/rails/generators/alchemy/views/views_generator.rb +1 -1
  127. data/lib/tasks/alchemy/convert.rake +60 -0
  128. metadata +79 -20
  129. data/.rspec +0 -1
  130. data/.travis.yml +0 -28
  131. data/app/models/alchemy/page/page_users.rb +0 -60
  132. data/app/views/alchemy/admin/elements/list.html.erb +0 -16
  133. data/app/views/alchemy/admin/pages/_page_for_links.html.erb +0 -53
  134. data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +0 -9
  135. data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +0 -8
  136. data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +0 -8
  137. data/lib/rails/generators/alchemy/install/files/_article_editor.html.erb +0 -5
  138. data/lib/rails/generators/alchemy/install/files/alchemy.de.yml +0 -31
  139. data/lib/rails/generators/alchemy/install/files/alchemy.es.yml +0 -31
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d15b38f5b661ee273e9b99e86f443784ef6ea5979557a98cd47c743853ac71bf
4
- data.tar.gz: 9a0610ad72088ab7b8d237d529e0ab5d52a7ecb6c40c04b30394ef3c8d6323ac
3
+ metadata.gz: 3627c5787085ffff82e37a3d35ca2ca42cc58c5ec8f44e10fa6ba91e4fbd4095
4
+ data.tar.gz: d2e1d6dbbae695b9a6e29df44d0ed8850952550e610fdfda6a156d519d19f3b6
5
5
  SHA512:
6
- metadata.gz: '086afcd9d02c25bac7f39acf06f7f8327801f803885501afc83114fa500be43838af96ea812a8766022e517a8ce8689a9189065e7868bc76c18161f6551079ac'
7
- data.tar.gz: 6a621a860ae8a1ed40ae62db8fa0025f2b8f95e662f1ffb328929213ec8638f05cddce70e4f1c037ee8c43d99f30e568ffb5693628721619dd3bc2b6efb607a4
6
+ metadata.gz: 72f44c680caaa741f59b3b33940a654774f53c94f8e3ce66d164135d52999007fe2d3b4ca0af80ee490f09366d758118d50498a5d22539662a5f81ba4379d52b
7
+ data.tar.gz: 1dd6222e477cffd173025f52b973d5f55f3f844f9f1731cfc2745b40b84a96622d51b74f331bb3d092462dbe20036622b14d802c64a0ee1e4f5552e37d19359d
@@ -0,0 +1,92 @@
1
+ name: CI
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ RSpec:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ fail-fast: false
10
+ matrix:
11
+ rails:
12
+ - '5.2'
13
+ - '6.0'
14
+ ruby:
15
+ - '2.5.x'
16
+ - '2.6.x'
17
+ database:
18
+ - mysql
19
+ - postgresql
20
+ env:
21
+ DB: ${{ matrix.database }}
22
+ MYSQL_PASSWORD: root
23
+ PGHOST: 127.0.0.1
24
+ PGUSER: postgres
25
+ RAILS_ENV: test
26
+ RAILS_VERSION: ${{ matrix.rails }}
27
+ CC_TEST_REPORTER_ID: bca4349e32f97919210ac8a450b04904b90683fcdd57d65a22c0f5065482bc22
28
+ services:
29
+ postgres:
30
+ image: postgres:10
31
+ ports: ['5432:5432']
32
+ options: --health-cmd pg_isready --health-interval 10s --health-timeout 5s --health-retries 5
33
+ steps:
34
+ - uses: actions/checkout@v1
35
+ - name: Set up Ruby
36
+ uses: actions/setup-ruby@v1
37
+ with:
38
+ ruby-version: ${{ matrix.ruby }}
39
+ - name: Restore apt cache
40
+ id: apt-cache
41
+ uses: actions/cache@preview
42
+ with:
43
+ path: /home/runner/apt/cache
44
+ key: ${{ runner.os }}-apt-${{ matrix.database }}
45
+ restore-keys: |
46
+ ${{ runner.os }}-apt-
47
+ - name: Install Postgres headers
48
+ if: matrix.database == 'postgresql'
49
+ run: |
50
+ mkdir -p /home/runner/apt/cache
51
+ sudo apt-get update -qq
52
+ sudo apt-get install -qq --fix-missing libpq-dev -o dir::cache::archives="/home/runner/apt/cache"
53
+ sudo chown -R runner /home/runner/apt/cache
54
+ - name: Install MySQL headers
55
+ if: matrix.database == 'mysql'
56
+ run: |
57
+ mkdir -p /home/runner/apt/cache
58
+ sudo apt-get update -qq
59
+ sudo apt-get install -qq --fix-missing libmysqlclient-dev -o dir::cache::archives="/home/runner/apt/cache"
60
+ sudo chown -R runner /home/runner/apt/cache
61
+ - name: Install bundler
62
+ run: |
63
+ gem install bundler
64
+ - name: Restore Ruby Gems cache
65
+ id: cache
66
+ uses: actions/cache@preview
67
+ with:
68
+ path: vendor/bundle
69
+ key: ${{ runner.os }}-bundle-${{ matrix.ruby }}-${{ matrix.rails }}-${{ matrix.database }}-${{ hashFiles('**/Gemfile') }}
70
+ restore-keys: |
71
+ ${{ runner.os }}-bundle-
72
+ - name: Install bundle
73
+ timeout-minutes: 10
74
+ run: |
75
+ bundle install --jobs 4 --retry 3 --path vendor/bundle
76
+ - name: Prepare database
77
+ run: |
78
+ bundle exec rake alchemy:spec:prepare
79
+ - name: Install code climate test reporter
80
+ run: |
81
+ curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
82
+ chmod +x ./cc-test-reporter
83
+ ./cc-test-reporter before-build
84
+ - name: Test with RSpec
85
+ run: |
86
+ bundle exec rspec
87
+ ./cc-test-reporter after-build --exit-code $?
88
+ - uses: actions/upload-artifact@master
89
+ if: failure()
90
+ with:
91
+ name: Screenshots
92
+ path: spec/dummy/tmp/screenshots
data/.gitignore CHANGED
@@ -21,3 +21,4 @@ spec/dummy/public/assets
21
21
  .ruby-gemset
22
22
  .ruby-version
23
23
  .env
24
+ .rspec
@@ -1,6 +1,62 @@
1
+ ## 4.4.0 (2020-01-06)
2
+
3
+ - Use contents settings for size in EssencePicture#picture_url [#1703](https://github.com/AlchemyCMS/alchemy_cms/pull/1703) ([tvdeyen](https://github.com/tvdeyen))
4
+ - Remove title tag from preview elements [#1701](https://github.com/AlchemyCMS/alchemy_cms/pull/1701) ([tvdeyen](https://github.com/tvdeyen))
5
+ - Remove custom JS logging [#1700](https://github.com/AlchemyCMS/alchemy_cms/pull/1700) ([tvdeyen](https://github.com/tvdeyen))
6
+ - Remove demo locale files [#1699](https://github.com/AlchemyCMS/alchemy_cms/pull/1699) ([tvdeyen](https://github.com/tvdeyen))
7
+ - Use alchemyPageSelect for Node page select [#1698](https://github.com/AlchemyCMS/alchemy_cms/pull/1698) ([tvdeyen](https://github.com/tvdeyen))
8
+ - Cache menu partials [#1697](https://github.com/AlchemyCMS/alchemy_cms/pull/1697) ([tvdeyen](https://github.com/tvdeyen))
9
+ - Update page tree to menu nodes Rake task [#1696](https://github.com/AlchemyCMS/alchemy_cms/pull/1696) ([tvdeyen](https://github.com/tvdeyen))
10
+ - Validate nodes name if page is absent [#1695](https://github.com/AlchemyCMS/alchemy_cms/pull/1695) ([tvdeyen](https://github.com/tvdeyen))
11
+ - Update the application layout installer template [#1691](https://github.com/AlchemyCMS/alchemy_cms/pull/1691) ([tvdeyen](https://github.com/tvdeyen))
12
+ - Update note about missing user class [#1690](https://github.com/AlchemyCMS/alchemy_cms/pull/1690) ([tvdeyen](https://github.com/tvdeyen))
13
+ - Use a Sprockets 3/4 manifest file [#1689](https://github.com/AlchemyCMS/alchemy_cms/pull/1689) ([tvdeyen](https://github.com/tvdeyen))
14
+ - Use select2 for internal page link in link overlay [#1685](https://github.com/AlchemyCMS/alchemy_cms/pull/1685) ([tvdeyen](https://github.com/tvdeyen))
15
+ - Do not consider nested elements "orphaned" [#1684](https://github.com/AlchemyCMS/alchemy_cms/pull/1684) ([mamhoff](https://github.com/mamhoff))
16
+ - Destroy page-dependent elements [#1683](https://github.com/AlchemyCMS/alchemy_cms/pull/1683) ([mamhoff](https://github.com/mamhoff))
17
+ - Add anchor link tab to link overlay [#1682](https://github.com/AlchemyCMS/alchemy_cms/pull/1682) ([tvdeyen](https://github.com/tvdeyen))
18
+ - Ensure the apt/cache folder exists while installing [#1678](https://github.com/AlchemyCMS/alchemy_cms/pull/1678) ([tvdeyen](https://github.com/tvdeyen))
19
+ - Cache apt packages between CI runs [#1677](https://github.com/AlchemyCMS/alchemy_cms/pull/1677) ([tvdeyen](https://github.com/tvdeyen))
20
+ - Use select2 with AJAX search for essence page select [#1675](https://github.com/AlchemyCMS/alchemy_cms/pull/1675) ([tvdeyen](https://github.com/tvdeyen))
21
+ - Eager load associated records [#1674](https://github.com/AlchemyCMS/alchemy_cms/pull/1674) ([tvdeyen](https://github.com/tvdeyen))
22
+ - Add support for testing with multiple Rails versions [#1673](https://github.com/AlchemyCMS/alchemy_cms/pull/1673) ([tvdeyen](https://github.com/tvdeyen))
23
+ - Page api pagination [#1672](https://github.com/AlchemyCMS/alchemy_cms/pull/1672) ([tvdeyen](https://github.com/tvdeyen))
24
+ - Adjust select2 loading-more indicator [#1671](https://github.com/AlchemyCMS/alchemy_cms/pull/1671) ([tvdeyen](https://github.com/tvdeyen))
25
+ - Test support fixes [#1669](https://github.com/AlchemyCMS/alchemy_cms/pull/1669) ([tvdeyen](https://github.com/tvdeyen))
26
+ - Build fixes [#1668](https://github.com/AlchemyCMS/alchemy_cms/pull/1668) ([tvdeyen](https://github.com/tvdeyen))
27
+ - Add Menus [#1667](https://github.com/AlchemyCMS/alchemy_cms/pull/1667) ([tvdeyen](https://github.com/tvdeyen))
28
+ - Add a label component [#1666](https://github.com/AlchemyCMS/alchemy_cms/pull/1666) ([tvdeyen](https://github.com/tvdeyen))
29
+ - Run bundle install on CI even if cache hits [#1665](https://github.com/AlchemyCMS/alchemy_cms/pull/1665) ([tvdeyen](https://github.com/tvdeyen))
30
+ - Moves switch_language method into languages_controller. [#1664](https://github.com/AlchemyCMS/alchemy_cms/pull/1664) ([tvdeyen](https://github.com/tvdeyen))
31
+ - Cache gems between CI runs [#1663](https://github.com/AlchemyCMS/alchemy_cms/pull/1663) ([tvdeyen](https://github.com/tvdeyen))
32
+ - Remove production gems from local Gemfile [#1662](https://github.com/AlchemyCMS/alchemy_cms/pull/1662) ([tvdeyen](https://github.com/tvdeyen))
33
+ - Touch contents updated_at column in pure SQL [#1661](https://github.com/AlchemyCMS/alchemy_cms/pull/1661) ([tvdeyen](https://github.com/tvdeyen))
34
+ - Convert page editing user methods into AR relations [#1658](https://github.com/AlchemyCMS/alchemy_cms/pull/1658) ([tvdeyen](https://github.com/tvdeyen))
35
+ - Ensure the admin locale is only set by available locales [#1655](https://github.com/AlchemyCMS/alchemy_cms/pull/1655) ([tvdeyen](https://github.com/tvdeyen))
36
+ - Add a GitHub actions ci.yml [#1654](https://github.com/AlchemyCMS/alchemy_cms/pull/1654) ([tvdeyen](https://github.com/tvdeyen))
37
+ - Adjust install generator to latest changes [#1649](https://github.com/AlchemyCMS/alchemy_cms/pull/1649) ([tvdeyen](https://github.com/tvdeyen))
38
+ - Deprecate _view suffix of element views [#1648](https://github.com/AlchemyCMS/alchemy_cms/pull/1648) ([tvdeyen](https://github.com/tvdeyen))
39
+ - Add a configurable logout method (default: delete) [#1647](https://github.com/AlchemyCMS/alchemy_cms/pull/1647) ([delphaber](https://github.com/delphaber))
40
+ - Deprecate render_essence helpers [#1644](https://github.com/AlchemyCMS/alchemy_cms/pull/1644) ([tvdeyen](https://github.com/tvdeyen))
41
+ - Deprecate element editors [#1643](https://github.com/AlchemyCMS/alchemy_cms/pull/1643) ([tvdeyen](https://github.com/tvdeyen))
42
+ - Deprecate local options in essence editors [#1642](https://github.com/AlchemyCMS/alchemy_cms/pull/1642) ([tvdeyen](https://github.com/tvdeyen))
43
+ - Ensure the EssencePage id regexp matches only numbers [#1641](https://github.com/AlchemyCMS/alchemy_cms/pull/1641) ([tvdeyen](https://github.com/tvdeyen))
44
+ - Use EssencePage in contact forms [#1640](https://github.com/AlchemyCMS/alchemy_cms/pull/1640) ([tvdeyen](https://github.com/tvdeyen))
45
+ - Add Alchemy::EssencePage [#1639](https://github.com/AlchemyCMS/alchemy_cms/pull/1639) ([tvdeyen](https://github.com/tvdeyen))
46
+ - FEAT: Render message and warnings in element editor [#1637](https://github.com/AlchemyCMS/alchemy_cms/pull/1637) ([tvdeyen](https://github.com/tvdeyen))
47
+ - Tackle Rails 6 deprecations [#1636](https://github.com/AlchemyCMS/alchemy_cms/pull/1636) ([tvdeyen](https://github.com/tvdeyen))
48
+ - Preload assets in tests [#1635](https://github.com/AlchemyCMS/alchemy_cms/pull/1635) ([tvdeyen](https://github.com/tvdeyen))
49
+ - Allow acts-as-list 1.0 [#1634](https://github.com/AlchemyCMS/alchemy_cms/pull/1634) ([tvdeyen](https://github.com/tvdeyen))
50
+ - Add Sprockets manifest file to dummy app [#1632](https://github.com/AlchemyCMS/alchemy_cms/pull/1632) ([tvdeyen](https://github.com/tvdeyen))
51
+ - Master now tracks 4.4.0.alpha [#1627](https://github.com/AlchemyCMS/alchemy_cms/pull/1627) ([tvdeyen](https://github.com/tvdeyen))
52
+ - Fix Cell Migration to maintain positions [#1625](https://github.com/AlchemyCMS/alchemy_cms/pull/1625) ([mamhoff](https://github.com/mamhoff))
53
+ - Cell Upgrader: Match quotation marks in cell name string [#1624](https://github.com/AlchemyCMS/alchemy_cms/pull/1624) ([mamhoff](https://github.com/mamhoff))
54
+ - Cell Migrator: Maintain element order in fixed elements [#1623](https://github.com/AlchemyCMS/alchemy_cms/pull/1623) ([mamhoff](https://github.com/mamhoff))
55
+ - Enhance cells upgrader to deal with render_elements from_page: x [#1622](https://github.com/AlchemyCMS/alchemy_cms/pull/1622) ([mamhoff](https://github.com/mamhoff))
56
+
1
57
  ## 4.3.2 (2019-11-08)
2
58
 
3
- - Allow SimpleForm 5 [#1660](https://github.com/AlchemyCMS/alchemy_cms/pull/1660) ([jkimmeyer](https://github.com/jkimmeyer))
59
+ - Allow simple form 5 [#1660](https://github.com/AlchemyCMS/alchemy_cms/pull/1633) ([jkimmeyer](https://github.com/jkimmeyer))
4
60
 
5
61
  ## 4.3.1 (2019-09-27)
6
62
 
@@ -9,7 +65,7 @@
9
65
  - Cell Migrator: Maintain element order in fixed elements [#1623](https://github.com/AlchemyCMS/alchemy_cms/pull/1623) ([mamhoff](https://github.com/mamhoff))
10
66
  - Enhance cells upgrader to deal with render_elements from_page: x [#1622](https://github.com/AlchemyCMS/alchemy_cms/pull/1622) ([mamhoff](https://github.com/mamhoff))
11
67
 
12
- # 4.3.0 (2019-08-23)
68
+ ## 4.3.0 (2019-08-23)
13
69
 
14
70
  - Add Rails 6 support [#1616](https://github.com/AlchemyCMS/alchemy_cms/pull/1616) ([tvdeyen](https://github.com/tvdeyen))
15
71
  - Use media_type over content_type in specs [#1615](https://github.com/AlchemyCMS/alchemy_cms/pull/1615) ([tvdeyen](https://github.com/tvdeyen))
@@ -541,3 +597,4 @@ No changes
541
597
  ## 3.0.0 (2014-07-03)
542
598
 
543
599
  [Release Notes](https://github.com/AlchemyCMS/alchemy_cms/releases/tag/v3.0.0)
600
+
data/Gemfile CHANGED
@@ -2,12 +2,15 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'rails', '~> 6.0.0'
5
+ rails_version = ENV.fetch('RAILS_VERSION', 6.0).to_f
6
+ gem 'rails', "~> #{rails_version}.0"
6
7
 
7
8
  # Profiling
8
9
  gem 'rack-mini-profiler', group: :development, require: false
9
10
 
10
- gem 'sqlite3', '~> 1.4.1' if ENV['DB'].nil? || ENV['DB'] == 'sqlite'
11
+ if ENV['DB'].nil? || ENV['DB'] == 'sqlite'
12
+ gem 'sqlite3', rails_version > 5.0 ? '~> 1.4.1' : '~> 1.3.6'
13
+ end
11
14
  gem 'mysql2', '~> 0.5.1' if ENV['DB'] == 'mysql'
12
15
  gem 'pg', '~> 1.0' if ENV['DB'] == 'postgresql'
13
16
  gem 'sassc-rails'
@@ -15,9 +18,6 @@ gem 'sassc-rails'
15
18
  group :development, :test do
16
19
  gem 'simplecov', require: false
17
20
  gem 'bootsnap', require: false
18
- if ENV['TRAVIS']
19
- gem 'codeclimate-test-reporter', '~> 1.0', require: false
20
- end
21
21
  unless ENV['CI']
22
22
  gem 'launchy'
23
23
  gem 'annotate'
@@ -30,5 +30,6 @@ group :development, :test do
30
30
  gem 'localeapp', '~> 3.0', require: false
31
31
  gem 'dotenv', '~> 2.2'
32
32
  gem 'github_fast_changelog', require: false
33
+ gem 'active_record_query_trace', require: false
33
34
  end
34
35
  end
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
1
  # AlchemyCMS
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/alchemy_cms.svg)](http://badge.fury.io/rb/alchemy_cms)
4
- [![Build Status](https://travis-ci.org/AlchemyCMS/alchemy_cms.svg?branch=master)](https://travis-ci.org/AlchemyCMS/alchemy_cms)
4
+ [![Build Status](https://github.com/AlchemyCMS/alchemy_cms/workflows/CI/badge.svg?branch=master)](https://github.com/AlchemyCMS/alchemy_cms/actions)
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/196c56c56568ed24a697/maintainability)](https://codeclimate.com/github/AlchemyCMS/alchemy_cms/maintainability)
6
6
  [![Test Coverage](https://api.codeclimate.com/v1/badges/196c56c56568ed24a697/test_coverage)](https://codeclimate.com/github/AlchemyCMS/alchemy_cms/test_coverage)
7
7
  [![Depfu](https://badges.depfu.com/badges/ebe56d2dd7b7044a8ae700cc81212a8e/overview.svg)](https://depfu.com/github/AlchemyCMS/alchemy_cms?project_id=4600)
@@ -124,11 +124,12 @@ The best practice is to use an initializer:
124
124
 
125
125
  ```ruby
126
126
  # config/initializers/alchemy.rb
127
- Alchemy.user_class_name = 'YourUserClass' # Defaults to 'User'
128
- Alchemy.current_user_method = 'current_admin_user' # Defaults to 'current_user'
129
- Alchemy.signup_path = '/your/signup/path' # Defaults to '/signup'
130
- Alchemy.login_path = '/your/login/path' # Defaults to '/login'
131
- Alchemy.logout_path = '/your/logout/path' # Defaults to '/logout'
127
+ Alchemy.user_class_name = 'YourUserClass' # Defaults to 'User'
128
+ Alchemy.current_user_method = 'current_admin_user' # Defaults to 'current_user'
129
+ Alchemy.signup_path = '/your/signup/path' # Defaults to '/signup'
130
+ Alchemy.login_path = '/your/login/path' # Defaults to '/login'
131
+ Alchemy.logout_path = '/your/logout/path' # Defaults to '/logout'
132
+ Alchemy.logout_method = 'http_verb_for_logout' # Defaults to 'delete'
132
133
  ```
133
134
 
134
135
  The only thing Alchemy needs to know from your user class is the `alchemy_roles` method.
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.require_paths = ['lib']
20
20
 
21
21
  gem.add_runtime_dependency 'active_model_serializers', ['~> 0.10.0']
22
- gem.add_runtime_dependency 'acts_as_list', ['~> 0.3']
22
+ gem.add_runtime_dependency 'acts_as_list', ['>= 0.3', '< 2']
23
23
  gem.add_runtime_dependency 'awesome_nested_set', ['~> 3.1']
24
24
  gem.add_runtime_dependency 'cancancan', ['>= 2.1', '< 4.0']
25
25
  gem.add_runtime_dependency 'coffee-rails', ['~> 4.0', '< 5.0']
@@ -38,15 +38,17 @@ Gem::Specification.new do |gem|
38
38
  gem.add_runtime_dependency 'responders', ['>= 2.0', '< 4.0']
39
39
  gem.add_runtime_dependency 'select2-rails', ['>= 3.5.9.1', '< 4.0']
40
40
  gem.add_runtime_dependency 'simple_form', ['>= 4.0', '< 6']
41
+ gem.add_runtime_dependency 'sprockets', ['>= 3.0', '< 5']
41
42
  gem.add_runtime_dependency 'turbolinks', ['>= 2.5']
42
43
 
43
44
  gem.add_development_dependency 'capybara', ['~> 3.0']
44
45
  gem.add_development_dependency 'capybara-screenshot', ['~> 1.0']
45
46
  gem.add_development_dependency 'factory_bot_rails', ['~> 5.0']
47
+ gem.add_development_dependency 'puma', ['~> 4.0']
46
48
  gem.add_development_dependency 'rails-controller-testing', ['~> 1.0']
47
49
  gem.add_development_dependency 'rspec-activemodel-mocks', ['~> 1.0']
48
50
  gem.add_development_dependency 'rspec-rails', ['>= 4.0.0.beta2']
49
- gem.add_development_dependency 'selenium-webdriver', ['~> 3.8']
51
+ gem.add_development_dependency 'webdrivers', ['~> 4.0']
50
52
  gem.add_development_dependency 'shoulda-matchers', ['~> 4.0']
51
53
 
52
54
  gem.post_install_message = <<-MSG
@@ -0,0 +1,15 @@
1
+ //= link alchemy/admin/all.css
2
+ //= link alchemy/admin/all.js
3
+ //= link alchemy/preview.js
4
+ //= link alchemy/menubar.css
5
+ //= link alchemy/menubar.js
6
+ //= link alchemy/print.css
7
+ //= link alchemy/welcome.css
8
+ //= link tinymce/plugins/alchemy_link/plugin.min.js
9
+ //= link tinymce/tinymce.min.js
10
+ //= link_directory ../stylesheets/tinymce/skins/alchemy/ .css
11
+ //= link_directory ../stylesheets/tinymce/skins/alchemy/img/
12
+ //= link_directory ../stylesheets/tinymce/skins/alchemy/fonts/
13
+ //= link_tree ../images/alchemy/
14
+ //= link_tree ../../../vendor/assets/fonts/
15
+ //= link_tree ../../../vendor/assets/images/
@@ -48,3 +48,4 @@
48
48
  //= require alchemy/alchemy.tooltips
49
49
  //= require alchemy/alchemy.translations
50
50
  //= require alchemy/alchemy.trash_window
51
+ //= require alchemy/page_select
@@ -68,7 +68,7 @@ $.extend Alchemy,
68
68
  Alchemy.setElementDirty $element
69
69
  false
70
70
 
71
- # Initializes all select tag with .alchemy_selectbox class as selectBoxIt instance
71
+ # Initializes all select tag with .alchemy_selectbox class as select2 instance
72
72
  # Pass a jQuery scope to only init a subset of selectboxes.
73
73
  SelectBox: (scope) ->
74
74
  $("select.alchemy_selectbox", scope).select2
@@ -76,18 +76,6 @@ $.extend Alchemy,
76
76
  dropdownAutoWidth: true
77
77
  return
78
78
 
79
- # Logs exception to js console, if present.
80
- debug: (e) ->
81
- if window["console"]
82
- console.warn(e)
83
- return
84
-
85
- # Logs errors to js console, if present.
86
- log_error: (e) ->
87
- if window["console"]
88
- console.error e
89
- return
90
-
91
79
  getUrlParam: (name) ->
92
80
  results = new RegExp("[\\?&]" + name + "=([^&#]*)").exec(window.location.href)
93
81
  results[1] or 0 if results
@@ -23,7 +23,7 @@ Alchemy.I18n =
23
23
  else
24
24
  translation
25
25
  else
26
- Alchemy.debug "Translations for locale #{Alchemy.locale} not found!"
26
+ console.warn "Translations for locale #{Alchemy.locale} not found!"
27
27
  key
28
28
 
29
29
  # Global utility method for translating a given string
@@ -18,18 +18,19 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
18
18
  # attach events we handle
19
19
  @attachEvents()
20
20
  # Store some jQuery objects for further reference
21
- @$page_anchor = $('#page_anchor', @dialog_body)
22
- @$internal_urlname = $('#internal_urlname', @dialog_body)
23
- @$internal_anchor = $('#internal_anchor', @dialog_body)
21
+ @$page_urlname = $('#page_urlname', @dialog_body)
22
+ @$element_anchor = $('#element_anchor', @dialog_body)
23
+ @$anchor_link = $('#anchor_link', @dialog_body)
24
24
  @$external_url = $('#external_url', @dialog_body)
25
25
  @$public_filename = $('#public_filename', @dialog_body)
26
26
  @$overlay_tabs = $('#overlay_tabs', @dialog_body)
27
27
  @$page_container = $('#page_selector_container')
28
- @initInternalAnchors()
29
28
  # if we edit an existing link
30
29
  if @link_object
31
30
  # we select the correct tab
32
31
  @selectTab()
32
+ @initPageSelect()
33
+ @initAnchorLinks()
33
34
 
34
35
  # Attaches click events to several buttons in the link dialog.
35
36
  attachEvents: ->
@@ -42,8 +43,12 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
42
43
  url = @$external_url.val()
43
44
  when 'file'
44
45
  url = @$public_filename.val()
46
+ when 'anchor'
47
+ url = @$anchor_link.val()
45
48
  else
46
- url = $("##{@link_type}_urlname").val()
49
+ url = @$page_urlname.val()
50
+ if @$element_anchor.val() != ''
51
+ url += "##{@$element_anchor.val()}"
47
52
  # Create the link
48
53
  @createLink
49
54
  url: url
@@ -51,38 +56,67 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
51
56
  target: $("##{@link_type}_link_target").val()
52
57
  false
53
58
 
54
- # Attaches click events to buttons in the link dialog that appear after the
55
- # page tree has finished loading.
56
- attachTreeEvents: ->
57
- # The select page and show elements links.
58
- $('a.sitemap_pagename_link, a.show_elements_to_link', @dialog_body).click (e) =>
59
- $this = $(e.currentTarget)
60
- page_id = $this.data('page-id')
61
- url = $this.data('url')
62
- # Select page in page tree
63
- @selectPage(page_id)
64
- # if the show elements link was clicked
65
- if $this.hasClass('show_elements_to_link')
66
- # we open the elements select for that page
67
- @showElementsSelect($this.attr('href'), url)
59
+ # Initializes the select2 based Page select
60
+ initPageSelect: ->
61
+ pageTemplate = HandlebarsTemplates.page
62
+ element_anchor_placeholder = @$element_anchor.attr('placeholder')
63
+ @$page_urlname.select2
64
+ placeholder: Alchemy.t('Search page')
65
+ allowClear: true
66
+ minimumInputLength: 3
67
+ ajax:
68
+ url: Alchemy.routes.api_pages_path
69
+ datatype: 'json'
70
+ quietMillis: 300
71
+ data: (term, page) ->
72
+ q:
73
+ name_cont: term
74
+ page: page
75
+ results: (data) ->
76
+ meta = data.meta
77
+ results:
78
+ data.pages.map (page) ->
79
+ id: "/#{page.urlname}"
80
+ name: page.name
81
+ urlname: page.urlname
82
+ page_id: page.id
83
+ more: meta.page * meta.per_page < meta.total_count
84
+ initSelection: ($element, callback) =>
85
+ urlname = $element.val()
86
+ $.get Alchemy.routes.api_pages_path,
87
+ q:
88
+ urlname_eq: urlname.replace(/^\//, '')
89
+ page: 1
90
+ per_page: 1,
91
+ (data) =>
92
+ page = data.pages[0]
93
+ if page
94
+ @initElementSelect(page.id)
95
+ callback
96
+ id: "/#{page.urlname}"
97
+ name: page.name
98
+ urlname: page.name
99
+ page_id: page.id
100
+ formatSelection: (page) ->
101
+ page.name
102
+ formatResult: (page) ->
103
+ pageTemplate(page: page)
104
+ .on 'change', (event) =>
105
+ if event.val == ''
106
+ @$element_anchor.val(element_anchor_placeholder)
107
+ @$element_anchor.select2('destroy').prop('disabled', true)
68
108
  else
69
- # store url
70
- @$internal_urlname.val('/' + url)
71
- false
72
- # Select the current page in the tree
73
- @selectInternalLinkTab()
74
-
75
- # Sets the page selected and scrolls it in the viewport.
76
- selectPage: (page_id) ->
77
- # deselect any selected page from page tree
78
- @deselectPage()
79
- # reset the internal anchor select
80
- @$internal_anchor.select2('val', '')
81
- $('#sitemap_sitename_' + page_id).addClass('selected_page')
82
- @$page_container.scrollTo("#sitemap_sitename_#{page_id}", {duration: 400, offset: -10})
83
-
84
- deselectPage: ->
85
- $('#sitemap .selected_page', @dialog_body).removeClass('selected_page')
109
+ @$element_anchor.val('')
110
+ @initElementSelect(event.added.page_id)
111
+
112
+ # Initializes the select2 based elements select
113
+ # reveals after a page has been selected
114
+ initElementSelect: (page_id) ->
115
+ $.get Alchemy.routes.api_elements_path, page_id: page_id, (data) =>
116
+ @$element_anchor.prop('disabled', false).removeAttr('placeholder').select2
117
+ data: [ id: '', text: Alchemy.t('None') ].concat data.elements.map (element) ->
118
+ id: element.dom_id
119
+ text: element.display_name
86
120
 
87
121
  # Creates a link if no validation errors are present.
88
122
  # Otherwise shows an error notice.
@@ -149,57 +183,24 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
149
183
  # Handles a file link.
150
184
  tab = $('#overlay_tab_file_link')
151
185
  @$public_filename.select2('val', @$link[0].pathname + @$link[0].search)
186
+ else if @$link.attr('href').match(/^#/)
187
+ # Handles an anchor link.
188
+ tab = $('#overlay_tab_anchor_link')
189
+ @$anchor_link.select2('val', @$link.attr('href'))
152
190
  else
153
191
  # Handles an internal link.
154
192
  tab = $('#overlay_tab_internal_link')
193
+ @initInternalLinkTab()
155
194
  # activate the tab jquery ui 1.10 style o.O
156
195
  @$overlay_tabs.tabs('option', 'active', $('#overlay_tabs > div').index(tab))
157
196
 
158
197
  # Handles actions for internal link tab.
159
- selectInternalLinkTab: ->
160
- return unless @$link
198
+ initInternalLinkTab: ->
161
199
  url = @$link.attr('href').split('#')
162
- urlname = url[0]
163
- anchor = url[1]
164
- if anchor
165
- # store the anchor
166
- @$page_anchor.val("##{anchor}")
167
- # and update the url field
168
- @$internal_urlname.val("#{urlname}##{anchor}")
169
- # if we linked an internal anchor
170
- if @$internal_urlname.val().match(/^#/)
171
- # we select the correct value from anchors select
172
- value = @$internal_urlname.val()
173
- @$internal_anchor.select2 'val', value.replace(/^#/, '')
174
- else
175
- @$internal_urlname.val(urlname)
176
- $sitemap_line = $('.sitemap_sitename').closest('[name="'+urlname+'"]')
177
- if ($sitemap_line.length > 0)
178
- # Select the line where the link was detected in.
179
- $sitemap_line.addClass('selected_page')
180
- @$page_container.scrollTo($sitemap_line.closest('li'), {duration: 400, offset: -10})
181
-
182
- # Opens a new Dialog that shows the elements from given page_id in a selectbox.
183
- # The value is stored as anchor and the url gets updated so it includes the anchor link
184
- showElementsSelect: (show_elements_url, urlname) ->
185
- dialog = new Alchemy.Dialog show_elements_url,
186
- size: '400x165'
187
- ready: =>
188
- $element_select = $('.elements_from_page_selector')
189
- # check if the urlname is the same as stored,
190
- current_urlname = @$internal_urlname.val().split('#')[0]
191
- if "/#{urlname}" == current_urlname
192
- # then we can select the current anchor in the selectbox
193
- $element_select.select2 'val', @$page_anchor.val()
194
- $element_select.change =>
195
- @$page_anchor.val $element_select.select2('val')
196
- $('button', dialog.dialog_body).click =>
197
- @$internal_urlname.val("/#{urlname}#{@$page_anchor.val()}")
198
- dialog.close()
199
- false
200
- return
201
- dialog.open()
202
- return
200
+ # update the url field
201
+ @$page_urlname.val(url[0])
202
+ # store the anchor
203
+ @$element_anchor.val(url[1])
203
204
 
204
205
  # Creates a temporay $('a') object that holds all values on it.
205
206
  createTempLink: ->
@@ -225,20 +226,16 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
225
226
  $('#errors', @dialog_body).show()
226
227
 
227
228
  # Populates the internal anchors select
228
- initInternalAnchors: ->
229
+ initAnchorLinks: ->
229
230
  frame = document.getElementById('alchemy_preview_window')
230
231
  elements = frame.contentDocument.getElementsByTagName('*')
231
232
  if elements.length > 0
232
233
  for element in elements
233
234
  if element.id
234
- @$internal_anchor.append("<option value='#{element.id}'>##{element.id}</option>")
235
+ @$anchor_link.append("<option value='##{element.id}'>##{element.id}</option>")
235
236
  else
236
- @$internal_anchor.html("<option>#{Alchemy.t('No anchors found')}</option>")
237
- @$internal_anchor.change (e) =>
238
- # deselect any selected page from page tree
239
- @deselectPage()
240
- # store the internal anchor as urlname
241
- $("#internal_urlname").val("##{e.target.value}")
237
+ @$anchor_link.html("<option>#{Alchemy.t('No anchors found')}</option>")
238
+ return
242
239
 
243
240
  # Public class methods
244
241