maglevcms 1.2.2 → 1.4.0

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/maglev/content/builder.rb +3 -1
  3. data/app/components/maglev/content/checkbox.rb +7 -1
  4. data/app/components/maglev/content/void.rb +11 -0
  5. data/app/controllers/concerns/maglev/fetchers_concern.rb +2 -1
  6. data/app/controllers/concerns/maglev/rendering_concern.rb +0 -2
  7. data/app/controllers/maglev/editor_controller.rb +4 -0
  8. data/app/frontend/admin/controllers/screenshot_controller.js +1 -1
  9. data/app/frontend/editor/components/dynamic-form/dynamic-input.vue +30 -10
  10. data/app/frontend/editor/components/dynamic-form/index.vue +2 -0
  11. data/app/frontend/editor/components/kit/color-input/core-input.vue +1 -1
  12. data/app/frontend/editor/components/kit/color-input.vue +1 -1
  13. data/app/frontend/editor/components/kit/divider.vue +22 -0
  14. data/app/frontend/editor/components/kit/hint.vue +12 -0
  15. data/app/frontend/editor/components/kit/index.js +4 -0
  16. data/app/frontend/editor/components/page/form/seo.vue +1 -1
  17. data/app/frontend/editor/components/section-block-pane/setting-list.vue +4 -0
  18. data/app/frontend/editor/components/section-highlighter/top-left-actions.vue +7 -1
  19. data/app/frontend/editor/components/section-list/list-item.vue +6 -1
  20. data/app/frontend/editor/components/section-pane/index.vue +2 -1
  21. data/app/frontend/editor/components/section-pane/setting-list.vue +4 -0
  22. data/app/frontend/editor/components/style-pane/index.vue +4 -0
  23. data/app/frontend/editor/locales/editor.fr.json +8 -2
  24. data/app/frontend/editor/locales/editor.pt-BR.json +257 -0
  25. data/app/frontend/editor/locales/index.js +3 -0
  26. data/app/frontend/editor/mixins/global.js +16 -0
  27. data/app/frontend/editor/router/index.js +1 -2
  28. data/app/frontend/editor/views/content-pane.vue +2 -2
  29. data/app/models/concerns/maglev/sections_concern.rb +17 -13
  30. data/app/models/concerns/maglev/translatable.rb +4 -0
  31. data/app/models/maglev/page.rb +6 -0
  32. data/app/models/maglev/section/setting.rb +22 -25
  33. data/app/models/maglev/setting_types/base.rb +10 -0
  34. data/app/models/maglev/setting_types/checkbox.rb +9 -0
  35. data/app/models/maglev/setting_types/collection_item.rb +13 -0
  36. data/app/models/maglev/setting_types/color.rb +6 -0
  37. data/app/models/maglev/setting_types/divider.rb +9 -0
  38. data/app/models/maglev/setting_types/hint.rb +9 -0
  39. data/app/models/maglev/setting_types/icon.rb +9 -0
  40. data/app/models/maglev/setting_types/image.rb +13 -0
  41. data/app/models/maglev/setting_types/link.rb +13 -0
  42. data/app/models/maglev/setting_types/select.rb +6 -0
  43. data/app/models/maglev/setting_types/text.rb +6 -0
  44. data/app/models/maglev/site/locales_concern.rb +12 -1
  45. data/app/models/maglev/site.rb +4 -0
  46. data/app/models/maglev/theme/style_setting.rb +1 -1
  47. data/app/models/maglev/theme.rb +35 -0
  48. data/app/services/maglev/add_site_locale.rb +64 -0
  49. data/app/services/maglev/app_container.rb +1 -0
  50. data/app/services/maglev/change_site_locales.rb +1 -1
  51. data/app/services/maglev/fetch_page.rb +7 -1
  52. data/app/services/maglev/fetch_section_screenshot_path.rb +1 -1
  53. data/app/services/maglev/get_page_fullpath.rb +5 -1
  54. data/app/services/maglev/persist_page.rb +15 -11
  55. data/lib/maglev/active_storage.rb +2 -2
  56. data/lib/maglev/engine.rb +6 -2
  57. data/lib/maglev/errors.rb +7 -0
  58. data/lib/maglev/preview_constraint.rb +15 -1
  59. data/lib/maglev/version.rb +1 -1
  60. metadata +23 -7
