maglevcms 1.1.6 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/app/components/maglev/content/image.rb +2 -0
  3. data/app/controllers/concerns/maglev/fetchers_concern.rb +1 -0
  4. data/app/controllers/concerns/maglev/standalone_sections_concern.rb +6 -0
  5. data/app/controllers/maglev/sitemap_controller.rb +31 -0
  6. data/app/frontend/editor/assets/remixicons/ri-palette-line.svg +1 -0
  7. data/app/frontend/editor/components/dynamic-form/dynamic-input.vue +2 -1
  8. data/app/frontend/editor/components/header-nav/publish-button.vue +1 -1
  9. data/app/frontend/editor/components/kit/collection-item-input.vue +5 -2
  10. data/app/frontend/editor/components/kit/color-input/core-input.vue +85 -0
  11. data/app/frontend/editor/components/kit/color-input/preset-button.vue +57 -0
  12. data/app/frontend/editor/components/kit/color-input/preset-dropdown.vue +46 -0
  13. data/app/frontend/editor/components/kit/color-input.vue +43 -0
  14. data/app/frontend/editor/components/kit/dropdown.vue +1 -0
  15. data/app/frontend/editor/components/kit/index.js +2 -2
  16. data/app/frontend/editor/components/kit/submit-button.vue +3 -3
  17. data/app/frontend/editor/components/kit/tabs.vue +2 -1
  18. data/app/frontend/editor/components/kit/text-input.vue +2 -2
  19. data/app/frontend/editor/misc/utils.js +32 -2
  20. data/app/frontend/editor/services/api.js +2 -2
  21. data/app/frontend/editor/spec/__mocks__/page.js +36 -36
  22. data/app/frontend/editor/spec/__mocks__/section.js +29 -29
  23. data/app/helpers/maglev/editor_helper.rb +1 -1
  24. data/app/helpers/maglev/page_preview_helper.rb +5 -1
  25. data/app/helpers/maglev/sitemap_helper.rb +13 -0
  26. data/app/models/concerns/maglev/sections_concern.rb +10 -0
  27. data/app/models/maglev/page/path_concern.rb +8 -1
  28. data/app/models/maglev/section/setting.rb +5 -0
  29. data/app/models/maglev/site/locales_concern.rb +8 -0
  30. data/app/services/concerns/maglev/get_page_sections/transform_collection_item_concern.rb +8 -1
  31. data/app/services/maglev/app_container.rb +2 -0
  32. data/app/services/maglev/fetch_collection_items.rb +6 -2
  33. data/app/services/maglev/persist_page.rb +23 -4
  34. data/app/services/maglev/setup_pages.rb +41 -5
  35. data/app/views/maglev/api/pages/_show.json.jbuilder +1 -2
  36. data/app/views/maglev/sitemap/index.xml.builder +21 -0
  37. data/config/routes.rb +1 -0
  38. data/db/migrate/20210830085101_create_maglev_page_paths.rb +1 -1
  39. data/db/migrate/20210906102712_add_canonical_to_pages.rb +1 -1
  40. data/db/migrate/20211008064437_add_locales_to_sites.rb +1 -1
  41. data/db/migrate/20211013210954_translate_section_content.rb +1 -1
  42. data/db/migrate/20211101205001_add_lock_version_to_maglev_pages.rb +1 -1
  43. data/db/migrate/20211116161121_better_page_path_canonical_indices.rb +1 -1
  44. data/db/migrate/20211124101005_fix_page_path_indices.rb +1 -1
  45. data/db/migrate/20211203224112_add_open_graph_tags_to_pages.rb +1 -1
  46. data/db/migrate/20220612092235_add_style_to_sites.rb +1 -1
  47. data/lib/generators/maglev/install_generator.rb +3 -2
  48. data/lib/generators/maglev/section_generator.rb +2 -1
  49. data/lib/generators/maglev/templates/section/app/theme/sections/%category%/%file_name%.yml.tt +13 -9
  50. data/lib/maglev/engine.rb +8 -2
  51. data/lib/maglev/version.rb +1 -1
  52. data/package.json +3 -3
  53. data/yarn.lock +799 -565
  54. metadata +14 -7
  55. data/app/frontend/editor/components/kit/color-picker.vue +0 -81
  56. /data/app/frontend/editor/assets/remixicons/{check-line.svg → ri-check-line.svg} +0 -0
