alchemy_cms 6.0.0.pre.rc7 → 6.0.2

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.

Potentially problematic release.


This version of alchemy_cms might be problematic. Click here for more details.

Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +15 -0
  3. data/CHANGELOG.md +38 -0
  4. data/Gemfile +15 -1
  5. data/README.md +4 -3
  6. data/alchemy_cms.gemspec +2 -2
  7. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +2 -0
  8. data/app/assets/stylesheets/alchemy/archive.scss +5 -0
  9. data/app/assets/stylesheets/alchemy/elements.scss +4 -0
  10. data/app/controllers/alchemy/admin/elements_controller.rb +20 -17
  11. data/app/controllers/alchemy/admin/pages_controller.rb +15 -7
  12. data/app/controllers/alchemy/api/base_controller.rb +4 -3
  13. data/app/controllers/alchemy/api/contents_controller.rb +1 -5
  14. data/app/controllers/alchemy/api/elements_controller.rb +2 -6
  15. data/app/controllers/alchemy/api/nodes_controller.rb +1 -0
  16. data/app/controllers/alchemy/api/pages_controller.rb +2 -6
  17. data/app/controllers/alchemy/base_controller.rb +7 -0
  18. data/app/controllers/alchemy/messages_controller.rb +0 -3
  19. data/app/controllers/alchemy/pages_controller.rb +0 -7
  20. data/app/helpers/alchemy/elements_helper.rb +17 -12
  21. data/app/models/alchemy/element.rb +13 -6
  22. data/app/models/alchemy/ingredient_validator.rb +1 -1
  23. data/app/models/alchemy/language.rb +1 -1
  24. data/app/models/alchemy/page/page_elements.rb +2 -2
  25. data/app/models/alchemy/page/page_naming.rb +1 -1
  26. data/app/models/alchemy/page.rb +1 -1
  27. data/app/models/alchemy/picture/transformations.rb +2 -2
  28. data/app/models/alchemy/picture.rb +1 -1
  29. data/app/models/alchemy/picture_variant.rb +3 -1
  30. data/app/models/alchemy/site.rb +1 -1
  31. data/app/views/alchemy/admin/clipboard/insert.js.erb +13 -0
  32. data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +27 -0
  33. data/app/views/alchemy/admin/elements/_element.html.erb +1 -23
  34. data/app/views/alchemy/admin/elements/_form.html.erb +5 -1
  35. data/app/views/alchemy/admin/partials/_routes.html.erb +4 -0
  36. data/app/views/alchemy/admin/resources/_form.html.erb +5 -0
  37. data/app/views/alchemy/essences/_essence_node_editor.html.erb +1 -1
  38. data/config/alchemy/config.yml +1 -0
  39. data/config/initializers/dragonfly.rb +2 -0
  40. data/lib/alchemy/config.rb +5 -1
  41. data/lib/alchemy/controller_actions.rb +2 -1
  42. data/lib/alchemy/dragonfly/processors/thumbnail.rb +27 -0
  43. data/lib/alchemy/element_definition.rb +2 -3
  44. data/lib/alchemy/elements_finder.rb +1 -2
  45. data/lib/alchemy/engine.rb +12 -1
  46. data/lib/alchemy/essence.rb +1 -27
  47. data/lib/alchemy/page_layout.rb +5 -1
  48. data/lib/alchemy/permissions.rb +2 -2
  49. data/lib/alchemy/resource.rb +16 -1
  50. data/lib/alchemy/test_support/essence_shared_examples.rb +0 -12
  51. data/lib/alchemy/upgrader/tasks/ingredients_migrator.rb +1 -1
  52. data/lib/alchemy/version.rb +1 -1
  53. data/lib/alchemy.rb +2 -4
  54. data/lib/generators/alchemy/base.rb +7 -3
  55. data/lib/generators/alchemy/install/install_generator.rb +4 -1
  56. data/package/src/image_loader.js +2 -2
  57. data/package/src/picture_editors.js +5 -5
  58. data/package.json +1 -1
  59. metadata +26 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d81ddf40cd98c283ac6b58332e03e6ed4094de86671f0dc80692a0de5c8292ea
4
- data.tar.gz: 1115141343d2e2310001c8ee1e58f9d8070a4c34c770226f9647a6fa09f05d7d
3
+ metadata.gz: 7302c6c464ed0c57f1b2113a1d7334eb4234e80ee75a68f43579895207c8c406
4
+ data.tar.gz: 26bd58edc3af02af5c418f082584cbfa897a16f26a670db08f147072df827a71
5
5
  SHA512:
6
- metadata.gz: f80e8e421037e50315254799456626f6b82ee4f30922d30920b2cec73ee7783a85fccf74b1a66a9a310fc2ca668844ad4d0daaa0b03ecca77cb4f4a1bb28c1e4
7
- data.tar.gz: 2898baf39517e918cfdf0b99f6d79ad61836e74083922e2c496dcebb539c057ea558b03040578eba16040313bff647d0dbdb6a27221cbdfd8b1c7e8a7e69e395
6
+ metadata.gz: edc87ff799f4940275d70cfc24f89c4af6dd7ef4f5e77eb3982d6a85a221cf158afa05874f7c996f7c2326fef6b4131a5b15b167daea7ae6b4c39a060ecbd28d
7
+ data.tar.gz: b2a2d119a9c10c098b579a03548f9c26d49e61104be1d3058cd1d8e7329f432078258ee5f7f5e67f62d78bdf661588a72232f28e12e48ee9cb33568ae2625bfc
@@ -11,13 +11,28 @@ jobs:
11
11
  rails:
12
12
  - "6.0"
13
13
  - "6.1"
14
+ - "7.0"
14
15
  ruby:
15
16
  - "2.6"
16
17
  - "2.7"
17
18
  - "3.0"
19
+ - "3.1"
18
20
  database:
19
21
  - mysql
20
22
  - postgresql
23
+ exclude:
24
+ - rails: "6.0"
25
+ ruby: "3.1"
26
+ database: mysql
27
+ - rails: "6.0"
28
+ ruby: "3.1"
29
+ database: postgresql
30
+ - rails: "7.0"
31
+ ruby: "2.6"
32
+ database: mysql
33
+ - rails: "7.0"
34
+ ruby: "2.6"
35
+ database: postgresql
21
36
  env:
22
37
  DB: ${{ matrix.database }}
23
38
  DB_USER: alchemy_user