@@ -21,5 +21,9 @@ module Maglev
21
21
  def find_section(type)
22
22
  sections&.find { |section| section['type'] == type }
23
23
  end
24
+
25
+ def translate_in(locale, source_locale)
26
+ translate_attr_in(:sections, locale, source_locale)
27
+ end
24
28
  end
25
29
  end
@@ -10,7 +10,7 @@ class Maglev::Theme::StyleSetting
10
10
 
11
11
  ## validations ##
12
12
  validates :id, :label, :type, :default, 'maglev/presence': true
13
- validates :type, inclusion: { in: %w[text color select checkbox] }
13
+ validates :type, inclusion: { in: %w[text color select checkbox divider hint] }
14
14
 
15
15
  ## methods ##
16
16
 
@@ -12,5 +12,40 @@ module Maglev
12
12
  validates :id, :name, presence: true
13
13
 
14
14
  ## methods ##
15
+
16
+ def find_setting!(section_id, block_id, setting_id)
17
+ setting = find_setting(section_id, block_id, setting_id)
18
+ raise Maglev::Errors::UnknownSetting.new(section_id, block_id, setting_id) if setting.nil?
19
+
20
+ setting
21
+ end
22
+
23
+ def find_setting(section_id, block_id, setting_id)
24
+ key = [section_id, block_id, setting_id].compact.join('.')
25
+ section_setting_types[key]
26
+ end
27
+
28
+ private
29
+
30
+ def section_setting_types
31
+ @section_setting_types ||= build_section_setting_types
32
+ end
33
+
34
+ def build_section_setting_types
35
+ hash = {}
36
+ sections.each do |section|
37
+ build_section_setting_types_from_settings(hash, section.id, section.settings)
38
+ section.blocks.each do |block|
39
+ build_section_setting_types_from_settings(hash, "#{section.id}.#{block.type}", block.settings)
40
+ end
41
+ end
42
+ hash
43
+ end
44
+
45
+ def build_section_setting_types_from_settings(hash, parent_key, settings)
46
+ settings.each do |setting|
47
+ hash["#{parent_key}.#{setting.id}"] = setting
48
+ end
49
+ end
15
50
  end
16
51
  end
@@ -0,0 +1,64 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ # Add a locale (instace of Maglev::Site::Locale) to a site
5
+ class AddSiteLocale
6
+ include Injectable
7
+
8
+ argument :site
9
+ argument :locale
10
+
11
+ def call
12
+ return if locale.blank? || !site.add_locale(locale)
13
+
14
+ ActiveRecord::Base.transaction do
15
+ unsafe_call
16
+ end
17
+ end
18
+
19
+ protected
20
+
21
+ def unsafe_call
22
+ # Set a default content for site_scoped sections
23
+ apply_to_site
24
+
25
+ site.save! # persist the new locale
26
+
27
+ # add a default content in the new locale to all the pages of the site
28
+ # based on the default locale. Also take care of the path.
29
+ apply_to_pages
30
+
31
+ true
32
+ end
33
+
34
+ def apply_to_site
35
+ Maglev::I18n.with_locale(locale.prefix) do
36
+ site.translate_in(locale.prefix, site.default_locale_prefix)
37
+ end
38
+ end
39
+
40
+ def apply_to_pages
41
+ resources.find_each do |page|
42
+ # the path will be the same as in the default locale
43
+ Maglev::I18n.with_locale(locale.prefix) do
44
+ page.path = default_page_path(page)
45
+ end
46
+
47
+ # set a default content which will be the same as in the default locale
48
+ page.translate_in(locale.prefix, site.default_locale_prefix)
49
+
50
+ page.save!
51
+ end
52
+ end
53
+
54
+ def default_page_path(page)
55
+ # we can't rely on page.default_path because the service can be called outside a HTTP request
56
+ # and so we don't know for sure if Maglev::I18n.default_locale has been correctly set.
57
+ page.paths.find_by(locale: site.default_locale.prefix)&.value
58
+ end
59
+
60
+ def resources
61
+ ::Maglev::Page
62
+ end
63
+ end
64
+ end
@@ -31,6 +31,7 @@ module Maglev
31
31
  dependency :persist_section_screenshot, class: Maglev::PersistSectionScreenshot,
