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.
- checksums.yaml +4 -4
- data/.github/workflows/brakeman-analysis.yml +2 -2
- data/.github/workflows/ci.yml +7 -7
- data/.github/workflows/lint.yml +17 -0
- data/.hound.yml +2 -3
- data/.rubocop.yml +4 -350
- data/.standard.yml +3 -0
- data/CHANGELOG.md +29 -0
- data/Gemfile +3 -1
- data/README.md +7 -9
- data/Rakefile +1 -1
- data/alchemy_cms.gemspec +2 -1
- data/app/assets/javascripts/alchemy/admin.js +0 -1
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +6 -1
- data/app/components/alchemy/ingredients/audio_view.rb +37 -0
- data/app/components/alchemy/ingredients/base_view.rb +38 -0
- data/app/components/alchemy/ingredients/boolean_view.rb +13 -0
- data/app/components/alchemy/ingredients/datetime_view.rb +22 -0
- data/app/components/alchemy/ingredients/file_view.rb +40 -0
- data/app/components/alchemy/ingredients/headline_view.rb +20 -0
- data/app/components/alchemy/ingredients/html_view.rb +9 -0
- data/app/components/alchemy/ingredients/link_view.rb +25 -0
- data/app/components/alchemy/ingredients/node_view.rb +11 -0
- data/app/components/alchemy/ingredients/page_view.rb +15 -0
- data/app/components/alchemy/ingredients/picture_view.rb +108 -0
- data/app/components/alchemy/ingredients/richtext_view.rb +22 -0
- data/app/components/alchemy/ingredients/select_view.rb +6 -0
- data/app/components/alchemy/ingredients/text_view.rb +41 -0
- data/app/components/alchemy/ingredients/video_view.rb +39 -0
- data/app/controllers/alchemy/admin/attachments_controller.rb +3 -3
- data/app/controllers/alchemy/admin/base_controller.rb +7 -7
- data/app/controllers/alchemy/admin/clipboard_controller.rb +2 -2
- data/app/controllers/alchemy/admin/elements_controller.rb +26 -11
- data/app/controllers/alchemy/admin/languages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/nodes_controller.rb +2 -2
- data/app/controllers/alchemy/admin/pages_controller.rb +10 -10
- data/app/controllers/alchemy/admin/pictures_controller.rb +14 -14
- data/app/controllers/alchemy/admin/resources_controller.rb +27 -28
- data/app/controllers/alchemy/admin/styleguide_controller.rb +1 -0
- data/app/controllers/alchemy/admin/tags_controller.rb +11 -11
- data/app/controllers/alchemy/api/base_controller.rb +2 -2
- data/app/controllers/alchemy/api/elements_controller.rb +11 -11
- data/app/controllers/alchemy/api/ingredients_controller.rb +1 -1
- data/app/controllers/alchemy/api/nodes_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +11 -11
- data/app/controllers/alchemy/attachments_controller.rb +3 -3
- data/app/controllers/alchemy/base_controller.rb +1 -1
- data/app/controllers/alchemy/messages_controller.rb +9 -9
- data/app/controllers/alchemy/pages_controller.rb +8 -19
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +1 -0
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +5 -7
- data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +5 -5
- data/app/decorators/alchemy/element_editor.rb +4 -4
- data/app/decorators/alchemy/ingredient_editor.rb +6 -6
- data/app/helpers/alchemy/admin/attachments_helper.rb +1 -1
- data/app/helpers/alchemy/admin/base_helper.rb +21 -22
- data/app/helpers/alchemy/admin/elements_helper.rb +1 -1
- data/app/helpers/alchemy/admin/form_helper.rb +1 -1
- data/app/helpers/alchemy/admin/navigation_helper.rb +7 -7
- data/app/helpers/alchemy/admin/pages_helper.rb +2 -2
- data/app/helpers/alchemy/admin/tags_helper.rb +3 -3
- data/app/helpers/alchemy/base_helper.rb +2 -2
- data/app/helpers/alchemy/elements_block_helper.rb +9 -7
- data/app/helpers/alchemy/elements_helper.rb +12 -12
- data/app/helpers/alchemy/pages_helper.rb +11 -11
- data/app/helpers/alchemy/url_helper.rb +1 -1
- data/app/mailers/alchemy/messages_mailer.rb +1 -1
- data/app/models/alchemy/attachment.rb +6 -6
- data/app/models/alchemy/base_record.rb +1 -0
- data/app/models/alchemy/eager_loading.rb +6 -6
- data/app/models/alchemy/element/definitions.rb +1 -1
- data/app/models/alchemy/element/element_ingredients.rb +3 -3
- data/app/models/alchemy/element.rb +2 -2
- data/app/models/alchemy/elements_repository.rb +1 -1
- data/app/models/alchemy/image_cropper_settings.rb +2 -2
- data/app/models/alchemy/ingredient.rb +14 -12
- data/app/models/alchemy/ingredient_validator.rb +1 -1
- data/app/models/alchemy/ingredients/datetime.rb +1 -1
- data/app/models/alchemy/ingredients/file.rb +5 -5
- data/app/models/alchemy/ingredients/headline.rb +4 -4
- data/app/models/alchemy/ingredients/picture.rb +27 -9
- data/app/models/alchemy/ingredients/richtext.rb +15 -12
- data/app/models/alchemy/ingredients/text.rb +6 -6
- data/app/models/alchemy/language/code.rb +1 -1
- data/app/models/alchemy/language.rb +4 -4
- data/app/models/alchemy/legacy_page_url.rb +1 -1
- data/app/models/alchemy/node.rb +2 -2
- data/app/models/alchemy/page/page_elements.rb +14 -14
- data/app/models/alchemy/page/page_naming.rb +4 -4
- data/app/models/alchemy/page/page_natures.rb +1 -1
- data/app/models/alchemy/page/page_scopes.rb +5 -5
- data/app/models/alchemy/page.rb +11 -11
- data/app/models/alchemy/picture/calculations.rb +2 -2
- data/app/models/alchemy/picture/transformations.rb +2 -2
- data/app/models/alchemy/picture/url.rb +4 -4
- data/app/models/alchemy/picture.rb +11 -10
- data/app/models/alchemy/picture_thumb/create.rb +1 -1
- data/app/models/alchemy/picture_thumb.rb +1 -1
- data/app/models/alchemy/picture_variant.rb +2 -3
- data/app/models/alchemy/tag.rb +8 -0
- data/app/models/concerns/alchemy/picture_thumbnails.rb +6 -6
- data/app/serializers/alchemy/base_serializer.rb +1 -1
- data/app/serializers/alchemy/page_tree_serializer.rb +7 -7
- data/app/services/alchemy/duplicate_element.rb +3 -3
- data/app/services/alchemy/tag_validations.rb +1 -1
- data/app/views/alchemy/admin/elements/_element.html.erb +3 -0
- data/app/views/alchemy/admin/pages/edit.html.erb +0 -3
- data/app/views/alchemy/admin/pages/update.js.erb +10 -4
- data/app/views/alchemy/admin/pictures/_infos.html.erb +1 -1
- data/app/views/alchemy/ingredients/_audio_view.html.erb +1 -14
- data/app/views/alchemy/ingredients/_boolean_view.html.erb +1 -1
- data/app/views/alchemy/ingredients/_datetime_view.html.erb +3 -9
- data/app/views/alchemy/ingredients/_file_view.html.erb +3 -16
- data/app/views/alchemy/ingredients/_headline_view.html.erb +4 -10
- data/app/views/alchemy/ingredients/_html_view.html.erb +1 -1
- data/app/views/alchemy/ingredients/_link_view.html.erb +4 -9
- data/app/views/alchemy/ingredients/_node_view.html.erb +1 -1
- data/app/views/alchemy/ingredients/_page_view.html.erb +1 -4
- data/app/views/alchemy/ingredients/_picture_view.html.erb +4 -5
- data/app/views/alchemy/ingredients/_richtext_editor.html.erb +11 -2
- data/app/views/alchemy/ingredients/_richtext_view.html.erb +3 -3
- data/app/views/alchemy/ingredients/_select_view.html.erb +1 -1
- data/app/views/alchemy/ingredients/_text_view.html.erb +3 -19
- data/app/views/alchemy/ingredients/_video_view.html.erb +3 -18
- data/app/views/alchemy/ingredients/shared/_link_tools.html.erb +1 -0
- data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +1 -0
- data/app/views/layouts/alchemy/admin.html.erb +7 -9
- data/bin/setup +37 -0
- data/bin/start +17 -0
- data/config/initializers/assets.rb +1 -0
- data/config/initializers/dragonfly.rb +1 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/initializers/mini_profiler.rb +1 -0
- data/config/initializers/simple_form.rb +3 -2
- data/config/locales/alchemy.en.yml +1 -1
- data/config/routes.rb +21 -20
- data/config/spring.rb +1 -0
- data/db/migrate/20230121212637_alchemy_six_point_one.rb +8 -8
- data/db/migrate/20230505132743_add_indexes_to_alchemy_pictures.rb +6 -0
- data/lib/alchemy/admin/locale.rb +3 -3
- data/lib/alchemy/admin/preview_url.rb +2 -2
- data/lib/alchemy/auth_accessors.rb +1 -1
- data/lib/alchemy/config.rb +1 -1
- data/lib/alchemy/controller_actions.rb +4 -4
- data/lib/alchemy/deprecation.rb +1 -0
- data/lib/alchemy/dragonfly/processors/thumbnail.rb +1 -1
- data/lib/alchemy/element_definition.rb +2 -2
- data/lib/alchemy/engine.rb +2 -1
- data/lib/alchemy/filetypes.rb +7 -7
- data/lib/alchemy/forms/builder.rb +4 -4
- data/lib/alchemy/i18n.rb +6 -4
- data/lib/alchemy/install/tasks.rb +2 -1
- data/lib/alchemy/name_conversions.rb +1 -1
- data/lib/alchemy/page_layout.rb +1 -1
- data/lib/alchemy/permissions.rb +5 -4
- data/lib/alchemy/resource.rb +10 -10
- data/lib/alchemy/resources_helper.rb +7 -7
- data/lib/alchemy/routing_constraints.rb +2 -2
- data/lib/alchemy/seeder.rb +12 -5
- data/lib/alchemy/shell.rb +2 -1
- data/lib/alchemy/taggable.rb +3 -2
- data/lib/alchemy/tasks/tidy.rb +1 -0
- data/lib/alchemy/test_support/capybara_helpers.rb +1 -1
- data/lib/alchemy/test_support/config_stubbing.rb +1 -0
- data/lib/alchemy/test_support/factories/element_factory.rb +4 -0
- data/lib/alchemy/test_support/factories/page_factory.rb +2 -2
- data/lib/alchemy/test_support/having_crop_action_examples.rb +9 -9
- data/lib/alchemy/test_support/having_picture_thumbnails_examples.rb +33 -33
- data/lib/alchemy/test_support/integration_helpers.rb +4 -3
- data/lib/alchemy/test_support/shared_contexts.rb +2 -1
- data/lib/alchemy/test_support/shared_dom_ids_examples.rb +9 -9
- data/lib/alchemy/test_support/shared_ingredient_examples.rb +12 -6
- data/lib/alchemy/test_support/shared_uploader_examples.rb +1 -0
- data/lib/alchemy/tinymce.rb +3 -26
- data/lib/alchemy/upgrader.rb +1 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +1 -0
- data/lib/generators/alchemy/base.rb +3 -2
- data/lib/generators/alchemy/elements/elements_generator.rb +2 -1
- data/lib/generators/alchemy/ingredient/ingredient_generator.rb +1 -0
- data/lib/generators/alchemy/install/files/application.html.erb +1 -1
- data/lib/generators/alchemy/install/install_generator.rb +2 -1
- data/lib/generators/alchemy/module/module_generator.rb +1 -0
- data/lib/generators/alchemy/page_layouts/page_layouts_generator.rb +1 -0
- data/lib/generators/alchemy/site_layouts/site_layouts_generator.rb +1 -0
- data/lib/generators/alchemy/views/views_generator.rb +2 -1
- data/lib/tasks/alchemy/thumbnails.rake +5 -5
- data/lib/tasks/alchemy/tidy.rake +1 -0
- data/lib/tasks/alchemy/upgrade.rake +6 -5
- data/package/admin.js +2 -0
- data/package/dist/admin.js +3 -3
- data/package/dist/admin.js.map +4 -4
- data/package/src/datepicker.js +1 -0
- data/package/src/tinymce.js +142 -0
- data/package.json +2 -2
- metadata +39 -7
- data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +0 -93
- data/app/presenters/alchemy/picture_view.rb +0 -88
- data/app/views/alchemy/admin/pages/_tinymce_custom_config.html.erb +0 -10
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
#
|
3
4
|
# Uncomment this and change the path if necessary to include your own
|
4
5
|
# components.
|
@@ -57,8 +58,8 @@ SimpleForm.setup do |config|
|
|
57
58
|
## Inputs
|
58
59
|
# b.use :input, class: 'input', error_class: 'is-invalid'
|
59
60
|
b.use :label_input
|
60
|
-
b.use :error, wrap_with: {
|
61
|
-
b.use :hint,
|
61
|
+
b.use :error, wrap_with: {tag: :small, class: :error}
|
62
|
+
b.use :hint, wrap_with: {tag: :small, class: :hint}
|
62
63
|
|
63
64
|
## full_messages_for
|
64
65
|
# If you want to display the full error message for the attribute, you can
|
@@ -125,6 +125,7 @@ en:
|
|
125
125
|
last_upload: Last upload only
|
126
126
|
recent: Recently uploaded only
|
127
127
|
without_tag: Without tag
|
128
|
+
deletable: Not linked by file content
|
128
129
|
attachment:
|
129
130
|
by_file_type:
|
130
131
|
name: File Type
|
@@ -136,7 +137,6 @@ en:
|
|
136
137
|
last_upload: Last upload only
|
137
138
|
recent: Recently uploaded only
|
138
139
|
without_tag: Without tag
|
139
|
-
deletable: Not linked by file content
|
140
140
|
|
141
141
|
# === Translations for ingredient validations
|
142
142
|
# Used when a user did not enter (correct) values to the ingredient field.
|
data/config/routes.rb
CHANGED
@@ -1,21 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "alchemy/routing_constraints"
|
3
4
|
|
4
5
|
Alchemy::Engine.routes.draw do
|
5
6
|
root to: "pages#index"
|
6
7
|
|
7
|
-
get "/sitemap.xml" => "pages#sitemap", format
|
8
|
+
get "/sitemap.xml" => "pages#sitemap", :format => "xml"
|
8
9
|
|
9
|
-
scope Alchemy.admin_path, {
|
10
|
-
get "/" => redirect("#{Alchemy.admin_path}/dashboard"), as
|
11
|
-
get "/dashboard" => "admin/dashboard#index", as
|
12
|
-
get "/dashboard/info" => "admin/dashboard#info", as
|
13
|
-
get "/help" => "admin/dashboard#help", as
|
14
|
-
get "/dashboard/update_check" => "admin/dashboard#update_check", as
|
15
|
-
get "/leave" => "admin/base#leave", as
|
10
|
+
scope Alchemy.admin_path, {constraints: Alchemy.admin_constraints} do
|
11
|
+
get "/" => redirect("#{Alchemy.admin_path}/dashboard"), :as => :admin
|
12
|
+
get "/dashboard" => "admin/dashboard#index", :as => :admin_dashboard
|
13
|
+
get "/dashboard/info" => "admin/dashboard#info", :as => :dashboard_info
|
14
|
+
get "/help" => "admin/dashboard#help", :as => :help
|
15
|
+
get "/dashboard/update_check" => "admin/dashboard#update_check", :as => :update_check
|
16
|
+
get "/leave" => "admin/base#leave", :as => :leave_admin
|
16
17
|
end
|
17
18
|
|
18
|
-
namespace :admin, {
|
19
|
+
namespace :admin, {path: Alchemy.admin_path, constraints: Alchemy.admin_constraints} do
|
19
20
|
resources :nodes
|
20
21
|
|
21
22
|
resources :pages do
|
@@ -106,21 +107,21 @@ Alchemy::Engine.routes.draw do
|
|
106
107
|
end
|
107
108
|
|
108
109
|
get "/attachment/:id/download(/:name)" => "attachments#download",
|
109
|
-
|
110
|
+
:as => :download_attachment
|
110
111
|
get "/attachment/:id/show(/:name)" => "attachments#show",
|
111
|
-
|
112
|
+
:as => :show_attachment
|
112
113
|
|
113
114
|
resources :messages, only: [:index, :new, :create]
|
114
115
|
resources :elements, only: :show
|
115
116
|
|
116
|
-
namespace :api, defaults: {
|
117
|
+
namespace :api, defaults: {format: "json"} do
|
117
118
|
resources :ingredients, only: [:index]
|
118
119
|
|
119
120
|
resources :elements, only: [:index, :show]
|
120
121
|
|
121
122
|
resources :pages, only: [:index] do
|
122
|
-
get "elements" => "elements#index", as
|
123
|
-
get "elements/:named" => "elements#index", as
|
123
|
+
get "elements" => "elements#index", :as => "elements"
|
124
|
+
get "elements/:named" => "elements#index", :as => "named_elements"
|
124
125
|
collection do
|
125
126
|
get :nested
|
126
127
|
end
|
@@ -129,8 +130,8 @@ Alchemy::Engine.routes.draw do
|
|
129
130
|
end
|
130
131
|
end
|
131
132
|
|
132
|
-
get "/pages/*urlname(.:format)" => "pages#show", as
|
133
|
-
get "/admin/pages/:id(.:format)" => "pages#show", as
|
133
|
+
get "/pages/*urlname(.:format)" => "pages#show", :as => "page"
|
134
|
+
get "/admin/pages/:id(.:format)" => "pages#show", :as => "preview_page"
|
134
135
|
|
135
136
|
resources :nodes, only: [:index] do
|
136
137
|
member do
|
@@ -141,13 +142,13 @@ Alchemy::Engine.routes.draw do
|
|
141
142
|
end
|
142
143
|
|
143
144
|
get "/:locale" => "pages#index",
|
144
|
-
constraints
|
145
|
-
as
|
145
|
+
:constraints => {locale: Alchemy::RoutingConstraints::LOCALE_REGEXP},
|
146
|
+
:as => :show_language_root
|
146
147
|
|
147
148
|
# The page show action has to be last route
|
148
149
|
constraints(locale: Alchemy::RoutingConstraints::LOCALE_REGEXP) do
|
149
150
|
get "(/:locale)/*urlname(.:format)" => "pages#show",
|
150
|
-
constraints
|
151
|
-
as
|
151
|
+
:constraints => Alchemy::RoutingConstraints.new,
|
152
|
+
:as => :show_page
|
152
153
|
end
|
153
154
|
end
|
data/config/spring.rb
CHANGED
@@ -64,7 +64,7 @@ class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.curre
|
|
64
64
|
t.integer "updater_id"
|
65
65
|
t.boolean "default", default: false, null: false
|
66
66
|
t.string "country_code", default: "", null: false
|
67
|
-
t.references "site", null: false, foreign_key: {
|
67
|
+
t.references "site", null: false, foreign_key: {to_table: :alchemy_sites}
|
68
68
|
t.string "locale"
|
69
69
|
t.index ["creator_id"], name: "index_alchemy_languages_on_creator_id"
|
70
70
|
t.index ["language_code", "country_code"], name: "index_alchemy_languages_on_language_code_and_country_code"
|
@@ -108,7 +108,7 @@ class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.curre
|
|
108
108
|
t.datetime "updated_at", null: false
|
109
109
|
t.integer "creator_id"
|
110
110
|
t.integer "updater_id"
|
111
|
-
t.references "language", null: false, foreign_key: {
|
111
|
+
t.references "language", null: false, foreign_key: {to_table: :alchemy_languages}
|
112
112
|
t.datetime "published_at", precision: nil
|
113
113
|
t.datetime "locked_at", precision: nil
|
114
114
|
t.index ["creator_id"], name: "index_alchemy_pages_on_creator_id"
|
@@ -122,7 +122,7 @@ class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.curre
|
|
122
122
|
|
123
123
|
unless table_exists?("alchemy_page_versions")
|
124
124
|
create_table "alchemy_page_versions" do |t|
|
125
|
-
t.references "page", null: false, foreign_key: {
|
125
|
+
t.references "page", null: false, foreign_key: {to_table: :alchemy_pages, on_delete: :cascade}
|
126
126
|
t.datetime "public_on", precision: nil
|
127
127
|
t.datetime "public_until", precision: nil
|
128
128
|
t.datetime "created_at", null: false
|
@@ -144,7 +144,7 @@ class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.curre
|
|
144
144
|
t.integer "updater_id"
|
145
145
|
t.integer "parent_element_id"
|
146
146
|
t.boolean "fixed", default: false, null: false
|
147
|
-
t.references "page_version", null: false, foreign_key: {
|
147
|
+
t.references "page_version", null: false, foreign_key: {to_table: :alchemy_page_versions, on_delete: :cascade}
|
148
148
|
t.index ["creator_id"], name: "index_alchemy_elements_on_creator_id"
|
149
149
|
t.index ["fixed"], name: "index_alchemy_elements_on_fixed"
|
150
150
|
t.index ["page_version_id", "parent_element_id"], name: "idx_alchemy_elements_on_page_version_id_and_parent_element_id"
|
@@ -155,7 +155,7 @@ class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.curre
|
|
155
155
|
|
156
156
|
unless table_exists?("alchemy_ingredients")
|
157
157
|
create_table "alchemy_ingredients" do |t|
|
158
|
-
t.references "element", null: false, foreign_key: {
|
158
|
+
t.references "element", null: false, foreign_key: {to_table: :alchemy_elements, on_delete: :cascade}
|
159
159
|
t.string "type", null: false
|
160
160
|
t.string "role", null: false
|
161
161
|
t.text "value"
|
@@ -186,8 +186,8 @@ class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.curre
|
|
186
186
|
t.integer "lft", null: false
|
187
187
|
t.integer "rgt", null: false
|
188
188
|
t.integer "depth", default: 0, null: false
|
189
|
-
t.references "page", foreign_key: {
|
190
|
-
t.references "language", null: false, foreign_key: {
|
189
|
+
t.references "page", foreign_key: {to_table: :alchemy_pages, on_delete: :restrict}
|
190
|
+
t.references "language", null: false, foreign_key: {to_table: :alchemy_languages}
|
191
191
|
t.integer "creator_id"
|
192
192
|
t.integer "updater_id"
|
193
193
|
t.datetime "created_at", null: false
|
@@ -222,7 +222,7 @@ class AlchemySixPointOne < ActiveRecord::Migration[ActiveRecord::Migration.curre
|
|
222
222
|
|
223
223
|
unless table_exists?("alchemy_picture_thumbs")
|
224
224
|
create_table "alchemy_picture_thumbs" do |t|
|
225
|
-
t.references "picture", null: false, foreign_key: {
|
225
|
+
t.references "picture", null: false, foreign_key: {to_table: :alchemy_pictures}
|
226
226
|
t.string "signature", null: false
|
227
227
|
t.text "uid", null: false
|
228
228
|
t.index ["signature"], name: "index_alchemy_picture_thumbs_on_signature", unique: true
|
data/lib/alchemy/admin/locale.rb
CHANGED
@@ -18,10 +18,10 @@ module Alchemy
|
|
18
18
|
# It respects the default translation from your +config/application.rb+ +default_locale+ config option.
|
19
19
|
#
|
20
20
|
def set_translation
|
21
|
-
if locale_change_needed?
|
22
|
-
|
21
|
+
locale = if locale_change_needed?
|
22
|
+
available_locale || ::I18n.default_locale
|
23
23
|
else
|
24
|
-
|
24
|
+
session[:alchemy_locale]
|
25
25
|
end
|
26
26
|
::I18n.locale = session[:alchemy_locale] = locale
|
27
27
|
end
|
@@ -48,7 +48,7 @@ module Alchemy
|
|
48
48
|
port: uri.port,
|
49
49
|
path: page.url_path,
|
50
50
|
userinfo: userinfo,
|
51
|
-
query: {
|
51
|
+
query: {alchemy_preview_mode: true}.to_param
|
52
52
|
).to_s
|
53
53
|
else
|
54
54
|
routes.admin_page_path(page)
|
@@ -73,7 +73,7 @@ module Alchemy
|
|
73
73
|
end
|
74
74
|
|
75
75
|
def uri_class
|
76
|
-
if uri.
|
76
|
+
if uri.instance_of?(URI::Generic)
|
77
77
|
raise MissingProtocolError, "Please provide the protocol with preview['host']"
|
78
78
|
else
|
79
79
|
uri.class
|
@@ -90,7 +90,7 @@ module Alchemy
|
|
90
90
|
@@user_class ||= begin
|
91
91
|
@@user_class_name.constantize
|
92
92
|
rescue NameError => e
|
93
|
-
if
|
93
|
+
if /#{Regexp.escape(@@user_class_name)}/.match?(e.message)
|
94
94
|
Rails.logger.warn <<~MSG
|
95
95
|
#{e.message}
|
96
96
|
#{e.backtrace.join("\n")}
|
data/lib/alchemy/config.rb
CHANGED
@@ -20,7 +20,7 @@ module Alchemy
|
|
20
20
|
|
21
21
|
# Returns a host string with the domain the app is running on.
|
22
22
|
def current_server
|
23
|
-
|
23
|
+
"#{request.protocol}#{request.host_with_port}"
|
24
24
|
end
|
25
25
|
|
26
26
|
# The current authorized user.
|
@@ -62,11 +62,11 @@ module Alchemy
|
|
62
62
|
# Try to find and stores current language for Alchemy.
|
63
63
|
#
|
64
64
|
def set_alchemy_language(lang = nil)
|
65
|
-
if lang
|
66
|
-
|
65
|
+
@language = if lang
|
66
|
+
lang.is_a?(Language) ? lang : load_alchemy_language_from_id_or_code(lang)
|
67
67
|
else
|
68
68
|
# find the best language and remember it for later
|
69
|
-
|
69
|
+
load_alchemy_language_from_params ||
|
70
70
|
load_alchemy_language_from_session ||
|
71
71
|
Language.default
|
72
72
|
end
|
data/lib/alchemy/deprecation.rb
CHANGED
@@ -19,7 +19,7 @@ module Alchemy
|
|
19
19
|
# resize all frames in a GIF
|
20
20
|
# @link https://imagemagick.org/script/command-line-options.php#coalesce
|
21
21
|
# @link https://imagemagick.org/script/command-line-options.php#deconstruct
|
22
|
-
@content&.mime_type == "image/gif" ? "-coalesce #{super} -deconstruct" : super
|
22
|
+
(@content&.mime_type == "image/gif") ? "-coalesce #{super} -deconstruct" : super
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -51,11 +51,11 @@ module Alchemy
|
|
51
51
|
YAML.safe_load(
|
52
52
|
ERB.new(File.read(definitions_file_path)).result,
|
53
53
|
permitted_classes: YAML_PERMITTED_CLASSES,
|
54
|
-
aliases: true
|
54
|
+
aliases: true
|
55
55
|
) || []
|
56
56
|
else
|
57
57
|
raise LoadError,
|
58
|
-
|
58
|
+
"Could not find elements.yml file! Please run `rails generate alchemy:install`"
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
data/lib/alchemy/engine.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Alchemy
|
3
4
|
class Engine < Rails::Engine
|
4
5
|
isolate_namespace Alchemy
|
@@ -32,7 +33,7 @@ module Alchemy
|
|
32
33
|
Ransack.configure do |config|
|
33
34
|
config.custom_arrows = {
|
34
35
|
up_arrow: '<i class="fa fas fa-xs fa-arrow-up"></i>',
|
35
|
-
down_arrow: '<i class="fa fas fa-xs fa-arrow-down"></i>'
|
36
|
+
down_arrow: '<i class="fa fas fa-xs fa-arrow-down"></i>'
|
36
37
|
}
|
37
38
|
end
|
38
39
|
end
|
data/lib/alchemy/filetypes.rb
CHANGED
@@ -8,7 +8,7 @@ module Alchemy
|
|
8
8
|
"audio/mpeg",
|
9
9
|
"audio/mp4",
|
10
10
|
"audio/wav",
|
11
|
-
"audio/x-wav"
|
11
|
+
"audio/x-wav"
|
12
12
|
]
|
13
13
|
|
14
14
|
IMAGE_FILE_TYPES = [
|
@@ -17,7 +17,7 @@ module Alchemy
|
|
17
17
|
"image/png",
|
18
18
|
"image/svg+xml",
|
19
19
|
"image/tiff",
|
20
|
-
"image/x-psd"
|
20
|
+
"image/x-psd"
|
21
21
|
]
|
22
22
|
|
23
23
|
VCARD_FILE_TYPES = ["text/x-vcard", "application/vcard"]
|
@@ -29,31 +29,31 @@ module Alchemy
|
|
29
29
|
"video/mpeg",
|
30
30
|
"video/quicktime",
|
31
31
|
"video/x-msvideo",
|
32
|
-
"video/x-ms-wmv"
|
32
|
+
"video/x-ms-wmv"
|
33
33
|
]
|
34
34
|
|
35
35
|
TEXT_FILE_TYPES = [
|
36
36
|
"application/rtf",
|
37
|
-
"text/plain"
|
37
|
+
"text/plain"
|
38
38
|
]
|
39
39
|
|
40
40
|
EXCEL_FILE_TYPES = [
|
41
41
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
42
42
|
"application/vnd.ms-excel",
|
43
43
|
"application/msexcel",
|
44
|
-
"text/csv"
|
44
|
+
"text/csv"
|
45
45
|
]
|
46
46
|
|
47
47
|
WORD_FILE_TYPES = [
|
48
48
|
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
49
49
|
"application/vnd.ms-word",
|
50
|
-
"application/msword"
|
50
|
+
"application/msword"
|
51
51
|
]
|
52
52
|
|
53
53
|
POWERPOINT_FILE_TYPES = [
|
54
54
|
"application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
55
55
|
"application/vnd.ms-powerpoint",
|
56
|
-
"application/mspowerpoint"
|
56
|
+
"application/mspowerpoint"
|
57
57
|
]
|
58
58
|
end
|
59
59
|
end
|
@@ -11,7 +11,7 @@ module Alchemy
|
|
11
11
|
if object.respond_to?(:attribute_fixed?) && object.attribute_fixed?(attribute_name)
|
12
12
|
options[:disabled] = true
|
13
13
|
options[:input_html] = options.fetch(:input_html, {}).merge(
|
14
|
-
"data-alchemy-tooltip" => Alchemy.t(:attribute_fixed, attribute: attribute_name)
|
14
|
+
"data-alchemy-tooltip" => Alchemy.t(:attribute_fixed, attribute: attribute_name)
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
@@ -31,8 +31,8 @@ module Alchemy
|
|
31
31
|
input_options = {
|
32
32
|
type: :text,
|
33
33
|
class: type,
|
34
|
-
data: {
|
35
|
-
value: date&.iso8601
|
34
|
+
data: {datepicker_type: type},
|
35
|
+
value: date&.iso8601
|
36
36
|
}.merge(options[:input_html] || {})
|
37
37
|
|
38
38
|
input attribute_name, as: :string, input_html: input_options
|
@@ -42,7 +42,7 @@ module Alchemy
|
|
42
42
|
#
|
43
43
|
def submit(label, options = {})
|
44
44
|
options = {
|
45
|
-
wrapper_html: {
|
45
|
+
wrapper_html: {class: "submit"}
|
46
46
|
}.update(options)
|
47
47
|
template.content_tag("div", options.delete(:wrapper_html)) do
|
48
48
|
template.content_tag("button", label, options.delete(:input_html))
|
data/lib/alchemy/i18n.rb
CHANGED
@@ -54,10 +54,12 @@ module Alchemy
|
|
54
54
|
end
|
55
55
|
|
56
56
|
def available_locales
|
57
|
-
|
58
|
-
|
59
|
-
f
|
60
|
-
|
57
|
+
Rails.application.config.i18n.available_locales || begin
|
58
|
+
@@available_locales ||= nil
|
59
|
+
@@available_locales || translation_files.collect { |f|
|
60
|
+
f.match(LOCALE_FILE_PATTERN)[1].to_sym
|
61
|
+
}.uniq.sort
|
62
|
+
end
|
61
63
|
end
|
62
64
|
|
63
65
|
def available_locales=(locales)
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require "thor"
|
3
4
|
|
4
5
|
module Alchemy
|
@@ -15,7 +16,7 @@ module Alchemy
|
|
15
16
|
mountpoint = ask("- At which path do you want to mount Alchemy CMS at?", default: mountpoint)
|
16
17
|
end
|
17
18
|
sentinel = /\.routes\.draw do(?:\s*\|map\|)?\s*$/
|
18
|
-
inject_into_file "./config/routes.rb", "\n mount Alchemy::Engine => '#{mountpoint}'\n", {
|
19
|
+
inject_into_file "./config/routes.rb", "\n mount Alchemy::Engine => '#{mountpoint}'\n", {after: sentinel, verbose: true}
|
19
20
|
end
|
20
21
|
|
21
22
|
def set_primary_language(code: "en", name: "English", auto_accept: false)
|
data/lib/alchemy/page_layout.rb
CHANGED
data/lib/alchemy/permissions.rb
CHANGED
@@ -89,7 +89,7 @@ module Alchemy
|
|
89
89
|
:alchemy_admin_pages,
|
90
90
|
:alchemy_admin_pictures,
|
91
91
|
:alchemy_admin_tags,
|
92
|
-
:alchemy_admin_users
|
92
|
+
:alchemy_admin_users
|
93
93
|
]
|
94
94
|
|
95
95
|
# Controller actions
|
@@ -127,7 +127,7 @@ module Alchemy
|
|
127
127
|
# Navigation
|
128
128
|
can :index, [
|
129
129
|
:alchemy_admin_languages,
|
130
|
-
:alchemy_admin_users
|
130
|
+
:alchemy_admin_users
|
131
131
|
]
|
132
132
|
|
133
133
|
# Resources
|
@@ -136,7 +136,7 @@ module Alchemy
|
|
136
136
|
:copy_language_tree,
|
137
137
|
:flush,
|
138
138
|
:order,
|
139
|
-
:switch_language
|
139
|
+
:switch_language
|
140
140
|
], Alchemy::Page
|
141
141
|
|
142
142
|
# Resources which may be locked via template permissions
|
@@ -149,7 +149,7 @@ module Alchemy
|
|
149
149
|
#
|
150
150
|
can([
|
151
151
|
:create,
|
152
|
-
:destroy
|
152
|
+
:destroy
|
153
153
|
], Alchemy::Page) { |p| p.editable_by?(@user) }
|
154
154
|
|
155
155
|
can(:publish, Alchemy::Page) do |page|
|
@@ -160,6 +160,7 @@ module Alchemy
|
|
160
160
|
can :manage, Alchemy::Attachment
|
161
161
|
can :manage, Alchemy::Tag
|
162
162
|
can :index, Alchemy::Language
|
163
|
+
can :switch, Alchemy::Language
|
163
164
|
end
|
164
165
|
end
|
165
166
|
|
data/lib/alchemy/resource.rb
CHANGED
@@ -101,8 +101,8 @@ module Alchemy
|
|
101
101
|
attr_accessor :resource_relations, :model_associations
|
102
102
|
attr_reader :model
|
103
103
|
|
104
|
-
DEFAULT_SKIPPED_ATTRIBUTES = %w
|
105
|
-
DEFAULT_SKIPPED_ASSOCIATIONS = %w
|
104
|
+
DEFAULT_SKIPPED_ATTRIBUTES = %w[id created_at creator_id]
|
105
|
+
DEFAULT_SKIPPED_ASSOCIATIONS = %w[creator]
|
106
106
|
SEARCHABLE_COLUMN_TYPES = [:string, :text]
|
107
107
|
|
108
108
|
def initialize(controller_path, module_definition = nil, custom_model = nil)
|
@@ -169,7 +169,7 @@ module Alchemy
|
|
169
169
|
name: col.name,
|
170
170
|
type: resource_column_type(col),
|
171
171
|
relation: resource_relation(col.name),
|
172
|
-
enum: enum_values_collection_for_select(col.name)
|
172
|
+
enum: enum_values_collection_for_select(col.name)
|
173
173
|
}.delete_if { |_k, v| v.blank? }
|
174
174
|
end.compact
|
175
175
|
end
|
@@ -183,16 +183,16 @@ module Alchemy
|
|
183
183
|
::I18n.t(key, scope: [
|
184
184
|
:activerecord, :attributes, model.model_name.i18n_key, "#{column_name}_values"
|
185
185
|
], default: key.humanize),
|
186
|
-
key
|
186
|
+
key
|
187
187
|
]
|
188
188
|
end
|
189
189
|
end
|
190
190
|
|
191
191
|
def sorted_attributes
|
192
|
-
@_sorted_attributes ||= attributes
|
193
|
-
sort_by
|
194
|
-
sort_by! { |attr| attr[:type] == :boolean ? 1 : 0 }
|
195
|
-
sort_by! { |attr| attr[:name] == "updated_at" ? 1 : 0 }
|
192
|
+
@_sorted_attributes ||= attributes
|
193
|
+
.sort_by { |attr| (attr[:name] == "name") ? 0 : 1 }
|
194
|
+
.sort_by! { |attr| (attr[:type] == :boolean) ? 1 : 0 }
|
195
|
+
.sort_by! { |attr| (attr[:name] == "updated_at") ? 1 : 0 }
|
196
196
|
end
|
197
197
|
|
198
198
|
def editable_attributes
|
@@ -281,7 +281,7 @@ module Alchemy
|
|
281
281
|
def searchable_relation_attribute(attribute)
|
282
282
|
{
|
283
283
|
name: "#{attribute[:relation][:model_association].name}_#{attribute[:relation][:attr_method]}",
|
284
|
-
type: attribute[:relation][:attr_type]
|
284
|
+
type: attribute[:relation][:attr_type]
|
285
285
|
}
|
286
286
|
end
|
287
287
|
|
@@ -325,7 +325,7 @@ module Alchemy
|
|
325
325
|
resource_relations[foreign_key] = options.merge(
|
326
326
|
model_association: association,
|
327
327
|
name: relation_name,
|
328
|
-
collection: collection
|
328
|
+
collection: collection
|
329
329
|
)
|
330
330
|
end
|
331
331
|
end
|
@@ -23,7 +23,7 @@ module Alchemy
|
|
23
23
|
|
24
24
|
def resource_url_proxy
|
25
25
|
if resource_handler.in_engine?
|
26
|
-
eval(resource_handler.engine_name)
|
26
|
+
eval(resource_handler.engine_name) # rubocop:disable Security/Eval
|
27
27
|
else
|
28
28
|
main_app
|
29
29
|
end
|
@@ -80,11 +80,11 @@ module Alchemy
|
|
80
80
|
value = record.present? ? record.send(attribute[:relation][:attr_method]) : Alchemy.t(:not_found)
|
81
81
|
elsif attribute_value && attribute[:type].to_s =~ /(date|time)/
|
82
82
|
localization_format = if attribute[:type] == :datetime
|
83
|
-
options[:datetime_format] || :
|
83
|
+
options[:datetime_format] || :"alchemy.default"
|
84
84
|
elsif attribute[:type] == :date
|
85
|
-
options[:date_format] || :
|
85
|
+
options[:date_format] || :"alchemy.default"
|
86
86
|
else
|
87
|
-
options[:time_format] || :
|
87
|
+
options[:time_format] || :"alchemy.time"
|
88
88
|
end
|
89
89
|
value = l(attribute_value, format: localization_format)
|
90
90
|
else
|
@@ -110,8 +110,8 @@ module Alchemy
|
|
110
110
|
options.merge(
|
111
111
|
as: "string",
|
112
112
|
input_html: {
|
113
|
-
data: {
|
114
|
-
}
|
113
|
+
data: {datepicker_type: input_type}
|
114
|
+
}
|
115
115
|
)
|
116
116
|
when "text"
|
117
117
|
options.merge(as: "text", input_html: {rows: 4})
|
@@ -135,7 +135,7 @@ module Alchemy
|
|
135
135
|
# If the attribute contains a resource_relation, then the table and column for related model will be returned.
|
136
136
|
#
|
137
137
|
def sortable_resource_header_column(attribute)
|
138
|
-
if relation = attribute[:relation]
|
138
|
+
if (relation = attribute[:relation])
|
139
139
|
"#{relation[:model_association].name}_#{relation[:attr_method]}"
|
140
140
|
else
|
141
141
|
attribute[:name]
|
@@ -32,9 +32,9 @@ module Alchemy
|
|
32
32
|
|
33
33
|
# We don't want to handle the Rails info routes.
|
34
34
|
def no_rails_route?
|
35
|
-
return true if !%w
|
35
|
+
return true if !%w[development test].include?(Rails.env)
|
36
36
|
|
37
|
-
|
37
|
+
!@params["urlname"].start_with?("rails/")
|
38
38
|
end
|
39
39
|
end
|
40
40
|
end
|