@@ -9,7 +9,7 @@ export const pageSections = [
9
9
  settings: [
10
10
  {
11
11
  id: 'link',
12
- value: { href: '#', text: 'Home', link_type: 'url' },
12
+ value: { href: '#', text: 'Home', linkType: 'url' },
13
13
  },
14
14
  ],
15
15
  },
@@ -19,7 +19,7 @@ export const pageSections = [
19
19
  settings: [
20
20
  {
21
21
  id: 'link',
22
- value: { href: '#', text: 'About us', link_type: 'url' },
22
+ value: { href: '#', text: 'About us', linkType: 'url' },
23
23
  },
24
24
  ],
25
25
  },
@@ -33,11 +33,11 @@ export const pageSections = [
33
33
  href: '//contact',
34
34
  text: 'Contact',
35
35
  email: null,
36
- link_id: 9,
37
- link_type: 'page',
38
- link_label: 'Contact us',
39
- section_id: null,
40
- open_new_window: false,
36
+ linkId: 9,
37
+ linkType: 'page',
38
+ linkLabel: 'Contact us',
39
+ sectionId: null,
40
+ openNewWindow: false,
41
41
  },
42
42
  },
43
43
  ],
@@ -52,11 +52,11 @@ export const pageSections = [
52
52
  href: '/products',
53
53
  text: 'Products #1',
54
54
  email: null,
55
- link_id: 'd870133f9a075477a96a58e7639d40c5',
56
- link_type: 'page',
57
- link_label: 'Products',
58
- section_id: null,
59
- open_new_window: true,
55
+ linkId: 'd870133f9a075477a96a58e7639d40c5',
56
+ linkType: 'page',
57
+ linkLabel: 'Products',
58
+ sectionId: null,
59
+ openNewWindow: true,
60
60
  },
61
61
  },
62
62
  ],
@@ -71,7 +71,7 @@ export const pageSections = [
71
71
  width: 572,
72
72
  height: 290,
73
73
  filename: 'Screen Shot 2021-06-30 at 3.44.04 PM.png',
74
- byte_size: 35070,
74
+ byteSize: 35070,
75
75
  },
76
76
  },
77
77
  ],
@@ -96,7 +96,7 @@ export const pageSections = [
96
96
  width: 516,
97
97
  height: 320,
98
98
  filename: 'img-91-3.jpg',
99
- byte_size: 41683,
99
+ byteSize: 41683,
100
100
  },
101
101
  },
102
102
  { id: 'button', value: { url: '#', text: 'Click here' } },
@@ -119,7 +119,7 @@ export const pageSections = [
119
119
  width: 1920,
120
120
  height: 1200,
121
121
  filename: 'img-97.jpg',
122
- byte_size: 458107,
122
+ byteSize: 458107,
123
123
  },
124
124
  },
125
125
  ],
@@ -137,7 +137,7 @@ export const pageSections = [
137
137
  width: 516,
138
138
  height: 400,
139
139
  filename: 'inner-74-2.jpg',
140
- byte_size: 63881,
140
+ byteSize: 63881,
141
141
  },
142
142
  },
143
143
  ],
@@ -155,7 +155,7 @@ export const pageSections = [
155
155
  width: 516,
156
156
  height: 320,
157
157
  filename: 'img-91-4.jpg',
158
- byte_size: 21808,
158
+ byteSize: 21808,
159
159
  },
160
160
  },
161
161
  ],
@@ -173,7 +173,7 @@ export const pageSections = [
173
173
  width: 1920,
174
174
  height: 1200,
175
175
  filename: 'img-91.jpg',
176
- byte_size: 180178,
176
+ byteSize: 180178,
177
177
  },
178
178
  },
179
179
  ],