32
32
  depends_on: %i[fetch_theme fetch_section_screenshot_path]
33
33
 
34
+ dependency :add_site_locale, class: Maglev::AddSiteLocale
34
35
  dependency :change_site_locales, class: Maglev::ChangeSiteLocales
35
36
 
36
37
  dependency :fetch_page, class: Maglev::FetchPage, depends_on: :fetch_site
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Maglev
4
4
  # Change the locales of a site.
5
- # The new locales are an array of maps with 2 required keys: :name & :prefix.
5
+ # The new locales are an array of Maglev::Site::Locale objects
6
6
  class ChangeSiteLocales
7
7
  include Injectable
8
8
 
@@ -10,6 +10,7 @@ module Maglev
10
10
  argument :locale
11
11
  argument :default_locale
12
12
  argument :fallback_to_default_locale, default: false
13
+ argument :only_visible, default: false
13
14
 
14
15
  def call
15
16
  page = fetch_page(path, locale)
@@ -20,7 +21,12 @@ module Maglev
20
21
  protected
21
22
 
22
23
  def fetch_page(path, locale)
23
- Maglev::Page.by_path(path || 'index', locale).first
24
+ page = pages.by_path(path || 'index', locale).first
25
+ !only_visible || (page&.visible? && only_visible) ? page : nil
26
+ end
27
+
28
+ def pages
29
+ Maglev::Page
24
30
  end
25
31
  end
26
32
  end
@@ -11,7 +11,7 @@ module Maglev
11
11
 
12
12
  def call
13
13
  path = "#{fetch_sections_path.call(theme: theme)}/#{section.category}/#{section.id}.jpg"
14
- absolute ? "#{Rails.root}/public/#{path}" : "/#{path}"
14
+ absolute ? Rails.root.join("public/#{path}").to_s : "/#{path}"
15
15
  end
16
16
  end
17
17
  end
@@ -44,7 +44,7 @@ module Maglev
44
44
 
45
45
  def build_fullpath(base_url, path)
46
46
  fullpath = [base_url]
47
- fullpath.push(locale) unless same_as_default_locale?
47
+ fullpath.push(locale) if prefix_by_default_locale?
48
48
  fullpath.push(path) unless path == 'index' # for SEO purpose)
49
49
  fullpath.push(nil) if fullpath == [nil] # avoid "" as the fullpath
50
50
  fullpath.join('/')
@@ -54,6 +54,10 @@ module Maglev
54
54
  @site ||= fetch_site.call
55
55
  end
56
56
 
57
+ def prefix_by_default_locale?
58
+ !same_as_default_locale?
59
+ end
60
+
57
61
  def same_as_default_locale?
58
62
  locale.to_s == default_locale.to_s
59
63
  end
@@ -29,9 +29,9 @@ module Maglev
29
29
  # the sections_translations attribute is put by the SetupPages service
30
30
  # when we generate a brand new site
31
31
  if page_attributes.key?(:sections_translations)
32
- page.prepare_sections_translations
32
+ page.prepare_sections_translations(theme)
33
33
  else
34
- page.prepare_sections
34
+ page.prepare_sections(theme)
35
35
  end
36
36
 
37
37
  page.save!
@@ -40,15 +40,7 @@ module Maglev
40
40
  def persist_site!
41
41
  return unless can_persist_site?
42
42
 
43
- # the sections_translations attribute is put by the SetupPages service
44
- # when we generate a brand new site
45
- if site_attributes.key?(:sections_translations)
46
- site.attributes = site_attributes
47
- site.prepare_sections_translations
48
- else
49
- site.attributes = site_attributes_with_consistent_sections
50
- site.prepare_sections
51
- end
43
+ assign_sections_to_site
52
44
 
53
45
  site.save!
54
46
  end
@@ -89,5 +81,17 @@ module Maglev
89
81
  site_attributes[:sections_translations].present?
90
82
  )
91
83
  end
