alchemy_cms 7.0.0.pre.a → 7.0.0.pre.b

Sign up to get free protection for your applications and to get access to all the features.
Files changed (199) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/brakeman-analysis.yml +2 -2
  3. data/.github/workflows/ci.yml +7 -7
  4. data/.github/workflows/lint.yml +17 -0
  5. data/.hound.yml +2 -3
  6. data/.rubocop.yml +4 -350
  7. data/.standard.yml +3 -0
  8. data/CHANGELOG.md +29 -0
  9. data/Gemfile +3 -1
  10. data/README.md +7 -9
  11. data/Rakefile +1 -1
  12. data/alchemy_cms.gemspec +2 -1
  13. data/app/assets/javascripts/alchemy/admin.js +0 -1
  14. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +6 -1
  15. data/app/components/alchemy/ingredients/audio_view.rb +37 -0
  16. data/app/components/alchemy/ingredients/base_view.rb +38 -0
  17. data/app/components/alchemy/ingredients/boolean_view.rb +13 -0
  18. data/app/components/alchemy/ingredients/datetime_view.rb +22 -0
  19. data/app/components/alchemy/ingredients/file_view.rb +40 -0
  20. data/app/components/alchemy/ingredients/headline_view.rb +20 -0
  21. data/app/components/alchemy/ingredients/html_view.rb +9 -0
  22. data/app/components/alchemy/ingredients/link_view.rb +25 -0
  23. data/app/components/alchemy/ingredients/node_view.rb +11 -0
  24. data/app/components/alchemy/ingredients/page_view.rb +15 -0
  25. data/app/components/alchemy/ingredients/picture_view.rb +108 -0
  26. data/app/components/alchemy/ingredients/richtext_view.rb +22 -0
  27. data/app/components/alchemy/ingredients/select_view.rb +6 -0
  28. data/app/components/alchemy/ingredients/text_view.rb +41 -0
  29. data/app/components/alchemy/ingredients/video_view.rb +39 -0
  30. data/app/controllers/alchemy/admin/attachments_controller.rb +3 -3
  31. data/app/controllers/alchemy/admin/base_controller.rb +7 -7
  32. data/app/controllers/alchemy/admin/clipboard_controller.rb +2 -2
  33. data/app/controllers/alchemy/admin/elements_controller.rb +26 -11
  34. data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
  35. data/app/controllers/alchemy/admin/nodes_controller.rb +2 -2
  36. data/app/controllers/alchemy/admin/pages_controller.rb +10 -10
  37. data/app/controllers/alchemy/admin/pictures_controller.rb +14 -14
  38. data/app/controllers/alchemy/admin/resources_controller.rb +27 -28
  39. data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
  40. data/app/controllers/alchemy/admin/tags_controller.rb +11 -11
  41. data/app/controllers/alchemy/api/base_controller.rb +2 -2
  42. data/app/controllers/alchemy/api/elements_controller.rb +11 -11
  43. data/app/controllers/alchemy/api/ingredients_controller.rb +1 -1
  44. data/app/controllers/alchemy/api/nodes_controller.rb +1 -1
  45. data/app/controllers/alchemy/api/pages_controller.rb +11 -11
  46. data/app/controllers/alchemy/attachments_controller.rb +3 -3
  47. data/app/controllers/alchemy/base_controller.rb +1 -1
  48. data/app/controllers/alchemy/messages_controller.rb +9 -9
  49. data/app/controllers/alchemy/pages_controller.rb +8 -19
  50. data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +1 -0
  51. data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -7
  52. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +5 -5
  53. data/app/decorators/alchemy/element_editor.rb +4 -4
  54. data/app/decorators/alchemy/ingredient_editor.rb +6 -6
  55. data/app/helpers/alchemy/admin/attachments_helper.rb +1 -1
  56. data/app/helpers/alchemy/admin/base_helper.rb +21 -22
  57. data/app/helpers/alchemy/admin/elements_helper.rb +1 -1
  58. data/app/helpers/alchemy/admin/form_helper.rb +1 -1
  59. data/app/helpers/alchemy/admin/navigation_helper.rb +7 -7
  60. data/app/helpers/alchemy/admin/pages_helper.rb +2 -2
  61. data/app/helpers/alchemy/admin/tags_helper.rb +3 -3
  62. data/app/helpers/alchemy/base_helper.rb +2 -2
  63. data/app/helpers/alchemy/elements_block_helper.rb +9 -7
  64. data/app/helpers/alchemy/elements_helper.rb +12 -12
  65. data/app/helpers/alchemy/pages_helper.rb +11 -11
  66. data/app/helpers/alchemy/url_helper.rb +1 -1
  67. data/app/mailers/alchemy/messages_mailer.rb +1 -1
  68. data/app/models/alchemy/attachment.rb +6 -6
  69. data/app/models/alchemy/base_record.rb +1 -0
  70. data/app/models/alchemy/eager_loading.rb +6 -6
  71. data/app/models/alchemy/element/definitions.rb +1 -1
  72. data/app/models/alchemy/element/element_ingredients.rb +3 -3
  73. data/app/models/alchemy/element.rb +2 -2
  74. data/app/models/alchemy/elements_repository.rb +1 -1
  75. data/app/models/alchemy/image_cropper_settings.rb +2 -2
  76. data/app/models/alchemy/ingredient.rb +14 -12
  77. data/app/models/alchemy/ingredient_validator.rb +1 -1
  78. data/app/models/alchemy/ingredients/datetime.rb +1 -1
  79. data/app/models/alchemy/ingredients/file.rb +5 -5
  80. data/app/models/alchemy/ingredients/headline.rb +4 -4
  81. data/app/models/alchemy/ingredients/picture.rb +27 -9
  82. data/app/models/alchemy/ingredients/richtext.rb +15 -12
  83. data/app/models/alchemy/ingredients/text.rb +6 -6
  84. data/app/models/alchemy/language/code.rb +1 -1
  85. data/app/models/alchemy/language.rb +4 -4
  86. data/app/models/alchemy/legacy_page_url.rb +1 -1
  87. data/app/models/alchemy/node.rb +2 -2
  88. data/app/models/alchemy/page/page_elements.rb +14 -14
  89. data/app/models/alchemy/page/page_naming.rb +4 -4
  90. data/app/models/alchemy/page/page_natures.rb +1 -1
  91. data/app/models/alchemy/page/page_scopes.rb +5 -5
  92. data/app/models/alchemy/page.rb +11 -11
  93. data/app/models/alchemy/picture/calculations.rb +2 -2
  94. data/app/models/alchemy/picture/transformations.rb +2 -2
  95. data/app/models/alchemy/picture/url.rb +4 -4
  96. data/app/models/alchemy/picture.rb +11 -10
  97. data/app/models/alchemy/picture_thumb/create.rb +1 -1
  98. data/app/models/alchemy/picture_thumb.rb +1 -1
  99. data/app/models/alchemy/picture_variant.rb +2 -3
  100. data/app/models/alchemy/tag.rb +8 -0
  101. data/app/models/concerns/alchemy/picture_thumbnails.rb +6 -6
  102. data/app/serializers/alchemy/base_serializer.rb +1 -1
  103. data/app/serializers/alchemy/page_tree_serializer.rb +7 -7
  104. data/app/services/alchemy/duplicate_element.rb +3 -3
  105. data/app/services/alchemy/tag_validations.rb +1 -1
  106. data/app/views/alchemy/admin/elements/_element.html.erb +3 -0
  107. data/app/views/alchemy/admin/pages/edit.html.erb +0 -3
  108. data/app/views/alchemy/admin/pages/update.js.erb +10 -4
  109. data/app/views/alchemy/admin/pictures/_infos.html.erb +1 -1
  110. data/app/views/alchemy/ingredients/_audio_view.html.erb +1 -14
  111. data/app/views/alchemy/ingredients/_boolean_view.html.erb +1 -1
  112. data/app/views/alchemy/ingredients/_datetime_view.html.erb +3 -9
  113. data/app/views/alchemy/ingredients/_file_view.html.erb +3 -16
  114. data/app/views/alchemy/ingredients/_headline_view.html.erb +4 -10
  115. data/app/views/alchemy/ingredients/_html_view.html.erb +1 -1
  116. data/app/views/alchemy/ingredients/_link_view.html.erb +4 -9
  117. data/app/views/alchemy/ingredients/_node_view.html.erb +1 -1
  118. data/app/views/alchemy/ingredients/_page_view.html.erb +1 -4
  119. data/app/views/alchemy/ingredients/_picture_view.html.erb +4 -5
  120. data/app/views/alchemy/ingredients/_richtext_editor.html.erb +11 -2
  121. data/app/views/alchemy/ingredients/_richtext_view.html.erb +3 -3
  122. data/app/views/alchemy/ingredients/_select_view.html.erb +1 -1
  123. data/app/views/alchemy/ingredients/_text_view.html.erb +3 -19
  124. data/app/views/alchemy/ingredients/_video_view.html.erb +3 -18
  125. data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +1 -0
  126. data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +1 -0
  127. data/app/views/layouts/alchemy/admin.html.erb +7 -9
  128. data/bin/setup +37 -0
  129. data/bin/start +17 -0
  130. data/config/initializers/assets.rb +1 -0
  131. data/config/initializers/dragonfly.rb +1 -0
  132. data/config/initializers/mime_types.rb +1 -0
  133. data/config/initializers/mini_profiler.rb +1 -0
  134. data/config/initializers/simple_form.rb +3 -2
  135. data/config/locales/alchemy.en.yml +1 -1
  136. data/config/routes.rb +21 -20
  137. data/config/spring.rb +1 -0
  138. data/db/migrate/20230121212637_alchemy_six_point_one.rb +8 -8
  139. data/db/migrate/20230505132743_add_indexes_to_alchemy_pictures.rb +6 -0
  140. data/lib/alchemy/admin/locale.rb +3 -3
  141. data/lib/alchemy/admin/preview_url.rb +2 -2
  142. data/lib/alchemy/auth_accessors.rb +1 -1
  143. data/lib/alchemy/config.rb +1 -1
  144. data/lib/alchemy/controller_actions.rb +4 -4
  145. data/lib/alchemy/deprecation.rb +1 -0
  146. data/lib/alchemy/dragonfly/processors/thumbnail.rb +1 -1
  147. data/lib/alchemy/element_definition.rb +2 -2
  148. data/lib/alchemy/engine.rb +2 -1
  149. data/lib/alchemy/filetypes.rb +7 -7
  150. data/lib/alchemy/forms/builder.rb +4 -4
  151. data/lib/alchemy/i18n.rb +6 -4
  152. data/lib/alchemy/install/tasks.rb +2 -1
  153. data/lib/alchemy/name_conversions.rb +1 -1
  154. data/lib/alchemy/page_layout.rb +1 -1
  155. data/lib/alchemy/permissions.rb +5 -4
  156. data/lib/alchemy/resource.rb +10 -10
  157. data/lib/alchemy/resources_helper.rb +7 -7
  158. data/lib/alchemy/routing_constraints.rb +2 -2
  159. data/lib/alchemy/seeder.rb +12 -5
  160. data/lib/alchemy/shell.rb +2 -1
  161. data/lib/alchemy/taggable.rb +3 -2
  162. data/lib/alchemy/tasks/tidy.rb +1 -0
  163. data/lib/alchemy/test_support/capybara_helpers.rb +1 -1
  164. data/lib/alchemy/test_support/config_stubbing.rb +1 -0
  165. data/lib/alchemy/test_support/factories/element_factory.rb +4 -0
  166. data/lib/alchemy/test_support/factories/page_factory.rb +2 -2
  167. data/lib/alchemy/test_support/having_crop_action_examples.rb +9 -9
  168. data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +33 -33
  169. data/lib/alchemy/test_support/integration_helpers.rb +4 -3
  170. data/lib/alchemy/test_support/shared_contexts.rb +2 -1
  171. data/lib/alchemy/test_support/shared_dom_ids_examples.rb +9 -9
  172. data/lib/alchemy/test_support/shared_ingredient_examples.rb +12 -6
  173. data/lib/alchemy/test_support/shared_uploader_examples.rb +1 -0
  174. data/lib/alchemy/tinymce.rb +3 -26
  175. data/lib/alchemy/upgrader.rb +1 -0
  176. data/lib/alchemy/version.rb +1 -1
  177. data/lib/alchemy_cms.rb +1 -0
  178. data/lib/generators/alchemy/base.rb +3 -2
  179. data/lib/generators/alchemy/elements/elements_generator.rb +2 -1
  180. data/lib/generators/alchemy/ingredient/ingredient_generator.rb +1 -0
  181. data/lib/generators/alchemy/install/files/application.html.erb +1 -1
  182. data/lib/generators/alchemy/install/install_generator.rb +2 -1
  183. data/lib/generators/alchemy/module/module_generator.rb +1 -0
  184. data/lib/generators/alchemy/page_layouts/page_layouts_generator.rb +1 -0
  185. data/lib/generators/alchemy/site_layouts/site_layouts_generator.rb +1 -0
  186. data/lib/generators/alchemy/views/views_generator.rb +2 -1
  187. data/lib/tasks/alchemy/thumbnails.rake +5 -5
  188. data/lib/tasks/alchemy/tidy.rake +1 -0
  189. data/lib/tasks/alchemy/upgrade.rake +6 -5
  190. data/package/admin.js +2 -0
  191. data/package/dist/admin.js +3 -3
  192. data/package/dist/admin.js.map +4 -4
  193. data/package/src/datepicker.js +1 -0
  194. data/package/src/tinymce.js +142 -0
  195. data/package.json +2 -2
  196. metadata +39 -7
  197. data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +0 -93
  198. data/app/presenters/alchemy/picture_view.rb +0 -88
  199. data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +0 -10