@@ -220,7 +220,7 @@ export const normalizedPage = {
220
220
  id: 'RiEo8C3f',
221
221
  type: 'navbar_item',
222
222
  settings: [
223
- { id: 'link', value: { href: '#', text: 'Home', link_type: 'url' } },
223
+ { id: 'link', value: { href: '#', text: 'Home', linkType: 'url' } },
224
224
  ],
225
225
  },
226
226
  P1fGieWs: {
@@ -229,7 +229,7 @@ export const normalizedPage = {
229
229
  settings: [
230
230
  {
231
231
  id: 'link',
232
- value: { href: '#', text: 'About us', link_type: 'url' },
232
+ value: { href: '#', text: 'About us', linkType: 'url' },
233
233
  },
234
234
  ],
235
235
  },
@@ -243,11 +243,11 @@ export const normalizedPage = {
243
243
  href: '//contact',
244
244
  text: 'Contact',
245
245
  email: null,
246
- link_id: 9,
247
- link_type: 'page',
248
- link_label: 'Contact us',
249
- section_id: null,
250
- open_new_window: false,
246
+ linkId: 9,
247
+ linkType: 'page',
248
+ linkLabel: 'Contact us',
249
+ sectionId: null,
250
+ openNewWindow: false,
251
251
  },
252
252
  },
253
253
  ],
@@ -262,11 +262,11 @@ export const normalizedPage = {
262
262
  href: '/products',
263
263
  text: 'Products #1',
264
264
  email: null,
265
- link_id: 'd870133f9a075477a96a58e7639d40c5',
266
- link_type: 'page',
267
- link_label: 'Products',
268
- section_id: null,
269
- open_new_window: true,
265
+ linkId: 'd870133f9a075477a96a58e7639d40c5',
266
+ linkType: 'page',
267
+ linkLabel: 'Products',
268
+ sectionId: null,
269
+ openNewWindow: true,
270
270
  },
271
271
  },
272
272
  ],
@@ -284,7 +284,7 @@ export const normalizedPage = {
284
284
  width: 1920,
285
285
  height: 1200,
286
286
  filename: 'img-97.jpg',
287
- byte_size: 458107,
287
+ byteSize: 458107,
288
288
  },
289
289
  },
290
290
  ],
@@ -302,7 +302,7 @@ export const normalizedPage = {
302
302
  width: 516,
303
303
  height: 400,
304
304
  filename: 'inner-74-2.jpg',
305
- byte_size: 63881,
305
+ byteSize: 63881,
306
306
  },
307
307
  },
308
308
  ],
@@ -320,7 +320,7 @@ export const normalizedPage = {
320
320
  width: 516,
321
321
  height: 320,
322
322
  filename: 'img-91-4.jpg',
323
- byte_size: 21808,
323
+ byteSize: 21808,
324
324
  },
325
325
  },
326
326
  ],
@@ -338,7 +338,7 @@ export const normalizedPage = {
338
338
  width: 1920,
339
339
  height: 1200,
340
340
  filename: 'img-91.jpg',
341
- byte_size: 180178,
341
+ byteSize: 180178,
342
342
  },
343
343
  },
344
344
  ],
@@ -358,7 +358,7 @@ export const normalizedPage = {
358
358
  width: 572,
359
359
  height: 290,
360
360
  filename: 'Screen Shot 2021-06-30 at 3.44.04 PM.png',
361
- byte_size: 35070,
361
+ byteSize: 35070,
362
362
  },
363
363
  },
364
364
  ],
@@ -383,7 +383,7 @@ export const normalizedPage = {
383
383
  width: 516,
384
384
  height: 320,
385
385
  filename: 'img-91-3.jpg',
386
- byte_size: 41683,
386
+ byteSize: 41683,
387
387
  },
388
388
  },
389
389
  { id: 'button', value: { url: '#', text: 'Click here' } },
@@ -18,7 +18,7 @@ export const simpleContentSection = {
18
18
  width: 516,
19
19
  height: 320,
20
20
  filename: 'img-91-3.jpg',
21
- byte_size: 41683,
21
+ byteSize: 41683,
22
22
  },
23
23
  },
24
24
  { id: 'button', value: { url: '#', text: 'Click here' } },