84
+
85
+ def assign_sections_to_site
86
+ # the sections_translations attribute is put by the SetupPages service
87
+ # when we generate a brand new site
88
+ if site_attributes.key?(:sections_translations)
89
+ site.attributes = site_attributes
90
+ site.prepare_sections_translations(theme)
91
+ else
92
+ site.attributes = site_attributes_with_consistent_sections
93
+ site.prepare_sections(theme)
94
+ end
95
+ end
92
96
  end
93
97
  end
@@ -5,10 +5,10 @@ module Maglev
5
5
  extend ActiveSupport::Concern
6
6
 
7
7
  included do
8
- after_commit :save_metadata_now, on: :create
9
-
10
8
  has_one_attached :file
11
9
 
10
+ after_commit :save_metadata_now, on: :create, prepend: true
11
+
12
12
  delegate :url, :download, to: :file
13
13
  end
14
14
 
data/lib/maglev/engine.rb CHANGED
@@ -54,7 +54,9 @@ module Maglev
54
54
  urls: ["/#{vite_ruby.config.public_output_dir}"],
55
55
  root: root.join(vite_ruby.config.public_dir),
56
56
  header_rules: [
57
- [:all, { "Access-Control-Allow-Origin": '*' }]
57
+ # rubocop:disable Style/StringHashKeys
58
+ [:all, { 'Access-Control-Allow-Origin' => '*' }]
59
+ # rubocop:enable Style/StringHashKeys
58
60
  ]
59
61
  else
60
62
  # mostly when running the application in production behind NGINX or APACHE
@@ -63,7 +65,9 @@ module Maglev
63
65
  urls: ["/#{vite_ruby.config.public_output_dir}"],
64
66
  root: root.join(vite_ruby.config.public_dir),
65
67
  header_rules: [
66
- [:all, { "Access-Control-Allow-Origin": '*' }]
68
+ # rubocop:disable Style/StringHashKeys
69
+ [:all, { 'Access-Control-Allow-Origin' => '*' }]
70
+ # rubocop:enable Style/StringHashKeys
67
71
  ]
68
72
  end
69
73
  end
data/lib/maglev/errors.rb CHANGED
@@ -4,5 +4,12 @@ module Maglev
4
4
  module Errors
5
5
  class NotAuthorized < StandardError; end
6
6
  class UnknownSection < StandardError; end
7
+
8
+ class UnknownSetting < StandardError
9
+ def initialize(section_id, block_id, setting_id)
10
+ key = [section_id, block_id].compact.join('.')
11
+ super("[#{key}] The #{setting_id} setting is undeclared OR its type is unknown.")
12
+ end
13
+ end
7
14
  end
8
15
  end
@@ -4,6 +4,8 @@ require 'uri'
4
4
 
5
5
  module Maglev
6
6
  class PreviewConstraint
7
+ CRAWLER_USER_AGENTS = /Googlebot|Twitterbot|facebookexternalhit/o.freeze
8
+
7
9
  attr_reader :preview_host
8
10
 
9
11
  def initialize(preview_host: nil)
@@ -11,7 +13,7 @@ module Maglev
11
13
  end
12
14
 
13
15
  def matches?(request)
14
- %i[html xml].include?(request.format.symbol) && (!preview_host || preview_host == request.host)
16
+ (accepted_format?(request) || crawler?(request)) && match_host?(request)
15
17
  end
16
18
 
17
19
  protected
@@ -21,5 +23,17 @@ module Maglev
21
23
 
22
24
  URI.parse(Maglev.config.preview_host).host # make sure we get only the host here
23
25
  end
26
+
27
+ def accepted_format?(request)
28
+ %i[html xml].include?(request.format.symbol)
29
+ end
30
+
31
+ def crawler?(request)
32
+ request.format.symbol.nil? && CRAWLER_USER_AGENTS.match?(request.user_agent)
33
+ end
34
+
35
+ def match_host?(request)
36
+ !preview_host || preview_host == request.host
37
+ end
24
38
  end
25
39
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Maglev
4
- VERSION = '1.2.2'
4
+ VERSION = '1.4.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maglevcms
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Didier Lafforgue
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-08 00:00:00.000000000 Z
11
+ date: 2023-11-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: jbuilder
@@ -56,9 +56,9 @@ dependencies:
56
56
  name: rails
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - "<="
59
+ - - "<"
60
60
  - !ruby/object:Gem::Version