@@ -159,9 +159,9 @@ module Alchemy
159
159
  scope: "ingredient_validations",
160
160
  default: [
161
161
  "fields.#{role}.#{error}".to_sym,
162
- "errors.#{error}".to_sym,
162
+ "errors.#{error}".to_sym
163
163
  ],
164
- field: Alchemy::Ingredient.translated_label_for(role, name),
164
+ field: Alchemy::Ingredient.translated_label_for(role, name)
165
165
  )
166
166
  end
167
167
  end
@@ -175,7 +175,7 @@ module Alchemy
175
175
  ingredient_definitions.each do |attributes|
176
176
  ingredients.build(
177
177
  role: attributes[:role],
178
- type: Alchemy::Ingredient.normalize_type(attributes[:type]),
178
+ type: Alchemy::Ingredient.normalize_type(attributes[:type])
179
179
  )
180
180
  end
181
181
  end
@@ -41,7 +41,7 @@ module Alchemy
41
41
  "taggable",
42
42
  "compact",
43
43
  "message",
44
- "deprecated",
44
+ "deprecated"
45
45
  ].freeze
46
46
 
47
47
  # All Elements that share the same page version and parent element and are fixed or not are considered a list.
@@ -100,7 +100,7 @@ module Alchemy
100
100
  scope :excluded, ->(names) { where.not(name: names) }