@@ -48,7 +48,7 @@ export const normalizedSimpleContentSection = {
48
48
  width: 516,
49
49
  height: 320,
50
50
  filename: 'img-91-3.jpg',
51
- byte_size: 41683,
51
+ byteSize: 41683,
52
52
  },
53
53
  },
54
54
  { id: 'button', value: { url: '#', text: 'Click here' } },
@@ -69,7 +69,7 @@ export const navContentSection = {
69
69
  settings: [
70
70
  {
71
71
  id: 'link',
72
- value: { href: '#', text: 'Home', link_type: 'url' },
72
+ value: { href: '#', text: 'Home', linkType: 'url' },
73
73
  },
74
74
  ],
75
75
  },
@@ -79,7 +79,7 @@ export const navContentSection = {
79
79
  settings: [
80
80
  {
81
81
  id: 'link',
82
- value: { href: '#', text: 'About us', link_type: 'url' },
82
+ value: { href: '#', text: 'About us', linkType: 'url' },
83
83
  },
84
84
  ],
85
85
  },
@@ -93,11 +93,11 @@ export const navContentSection = {
93
93
  href: '//contact',
94
94
  text: 'Contact',
95
95
  email: null,
96
- link_id: 9,
97
- link_type: 'page',
98
- link_label: 'Contact us',
99
- section_id: null,
100
- open_new_window: false,
96
+ linkId: 9,
97
+ linkType: 'page',
98
+ linkLabel: 'Contact us',
99
+ sectionId: null,
100
+ openNewWindow: false,
101
101
  },
102
102
  },
103
103
  ],
@@ -112,11 +112,11 @@ export const navContentSection = {
112
112
  href: '/products',
113
113
  text: 'Products #1',
114
114
  email: null,
115
- link_id: 'd870133f9a075477a96a58e7639d40c5',
116
- link_type: 'page',
117
- link_label: 'Products',
118
- section_id: null,
119
- open_new_window: true,
115
+ linkId: 'd870133f9a075477a96a58e7639d40c5',
116
+ linkType: 'page',
117
+ linkLabel: 'Products',
118
+ sectionId: null,
119
+ openNewWindow: true,
120
120
  },
121
121
  },
122
122
  ],
@@ -131,7 +131,7 @@ export const navContentSection = {
131
131
  width: 572,
132
132
  height: 290,
133
133
  filename: 'Screen Shot 2021-06-30 at 3.44.04 PM.png',
134
- byte_size: 35070,
134
+ byteSize: 35070,
135
135
  },
136
136
  },
137
137
  ],
@@ -144,7 +144,7 @@ export const normalizedNavContentSection = {
144
144
  id: 'RiEo8C3f',
145
145
  type: 'navbar_item',
146
146
  settings: [
147
- { id: 'link', value: { href: '#', text: 'Home', link_type: 'url' } },
147
+ { id: 'link', value: { href: '#', text: 'Home', linkType: 'url' } },
148
148
  ],
149
149
  },
150
150
  P1fGieWs: {
@@ -153,7 +153,7 @@ export const normalizedNavContentSection = {
153
153
  settings: [
154
154
  {
155
155
  id: 'link',
156
- value: { href: '#', text: 'About us', link_type: 'url' },
156
+ value: { href: '#', text: 'About us', linkType: 'url' },
157
157
  },
158
158
  ],
159
159
  },
@@ -167,11 +167,11 @@ export const normalizedNavContentSection = {
167
167
  href: '//contact',
168
168
  text: 'Contact',
169
169
  email: null,
170
- link_id: 9,
171
- link_type: 'page',
172
- link_label: 'Contact us',
173
- section_id: null,
174
- open_new_window: false,
170
+ linkId: 9,
171
+ linkType: 'page',
172
+ linkLabel: 'Contact us',
173
+ sectionId: null,
174
+ openNewWindow: false,
175
175
  },
176
176
  },
177
177
  ],