61
- version: '7.1'
61
+ version: '7.2'
62
62
  - - ">="
63
63
  - !ruby/object:Gem::Version
64
64
  version: '6'
@@ -66,9 +66,9 @@ dependencies:
66
66
  prerelease: false
67
67
  version_requirements: !ruby/object:Gem::Requirement
68
68
  requirements:
69
- - - "<="
69
+ - - "<"
70
70
  - !ruby/object:Gem::Version
71
- version: '7.1'
71
+ version: '7.2'
72
72
  - - ">="
73
73
  - !ruby/object:Gem::Version
74
74
  version: '6'
@@ -133,6 +133,7 @@ files:
133
133
  - app/components/maglev/content/link.rb
134
134
  - app/components/maglev/content/select.rb
135
135
  - app/components/maglev/content/text.rb
136
+ - app/components/maglev/content/void.rb
136
137
  - app/components/maglev/page_component.rb
137
138
  - app/components/maglev/section_component.rb
138
139
  - app/components/maglev/tag_helper.rb
@@ -551,7 +552,9 @@ files:
551
552
  - app/frontend/editor/components/kit/color-input/preset-button.vue
552
553
  - app/frontend/editor/components/kit/color-input/preset-dropdown.vue
553
554
  - app/frontend/editor/components/kit/confirmation-button.vue
555
+ - app/frontend/editor/components/kit/divider.vue
554
556
  - app/frontend/editor/components/kit/dropdown.vue
557
+ - app/frontend/editor/components/kit/hint.vue
555
558
  - app/frontend/editor/components/kit/icon-input.vue
556
559
  - app/frontend/editor/components/kit/icon.vue
557
560
  - app/frontend/editor/components/kit/image-input.vue
@@ -625,6 +628,7 @@ files:
625
628
  - app/frontend/editor/locales/editor.en.json
626
629
  - app/frontend/editor/locales/editor.es.json
627
630
  - app/frontend/editor/locales/editor.fr.json
631
+ - app/frontend/editor/locales/editor.pt-BR.json
628
632
  - app/frontend/editor/locales/index.js
629
633
  - app/frontend/editor/main.js
630
634
  - app/frontend/editor/misc/__tests__/utils.spec.js
@@ -719,6 +723,17 @@ files:
719
723
  - app/models/maglev/section/block.rb
720
724
  - app/models/maglev/section/content_concern.rb
721
725
  - app/models/maglev/section/setting.rb
726
+ - app/models/maglev/setting_types/base.rb
727
+ - app/models/maglev/setting_types/checkbox.rb
728
+ - app/models/maglev/setting_types/collection_item.rb
729
+ - app/models/maglev/setting_types/color.rb
730
+ - app/models/maglev/setting_types/divider.rb
731
+ - app/models/maglev/setting_types/hint.rb
732
+ - app/models/maglev/setting_types/icon.rb
733
+ - app/models/maglev/setting_types/image.rb
734
+ - app/models/maglev/setting_types/link.rb
735
+ - app/models/maglev/setting_types/select.rb
736
+ - app/models/maglev/setting_types/text.rb
722
737
  - app/models/maglev/site.rb
723
738
  - app/models/maglev/site/locale.rb
724
739
  - app/models/maglev/site/locales_concern.rb
@@ -730,6 +745,7 @@ files:
730
745
  - app/services/concerns/maglev/get_page_sections/transform_collection_item_concern.rb
731
746
  - app/services/concerns/maglev/get_page_sections/transform_link_concern.rb
732
747
  - app/services/concerns/maglev/get_page_sections/transform_text_concern.rb
748
+ - app/services/maglev/add_site_locale.rb
733
749
  - app/services/maglev/app_container.rb
734
750
  - app/services/maglev/change_site_locales.rb
735
751
  - app/services/maglev/clone_page.rb
@@ -845,7 +861,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
845
861
  - !ruby/object:Gem::Version
846
862
  version: '0'
847
863
  requirements: []
848
- rubygems_version: 3.2.32
864
+ rubygems_version: 3.3.26
849
865
  signing_key:
850
866
  specification_version: 4
851
867
  summary: Page builder Ruby on Rails