data/CHANGELOG.md CHANGED
@@ -1,3 +1,41 @@
1
+ ## 6.0.2 (2022-04-27)
2
+
3
+ - Remove JSON decode from ingredient data store [#2323](https://github.com/AlchemyCMS/alchemy_cms/pull/2323) ([tvdeyen](https://github.com/tvdeyen))
4
+ - Eagerload at the controller or job layer [#2313](https://github.com/AlchemyCMS/alchemy_cms/pull/2313) ([mamhoff](https://github.com/mamhoff))
5
+
6
+ ## 6.0.1 (2022-04-26)
7
+
8
+ - Allow passing a different partial to `render_element` [#2322](https://github.com/AlchemyCMS/alchemy_cms/pull/2322) ([mamhoff](https://github.com/mamhoff))
9
+ - Allow render_elements to take a block [#2321](https://github.com/AlchemyCMS/alchemy_cms/pull/2321) ([mamhoff](https://github.com/mamhoff))
10
+ - Remove old unused root_page ivar [#2320](https://github.com/AlchemyCMS/alchemy_cms/pull/2320) ([tvdeyen](https://github.com/tvdeyen))
11
+ - Raise on non-existing locale [#2319](https://github.com/AlchemyCMS/alchemy_cms/pull/2319) ([mamhoff](https://github.com/mamhoff))
12
+ - chore: Remove unnecessary puts from spec [#2318](https://github.com/AlchemyCMS/alchemy_cms/pull/2318) ([tvdeyen](https://github.com/tvdeyen))
13
+ - Fix gif resizing [#2315](https://github.com/AlchemyCMS/alchemy_cms/pull/2315) ([kulturbande](https://github.com/kulturbande))
14
+ - Refactor: Use page version's element repository rather than a new one [#2312](https://github.com/AlchemyCMS/alchemy_cms/pull/2312) ([mamhoff](https://github.com/mamhoff))
15
+ - Deprecate Alchemy::Element.available [#2309](https://github.com/AlchemyCMS/alchemy_cms/pull/2309) ([mamhoff](https://github.com/mamhoff))
16
+ - Explicitly set "store" for MariaDB [#2308](https://github.com/AlchemyCMS/alchemy_cms/pull/2308) ([mamhoff](https://github.com/mamhoff))
17
+ - Set preview mode earlier [#2307](https://github.com/AlchemyCMS/alchemy_cms/pull/2307) ([mamhoff](https://github.com/mamhoff))
18
+ - Fix updating the public_on date on persisted pages [#2305](https://github.com/AlchemyCMS/alchemy_cms/pull/2305) ([mamhoff](https://github.com/mamhoff))
19
+ - Allow opting out of Turbolinks in non-Alchemy controllers [#2302](https://github.com/AlchemyCMS/alchemy_cms/pull/2302) ([dssjoblom](https://github.com/dssjoblom))
20
+ - Explicitly validate uniqueness without case sensitivity [#2300](https://github.com/AlchemyCMS/alchemy_cms/pull/2300) ([mamhoff](https://github.com/mamhoff))
21
+ - Fix frozen string error when mixing template engines [#2299](https://github.com/AlchemyCMS/alchemy_cms/pull/2299) ([gr8bit](https://github.com/gr8bit))
22
+ - Do not flatten gifs if converted to webp [#2293](https://github.com/AlchemyCMS/alchemy_cms/pull/2293) ([tvdeyen](https://github.com/tvdeyen))
23
+ - Allow pasting into parent element with only one nested element type [#2292](https://github.com/AlchemyCMS/alchemy_cms/pull/2292) ([dbwinger](https://github.com/dbwinger))
24
+ - Restrict Node select to the site/language of the page being edited [#2277](https://github.com/AlchemyCMS/alchemy_cms/pull/2277) ([dbwinger](https://github.com/dbwinger))
25
+ - Add Ruby 3.1 support [#2229](https://github.com/AlchemyCMS/alchemy_cms/pull/2229) ([tvdeyen](https://github.com/tvdeyen))
26
+
27
+ ## 6.0.0 (2022-04-11)
28
+
29
+ - [ruby - main] Allow ransack version 3.0.1 [#2287](https://github.com/AlchemyCMS/alchemy_cms/pull/2287) ([depfu](https://github.com/apps/depfu))
30
+ - Fix image loader [#2285](https://github.com/AlchemyCMS/alchemy_cms/pull/2285) ([tvdeyen](https://github.com/tvdeyen))
31
+ - Don't delete locals in render_element so they can be used by all elements in render_elements [#2283](https://github.com/AlchemyCMS/alchemy_cms/pull/2283) ([dbwinger](https://github.com/dbwinger))
32
+ - Don't hardcode URLs in Javascript [#2282](https://github.com/AlchemyCMS/alchemy_cms/pull/2282) ([dssjoblom](https://github.com/dssjoblom))
33
+ - [ruby - main] Allow ransack 3.0.0 [#2278](https://github.com/AlchemyCMS/alchemy_cms/pull/2278) ([depfu](https://github.com/apps/depfu))
34
+ - Show site and language name on page select in Link dialog [#2276](https://github.com/AlchemyCMS/alchemy_cms/pull/2276) ([dbwinger](https://github.com/dbwinger))
35
+ - Allow webp as image file format [#2274](https://github.com/AlchemyCMS/alchemy_cms/pull/2274) ([tvdeyen](https://github.com/tvdeyen))
36
+ - Rails 7 Support [#2225](https://github.com/AlchemyCMS/alchemy_cms/pull/2225) ([tvdeyen](https://github.com/tvdeyen))
37
+ - Support AR enums in resource models [#2210](https://github.com/AlchemyCMS/alchemy_cms/pull/2210) ([robinboening](https://github.com/robinboening))
38
+
1
39
  ## 6.0.0-rc7 (2022-03-28)
2
40
 
3
41
  - fix(Sitemap): Use response data [#2272](https://github.com/AlchemyCMS/alchemy_cms/pull/2272) ([tvdeyen](https://github.com/tvdeyen))
data/Gemfile CHANGED
@@ -3,11 +3,13 @@ source "https://rubygems.org"
3
3
 
4
4
  gemspec
5
5
 
6
- rails_version = ENV.fetch("RAILS_VERSION", 6.1).to_f
6
+ rails_version = ENV.fetch("RAILS_VERSION", 7.0).to_f
7
7
  # Necessary until a new 6.1.5 version has been released
8
8
  # https://github.com/rails/rails/pull/44691
9
9
  if rails_version.to_s.match?(/6.1/)
10
10
  gem "rails", git: "https://github.com/rails/rails", branch: "6-1-stable"
11
+ elsif rails_version.to_s.match?(/7.0/)
12
+ gem "rails", git: "https://github.com/rails/rails", branch: "7-0-stable"
11
13
  else
12
14
  gem "rails", "~> #{rails_version}.0"
13
15
  end
@@ -46,3 +48,15 @@ group :development, :test do
46
48
  gem "brakeman", require: false
47
49
  end
48
50
  end
51
+
52
+ # Ruby 3.1 split out the net-smtp gem
53
+ # Necessary until https://github.com/mikel/mail/pull/1439
54
+ # got merged and released.
55
+ if Gem.ruby_version >= Gem::Version.new("3.1.0")
56
+ if rails_version.to_s.match?(/6.1/)
57
+ # Rails 6.1 needs this as well
58
+ gem "net-pop", "~> 0.1.0", require: false
59
+ gem "net-imap", "~> 0.2.0", require: false
60
+ end
61
+ gem "net-smtp", "~> 0.3.0", require: false
62
+ end
data/README.md CHANGED
@@ -18,7 +18,7 @@ Alchemy is an open source CMS engine written in Ruby on Rails.
18
18
 
19
19
  Read more about Alchemy on the [website](https://alchemy-cms.com) and in the [guidelines](https://guides.alchemy-cms.com).
20
20
 
21
- **CAUTION: This main branch is a development branch that *can* contain bugs. For productive environments you should use the [current Ruby gem version](https://rubygems.org/gems/alchemy_cms), or the [latest stable branch (5.2-stable)](https://github.com/AlchemyCMS/alchemy_cms/tree/5.2-stable).**
21
+ **CAUTION: This main branch is a development branch that *can* contain bugs. For productive environments you should use the [current Ruby gem version](https://rubygems.org/gems/alchemy_cms), or the [latest stable branch (6.0-stable)](https://github.com/AlchemyCMS/alchemy_cms/tree/6.0-stable).**
22
22
 
23
23
 
24
24
  ## ✅ Features
@@ -27,6 +27,7 @@ Read more about Alchemy on the [website](https://alchemy-cms.com) and in the [gu
27
27
  - A rich RESTful API
28
28
  - Intuitive admin interface with live preview
29
29
  - Multi language and multi domain
30
+ - Page versioning
30
31
  - SEO friendly urls
31
32
  - User Access Control
32
33
  - Build in contact form mailer
@@ -51,9 +52,9 @@ or visit the existing demo at https://alchemy-demo.herokuapp.com
51
52
 
52
53
  ## 🚂 Rails Version
53
54
 
54
- **This version of AlchemyCMS runs with Rails 6.0**
55
+ **This version of AlchemyCMS runs with Rails 7.0, 6.1 and 6.0**
55
56
 
56
- * For a Rails 5.2 compatible version use the [`5.2-stable` branch](https://github.com/AlchemyCMS/alchemy_cms/tree/5.2-stable).
57
+ * For a Rails 5.2 compatible version use the [`5.3-stable` branch](https://github.com/AlchemyCMS/alchemy_cms/tree/5.3-stable).
57
58
  * For a Rails 5.0 or 5.1 compatible version use the [`4.5-stable` branch](https://github.com/AlchemyCMS/alchemy_cms/tree/4.5-stable).
58
59
  * For a Rails 4.2 compatible version use the [`3.6-stable` branch](https://github.com/AlchemyCMS/alchemy_cms/tree/3.6-stable).
59
60
  * For a Rails 4.0/4.1 compatible version use the [`3.1-stable` branch](https://github.com/AlchemyCMS/alchemy_cms/tree/3.1-stable).
data/alchemy_cms.gemspec CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |gem|
29
29
  activesupport
30
30
  railties
31
31
  ].each do |rails_gem|
32
- gem.add_runtime_dependency rails_gem, [">= 6.0", "< 6.2"]
32
+ gem.add_runtime_dependency rails_gem, [">= 6.0", "< 7.1"]
33
33
  end
34
34
 
35
35
  gem.add_runtime_dependency "active_model_serializers", ["~> 0.10.0"]
@@ -46,7 +46,7 @@ Gem::Specification.new do |gem|
46
46
  gem.add_runtime_dependency "kaminari", ["~> 1.1"]
47
47
  gem.add_runtime_dependency "originator", ["~> 3.1"]
48
48
  gem.add_runtime_dependency "non-stupid-digest-assets", ["~> 1.0.8"]
49
- gem.add_runtime_dependency "ransack", [">= 1.8", "<= 2.6.0"] # 2.4.2 dropped Ruby 2.5 support in a patch level release
49
+ gem.add_runtime_dependency "ransack", [">= 1.8", "< 4.0"]
50
50
  gem.add_runtime_dependency "request_store", ["~> 1.2"]
51
51
  gem.add_runtime_dependency "responders", [">= 2.0", "< 4.0"]
52
52
  gem.add_runtime_dependency "sassc-rails", ["~> 2.1"]
@@ -87,6 +87,8 @@ class window.Alchemy.LinkDialog extends Alchemy.Dialog
87
87
  name: page.name
88
88
  url_path: page.url_path
89
89
  page_id: page.id
90
+ language: page.language
91
+ site: page.site
90
92
  more: meta.page * meta.per_page < meta.total_count
91
93
  initSelection: ($element, callback) =>
92
94
  urlname = $element.val()
@@ -65,6 +65,11 @@ div#image_assign_filter_and_image_sizing {
65
65
  width: 100%;
66
66
  height: 100%;
67
67
  object-fit: contain;
68
+
69
+ &[src$=".svg"] {
70
+ width: auto;
71
+ height: auto;
72
+ }
68
73
  }
69
74
 
70
75
  .picture_name {
@@ -545,6 +545,10 @@
545
545
  font-size: 4em;
546
546
  color: $medium-gray;
547
547
  vertical-align: top;
548
+
549
+ &.error {
550
+ font-size: 1.2em;
551
+ }
548
552
  }
549
553
 
550
554
  .essence_picture_css_class {
@@ -12,6 +12,7 @@ module Alchemy
12
12
  elements = @page_version.elements.order(:position).includes(*element_includes)
13
13
  @elements = elements.not_nested.unfixed
14
14
  @fixed_elements = elements.not_nested.fixed
15
+ load_clipboard_items
15
16
  end
16
17
 
17
18
  def new
@@ -20,8 +21,7 @@ module Alchemy
20
21
  @parent_element = Element.find_by(id: params[:parent_element_id])
21
22
  @elements = @page.available_elements_within_current_scope(@parent_element)
22
23
  @element = @page_version.elements.build
23
- @clipboard = get_clipboard("elements")
24
- @clipboard_items = Element.all_from_clipboard_for_page(@clipboard, @page)
24
+ load_clipboard_items
25
25
  end
26
26
 
27
27
  # Creates a element as discribed in config/alchemy/elements.yml on page via AJAX.
@@ -44,8 +44,7 @@ module Alchemy
44
44
  else
45
45
  @element.page_version = @page_version
46
46
  @elements = @page.available_element_definitions
47
- @clipboard = get_clipboard("elements")
48
- @clipboard_items = Element.all_from_clipboard_for_page(@clipboard, @page)
47
+ load_clipboard_items
49
48
  render :new
50
49
  end
51
50
  end
@@ -106,18 +105,14 @@ module Alchemy
106
105
  def element_includes
107
106
  [
108
107
  {
109
- contents: {
110
- essence: :ingredient_association,
111
- },
108
+ contents: :essence,
112
109
  ingredients: :related_object,
113
110
  },
114
111
  :tags,
115
112
  {
116
113
  all_nested_elements: [
117
114
  {
118
- contents: {
119
- essence: :ingredient_association,
120
- },
115
+ contents: :essence,
121
116
  ingredients: :related_object,
122
117
  },
123
118
  :tags,
@@ -130,19 +125,27 @@ module Alchemy
130
125
  @element = Element.find(params[:id])
131
126
  end
132
127
 
128
+ def load_clipboard_items
129
+ @clipboard = get_clipboard("elements")
130
+ @clipboard_items = Element.all_from_clipboard_for_page(@clipboard, @page)
131
+ end
132
+
133
133
  def element_from_clipboard
134
134
  @element_from_clipboard ||= begin
135
- @clipboard = get_clipboard("elements")
136
- @clipboard.detect { |item| item["id"].to_i == params[:paste_from_clipboard].to_i }
137
- end
135
+ @clipboard = get_clipboard("elements")
136
+ @clipboard.detect { |item| item["id"].to_i == params[:paste_from_clipboard].to_i }
137
+ end
138
138
  end
139
139
 
140
140
  def paste_element_from_clipboard
141
141
  @source_element = Element.find(element_from_clipboard["id"])
142
- element = Element.copy(@source_element, {
143
- parent_element_id: create_element_params[:parent_element_id],
144
- page_version_id: @page_version.id,
145
- })
142
+ element = Element.copy(
143
+ @source_element,
144
+ {
145
+ parent_element_id: create_element_params[:parent_element_id],
146
+ page_version_id: @page_version.id,
147
+ }
148
+ )
146
149
  if element_from_clipboard["action"] == "cut"
147
150
  @cut_element_id = @source_element.id
148
151
  @clipboard.delete_if { |item| item["id"] == @source_element.id.to_s }
@@ -23,9 +23,7 @@ module Alchemy
23
23
  before_action :set_root_page,
24
24
  only: [:index, :show, :order]
25
25
 
26
- before_action :run_on_page_layout_callbacks,
27
- if: :run_on_page_layout_callbacks?,
28
- only: [:show]
26
+ before_action :set_preview_mode, only: [:show]
29
27
 
30
28
  before_action :load_languages_and_layouts,
31
29
  unless: -> { @page_root },
@@ -35,6 +33,10 @@ module Alchemy
35
33
 
36
34
  before_action :set_page_version, only: [:show, :edit]
37
35
 
36
+ before_action :run_on_page_layout_callbacks,
37
+ if: :run_on_page_layout_callbacks?,
38
+ only: [:show]
39
+
38
40
  def index
39
41
  @query = @current_language.pages.contentpages.ransack(search_filter_params[:q])
40
42
 
@@ -64,7 +66,6 @@ module Alchemy
64
66
  # Used by page preview iframe in Page#edit view.
65
67
  #
66
68
  def show
67
- @preview_mode = true
68
69
  Page.current_preview = @page
69
70
  # Setting the locale to pages language, so the page content has it's correct translations.
70
71
  ::I18n.locale = @page.language.locale
@@ -179,9 +180,12 @@ module Alchemy
179
180
  @pages_locked_by_user = Page.from_current_site.locked_by(current_alchemy_user)
180
181
  respond_to do |format|
181
182
  format.js
182
- format.html {
183
- redirect_to params[:redirect_to].blank? ? admin_pages_path : params[:redirect_to]
184
- }
183
+ format.html do
184
+ redirect_to(
185
+ params[:redirect_to].presence || admin_pages_path,
186
+ allow_other_host: true,
187
+ )
188
+ end
185
189
  end
186
190
  end
187
191
 
@@ -394,6 +398,10 @@ module Alchemy
394
398
  @languages_with_page_tree = Language.on_current_site.with_root_page
395
399
  @page_layouts = PageLayout.layouts_for_select(@language.id)
396
400
  end
401
+
402
+ def set_preview_mode
403
+ @preview_mode = true
404
+ end
397
405
  end
398
406
  end
399
407
  end
@@ -5,17 +5,18 @@ module Alchemy
5
5
  layout false
6
6
  respond_to :json
7
7
 
8
- rescue_from CanCan::AccessDenied, with: :render_not_authorized
8
+ rescue_from CanCan::AccessDenied, with: :render_not_authorized
9
9
  rescue_from ActiveRecord::RecordNotFound, with: :render_not_found
10
+ rescue_from ActionController::RoutingError, with: :render_not_found
10
11
 
11
12
  private
12
13
 
13
14
  def render_not_authorized
14
- render json: {error: "Not authorized"}, status: 403
15
+ render json: { error: "Not authorized" }, status: 403
15
16
  end
16
17
 
17
18
  def render_not_found
18
- render json: {error: "Record not found"}, status: 404
19
+ render json: { error: "Record not found" }, status: 404
19
20
  end
20
21
  end
21
22
  end
@@ -46,11 +46,7 @@ module Alchemy
46
46
  private
47
47
 
48
48
  def content_includes
49
- [
50
- {
51
- essence: :ingredient_association,
52
- },
53
- ]
49
+ %i[essence]
54
50
  end
55
51
  end
56
52
  end
@@ -47,18 +47,14 @@ module Alchemy
47
47
  {
48
48
  nested_elements: [
49
49
  {
50
- contents: {
51
- essence: :ingredient_association,
52
- },
50
+ contents: :essence,
53
51
  ingredients: :related_object,
54
52
  },
55
53
  :tags,
56
54
  ],
57
55
  },
58
56
  {
59
- contents: {
60
- essence: :ingredient_association,
61
- },
57
+ contents: :essence,
62
58
  ingredients: :related_object,
63
59
  },
64
60
  :tags,
@@ -8,6 +8,7 @@ module Alchemy
8
8
  def index
9
9
  @nodes = Node.all
10
10
  @nodes = @nodes.includes(:parent)
11
+ @nodes = @nodes.where(language_id: params[:language_id]) if params[:language_id]
11
12
  @nodes = @nodes.ransack(params[:filter]).result
12
13
 
13
14
  if params[:page]
@@ -112,17 +112,13 @@ module Alchemy
112
112
  {
113
113
  nested_elements: [
114
114
  {
115
- contents: {
116
- essence: :ingredient_association,
117
- },
115
+ contents: :essence,
118
116
  },
119
117
  :tags,
120
118
  ],
121
119
  },
122
120
  {
123
- contents: {
124
- essence: :ingredient_association,
125
- },
121
+ contents: :essence,
126
122
  },
127
123
  :tags,
128
124
  ],
@@ -9,6 +9,13 @@ module Alchemy
9
9
  include Alchemy::ControllerActions
10
10
  include Alchemy::Modules
11
11
 
12
+ # Include Turbolinks explicitly in case Alchemy is embedded into a
13
+ # larger application that doesn't work with Turbolinks. The app
14
+ # can then set config.turbolinks.auto_include = false so that
15
+ # Turbolinks is not included in the app controllers.
16
+ include Turbolinks::Controller
17
+ ::ActionDispatch::Assertions.include ::Turbolinks::Assertions
18
+
12
19
  protect_from_forgery
13
20
 
14
21
  before_action :mailer_set_url_options
@@ -62,7 +62,6 @@ module Alchemy
62
62
  end
63
63
 
64
64
  @page = @element.page
65
- @root_page = @page.get_language_root
66
65
  if @message.valid?
67
66
  MessagesMailer.contact_form_mail(@message, mail_to, mail_from, subject).deliver
68
67
  redirect_to_success_page
@@ -122,8 +121,6 @@ module Alchemy
122
121
  if @page.blank?
123
122
  raise "Page for page_layout #{mailer_config["page_layout_name"]} not found"
124
123
  end
125
-
126
- @root_page = @page.get_language_root
127
124
  end
128
125
 
129
126
  def message_params
@@ -32,9 +32,6 @@ module Alchemy
32
32
  if: :locale_prefix_missing?,
33
33
  only: [:index, :show]
34
34
 
35
- # We only need to set the +@root_page+ if we are sure that no more redirects happen.
36
- before_action :set_root_page, only: [:index, :show]
37
-
38
35
  # Page layout callbacks need to run after all other callbacks
39
36
  before_action :run_on_page_layout_callbacks,
40
37
  if: :run_on_page_layout_callbacks?,
@@ -199,10 +196,6 @@ module Alchemy
199
196
  end
200
197
  end
201
198
 
202
- def set_root_page
203
- @root_page ||= Language.current_root_page
204
- end
205
-
206
199
  def signup_required?
207
200
  if Alchemy.user_class.respond_to?(:admins)
208
201
  Alchemy.user_class.admins.empty? && @page.nil?
@@ -70,7 +70,7 @@ module Alchemy
70
70
  # A class instance that will return elements that get rendered.
71
71
  # Use this for your custom element loading logic in views.
72
72
  #
73
- def render_elements(options = {})
73
+ def render_elements(options = {}, &blk)
74
74
  options = {
75
75
  from_page: @page,
76
76
  render_format: "html",
@@ -86,11 +86,12 @@ module Alchemy
86
86
 
87
87
  elements = finder.elements(page_version: page_version)
88
88
 
89
- buff = []
90
- elements.each_with_index do |element, i|
91
- buff << render_element(element, options, i + 1)
92
- end
93
- buff.join(options[:separator]).html_safe
89
+ default_rendering = ->(element, i) { render_element(element, options, i + 1) }
90
+ if block_given?
91
+ elements.map.with_index(&blk)
92
+ else
93
+ elements.map.with_index(&default_rendering)
94
+ end.join(options[:separator]).html_safe
94
95
  end
95
96
 
96
97
  # This helper renders a {Alchemy::Element} view partial.
@@ -125,7 +126,7 @@ module Alchemy
125
126
  #
126
127
  # == Usage
127
128
  #
128
- # <%= render_element(Alchemy::Element.available.named(:headline).first) %>
129
+ # <%= render_element(Alchemy::Element.published.named(:headline).first) %>
129
130
  #
130
131
  # @param [Alchemy::Element] element
131
132
  # The element you want to render the view for
@@ -146,11 +147,15 @@ module Alchemy
146
147
 
147
148
  element.store_page(@page)
148
149
 
149
- render element, {
150
- element: element,
151
- counter: counter,
152
- options: options,
153
- }.merge(options.delete(:locals) || {})
150
+ render(
151
+ partial: options[:partial] || element.to_partial_path,
152
+ object: element,
153
+ locals: {
154
+ element: element,
155
+ counter: counter,
156
+ options: options.except(:locals, :partial),
157
+ }.merge(options[:locals] || {}),
158
+ )
154
159
  rescue ActionView::MissingTemplate => e
155
160
  warning(%(
156
161
  Element view partial not found for #{element.name}.\n
@@ -70,7 +70,7 @@ module Alchemy
70
70
  dependent: :destroy
71
71
 
72
72
  has_many :nested_elements,
73
- -> { order(:position).available },
73
+ -> { order(:position).published },
74
74
  class_name: "Alchemy::Element",
75
75
  foreign_key: :parent_element_id,
76
76
  dependent: :destroy,
@@ -159,7 +159,7 @@ module Alchemy
159
159
  end
160
160
 
161
161
  def all_from_clipboard(clipboard)
162
- return [] if clipboard.nil?
162
+ return none if clipboard.nil?
163
163
 
164
164
  where(id: clipboard.collect { |e| e["id"] })
165
165
  end
@@ -167,12 +167,19 @@ module Alchemy
167
167
  # All elements in clipboard that could be placed on page
168
168
  #
169
169
  def all_from_clipboard_for_page(clipboard, page)
170
- return [] if clipboard.nil? || page.nil?
170
+ return none if clipboard.nil? || page.nil?
171
171
 
172
- all_from_clipboard(clipboard).select { |ce|
173
- page.available_element_names.include?(ce.name)
174
- }
172
+ all_from_clipboard(clipboard).where(name: page.available_element_names)
175
173
  end
174
+
175
+ # All elements in clipboard that could be placed as a child of `parent_element`
176
+ def all_from_clipboard_for_parent_element(clipboard, parent_element)
177
+ return none if clipboard.nil? || parent_element.nil?
178
+
179
+ all_from_clipboard(clipboard).where(name: parent_element.definition["nestable_elements"])
180
+ end
181
+
182
+ deprecate available: :published, deprecator: Alchemy::Deprecation
176
183
  end
177
184
 
178
185
  # Returns next public element from same page.
@@ -88,7 +88,7 @@ module Alchemy
88
88
 
89
89
  def duplicates
90
90
  ingredient.class
91
- .joins(:element).merge(Alchemy::Element.available)
91
+ .joins(:element).merge(Alchemy::Element.published)
92
92
  .where(Alchemy::Element.table_name => { name: ingredient.element.name })
93
93
  .where(value: ingredient.value)
94
94
  .where.not(id: ingredient.id)
@@ -38,7 +38,7 @@ module Alchemy
38
38
 
39
39
  validates :language_code,
40
40
  presence: true,
41
- uniqueness: { scope: [:site_id, :country_code] },
41
+ uniqueness: { scope: [:site_id, :country_code], case_sensitive: false },
42
42
  format: { with: /\A[a-z]{2}\z/, if: -> { language_code.present? } }
43
43
 
44
44
  validates :country_code,
@@ -15,8 +15,8 @@ module Alchemy
15
15
  source: :elements,
16
16
  ) do
17
17
  has_many :all_elements
18
- has_many :elements, -> { not_nested.unfixed.available }
19
- has_many :fixed_elements, -> { fixed.available }
18
+ has_many :elements, -> { not_nested.unfixed.published }
19
+ has_many :fixed_elements, -> { fixed.published }
20
20
  end
21
21
 
22
22
  has_many :contents, through: :elements
@@ -15,7 +15,7 @@ module Alchemy
15
15
  validates :name,
16
16
  presence: true
17
17
  validates :urlname,
18
- uniqueness: { scope: [:language_id, :layoutpage], if: -> { urlname.present? } },
18
+ uniqueness: { scope: [:language_id, :layoutpage], if: -> { urlname.present? }, case_sensitive: false },
19
19
  exclusion: { in: RESERVED_URLNAMES },
20
20
  length: { minimum: 3, if: -> { urlname.present? } }
21
21
 
@@ -117,7 +117,7 @@ module Alchemy
117
117
  has_many :nodes, class_name: "Alchemy::Node", inverse_of: :page
118
118
  has_many :versions, class_name: "Alchemy::PageVersion", inverse_of: :page, dependent: :destroy
119
119
  has_one :draft_version, -> { drafts }, class_name: "Alchemy::PageVersion"
120
- has_one :public_version, -> { published }, class_name: "Alchemy::PageVersion"
120
+ has_one :public_version, -> { published }, class_name: "Alchemy::PageVersion", autosave: -> { persisted? }
121
121
 
122
122
  before_validation :set_language,
123
123
  if: -> { language.nil? }
@@ -30,7 +30,7 @@ module Alchemy
30
30
  # Returns the rendered resized image using imagemagick directly.
31
31
  #
32
32
  def resize(size, upsample = false)
33
- image_file.thumb(upsample ? size : "#{size}>")
33
+ image_file.thumbnail(upsample ? size : "#{size}>")
34
34
  end
35
35
 
36
36
  # Returns true if picture's width is greater than it's height
@@ -119,7 +119,7 @@ module Alchemy
119
119
  if is_smaller_than?(dimensions) && upsample == false
120
120
  dimensions = reduce_to_image(dimensions)
121
121
  end
122
- image_file.thumb("#{dimensions_to_string(dimensions)}#")
122
+ image_file.thumbnail("#{dimensions_to_string(dimensions)}#")
123
123
  end
124
124
 
125
125
  # Use imagemagick to custom crop an image. Uses -thumbnail for better performance when resizing.