alchemy_cms 6.0.4 → 6.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e9bfd92678d3b4ae867e8c3938a0277d7698fb6fbcfb80a0210f0c4371990486
4
- data.tar.gz: ce854781846eadaecdbe717ab435a38d357cda54863707b2c62a61cf4730884b
3
+ metadata.gz: b0fce84117963b495d370420cf9284024ee5f64b9016c19d711611e73ab7c37b
4
+ data.tar.gz: 693fbc3e13673bb75eef4defb7c660b20840b27fee01730f73ab7946fa7cb823
5
5
  SHA512:
6
- metadata.gz: 51391e56da530c900189d8c16b756d9084fac351cfc50ebc2ee9b7181d7148c826daf39bdd284100261aa6e4ae5c1a4f28eb266c1a31d9fd1ad31f21e2cda398
7
- data.tar.gz: 244eb43ca4783a572c5885c69571264a50d4154a5ccfc8b5af806f1343497cc38a8157a1b8c039262d60ea8f4cd6a3a19777943ca9b1c0654a6cd473d3f9f025
6
+ metadata.gz: 77b35133d99ad3458fe8c1c37abb70dc120841844f7dfeabde471fbc3740d551d726057b1f306c1890dcc39c1e89fe0e16d6fb18ebfda23888da8b3c5d4178f4
7
+ data.tar.gz: 0e34ec1637dcfe6a580f3f846b4237859efbdd0c415b0d7dda109a1eac4d0553cd7206a52c31b5396834334931a862879e49fe52f69424a69ec8891b2c98fc02
data/CHANGELOG.md CHANGED
@@ -1,3 +1,21 @@
1
+ ## 6.0.7 (2022-06-04)
2
+
3
+ - Eagerly generate thumbs for srcset images in task as well [#2344](https://github.com/AlchemyCMS/alchemy_cms/pull/2344) ([tvdeyen](https://github.com/tvdeyen))
4
+ - Use HashWithIndifferentAccess for Page definition. Key hint translation by page_layout [#2343](https://github.com/AlchemyCMS/alchemy_cms/pull/2343) ([dbwinger](https://github.com/dbwinger))
5
+
6
+ ## 6.0.6 (2022-05-30)
7
+
8
+ - Add task to eagerly generate ingredients pictures thumbnails [#2342](https://github.com/AlchemyCMS/alchemy_cms/pull/2342) ([tvdeyen](https://github.com/tvdeyen))
9
+ - Add spec for ingredients migrator; fix preloading in Rails 6.1+ [#2340](https://github.com/AlchemyCMS/alchemy_cms/pull/2340) ([mamhoff](https://github.com/mamhoff))
10
+ - Extract element ingredient migrator [#2337](https://github.com/AlchemyCMS/alchemy_cms/pull/2337) ([tvdeyen](https://github.com/tvdeyen))
11
+ - Update published_at only after page has been published. [#2331](https://github.com/AlchemyCMS/alchemy_cms/pull/2331) ([pascalbetz](https://github.com/pascalbetz))
12
+ - Add element groups functionality for cleaning up editors [#2124](https://github.com/AlchemyCMS/alchemy_cms/pull/2124) ([dbwinger](https://github.com/dbwinger))
13
+ - Eagerload at the controller or job layer [#2313](https://github.com/AlchemyCMS/alchemy_cms/pull/2313) ([mamhoff](https://github.com/mamhoff))
14
+
15
+ ## 6.0.5 (2022-05-11)
16
+
17
+ - Extract element ingredient migrator [#2337](https://github.com/AlchemyCMS/alchemy_cms/pull/2337) ([tvdeyen](https://github.com/tvdeyen))
18
+
1
19
  ## 6.0.4 (2022-05-06)
2
20
 
3
21
  - Add support for Rails' recycable cache keys [#2334](https://github.com/AlchemyCMS/alchemy_cms/pull/2334) ([tvdeyen](https://github.com/tvdeyen))
@@ -15,6 +15,7 @@ Alchemy.ElementEditors =
15
15
  init: ->
16
16
  @element_area = $("#element_area")
17
17
  @bindEvents()
18
+ @expandContentGroups()
18
19
  return
19
20
 
20
21
  # Binds click events on several DOM elements from element editors
@@ -36,12 +37,20 @@ Alchemy.ElementEditors =
36
37
  # Binds the custom SaveElement event
37
38
  @element_area.on "SaveElement.Alchemy", '.element-editor', (e, data) =>
38
39
  @onSaveElement(e, data)
40
+ @element_area.on "click", '[data-toggle-content-group]', (e) =>
41
+ @onToggleContentGroup(e)
39
42
  # Listen to postMessage messages from the preview frame
40
43
  window.addEventListener 'message', (e) =>
41
44
  @onMessage(e.data)
42
45
  true
43
46
  return
44
47
 
48
+ # Expands content groups that are stored in sessionStorage as expanded
49
+ expandContentGroups: ->
50
+ if $expanded_content_groups = sessionStorage.getItem('Alchemy.expanded_content_groups')
51
+ for header_id in JSON.parse($expanded_content_groups) then do (header_id) =>
52
+ $('#' + header_id).closest('.content-group').addClass('expanded');
53
+
45
54
  # Selects and scrolls to element with given id in the preview window.
46
55
  #
47
56
  focusElementPreview: (element_id) ->
@@ -170,6 +179,23 @@ Alchemy.ElementEditors =
170
179
  Alchemy.Buttons.enable($element)
171
180
  true
172
181
 
182
+ # Toggle visibility of the content fields in the group
183
+ onToggleContentGroup: (event) ->
184
+ $group_div = $(event.currentTarget).closest('.content-group');
185
+ $group_div.toggleClass('expanded');
186
+
187
+ $expanded_content_groups = JSON.parse(sessionStorage.getItem('Alchemy.expanded_content_groups') || '[]');
188
+ # Add or remove depending on whether this content group is expanded
189
+ if $group_div.hasClass('expanded')
190
+ if $expanded_content_groups.indexOf(event.currentTarget.id) == -1
191
+ $expanded_content_groups.push(event.currentTarget.id);
192
+ else
193
+ $expanded_content_groups = $expanded_content_groups.filter (value) ->
194
+ value != event.currentTarget.id
195
+
196
+ sessionStorage.setItem('Alchemy.expanded_content_groups', JSON.stringify($expanded_content_groups))
197
+ false
198
+
173
199
  # Event handlers
174
200
 
175
201
  onMessage: (data) ->
@@ -414,6 +414,41 @@
414
414
  }
415
415
  }
416
416
 
417
+ .content-group {
418
+ width: 100%;
419
+ padding: $default-padding 0;
420
+ position: relative;
421
+ border-bottom: 1px solid $medium-gray;
422
+
423
+ &:last-child {
424
+ border-bottom: none;
425
+ padding-bottom: 0;
426
+ }
427
+
428
+ .content-group-header {
429
+ display: flex;
430
+ align-items: center;
431
+ justify-content: space-between;
432
+ font-weight: bold;
433
+ text-decoration: none;
434
+ padding: $default-padding 1px;
435
+ }
436
+
437
+ .content-group-contents {
438
+ display: none;
439
+ }
440
+
441
+ &.expanded {
442
+ .content-group-contents {
443
+ display: block;
444
+ }
445
+
446
+ .content-group-expand {
447
+ @extend .fa-angle-up;
448
+ }
449
+ }
450
+ }
451
+
417
452
  .element-content-editors,
418
453
  .element-ingredient-editors {
419
454
  display: flex;
@@ -324,7 +324,7 @@ module Alchemy
324
324
  end
325
325
 
326
326
  def load_resource
327
- @page = Page.find(params[:id])
327
+ @page = Page.includes(page_includes).find(params[:id])
328
328
  end
329
329
 
330
330
  def pages_from_raw_request
@@ -402,6 +402,10 @@ module Alchemy
402
402
  def set_preview_mode
403
403
  @preview_mode = true
404
404
  end
405
+
406
+ def page_includes
407
+ Alchemy::EagerLoading.page_includes(version: :draft_version)
408
+ end
405
409
  end
406
410
  end
407
411
  end
@@ -104,7 +104,14 @@ module Alchemy
104
104
  # If no index page and no admin users are present we show the "Welcome to Alchemy" page.
105
105
  #
106
106
  def load_index_page
107
- @page ||= Language.current_root_page
107
+ @page ||= begin
108
+ Alchemy::Page.
109
+ contentpages.
110
+ language_roots.
111
+ where(language: Language.current).
112
+ includes(page_includes).
113
+ first
114
+ end
108
115
  render template: "alchemy/welcome", layout: false if signup_required?
109
116
  end
110
117
 
@@ -120,10 +127,13 @@ module Alchemy
120
127
  def load_page
121
128
  page_not_found! unless Language.current
122
129
 
123
- @page ||= Language.current.pages.contentpages.find_by(
124
- urlname: params[:urlname],
125
- language_code: params[:locale] || Language.current.code,
126
- )
130
+ @page ||= begin
131
+ Alchemy::Page.
132
+ contentpages.
133
+ where(language: Language.current).
134
+ includes(page_includes).
135
+ find_by(urlname: params[:urlname])
136
+ end
127
137
  end
128
138
 
129
139
  def enforce_locale
@@ -234,5 +244,9 @@ module Alchemy
234
244
  def page_not_found!
235
245
  not_found_error!("Alchemy::Page not found \"#{request.fullpath}\"")
236
246
  end
247
+
248
+ def page_includes
249
+ Alchemy::EagerLoading.page_includes(version: :public_version)
250
+ end
237
251
  end
238
252
  end
@@ -36,6 +36,29 @@ module Alchemy
36
36
  element.definition.fetch(:ingredients, []).any?
37
37
  end
38
38
 
39
+ # Returns the translated content/ingredient group for displaying in admin editor group headings
40
+ #
41
+ # Translate it in your locale yml file:
42
+ #
43
+ # alchemy:
44
+ # element_groups:
45
+ # foo: Bar
46
+ #
47
+ # Optionally you can scope your ingredient role to an element:
48
+ #
49
+ # alchemy:
50
+ # element_groups:
51
+ # article:
52
+ # foo: Baz
53
+ #
54
+ def translated_group(group)
55
+ Alchemy.t(
56
+ group,
57
+ scope: "element_groups.#{element.name}",
58
+ default: Alchemy.t("element_groups.#{group}", default: group.humanize),
59
+ )
60
+ end
61
+
39
62
  # CSS classes for the element editor partial.
40
63
  def css_classes
41
64
  [
@@ -4,7 +4,10 @@ module Alchemy
4
4
  class PublishPageJob < BaseJob
5
5
  queue_as :default
6
6
 
7
- def perform(page, public_on:)
7
+ def perform(page_id, public_on:)
8
+ page = Alchemy::Page.includes(
9
+ Alchemy::EagerLoading.page_includes(version: :draft_version)
10
+ ).find(page_id)
8
11
  Alchemy::Page::Publisher.new(page).publish!(public_on: public_on)
9
12
  end
10
13
  end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ # Eager loading parameters for loading pages
5
+ class EagerLoading
6
+ PAGE_VERSIONS = %i[draft_version public_version]
7
+
8
+ class << self
9
+ # Eager loading parameters for {ActiveRecord::Base.includes}
10
+ #
11
+ # Pass this to +includes+ whereever you load an {Alchemy::Page}
12
+ #
13
+ # Alchemy::Page.includes(Alchemy::EagerLoading.page_includes).find_by(urlname: "my-page")
14
+ #
15
+ # @param version [Symbol] Type of page version to eager load
16
+ # @return [Array]
17
+ def page_includes(version: :public_version)
18
+ raise UnsupportedPageVersion unless version.in? PAGE_VERSIONS
19
+
20
+ [
21
+ :tags,
22
+ {
23
+ language: :site,
24
+ version => {
25
+ elements: [
26
+ :page,
27
+ :touchable_pages,
28
+ {
29
+ ingredients: :related_object,
30
+ contents: :essence,
31
+ },
32
+ ],
33
+ },
34
+ },
35
+ ]
36
+ end
37
+ end
38
+ end
39
+ end
@@ -12,7 +12,9 @@ module Alchemy
12
12
 
13
13
  # Copies all currently visible elements to the public version of page
14
14
  #
15
- # Creates a new published version if none exists yet.
15
+ # Creates a new published version if none exists yet and updates
16
+ # the `published_at` timestamp of the page.
17
+ # `published_at` is used as a cache key.
16
18
  #
17
19
  # Sends a publish notification to all registered publish targets
18
20
  #
@@ -32,6 +34,7 @@ module Alchemy
32
34
  end
33
35
  end
34
36
  end
37
+ page.update(published_at: public_on)
35
38
  end
36
39
 
37
40
  Alchemy.publish_targets.each { |p| p.perform_later(page) }
@@ -457,15 +457,10 @@ module Alchemy
457
457
  end
458
458
  end
459
459
 
460
- # Creates a public version of the page.
461
- #
462
- # Sets the +published_at+ value to current time
463
- #
464
- # The +published_at+ attribute is used as +cache_key+.
460
+ # Creates a public version of the page in the background.
465
461
  #
466
462
  def publish!(current_time = Time.current)
467
- update(published_at: current_time)
468
- PublishPageJob.perform_later(self, public_on: current_time)
463
+ PublishPageJob.perform_later(id, public_on: current_time)
469
464
  end
470
465
 
471
466
  # Sets the public_on date on the published version
@@ -570,6 +565,12 @@ module Alchemy
570
565
  locker.try(:name) || Alchemy.t("unknown")
571
566
  end
572
567
 
568
+ # Key hint translations by page layout, rather than the default name.
569
+ #
570
+ def hint_translation_attribute
571
+ page_layout
572
+ end
573
+
573
574
  # Menus (aka. root nodes) this page is attached to
574
575
  #
575
576
  def menus
@@ -46,7 +46,7 @@ module Alchemy
46
46
  end
47
47
 
48
48
  def element_repository
49
- ElementsRepository.new(elements.includes({ contents: :essence }, :tags))
49
+ ElementsRepository.new(elements)
50
50
  end
51
51
 
52
52
  private
@@ -23,15 +23,44 @@
23
23
  html: {id: "element_#{element.id}_form".html_safe, class: 'element-content'} do |f| %>
24
24
 
25
25
  <div id="element_<%= element.id %>_errors" class="element_errors"></div>
26
+
27
+ <!-- Ingredients -->
26
28
  <% if element.has_ingredients_defined? %>
27
29
  <div class="element-ingredient-editors">
28
- <%= render element.ingredients, element_form: f %>
29
- </div>
30
- <% else %>
31
- <div id="element_<%= element.id %>_content" class="element-content-editors">
32
- <%= render element.contents %>
30
+ <%= render element.ingredients.select { |i| !i.definition[:group] }, element_form: f %>
31
+
32
+ <!-- Each ingredient group -->
33
+ <% element.ingredients.select { |i| i.definition[:group] }.group_by { |i| i.definition[:group] }.each do |group, ingredients| %>
34
+ <div class="content-group">
35
+ <%= link_to '#', id: "element_#{element.id}_content_group_#{group.parameterize.underscore}_header", class: 'content-group-header', data: { toggle_content_group: true } do %>
36
+ <%= element.translated_group group %>
37
+ <i class="content-group-expand icon fa-fw fa-angle-down fas"></i>
38
+ <% end %>
39
+ <%= content_tag :div, id: "element_#{element.id}_content_group_#{group.parameterize.underscore}", class: 'content-group-contents' do %>
40
+ <%= render ingredients, element_form: f %>
41
+ <% end %>
42
+ </div>
43
+ <% end %>
33
44
  </div>
34
45
  <% end %>
46
+ <!-- Contents -->
47
+ <div id="element_<%= element.id %>_content" class="element-content-editors">
48
+ <%= render element.contents.select { |c| !c.definition[:group] } %>
49
+
50
+ <!-- Each content group -->
51
+ <% element.contents.select { |c| c.definition[:group] }.group_by { |c| c.definition[:group] }.each do |group, contents| %>
52
+ <div class="content-group">
53
+ <%= link_to '#', id: "element_#{element.id}_content_group_#{group.parameterize.underscore}_header", class: 'content-group-header', data: { toggle_content_group: true } do %>
54
+ <%= element.translated_group group %>
55
+ <i class="content-group-expand icon fa-fw fa-angle-down fas"></i>
56
+ <% end %>
57
+ <%= content_tag :div, id: "element_#{element.id}_content_group_#{group.parameterize.underscore}", class: 'content-group-contents' do %>
58
+ <%= render contents, element_form: f %>
59
+ <% end %>
60
+ </div>
61
+ <% end %>
62
+ </div>
63
+
35
64
  <% if element.taggable? %>
36
65
  <div class="autocomplete_tag_list">
37
66
  <%= f.label :tag_list %>
@@ -11,7 +11,7 @@ module Alchemy
11
11
  # Raised if no default language configuration can be found.
12
12
  def message
13
13
  "No default language configuration found!" \
14
- " Please ensure that you have a 'default_language' defined in Alchemy configuration file."
14
+ " Please ensure that you have a 'default_language' defined in Alchemy configuration file."
15
15
  end
16
16
  end
17
17
 
@@ -19,7 +19,7 @@ module Alchemy
19
19
  # Raised if no default site configuration can be found.
20
20
  def message
21
21
  "No default site configuration found!" \
22
- " Please ensure that you have a 'default_site' defined in Alchemy configuration file."
22
+ " Please ensure that you have a 'default_site' defined in Alchemy configuration file."
23
23
  end
24
24
  end
25
25
 
@@ -90,4 +90,10 @@ module Alchemy
90
90
  "You need to provide a current_user method in your ApplicationController that returns the current authenticated user."
91
91
  end
92
92
  end
93
+
94
+ class UnsupportedPageVersion < StandardError
95
+ def message
96
+ "Unknown Version! Please use one of #{Alchemy::EagerLoading::PAGE_VERSIONS.join(", ")}"
97
+ end
98
+ end
93
99
  end
@@ -8,7 +8,7 @@ module Alchemy
8
8
  # They are defined in +config/alchemy/page_layout.yml+ file.
9
9
  #
10
10
  def all
11
- @definitions ||= read_definitions_file
11
+ @definitions ||= read_definitions_file.map(&:with_indifferent_access)
12
12
  end
13
13
 
14
14
  # Add additional page definitions to collection.
@@ -151,11 +151,13 @@ module Alchemy
151
151
  #
152
152
  def read_definitions_file
153
153
  if File.exist?(layouts_file_path)
154
- YAML.safe_load(
155
- ERB.new(File.read(layouts_file_path)).result,
156
- permitted_classes: YAML_PERMITTED_CLASSES,
157
- aliases: true,
158
- ) || []
154
+ Array.wrap(
155
+ YAML.safe_load(
156
+ ERB.new(File.read(layouts_file_path)).result,
157
+ permitted_classes: YAML_PERMITTED_CLASSES,
158
+ aliases: true,
159
+ ) || []
160
+ )
159
161
  else
160
162
  raise LoadError, "Could not find page_layouts.yml file! Please run `rails generate alchemy:install`"
161
163
  end
@@ -16,7 +16,7 @@ module Alchemy::Upgrader::Tasks
16
16
  # eager load all elements that have ingredients defined but no ingredient records yet.
17
17
  all_elements = Alchemy::Element
18
18
  .named(elements_with_ingredients.map { |d| d[:name] })
19
- .includes(contents: :essence)
19
+ .preload(contents: :essence)
20
20
  .left_outer_joins(:ingredients).where(alchemy_ingredients: { id: nil })
21
21
  .to_a
22
22
  elements_with_ingredients.map do |element_definition|
@@ -24,31 +24,8 @@ module Alchemy::Upgrader::Tasks
24
24
  if elements.any?
25
25
  puts "-- Creating ingredients for #{elements.count} #{element_definition[:name]}(s)"
26
26
  elements.each do |element|
27
- Alchemy::Element.transaction do
28
- element_definition[:ingredients].each do |ingredient_definition|
29
- content = element.content_by_name(ingredient_definition[:role])
30
- next unless content
31
-
32
- essence = content.essence
33
- ingredient = element.ingredients.build(
34
- role: ingredient_definition[:role],
35
- type: Alchemy::Ingredient.normalize_type(ingredient_definition[:type]),
36
- )
37
- belongs_to_associations = essence.class.reflect_on_all_associations(:belongs_to)
38
- if belongs_to_associations.any?
39
- ingredient.related_object = essence.public_send(belongs_to_associations.first.name)
40
- else
41
- ingredient.value = content.ingredient
42
- end
43
- data = ingredient.class.stored_attributes.fetch(:data, []).each_with_object({}) do |attr, d|
44
- d[attr] = essence.public_send(attr)
45
- end
46
- ingredient.data = data
47
- print "."
48
- ingredient.save!
49
- content.destroy!
50
- end
51
- end
27
+ MigrateElementIngredients.call(element)
28
+ print "."
52
29
  end
53
30
  puts "\n"
54
31
  else
@@ -58,5 +35,38 @@ module Alchemy::Upgrader::Tasks
58
35
  end
59
36
  end
60
37
  end
38
+
39
+ class MigrateElementIngredients
40
+ def self.call(element)
41
+ Alchemy::Element.transaction do
42
+ element.definition[:ingredients].each do |ingredient_definition|
43
+ ingredient = element.ingredients.build(
44
+ role: ingredient_definition[:role],
45
+ type: Alchemy::Ingredient.normalize_type(ingredient_definition[:type]),
46
+ )
47
+
48
+ content = element.content_by_name(ingredient_definition[:role])
49
+ if content
50
+ essence = content.essence
51
+ if essence
52
+ belongs_to_associations = essence.class.reflect_on_all_associations(:belongs_to)
53
+ if belongs_to_associations.any?
54
+ ingredient.related_object = essence.public_send(belongs_to_associations.first.name)
55
+ else
56
+ ingredient.value = content.ingredient
57
+ end
58
+ data = ingredient.class.stored_attributes.fetch(:data, []).each_with_object({}) do |attr, d|
59
+ d[attr] = essence.public_send(attr)
60
+ end
61
+ ingredient.data = data
62
+ end
63
+ content.destroy!
64
+ end
65
+
66
+ ingredient.save!
67
+ end
68
+ end
69
+ end
70
+ end
61
71
  end
62
72
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "6.0.4"
4
+ VERSION = "6.0.7"
5
5
 
6
6
  def self.version
7
7
  VERSION
@@ -6,6 +6,7 @@ namespace :alchemy do
6
6
  task thumbnails: [
7
7
  "alchemy:generate:picture_thumbnails",
8
8
  "alchemy:generate:essence_picture_thumbnails",
9
+ "alchemy:generate:ingredient_picture_thumbnails",
9
10
  ]
10
11
 
11
12
  desc "Generates thumbnails for Alchemy Pictures."
@@ -31,6 +32,38 @@ namespace :alchemy do
31
32
  essence_pictures.find_each do |essence_picture|
32
33
  puts essence_picture.picture_url
33
34
  puts essence_picture.thumbnail_url
35
+
36
+ essence_picture.settings.fetch(:srcset, []).each do |src|
37
+ puts essence_picture.picture_url(src)
38
+ end
39
+ end
40
+
41
+ puts "Done!"
42
+ end
43
+
44
+ desc "Generates thumbnails for Alchemy Picture Ingredients (set ELEMENTS=element1,element2 to only generate thumbnails for a subset of elements)."
45
+ task ingredient_picture_thumbnails: :environment do
46
+ ingredient_pictures = Alchemy::Ingredients::Picture.
47
+ joins(:element).
48
+ preload({ related_object: :thumbs }).
49
+ merge(Alchemy::Element.available)
50
+
51
+ if ENV["ELEMENTS"].present?
52
+ ingredient_pictures = ingredient_pictures.merge(
53
+ Alchemy::Element.named(ENV["ELEMENTS"].split(","))
54
+ )
55
+ end
56
+
57
+ puts "Regenerate #{ingredient_pictures.count} ingredient picture thumbnails."
58
+ puts "Please wait..."
59
+
60
+ ingredient_pictures.find_each do |ingredient_picture|
61
+ puts ingredient_picture.picture_url
62
+ puts ingredient_picture.thumbnail_url
63
+
64
+ ingredient_picture.settings.fetch(:srcset, []).each do |src|
65
+ puts ingredient_picture.picture_url(src)
66
+ end
34
67
  end
35
68
 
36
69
  puts "Done!"
data/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alchemy_cms/admin",
3
- "version": "6.0.4",
3
+ "version": "6.0.7",
4
4
  "description": "AlchemyCMS",
5
5
  "browser": "package/admin.js",
6
6
  "files": [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: alchemy_cms
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.4
4
+ version: 6.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Thomas von Deyen
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2022-05-06 00:00:00.000000000 Z
16
+ date: 2022-06-04 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: actionmailer
@@ -916,6 +916,7 @@ files:
916
916
  - app/models/alchemy/base_record.rb
917
917
  - app/models/alchemy/content.rb
918
918
  - app/models/alchemy/content/factory.rb
919
+ - app/models/alchemy/eager_loading.rb
919
920
  - app/models/alchemy/element.rb
920
921
  - app/models/alchemy/element/definitions.rb
921
922
  - app/models/alchemy/element/element_contents.rb