101
101
  scope :fixed, -> { where(fixed: true) }
102
102
  scope :unfixed, -> { where(fixed: false) }
103
- scope :from_current_site, -> { where(Language.table_name => { site_id: Site.current || Site.default }).joins(page: "language") }
103
+ scope :from_current_site, -> { where(Language.table_name => {site_id: Site.current || Site.default}).joins(page: "language") }
104
104
  scope :folded, -> { where(folded: true) }
105
105
  scope :expanded, -> { where(folded: false) }
106
106
  scope :not_nested, -> { where(parent_element_id: nil) }
@@ -102,7 +102,7 @@ module Alchemy
102
102
  # Elements off setted by
103
103
  # @return [Alchemy::ElementRepository]
104
104
  def offset(offset)
105
- self.class.new elements[offset.to_i..-1]
105
+ self.class.new elements[offset.to_i..]
106
106
  end
107
107
 
108
108
  # Elements limitted by
@@ -21,7 +21,7 @@ module Alchemy
21
21
  min_size: large_enough? ? min_size : false,
22
22
  ratio: ratio,
23
23
  default_box: default_box,
24
- image_size: [image_width, image_height],
24
+ image_size: [image_width, image_height]
25
25
  }.freeze
26
26
  end
27
27
 
@@ -80,7 +80,7 @@ module Alchemy
80
80
  default_crop_from[0],