@@ -186,11 +186,11 @@ export const normalizedNavContentSection = {
186
186
  href: '/products',
187
187
  text: 'Products #1',
188
188
  email: null,
189
- link_id: 'd870133f9a075477a96a58e7639d40c5',
190
- link_type: 'page',
191
- link_label: 'Products',
192
- section_id: null,
193
- open_new_window: true,
189
+ linkId: 'd870133f9a075477a96a58e7639d40c5',
190
+ linkType: 'page',
191
+ linkLabel: 'Products',
192
+ sectionId: null,
193
+ openNewWindow: true,
194
194
  },
195
195
  },
196
196
  ],
@@ -210,7 +210,7 @@ export const normalizedNavContentSection = {
210
210
  width: 572,
211
211
  height: 290,
212
212
  filename: 'Screen Shot 2021-06-30 at 3.44.04 PM.png',
213
- byte_size: 35070,
213
+ byteSize: 35070,
214
214
  },
215
215
  },
216
216
  ],
@@ -226,7 +226,7 @@ export const navContentSectionBlock = {
226
226
  settings: [
227
227
  {
228
228
  id: 'link',
229
- value: { href: '#', text: 'Foo', link_type: 'url' },
229
+ value: { href: '#', text: 'Foo', linkType: 'url' },
230
230
  },
231
231
  ],
232
232
  }
@@ -16,7 +16,7 @@ module Maglev
16
16
  end
17
17
 
18
18
  def api_base_path
19
- "#{root_path}api"
19
+ api_root_path
20
20
  end
21
21
 
22
22
  def editor_window_title
@@ -16,11 +16,15 @@ module Maglev
16
16
  # rubocop:enable Rails/OutputSafety
17
17
 
18
18
  def render_maglev_section(type, site: nil, theme: nil, page: nil, page_sections: nil)
19
+ sections = (page_sections || maglev_page_sections).find_all do |section|
20
+ (section['type'] || section[:type]).start_with?(type.to_s)
21
+ end
22
+
19
23
  render_maglev_sections(
20
24
  site: site,
21
25
  theme: theme,
22
26
  page: page,
23
- page_sections: (page_sections || maglev_page_sections).find_all { |section| section['type'] == type.to_s }
27
+ page_sections: sections
24
28
  )
25
29
  end