81
81
  default_crop_from[1],
82
82
  default_crop_from[0] + default_crop_size[0],
83
- default_crop_from[1] + default_crop_size[1],
83
+ default_crop_from[1] + default_crop_size[1]
84
84
  ]
85
85
  end
86
86
  end
@@ -19,7 +19,7 @@ module Alchemy
19
19
  if: -> { definition.key?(:default) && value.nil? }
20
20
 
21
21
  validates :type, presence: true
22
- validates :role, presence: true, uniqueness: { scope: :element_id, case_sensitive: false }
22
+ validates :role, presence: true, uniqueness: {scope: :element_id, case_sensitive: false}
23
23
 
24
24
  validates_with Alchemy::IngredientValidator, on: :update, if: :has_validations?
25
25
 
@@ -75,7 +75,7 @@ module Alchemy
75
75
  Alchemy.t(
76
76
  role,
77
77
  scope: "ingredient_roles.#{element_name}",
78
- default: Alchemy.t("ingredient_roles.#{role}", default: role.humanize),
78
+ default: Alchemy.t("ingredient_roles.#{role}", default: role.humanize)
79
79
  )
80
80
  end
81
81
 
@@ -100,16 +100,6 @@ module Alchemy
100
100
  definition[:settings] || {}
101
101
  end
102
102
 
103
- # Fetches value from settings
104
- #
105
- # @param key [Symbol] - The hash key you want to fetch the value from
106
- # @param options [Hash] - An optional Hash that can override the settings.
107
- # Normally passed as options hash into the ingredient
108
- # editor view.
109
- def settings_value(key, options = {})
110
- settings.merge(options || {})[key.to_sym]
111
- end
112
-
113
103
  # Definition hash for this ingredient from +elements.yml+ file.
114
104
  #
115
105
  def definition
@@ -165,8 +155,20 @@ module Alchemy
165
155
  !!definition[:as_element_title]
166
156
  end
167
157
 
158
+ # The view component of the ingredient with mapped options.
159
+ #
160
+ # @param options [Hash] - Passed to the view component as keyword arguments
161
+ # @param html_options [Hash] - Passed to the view component
162
+ def as_view_component(options: {}, html_options: {})
163
+ view_component_class.new(self, **options, html_options: html_options)
164
+ end
165
+
168
166
  private
169
167
 
168
+ def view_component_class
169
+ @_view_component_class ||= "#{self.class.name}View".constantize
170
+ end
171
+
170
172
  def hint_translation_attribute
171
173
  role
172
174
  end
@@ -89,7 +89,7 @@ module Alchemy
89
89
  def duplicates
90
90
  ingredient.class
91
91
  .joins(:element).merge(Alchemy::Element.published)
92
- .where(Alchemy::Element.table_name => { name: ingredient.element.name })
92
+ .where(Alchemy::Element.table_name => {name: ingredient.element.name})
93
93
  .where(value: ingredient.value)
94
94
  .where.not(id: ingredient.id)
95
95
  end
@@ -15,7 +15,7 @@ module Alchemy
15
15
  def preview_text(_maxlength = nil)
16
16
  return "" unless value
17
17
 
18
- ::I18n.l(value, format: :'alchemy.ingredient_date')
18
+ ::I18n.l(value, format: :"alchemy.ingredient_date")
19
19
  end
20
20
  end
21
21
  end
@@ -13,11 +13,11 @@ module Alchemy
13
13
  :title
14
14
 
15
15
  allow_settings %i[
16
- css_classes
17
- except
18
- link_text
19
- only
20
- ]
16
+ css_classes
17
+ except
18
+ link_text
19
+ only
20
+ ]
21
21
 
22
22
  related_object_alias :attachment, class_name: "Alchemy::Attachment"
23
23
 
@@ -13,10 +13,10 @@ module Alchemy
13
13
  :size
14
14
 
15
15
  allow_settings %i[
16
- anchor
17
- levels
18
- sizes
19
- ]
16
+ anchor
17
+ levels
18
+ sizes
19
+ ]
20
20
 
21
21
  before_create :set_level_and_size
22
22
 
@@ -28,15 +28,15 @@ module Alchemy
28
28
  related_object_alias :picture, class_name: "Alchemy::Picture"
29
29
 
30
30
  allow_settings %i[
31
- crop
32
- css_classes
33
- fixed_ratio
34
- linkable
35
- size
36
- sizes
37
- srcset
38
- upsample
39
- ]
31
+ crop
32
+ css_classes
33
+ fixed_ratio
34
+ linkable
35
+ size
36
+ sizes
37
+ srcset
38
+ upsample
39
+ ]
40
40
 
41
41
  # The first 30 characters of the pictures name
42
42
  #
@@ -47,6 +47,24 @@ module Alchemy
47
47
  def preview_text(max_length = 30)
48
48
  picture&.name.to_s[0..max_length - 1]
49
49
  end
50
+
51
+ # The picture view component with mapped options.
52
+ #
53
+ # @param options [Hash] - Passed to the view component
54
+ # @param html_options [Hash] - Passed to the view component
55
+ #
56
+ # @return Alchemy::Ingredients::PictureView
57
+ def as_view_component(options: {}, html_options: {})
58
+ PictureView.new(
59
+ self,
60
+ show_caption: options.delete(:show_caption),
61
+ disable_link: options.delete(:disable_link),
62
+ srcset: options.delete(:srcset),
63
+ sizes: options.delete(:sizes),
64
+ picture_options: options,
65
+ html_options: html_options
66
+ )
67
+ end
50
68
  end
51
69
  end
52
70
  end
@@ -10,10 +10,10 @@ module Alchemy
10
10
  :sanitized_body
11
11
 
12
12
  allow_settings %i[
13
- plain_text
14
- sanitizer
15
- tinymce
16
- ]
13
+ plain_text
14
+ sanitizer
15
+ tinymce
16
+ ]
17
17
 
18
18
  before_save :strip_content
19
19
  before_save :sanitize_content
@@ -28,15 +28,23 @@ module Alchemy
28
28
  stripped_body.to_s[0..max_length - 1]
29
29
  end
30
30
 
31
- # Returns css class names for the editor textarea.
32
- def tinymce_class_name
33
- "has_tinymce#{has_custom_tinymce_config? ? " #{element.name}_#{role}" : ""}"
31
+ def element_id
32
+ "tinymce_#{id}"
34
33
  end
35
34
 
36
35
  def has_tinymce?
37
36
  true
38
37
  end
39
38
 