26
30
 
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Maglev
4
+ module SitemapHelper
5
+ def sitemap_url(host, page, locale = nil)
6
+ path = maglev_services.get_page_fullpath.call(page: page, locale: locale)
7
+
8
+ return path if path =~ %r{^https?://}
9
+
10
+ [host, path].join
11
+ end
12
+ end
13
+ end
@@ -11,6 +11,16 @@ module Maglev::SectionsConcern
11
11
  end
12
12
  end
13
13
 
14
+ def prepare_sections_translations
15
+ return if sections_translations.blank?
16
+
17
+ sections_translations.each_key do |locale|
18
+ Maglev::I18n.with_locale(locale) do
19
+ prepare_sections
20
+ end
21
+ end
22
+ end
23
+
14
24
  private
15
25
 
16
26
  def prepare_section(section)
@@ -27,7 +27,14 @@ module Maglev::Page::PathConcern
27
27
  end
28
28
 
29
29
  def path=(value)
30
- current_path.value = value
30
+ unless value.respond_to?(:each_pair)
31
+ current_path.value = value
32
+ return
33
+ end
34
+
35
+ value.each_pair do |locale, new_path|
36
+ Maglev::I18n.with_locale(locale) { self.path = new_path }
37
+ end
31
38
  end
32
39
 
33
40
  def current_path
@@ -21,6 +21,7 @@ class Maglev::Section::Setting
21
21
  when :image then build_default_image_content(default)
22
22
  when :link then build_default_link_content(default)
23
23
  when :checkbox then build_default_checkbox_content(default)
24
+ when :collection_item then build_default_collection_item_content(default)
24
25
  else
25
26
  default || label
26
27
  end
@@ -42,6 +43,10 @@ class Maglev::Section::Setting
42
43
  default.presence || false
43
44
  end
44
45
 
46
+ def build_default_collection_item_content(default)
47
+ { id: default }
48
+ end
49
+
45
50
  ## class methods ##
46
51
  def self.build(hash)
47
52
  attributes = hash.slice('id', 'label', 'type', 'default')
@@ -24,6 +24,14 @@ module Maglev::Site::LocalesConcern
24
24
  locales.map { |locale| locale.prefix.to_sym }
25
25
  end
26
26
 
27
+ def each_locale
28
+ locale_prefixes.each do |locale|
29
+ Maglev::I18n.with_locale(locale) do
30
+ yield(locale)
31
+ end
32
+ end
33
+ end
34
+
27
35
  class LocalesSerializer
28
36
  def self.dump(array)
29
37
  (array || []).map(&:as_json)
@@ -3,7 +3,12 @@
3
3
  # rubocop:disable Style/ClassAndModuleChildren
4
4
  module Maglev::GetPageSections::TransformCollectionItemConcern
5
5
  def transform_collection_item_content_setting(content, setting)
6
- item_id = content.dig('value', 'id')
6
+ # the content might come from the default value of the collection_item setting
7
+ # rubocop:disable Style/StringHashKeys
8
+ content['value'] = { 'id' => 'any' } if content&.dig('value') == 'any'
9
+ # rubocop:enable Style/StringHashKeys
10
+
11
+ item_id = content&.dig('value', 'id')
7
12
  return if item_id.blank?
8
13
 
9
14
  item = fetch_collection_items.call(
@@ -11,6 +16,8 @@ module Maglev::GetPageSections::TransformCollectionItemConcern
11
16
  id: item_id
12
17
  )
13
18
 
19
+ return unless item
20
+
14
21
  content['value']['label'] = item.label
15
22
  content['value']['item'] = item.source
16
23
  end
@@ -31,6 +31,8 @@ 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 :change_site_locales, class: Maglev::ChangeSiteLocales
35
+
34
36
  dependency :fetch_page, class: Maglev::FetchPage, depends_on: :fetch_site
35
37
  dependency :get_page_fullpath, class: Maglev::GetPageFullpath, depends_on: %i[fetch_site get_base_url]
36
38
  dependency :get_page_sections, class: Maglev::GetPageSections,
@@ -33,7 +33,7 @@ module Maglev
33
33
 
34
34
  def fetch_item
35
35
  build_item(
36
- fetch_original_items.find_by(id: id)
36
+ id == 'any' ? fetch_original_items.first : fetch_original_items.find_by(id: id)
37
37
  )
38
38
  end
39
39
 
@@ -78,7 +78,11 @@ module Maglev
78
78
  end
79
79
 
80
80
  def collection
81
- config.collections[collection_id.to_sym]
81
+ config.collections[collection_id.to_sym].tap do |collection|
82
+ next if collection
83
+
84
+ raise "[Maglev] unregistered '#{collection_id}' collection in the Maglev configuration."
85
+ end
82
86
  end
83
87
 
84
88
  def build_item(original_item)
@@ -25,15 +25,31 @@ module Maglev
25
25
 
26
26
  def persist_page!
27
27
  page.attributes = page_attributes
28
- page.prepare_sections
28
+
29
+ # the sections_translations attribute is put by the SetupPages service
30
+ # when we generate a brand new site
31
+ if page_attributes.key?(:sections_translations)
32
+ page.prepare_sections_translations
33
+ else
34
+ page.prepare_sections
35
+ end
36
+
29
37
  page.save!
30
38
  end
31
39
 
32
40
  def persist_site!
33
41
  return unless can_persist_site?
34
42
 
35
- site.attributes = site_attributes_with_consistent_sections
36
- site.prepare_sections
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
52
+
37
53
  site.save!
38
54
  end
39
55
 
@@ -68,7 +84,10 @@ module Maglev
68
84
  end
69
85
 
70
86
  def can_persist_site?
71
- site_attributes.present? && site_attributes[:sections].present?
87
+ site_attributes.present? && (
88
+ site_attributes[:sections].present? ||
89
+ site_attributes[:sections_translations].present?
90
+ )
72
91
  end
73
92
  end
74
93
  end
@@ -13,7 +13,9 @@ module Maglev
13
13
 
14
14
  def call
15
15
  pages&.map do |page_attributes|
16
- create_page(page_attributes)
16
+ create_page(
17
+ attributes_in_all_locales(page_attributes.with_indifferent_access)
18
+ )
17
19
  end
18
20
  end
19
21
 
@@ -34,12 +36,46 @@ module Maglev
34
36
  end
35
37
 
36
38
  def site_attributes_from(page_attributes)
39
+ if page_attributes.include?(:sections_translations)
40
+ { sections_translations: site_sections_translations(page_attributes) }
41
+ else
42
+ { sections: select_site_scoped_sections(page_attributes[:sections]) }
43
+ end.compact || {}
44
+ end
45
+
46
+ def site_sections_translations(page_attributes)
47
+ sections_translations = page_attributes[:sections_translations].transform_values do |sections|
48
+ select_site_scoped_sections(sections)
49
+ end
50
+ sections_translations.any? { |_, sections| sections.blank? } ? nil : sections_translations
51
+ end
52
+
53
+ def attributes_in_all_locales(attributes)
37
54
  {
38
- sections: (page_attributes[:sections] || []).find_all do |section|
39
- definition = theme.sections.find(section['type'])
40
- definition.site_scoped?
41
- end
55
+ title_translations: value_in_all_locales(attributes[:title]),
56
+ sections_translations: value_in_all_locales(attributes[:sections]),
57
+ path: value_in_all_locales(attributes[:path])
42
58
  }
43
59
  end
60
+
61
+ def value_in_all_locales(value)
62
+ if value.respond_to?(:each_pair)
63
+ default_value = value[site.default_locale_prefix]
64
+ fill_translations(default_value).merge(value)
65
+ else
66
+ fill_translations(value)
67
+ end
68
+ end
69
+
70
+ def fill_translations(value)
71
+ site.locale_prefixes.index_with { |_locale| value }
72
+ end
73
+
74
+ def select_site_scoped_sections(sections)
75
+ (sections || []).find_all do |section|
76
+ definition = theme.sections.find(section['type'])
77
+ definition.site_scoped?
78
+ end
79
+ end
44
80
  end
45
81
  end
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- json.sections services.get_page_sections.call(page: page)
4
-
5
3
  json.key_format! camelize: :lower
6
4
  json.deep_format_keys!
7
5
 
@@ -20,5 +18,6 @@ json.og_image_url page.og_image_url
20
18
  json.preview_url services.get_page_fullpath.call(page: page, preview_mode: true, locale: content_locale)
21
19
  json.live_url services.get_page_fullpath.call(page: page, preview_mode: false, locale: content_locale)
22
20
  json.section_names services.get_page_section_names.call(page: page)
21
+ json.sections services.get_page_sections.call(page: page)
23
22
  json.lock_version page.lock_version
24
23
  json.translated page.path.present?
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ xml.instruct!
4
+
5
+ xml.urlset xmlns: 'http://www.google.com/schemas/sitemap/0.9', "xmlns:xhtml": 'http://www.w3.org/1999/xhtml' do
6
+ @pages.each do |page|
7
+ xml.url do
8
+ xml.loc sitemap_url(@host, page, maglev_site.default_locale_prefix)
9
+ xml.lastmod page.updated_at.strftime('%Y-%m-%d')
10
+
11
+ if maglev_site.locales.size > 1
12
+ maglev_site.locales.each do |locale|
13
+ xml.xhtml :link,
14
+ rel: 'alternate',
15
+ hreflang: locale.prefix,
16
+ href: sitemap_url(@host, page, locale.prefix)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
data/config/routes.rb CHANGED
@@ -5,6 +5,7 @@ Maglev::Engine.routes.draw do
5
5
  # API
6
6
  constraints format: :json do
7
7
  namespace :api do
8
+ root to: proc { [200, {}, ['{}']] }
8
9
  resource :site, only: :show
9
10
  resources :pages do
10
11
  resources :clones, controller: :page_clones, only: :create
@@ -1,4 +1,4 @@
1
- class CreateMaglevPagePaths < ActiveRecord::Migration[6.1]
1
+ class CreateMaglevPagePaths < ActiveRecord::Migration[6.0]
2
2
  def change
3
3
  create_table :maglev_page_paths do |t|
4
4
  t.references :maglev_page