39
+ # Returns true if there is a tinymce setting defined that contains settings.
40
+ def has_custom_tinymce_config?
41
+ custom_tinymce_config.is_a?(Hash)
42
+ end
43
+
44
+ def custom_tinymce_config
45
+ settings[:tinymce]
46
+ end
47
+
40
48
  private
41
49
 
42
50
  def strip_content
@@ -53,11 +61,6 @@ module Alchemy
53
61
  def sanitizer_settings
54
62
  settings[:sanitizer] || {}
55
63
  end
56
-
57
- # Returns true if there is a tinymce setting defined that contains settings.
58
- def has_custom_tinymce_config?
59
- settings[:tinymce].is_a?(Hash)
60
- end
61
64
  end
62
65
  end
63
66
  end
@@ -17,12 +17,12 @@ module Alchemy
17
17
  :link_class_name
18
18
 
19
19
  allow_settings %i[
20
- anchor
21
- disable_link
22
- display_inline
23
- input_type
24
- linkable
25
- ]
20
+ anchor
21
+ disable_link
22
+ display_inline
23
+ input_type
24
+ linkable
25
+ ]
26
26
  end
27
27
  end
28
28
  end
@@ -17,7 +17,7 @@ module Alchemy::Language::Code
17
17
  codes << "" if codes.length == 1
18
18
  on_current_site.find_by(
19
19
  language_code: codes[0],
20
- country_code: codes[1],
20
+ country_code: codes[1]
21
21
  )
22
22
  end
23
23
  end
@@ -38,11 +38,11 @@ module Alchemy
38
38
 
39
39
  validates :language_code,
40
40
  presence: true,
41
- uniqueness: { scope: [:site_id, :country_code], case_sensitive: false },
42
- format: { with: /\A[a-z]{2}\z/, if: -> { language_code.present? } }
41
+ uniqueness: {scope: [:site_id, :country_code], case_sensitive: false},
42
+ format: {with: /\A[a-z]{2}\z/, if: -> { language_code.present? }}
43
43
 
44
44
  validates :country_code,
45
- format: { with: /\A[a-zA-Z]{2}\z/, if: -> { country_code.present? } }
45
+ format: {with: /\A[a-zA-Z]{2}\z/, if: -> { country_code.present? }}
46
46
 
47
47
  validate :presence_of_default_language
48
48
  validate :publicity_of_default_language
@@ -60,7 +60,7 @@ module Alchemy
60
60
  end
61
61
 
62
62
  scope :published, -> { where(public: true) }
63
- scope :with_root_page, -> { joins(:pages).where(Page.table_name => { language_root: true }) }
63
+ scope :with_root_page, -> { joins(:pages).where(Page.table_name => {language_root: true}) }
64
64
 
65
65
  class << self
66
66
  def on_site(site)
@@ -18,5 +18,5 @@ class Alchemy::LegacyPageUrl < ActiveRecord::Base
18
18
 
19
19
  validates :urlname,
20
20
  presence: true,
21
- format: {with: /\A[:\.\w\-+_\/\?&%;=#]*\z/}
21
+ format: {with: /\A[:.\w\-+_\/?&%;=#]*\z/}
22
22
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Alchemy
4
4
  class Node < BaseRecord
5
- VALID_URL_REGEX = /\A(\/|\D[a-z\+\d\.\-]+:)/
5
+ VALID_URL_REGEX = /\A(\/|\D[a-z+\d.-]+:)/
6
6
 
7
7
  before_destroy :check_if_related_node_ingredients_present
8
8
 
@@ -24,7 +24,7 @@ module Alchemy
24
24
 
25
25
  validates :menu_type, presence: true
26
26
  validates :name, presence: true, if: -> { page.nil? }
27
- validates :url, format: { with: VALID_URL_REGEX }, unless: -> { url.nil? }
27
+ validates :url, format: {with: VALID_URL_REGEX}, unless: -> { url.nil? }
28
28
 
29
29
  # Returns the name
30
30
  #
@@ -12,7 +12,7 @@ module Alchemy
12
12
  class_name: "Alchemy::Element",
13
13
  through: :public_version,
14
14
  inverse_of: :page,
15
- source: :elements,
15
+ source: :elements
16
16
  ) do
17
17
  has_many :all_elements
18
18
  has_many :elements, -> { not_nested.unfixed.published }
@@ -42,7 +42,7 @@ module Alchemy
42
42
  repository.not_nested.each.with_index(1) do |element, position|
43
43
  Alchemy::DuplicateElement.new(element, repository: repository).call(
44
44
  page_version_id: target.draft_version.id,
45
- position: position,
45
+ position: position
46
46
  )
47
47
  end
48
48
  end
@@ -72,11 +72,11 @@ module Alchemy
72
72
  #
73
73
  def available_element_definitions(only_element_named = nil)
74
74
  @_element_definitions ||= if only_element_named
75
- definition = Element.definition_by_name(only_element_named)
76
- element_definitions_by_name(definition["nestable_elements"])
77
- else
78
- element_definitions
79
- end
75
+ definition = Element.definition_by_name(only_element_named)
76
+ element_definitions_by_name(definition["nestable_elements"])
77
+ else
78
+ element_definitions
79
+ end
80
80
 
81
81
  return [] if @_element_definitions.blank?
82
82
 
@@ -98,13 +98,13 @@ module Alchemy
98
98
  #
99
99
  def available_elements_within_current_scope(parent)
100
100
  @_available_elements = if parent
101
- parents_unique_nested_elements = parent.nested_elements.where(unique: true).pluck(:name)
102
- available_element_definitions(parent.name).reject do |e|
103
- parents_unique_nested_elements.include? e["name"]
104
- end
105
- else
106
- available_element_definitions
101
+ parents_unique_nested_elements = parent.nested_elements.where(unique: true).pluck(:name)
102
+ available_element_definitions(parent.name).reject do |e|
103
+ parents_unique_nested_elements.include? e["name"]
107
104
  end
105
+ else
106
+ available_element_definitions
107
+ end
108
108
  end
109
109
 
110
110
  # All element definitions defined for page's page layout
@@ -160,7 +160,7 @@ module Alchemy
160
160
  #
161
161
  def richtext_ingredients_ids
162
162
  Alchemy::Ingredient.richtexts.joins(:element)
163
- .where(Element.table_name => { page_version_id: draft_version.id, folded: false })
163
+ .where(Element.table_name => {page_version_id: draft_version.id, folded: false})
164
164
  .select(&:has_tinymce?)
165
165
  .collect(&:id)
166
166
  end
@@ -5,7 +5,7 @@ module Alchemy
5
5
  module PageNaming
6
6
  extend ActiveSupport::Concern
7
7
  include NameConversions
8
- RESERVED_URLNAMES = %w(admin messages new)
8
+ RESERVED_URLNAMES = %w[admin messages new]
9
9
 
10
10
  included do
11
11
  before_validation :set_urlname,
@@ -15,9 +15,9 @@ module Alchemy
15
15
  validates :name,
16
16
  presence: true
17
17
  validates :urlname,
18
- uniqueness: { scope: [:language_id, :layoutpage], if: -> { urlname.present? }, case_sensitive: false },
19
- exclusion: { in: RESERVED_URLNAMES },
20
- length: { minimum: 3, if: -> { urlname.present? } }
18
+ uniqueness: {scope: [:language_id, :layoutpage], if: -> { urlname.present? }, case_sensitive: false},
19
+ exclusion: {in: RESERVED_URLNAMES},
20
+ length: {minimum: 3, if: -> { urlname.present? }}
21
21
 
22
22
  before_save :set_title,
23
23
  if: -> { title.blank? }
@@ -58,7 +58,7 @@ module Alchemy
58
58
  {
59
59
  public: public?,
60
60
  locked: locked?,
61
- restricted: restricted?,
61
+ restricted: restricted?
62
62
  }
63
63
  end
64
64
 
@@ -49,9 +49,9 @@ module Alchemy
49
49
  #
50
50
  scope :published,
51
51
  -> {
52
- joins(:language, :versions).
53
- merge(Language.published).
54
- merge(PageVersion.public_on(Time.current))
52
+ joins(:language, :versions)
53
+ .merge(Language.published)
54
+ .merge(PageVersion.public_on(Time.current))
55
55
  }
56
56
 
57
57
  # All pages that are a published language root
@@ -59,7 +59,7 @@ module Alchemy
59
59
  scope :public_language_roots,
60
60
  -> {
61
61
  published.language_roots.where(
62
- language_code: Language.published.pluck(:language_code),
62
+ language_code: Language.published.pluck(:language_code)
63
63
  )
64
64
  }
65
65
 
@@ -98,7 +98,7 @@ module Alchemy
98
98
  #
99
99
  scope :from_current_site,
100
100
  -> {
101
- where(Language.table_name => { site_id: Site.current || Site.default }).joins(:language)
101
+ where(Language.table_name => {site_id: Site.current || Site.default}).joins(:language)
102
102
  }
103
103
 
104
104
  # All pages for xml sitemap
@@ -53,10 +53,10 @@ module Alchemy
53
53
  public_on: nil,
54
54
  public_until: nil,
55
55
  locked_at: nil,
56
- locked_by: nil,
56
+ locked_by: nil
57
57
  }
58
58
 
59
- SKIPPED_ATTRIBUTES_ON_COPY = %w(
59
+ SKIPPED_ATTRIBUTES_ON_COPY = %w[
60
60
  id
61
61
  updated_at
62
62
  created_at
@@ -67,7 +67,7 @@ module Alchemy
67
67
  depth
68
68
  urlname
69
69
  cached_tag_list
70
- )
70
+ ]
71
71
 
72
72
  PERMITTED_ATTRIBUTES = [
73
73
  :meta_description,
@@ -85,7 +85,7 @@ module Alchemy
85
85
  :title,
86
86
  :urlname,
87
87
  :layoutpage,
88
- :menu_id,
88
+ :menu_id
89
89
  ]
90
90
 
91
91
  acts_as_nested_set(dependent: :destroy, scope: [:layoutpage, :language_id])
@@ -185,12 +185,12 @@ module Alchemy
185
185
  [
186
186
  {
187
187
  name: :by_page_layout,
188
- values: PageLayout.all.map { |p| [Alchemy.t(p["name"], scope: "page_layout_names"), p["name"]] },
188
+ values: PageLayout.all.map { |p| [Alchemy.t(p["name"], scope: "page_layout_names"), p["name"]] }
189
189
  },
190
190
  {
191
191
  name: :status,
192
- values: %w[published not_public restricted],
193
- },
192
+ values: %w[published not_public restricted]
193
+ }
194
194
  ]
195
195
  end
196
196
 
@@ -248,7 +248,7 @@ module Alchemy
248
248
  parent: new_parent,
249
249
  language: new_parent&.language,
250
250
  name: new_name,
251
- title: new_name,
251
+ title: new_name
252
252
  })
253
253
  if source.children.any?
254
254
  source.copy_children_to(page)
@@ -276,7 +276,7 @@ module Alchemy
276
276
  link_target_options = Config.get(:link_target_options)
277
277
  link_target_options.each do |option|
278
278
  options << [Alchemy.t(option, scope: "link_target_options",
279
- default: option.to_s.humanize), option]
279
+ default: option.to_s.humanize), option]
280
280
  end
281
281
  options
282
282
  end
@@ -450,7 +450,7 @@ module Alchemy
450
450
  new_child = Page.copy(child, {
451
451
  parent_id: new_parent.id,
452
452
  language_id: new_parent.language_id,
453
- language_code: new_parent.language_code,
453
+ language_code: new_parent.language_code
454
454
  })
455
455
  new_child.move_to_child_of(new_parent)
456
456
  child.copy_children_to(new_child) unless child.children.blank?
@@ -491,7 +491,7 @@ module Alchemy
491
491
  # A tree node with new lft, rgt, depth, url, parent_id and restricted indexes to be updated
492
492
  #
493
493
  def update_node!(node)
494
- hash = { lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted }
494
+ hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
495
495
 
496
496
  if urlname != node.url
497
497
  LegacyPageUrl.create(page_id: id, urlname: urlname)
@@ -32,7 +32,7 @@ module Alchemy
32
32
 
33
33
  {
34
34
  width: width,
35
- height: height,
35
+ height: height
36
36
  }
37
37
  end
38
38
 
@@ -41,7 +41,7 @@ module Alchemy
41
41
  def image_size
42
42
  {
43
43
  width: image_file_width,
44
- height: image_file_height,
44
+ height: image_file_height
45
45
  }
46
46
  end
47
47
  end
@@ -59,7 +59,7 @@ module Alchemy
59
59
  y = 0 if y.nil?
60
60
  {
61
61
  x: x,
62
- y: y,
62
+ y: y
63
63
  }
64
64
  end
65
65
 
@@ -108,7 +108,7 @@ module Alchemy
108
108
  def reduce_to_image(dimensions)
109
109
  {
110
110
  width: [dimensions[:width].to_i, image_file_width.to_i].min,
111
- height: [dimensions[:height].to_i, image_file_height.to_i].min,
111
+ height: [dimensions[:height].to_i, image_file_height.to_i].min
112
112
  }
113
113
  end
114
114
  end
@@ -44,10 +44,10 @@ module Alchemy
44
44
 
45
45
  def find_thumb_by(signature)
46
46
  @thumb = if variant.picture.thumbs.loaded?
47
- variant.picture.thumbs.find { |t| t.signature == signature }
48
- else
49
- variant.picture.thumbs.find_by(signature: signature)
50
- end
47
+ variant.picture.thumbs.find { |t| t.signature == signature }
48
+ else
49
+ variant.picture.thumbs.find_by(signature: signature)
50
+ end
51
51
  end
52
52
  end
53
53
  end