alchemy_cms 4.1.2 → 4.2.0.rc1
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.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/Bug_report.md +0 -5
- data/.rubocop.yml +4 -1
- data/.travis.yml +3 -3
- data/CHANGELOG.md +29 -10
- data/Gemfile +5 -7
- data/README.md +114 -62
- data/Rakefile +2 -2
- data/alchemy_cms.gemspec +5 -5
- data/app/assets/images/alchemy/icon.svg +1 -1
- data/app/assets/javascripts/alchemy/admin.js +2 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +0 -24
- data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +11 -9
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +7 -24
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +9 -8
- data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +38 -0
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +2 -4
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +1 -1
- data/app/assets/stylesheets/alchemy/_mixins.scss +2 -1
- data/app/assets/stylesheets/alchemy/_variables.scss +7 -2
- data/app/assets/stylesheets/alchemy/admin.scss +2 -1
- data/app/assets/stylesheets/alchemy/archive.scss +18 -4
- data/app/assets/stylesheets/alchemy/buttons.scss +1 -1
- data/app/assets/stylesheets/alchemy/dialogs.scss +1 -1
- data/app/assets/stylesheets/alchemy/elements.scss +154 -90
- data/app/assets/stylesheets/alchemy/filter_field.scss +30 -0
- data/app/assets/stylesheets/alchemy/flatpickr.scss +839 -0
- data/app/assets/stylesheets/alchemy/forms.scss +5 -1
- data/app/assets/stylesheets/alchemy/frame.scss +6 -14
- data/app/assets/stylesheets/alchemy/navigation.scss +109 -98
- data/app/assets/stylesheets/alchemy/search.scss +11 -29
- data/app/assets/stylesheets/alchemy/tables.scss +0 -23
- data/app/assets/stylesheets/alchemy/tags.scss +4 -27
- data/app/assets/stylesheets/alchemy/toolbar.scss +12 -2
- data/app/assets/stylesheets/tinymce/skins/alchemy/skin.min.css.scss +4 -33
- data/app/controllers/alchemy/admin/attachments_controller.rb +1 -12
- data/app/controllers/alchemy/admin/contents_controller.rb +2 -24
- data/app/controllers/alchemy/admin/elements_controller.rb +11 -49
- data/app/controllers/alchemy/admin/pages_controller.rb +1 -1
- data/app/controllers/alchemy/admin/pictures_controller.rb +1 -14
- data/app/controllers/alchemy/api/contents_controller.rb +1 -1
- data/app/controllers/alchemy/api/elements_controller.rb +1 -1
- data/app/controllers/alchemy/api/pages_controller.rb +1 -1
- data/app/controllers/concerns/alchemy/admin/archive_overlay.rb +20 -0
- data/app/helpers/alchemy/admin/base_helper.rb +8 -18
- data/app/helpers/alchemy/admin/elements_helper.rb +55 -85
- data/app/helpers/alchemy/admin/pictures_helper.rb +0 -23
- data/app/helpers/alchemy/elements_helper.rb +80 -120
- data/app/helpers/alchemy/pages_helper.rb +5 -24
- data/app/models/alchemy/content.rb +0 -1
- data/app/models/alchemy/content/factory.rb +33 -57
- data/app/models/alchemy/element.rb +46 -66
- data/app/models/alchemy/element/element_contents.rb +2 -2
- data/app/models/alchemy/page.rb +34 -4
- data/app/models/alchemy/page/page_elements.rb +30 -122
- data/app/serializers/alchemy/attachment_serializer.rb +0 -2
- data/app/serializers/alchemy/content_serializer.rb +0 -2
- data/app/serializers/alchemy/element_serializer.rb +0 -3
- data/app/serializers/alchemy/essence_boolean_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_date_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_file_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_html_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_link_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_picture_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_richtext_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_select_serializer.rb +0 -2
- data/app/serializers/alchemy/essence_text_serializer.rb +0 -2
- data/app/serializers/alchemy/legacy_element_serializer.rb +0 -3
- data/app/serializers/alchemy/page_serializer.rb +2 -8
- data/app/serializers/alchemy/page_tree_serializer.rb +1 -1
- data/app/serializers/alchemy/picture_serializer.rb +0 -2
- data/app/views/alchemy/admin/clipboard/index.html.erb +2 -2
- data/app/views/alchemy/admin/clipboard/insert.js.erb +9 -12
- data/app/views/alchemy/admin/contents/create.js.erb +4 -30
- data/app/views/alchemy/admin/elements/_element.html.erb +27 -12
- data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_new_element_form.html.erb +0 -10
- data/app/views/alchemy/admin/elements/create.js.erb +12 -12
- data/app/views/alchemy/admin/elements/fold.js.erb +1 -1
- data/app/views/alchemy/admin/elements/index.html.erb +20 -19
- data/app/views/alchemy/admin/elements/publish.js.erb +5 -0
- data/app/views/alchemy/admin/elements/trash.js.erb +4 -1
- data/app/views/alchemy/admin/essence_pictures/assign.js.erb +0 -7
- data/app/views/alchemy/admin/essence_pictures/destroy.js.erb +0 -22
- data/app/views/alchemy/admin/pages/_publication_fields.html.erb +2 -4
- data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/index.html.erb +14 -10
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +7 -5
- data/app/views/alchemy/admin/partials/_routes.html.erb +0 -1
- data/app/views/alchemy/admin/partials/_search_form.html.erb +6 -4
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +6 -3
- data/app/views/alchemy/admin/pictures/index.html.erb +1 -1
- data/app/views/alchemy/admin/trash/index.html.erb +8 -7
- data/app/views/alchemy/elements/_editor_not_found.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_picture_editor.html.erb +4 -19
- data/app/views/layouts/alchemy/admin.html.erb +1 -0
- data/bin/rspec +0 -5
- data/config/alchemy/config.yml +3 -0
- data/config/brakeman.ignore +1 -1
- data/config/locales/alchemy.en.yml +6 -12
- data/config/routes.rb +1 -5
- data/db/migrate/20180226123013_alchemy_four_point_zero.rb +0 -29
- data/db/migrate/20180519204655_add_fixed_to_alchemy_elements.rb +6 -0
- data/lib/alchemy/admin/locale.rb +1 -1
- data/lib/alchemy/cache_digests/template_tracker.rb +4 -27
- data/lib/alchemy/elements_finder.rb +111 -0
- data/lib/alchemy/errors.rb +0 -4
- data/lib/alchemy/modules.rb +49 -18
- data/lib/alchemy/tasks/tidy.rb +3 -40
- data/lib/alchemy/test_support/controller_requests.rb +1 -1
- data/lib/alchemy/test_support/essence_shared_examples.rb +1 -1
- data/lib/alchemy/test_support/factories/attachment_factory.rb +5 -3
- data/lib/alchemy/test_support/factories/content_factory.rb +4 -4
- data/lib/alchemy/test_support/factories/dummy_user_factory.rb +5 -5
- data/lib/alchemy/test_support/factories/element_factory.rb +12 -7
- data/lib/alchemy/test_support/factories/essence_text_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/language_factory.rb +13 -13
- data/lib/alchemy/test_support/factories/page_factory.rb +18 -17
- data/lib/alchemy/test_support/factories/picture_factory.rb +6 -4
- data/lib/alchemy/test_support/factories/site_factory.rb +6 -6
- data/lib/alchemy/tinymce.rb +1 -1
- data/lib/alchemy/upgrader/four_point_two.rb +68 -0
- data/lib/alchemy/upgrader/tasks/cells_migration.rb +41 -0
- data/lib/alchemy/upgrader/tasks/cells_upgrader.rb +146 -0
- data/lib/alchemy/upgrader/tasks/picture_gallery_migration.rb +65 -0
- data/lib/alchemy/upgrader/tasks/picture_gallery_upgrader.rb +195 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +1 -0
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +1 -0
- data/lib/rails/generators/alchemy/elements/templates/editor.html.erb +0 -3
- data/lib/rails/generators/alchemy/elements/templates/editor.html.haml +0 -3
- data/lib/rails/generators/alchemy/elements/templates/editor.html.slim +0 -3
- data/lib/rails/generators/alchemy/elements/templates/view.html.erb +3 -14
- data/lib/rails/generators/alchemy/elements/templates/view.html.haml +3 -10
- data/lib/rails/generators/alchemy/elements/templates/view.html.slim +3 -10
- data/lib/tasks/alchemy/tidy.rake +1 -23
- data/lib/tasks/alchemy/upgrade.rake +44 -1
- data/vendor/assets/javascripts/flatpickr/flatpickr.min.js +2 -0
- data/vendor/assets/javascripts/tinymce/license.txt +0 -0
- data/vendor/assets/javascripts/tinymce/tinymce.min.js +2 -2
- metadata +25 -31
- data/app/assets/stylesheets/alchemy/jquery.datetimepicker.scss +0 -478
- data/app/models/alchemy/cell.rb +0 -95
- data/app/models/alchemy/page/page_cells.rb +0 -69
- data/app/serializers/alchemy/cell_serializer.rb +0 -19
- data/app/views/alchemy/admin/contents/new.html.erb +0 -11
- data/app/views/alchemy/admin/contents/order.js.erb +0 -3
- data/app/views/alchemy/admin/elements/_add_picture.html.erb +0 -14
- data/app/views/alchemy/admin/elements/_picture_gallery_editor.html.erb +0 -24
- data/bin/spring +0 -16
- data/lib/alchemy/test_support/factories/cell_factory.rb +0 -9
- data/vendor/assets/javascripts/date-formatter.js +0 -161
- data/vendor/assets/javascripts/jquery_plugins/jquery.datetimepicker.full.min.js +0 -2
|
@@ -24,12 +24,22 @@
|
|
|
24
24
|
.toolbar_buttons {
|
|
25
25
|
margin-right: 8px;
|
|
26
26
|
white-space: nowrap;
|
|
27
|
+
overflow-x: auto;
|
|
28
|
+
overflow-y: visible;
|
|
29
|
+
max-width: calc(100vw - #{$collapsed-main-menu-width + 65px});
|
|
30
|
+
-webkit-overflow-scrolling: touch;
|
|
31
|
+
|
|
32
|
+
@media screen and (min-width: $medium-screen-break-point) {
|
|
33
|
+
overflow: visible;
|
|
34
|
+
}
|
|
27
35
|
|
|
28
36
|
&.right {
|
|
29
37
|
position: absolute;
|
|
30
|
-
right:
|
|
31
|
-
top:
|
|
38
|
+
right: -8px;
|
|
39
|
+
top: 0;
|
|
32
40
|
margin-left: 8px;
|
|
41
|
+
padding: 8px;
|
|
42
|
+
background-color: $toolbar-bg-color;
|
|
33
43
|
|
|
34
44
|
label {
|
|
35
45
|
left: auto;
|
|
@@ -28,9 +28,6 @@
|
|
|
28
28
|
direction: ltr;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
.mce-widget button {
|
|
32
|
-
}
|
|
33
|
-
|
|
34
31
|
.mce-container *[unselectable] {
|
|
35
32
|
user-select: none;
|
|
36
33
|
}
|
|
@@ -70,6 +67,8 @@
|
|
|
70
67
|
overflow: hidden;
|
|
71
68
|
height: 100%;
|
|
72
69
|
z-index: 100;
|
|
70
|
+
background: #fff;
|
|
71
|
+
border-radius: 0;
|
|
73
72
|
|
|
74
73
|
.mce-resizehandle {
|
|
75
74
|
display: none;
|
|
@@ -337,21 +336,6 @@ div.mce-tinymce-inline {
|
|
|
337
336
|
}
|
|
338
337
|
}
|
|
339
338
|
|
|
340
|
-
.mce-fullscreen {
|
|
341
|
-
border: 0;
|
|
342
|
-
padding: 0;
|
|
343
|
-
margin: 0;
|
|
344
|
-
overflow: hidden;
|
|
345
|
-
background: #fff;
|
|
346
|
-
height: 100%;
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
div.mce-fullscreen {
|
|
350
|
-
position: fixed;
|
|
351
|
-
top: 0;
|
|
352
|
-
left: 0;
|
|
353
|
-
}
|
|
354
|
-
|
|
355
339
|
#mce-modal-block {
|
|
356
340
|
opacity: 0;
|
|
357
341
|
position: fixed;
|
|
@@ -722,9 +706,7 @@ body .mce-abs-layout-item {
|
|
|
722
706
|
|
|
723
707
|
&.mce-active,
|
|
724
708
|
&.mce-active:hover {
|
|
725
|
-
background-color:
|
|
726
|
-
background-image: linear-gradient(#e5e5e5, #cccccc);
|
|
727
|
-
box-shadow: #c4c4c4 0 1px 2px inset;
|
|
709
|
+
background-color: $default-border-color;
|
|
728
710
|
|
|
729
711
|
button i {
|
|
730
712
|
color: #000;
|
|
@@ -732,18 +714,7 @@ body .mce-abs-layout-item {
|
|
|
732
714
|
}
|
|
733
715
|
|
|
734
716
|
&:not(.mce-disabled):active {
|
|
735
|
-
background-color:
|
|
736
|
-
background-image: -moz-linear-gradient(top,#e6e6e6,#c0c0c0);
|
|
737
|
-
background-image: -webkit-gradient(linear,0 0,0 100%,from(#e6e6e6),to(#c0c0c0));
|
|
738
|
-
background-image: -webkit-linear-gradient(top,#e6e6e6,#c0c0c0);
|
|
739
|
-
background-image: -o-linear-gradient(top,#e6e6e6,#c0c0c0);
|
|
740
|
-
background-image: linear-gradient(to bottom,#e6e6e6,#c0c0c0);
|
|
741
|
-
background-repeat: repeat-x;
|
|
742
|
-
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr= '#ffe6e6e6',endColorstr='#ffc0c0c0',GradientType=0);
|
|
743
|
-
zoom: 1;
|
|
744
|
-
-webkit-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
|
|
745
|
-
-moz-box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
|
|
746
|
-
box-shadow: inset 0 2px 4px rgba(0,0,0,0.15),0 1px 2px rgba(0,0,0,0.05);
|
|
717
|
+
background-color: $default-border-color;
|
|
747
718
|
}
|
|
748
719
|
}
|
|
749
720
|
|
|
@@ -4,6 +4,7 @@ module Alchemy
|
|
|
4
4
|
module Admin
|
|
5
5
|
class AttachmentsController < ResourcesController
|
|
6
6
|
include UploaderResponses
|
|
7
|
+
include ArchiveOverlay
|
|
7
8
|
|
|
8
9
|
helper 'alchemy/admin/tags'
|
|
9
10
|
|
|
@@ -85,18 +86,6 @@ module Alchemy
|
|
|
85
86
|
end
|
|
86
87
|
end
|
|
87
88
|
|
|
88
|
-
def in_overlay?
|
|
89
|
-
params[:content_id].present?
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def archive_overlay
|
|
93
|
-
@content = Content.find_by(id: params[:content_id])
|
|
94
|
-
respond_to do |format|
|
|
95
|
-
format.html { render partial: 'archive_overlay' }
|
|
96
|
-
format.js { render action: 'archive_overlay' }
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
89
|
def attachment_attributes
|
|
101
90
|
params.require(:attachment).permit(:file, :name, :file_name, :tag_list)
|
|
102
91
|
end
|
|
@@ -8,36 +8,14 @@ module Alchemy
|
|
|
8
8
|
authorize_resource class: Alchemy::Content
|
|
9
9
|
|
|
10
10
|
def create
|
|
11
|
-
@
|
|
12
|
-
@content = Content.create_from_scratch(@element, content_params)
|
|
11
|
+
@content = Content.create(content_params)
|
|
13
12
|
@html_options = params[:html_options] || {}
|
|
14
|
-
if picture_gallery_editor?
|
|
15
|
-
@content.update_essence(picture_id: params[:picture_id])
|
|
16
|
-
@gallery_pictures = @element.contents.gallery_pictures
|
|
17
|
-
options_from_params[:sortable] = @gallery_pictures.size > 1
|
|
18
|
-
@content_dom_id = "#add_picture_#{@element.id}"
|
|
19
|
-
else
|
|
20
|
-
@content_dom_id = "#add_content_for_element_#{@element.id}"
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def order
|
|
25
|
-
Content.transaction do
|
|
26
|
-
params[:content_ids].each_with_index do |id, idx|
|
|
27
|
-
Content.where(id: id).update_all(position: idx + 1)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
@notice = Alchemy.t("Successfully saved content position")
|
|
31
13
|
end
|
|
32
14
|
|
|
33
15
|
private
|
|
34
16
|
|
|
35
17
|
def content_params
|
|
36
|
-
params.require(:content).permit(:element_id, :name, :ingredient
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def picture_gallery_editor?
|
|
40
|
-
params[:content][:essence_type] == 'Alchemy::EssencePicture' && options_from_params[:grouped] == 'true'
|
|
18
|
+
params.require(:content).permit(:element_id, :name, :ingredient)
|
|
41
19
|
end
|
|
42
20
|
end
|
|
43
21
|
end
|
|
@@ -8,12 +8,8 @@ module Alchemy
|
|
|
8
8
|
|
|
9
9
|
def index
|
|
10
10
|
@page = Page.find(params[:page_id])
|
|
11
|
-
@
|
|
12
|
-
|
|
13
|
-
@elements = @page.elements.not_trashed
|
|
14
|
-
else
|
|
15
|
-
@elements = @page.elements_grouped_by_cells
|
|
16
|
-
end
|
|
11
|
+
@elements = @page.elements
|
|
12
|
+
@fixed_elements = @page.fixed_elements
|
|
17
13
|
end
|
|
18
14
|
|
|
19
15
|
def list
|
|
@@ -39,21 +35,14 @@ module Alchemy
|
|
|
39
35
|
Element.transaction do
|
|
40
36
|
if @paste_from_clipboard = params[:paste_from_clipboard].present?
|
|
41
37
|
@element = paste_element_from_clipboard
|
|
42
|
-
@cell = @element.cell
|
|
43
38
|
else
|
|
44
|
-
@element = Element.
|
|
45
|
-
if @page.can_have_cells?
|
|
46
|
-
@cell = find_or_create_cell
|
|
47
|
-
@element.cell = @cell
|
|
48
|
-
end
|
|
49
|
-
@element.save
|
|
39
|
+
@element = Element.create(create_element_params)
|
|
50
40
|
end
|
|
51
41
|
if @page.definition['insert_elements_at'] == 'top'
|
|
52
42
|
@insert_at_top = true
|
|
53
43
|
@element.move_to_top
|
|
54
44
|
end
|
|
55
45
|
end
|
|
56
|
-
@cell_name = @cell.nil? ? "for_other_elements" : @cell.name
|
|
57
46
|
if @element.valid?
|
|
58
47
|
render :create
|
|
59
48
|
else
|
|
@@ -95,11 +84,10 @@ module Alchemy
|
|
|
95
84
|
@parent_element = Element.find_by(id: params[:parent_element_id])
|
|
96
85
|
Element.transaction do
|
|
97
86
|
params.fetch(:element_ids, []).each_with_index do |element_id, idx|
|
|
98
|
-
# Ensure to set page_id
|
|
99
|
-
#
|
|
87
|
+
# Ensure to set page_id and parent_element_id to the current
|
|
88
|
+
# because of trashed elements could still have old values
|
|
100
89
|
Element.where(id: element_id).update_all(
|
|
101
90
|
page_id: params[:page_id],
|
|
102
|
-
cell_id: params[:cell_id],
|
|
103
91
|
parent_element_id: params[:parent_element_id],
|
|
104
92
|
position: idx + 1
|
|
105
93
|
)
|
|
@@ -120,24 +108,6 @@ module Alchemy
|
|
|
120
108
|
@element = Element.find(params[:id])
|
|
121
109
|
end
|
|
122
110
|
|
|
123
|
-
# Returns the cell for element name in params.
|
|
124
|
-
# Creates the cell if necessary.
|
|
125
|
-
def find_or_create_cell
|
|
126
|
-
if @paste_from_clipboard
|
|
127
|
-
element_with_cell_name = params[:paste_from_clipboard]
|
|
128
|
-
else
|
|
129
|
-
element_with_cell_name = params[:element][:name]
|
|
130
|
-
end
|
|
131
|
-
return nil if element_with_cell_name.blank?
|
|
132
|
-
return nil unless element_with_cell_name.include?('#')
|
|
133
|
-
cell_name = element_with_cell_name.split('#').last
|
|
134
|
-
cell_definition = Cell.definition_for(cell_name)
|
|
135
|
-
if cell_definition.blank?
|
|
136
|
-
raise CellDefinitionError, "Cell definition not found for #{cell_name}"
|
|
137
|
-
end
|
|
138
|
-
@page.cells.find_or_create_by(name: cell_definition['name'])
|
|
139
|
-
end
|
|
140
|
-
|
|
141
111
|
def element_from_clipboard
|
|
142
112
|
@element_from_clipboard ||= begin
|
|
143
113
|
@clipboard = get_clipboard('elements')
|
|
@@ -147,26 +117,18 @@ module Alchemy
|
|
|
147
117
|
|
|
148
118
|
def paste_element_from_clipboard
|
|
149
119
|
@source_element = Element.find(element_from_clipboard['id'])
|
|
150
|
-
|
|
120
|
+
element = Element.copy(@source_element, {
|
|
151
121
|
parent_element_id: create_element_params[:parent_element_id],
|
|
152
|
-
page_id: @page.id
|
|
153
|
-
|
|
154
|
-
if @page.can_have_cells?
|
|
155
|
-
new_attributes = new_attributes.merge({cell_id: find_or_create_cell.try(:id)})
|
|
156
|
-
end
|
|
157
|
-
element = Element.copy(@source_element, new_attributes)
|
|
122
|
+
page_id: @page.id}
|
|
123
|
+
)
|
|
158
124
|
if element_from_clipboard['action'] == 'cut'
|
|
159
|
-
|
|
125
|
+
@cut_element_id = @source_element.id
|
|
126
|
+
@clipboard.delete_if { |item| item['id'] == @source_element.id.to_s }
|
|
127
|
+
@source_element.destroy
|
|
160
128
|
end
|
|
161
129
|
element
|
|
162
130
|
end
|
|
163
131
|
|
|
164
|
-
def cut_element
|
|
165
|
-
@cutted_element_id = @source_element.id
|
|
166
|
-
@clipboard.delete_if { |item| item['id'] == @source_element.id.to_s }
|
|
167
|
-
@source_element.destroy
|
|
168
|
-
end
|
|
169
|
-
|
|
170
132
|
def contents_params
|
|
171
133
|
params.fetch(:contents, {}).permit!
|
|
172
134
|
end
|
|
@@ -49,7 +49,7 @@ module Alchemy
|
|
|
49
49
|
Page.current_preview = @page
|
|
50
50
|
# Setting the locale to pages language, so the page content has it's correct translations.
|
|
51
51
|
::I18n.locale = @page.language.locale
|
|
52
|
-
render
|
|
52
|
+
render(layout: Alchemy::Config.get(:admin_page_preview_layout) || 'application')
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def info
|
|
@@ -4,6 +4,7 @@ module Alchemy
|
|
|
4
4
|
module Admin
|
|
5
5
|
class PicturesController < Alchemy::Admin::ResourcesController
|
|
6
6
|
include UploaderResponses
|
|
7
|
+
include ArchiveOverlay
|
|
7
8
|
|
|
8
9
|
helper 'alchemy/admin/tags'
|
|
9
10
|
|
|
@@ -143,20 +144,6 @@ module Alchemy
|
|
|
143
144
|
end
|
|
144
145
|
end
|
|
145
146
|
|
|
146
|
-
def in_overlay?
|
|
147
|
-
params[:element_id].present?
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def archive_overlay
|
|
151
|
-
@content = Content.select('id').find_by(id: params[:content_id])
|
|
152
|
-
@element = Element.select('id').find_by(id: params[:element_id])
|
|
153
|
-
|
|
154
|
-
respond_to do |format|
|
|
155
|
-
format.html { render partial: 'archive_overlay' }
|
|
156
|
-
format.js { render action: 'archive_overlay' }
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
147
|
def redirect_to_index
|
|
161
148
|
do_redirect_to admin_pictures_path(search_filter_params)
|
|
162
149
|
end
|
|
@@ -16,7 +16,7 @@ module Alchemy
|
|
|
16
16
|
if params[:page_layout].present?
|
|
17
17
|
@pages = @pages.where(page_layout: params[:page_layout])
|
|
18
18
|
end
|
|
19
|
-
|
|
19
|
+
render json: @pages, adapter: :json, root: :pages
|
|
20
20
|
end
|
|
21
21
|
|
|
22
22
|
# Returns all pages as nested json object for tree views
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module Alchemy
|
|
2
|
+
module Admin
|
|
3
|
+
module ArchiveOverlay
|
|
4
|
+
private
|
|
5
|
+
|
|
6
|
+
def in_overlay?
|
|
7
|
+
params[:content_id].present?
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def archive_overlay
|
|
11
|
+
@content = Content.find_by(id: params[:content_id])
|
|
12
|
+
|
|
13
|
+
respond_to do |format|
|
|
14
|
+
format.html { render partial: 'archive_overlay' }
|
|
15
|
+
format.js { render action: 'archive_overlay' }
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -106,7 +106,6 @@ module Alchemy
|
|
|
106
106
|
concat text_field_tag(nil, nil, options)
|
|
107
107
|
concat render_icon(:search)
|
|
108
108
|
concat link_to(render_icon(:times, size: 'xs'), '', class: 'js_filter_field_clear', title: Alchemy.t(:click_to_show_all))
|
|
109
|
-
concat content_tag(:label, Alchemy.t(:search), for: options[:id])
|
|
110
109
|
end
|
|
111
110
|
end
|
|
112
111
|
|
|
@@ -215,13 +214,6 @@ module Alchemy
|
|
|
215
214
|
"Alchemy CMS - #{title}"
|
|
216
215
|
end
|
|
217
216
|
|
|
218
|
-
# (internal) Returns max image count as integer or nil. Used for the picture editor in element editor views.
|
|
219
|
-
def max_image_count
|
|
220
|
-
return nil if !@options
|
|
221
|
-
image_count = @options[:maximum_amount_of_images] || @options[:max_images]
|
|
222
|
-
image_count.blank? ? nil : image_count.to_i
|
|
223
|
-
end
|
|
224
|
-
|
|
225
217
|
# Renders a toolbar button for the Alchemy toolbar
|
|
226
218
|
#
|
|
227
219
|
# == Example
|
|
@@ -338,9 +330,6 @@ module Alchemy
|
|
|
338
330
|
# If you pass +'datetime'+ as +:type+ the datepicker will also have a Time select.
|
|
339
331
|
# If you pass +'time'+ as +:type+ the datepicker will only have a Time select.
|
|
340
332
|
#
|
|
341
|
-
# The date value gets localized via +I18n.l+. The format on Time and Date is +datepicker+, +timepicker+
|
|
342
|
-
# or +datetimepicker+, if you pass another +type+.
|
|
343
|
-
#
|
|
344
333
|
# This helper always renders "text" as input type because:
|
|
345
334
|
# HTML5 supports input types like 'date' but Browsers are using the users OS settings
|
|
346
335
|
# to validate the input format. Since Alchemy is localized in the backend the date formats
|
|
@@ -374,7 +363,7 @@ module Alchemy
|
|
|
374
363
|
type = html_options.delete(:type) || 'date'
|
|
375
364
|
date = html_options.delete(:value) || object.send(method.to_sym).presence
|
|
376
365
|
date = Time.zone.parse(date) if date.is_a?(String)
|
|
377
|
-
value = date ?
|
|
366
|
+
value = date ? date.iso8601 : nil
|
|
378
367
|
|
|
379
368
|
text_field object.class.name.demodulize.underscore.to_sym,
|
|
380
369
|
method.to_sym, {type: "text", class: type, "data-datepicker-type" => type, value: value}.merge(html_options)
|
|
@@ -402,14 +391,15 @@ module Alchemy
|
|
|
402
391
|
|
|
403
392
|
# (internal) Returns options for the clipboard select tag
|
|
404
393
|
def clipboard_select_tag_options(items)
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
394
|
+
options = items.map do |item|
|
|
395
|
+
if item.respond_to?(:display_name_with_preview_text)
|
|
396
|
+
name = item.display_name_with_preview_text
|
|
397
|
+
else
|
|
398
|
+
name = item.name
|
|
410
399
|
end
|
|
411
|
-
|
|
400
|
+
[name, item.id]
|
|
412
401
|
end
|
|
402
|
+
options_for_select(options)
|
|
413
403
|
end
|
|
414
404
|
|
|
415
405
|
# Returns the regular expression used for external url validation in link dialog.
|
|
@@ -3,42 +3,69 @@
|
|
|
3
3
|
module Alchemy
|
|
4
4
|
module Admin
|
|
5
5
|
module ElementsHelper
|
|
6
|
-
include Alchemy::ElementsHelper
|
|
7
6
|
include Alchemy::ElementsBlockHelper
|
|
8
7
|
include Alchemy::Admin::BaseHelper
|
|
9
8
|
include Alchemy::Admin::ContentsHelper
|
|
10
9
|
include Alchemy::Admin::EssencesHelper
|
|
11
10
|
|
|
12
|
-
# Renders
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
#
|
|
11
|
+
# Renders a {Alchemy::Element} editor partial.
|
|
12
|
+
#
|
|
13
|
+
# A element editor partial is the form presented to the content author in page edit mode.
|
|
14
|
+
#
|
|
15
|
+
# The partial is located in <tt>app/views/alchemy/elements</tt>.
|
|
16
|
+
#
|
|
17
|
+
# == Partial naming
|
|
18
|
+
#
|
|
19
|
+
# The partials have to be named after the name of the element as defined in the <tt>elements.yml</tt> file and has to be suffixed with <tt>_editor</tt>.
|
|
20
|
+
#
|
|
21
|
+
# === Example
|
|
22
|
+
#
|
|
23
|
+
# Given a headline element
|
|
24
|
+
#
|
|
25
|
+
# # elements.yml
|
|
26
|
+
# - name: headline
|
|
27
|
+
# contents:
|
|
28
|
+
# - name: text
|
|
29
|
+
# type: EssenceText
|
|
18
30
|
#
|
|
19
|
-
#
|
|
20
|
-
# Just place this helper inside your element editor view, pass the element as parameter and that's it.
|
|
31
|
+
# Then your element editor partial has to be named:
|
|
21
32
|
#
|
|
22
|
-
#
|
|
33
|
+
# app/views/alchemy/elements/_headline_editor.html.{erb|haml|slim}
|
|
23
34
|
#
|
|
24
|
-
#
|
|
35
|
+
# === Element partials generator
|
|
25
36
|
#
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
37
|
+
# You can use this handy generator to let Alchemy generate the partials for you:
|
|
38
|
+
#
|
|
39
|
+
# $ rails generate alchemy:elements --skip
|
|
40
|
+
#
|
|
41
|
+
# == Usage
|
|
42
|
+
#
|
|
43
|
+
# <%= render_editor(Alchemy::Element.published.named(:headline).first) %>
|
|
44
|
+
#
|
|
45
|
+
# @param [Alchemy::Element] element
|
|
46
|
+
# The element you want to render the editor for
|
|
47
|
+
#
|
|
48
|
+
# @note If the partial is not found
|
|
49
|
+
# <tt>alchemy/elements/_editor_not_found.html.erb</tt> gets rendered.
|
|
50
|
+
#
|
|
51
|
+
def render_editor(element)
|
|
52
|
+
if element.nil?
|
|
53
|
+
warning('Element is nil')
|
|
54
|
+
render "alchemy/elements/editor_not_found", {name: 'nil'}
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
render "alchemy/elements/#{element.name}_editor", element: element
|
|
59
|
+
rescue ActionView::MissingTemplate => e
|
|
60
|
+
warning(%(
|
|
61
|
+
Element editor partial not found for #{element.name}.\n
|
|
62
|
+
#{e}
|
|
63
|
+
))
|
|
64
|
+
render "alchemy/elements/editor_not_found", {
|
|
65
|
+
name: element.name,
|
|
66
|
+
error: "Element editor partial not found.<br>Use <code>rails generate alchemy:elements</code> to generate it."
|
|
30
67
|
}
|
|
31
|
-
options = default_options.merge(options)
|
|
32
|
-
render(
|
|
33
|
-
partial: "alchemy/admin/elements/picture_gallery_editor",
|
|
34
|
-
locals: {
|
|
35
|
-
pictures: element.contents.gallery_pictures,
|
|
36
|
-
element: element,
|
|
37
|
-
options: options
|
|
38
|
-
}
|
|
39
|
-
)
|
|
40
68
|
end
|
|
41
|
-
alias_method :render_picture_editor, :render_picture_gallery_editor
|
|
42
69
|
|
|
43
70
|
# Returns an elements array for select helper.
|
|
44
71
|
#
|
|
@@ -55,57 +82,16 @@ module Alchemy
|
|
|
55
82
|
end
|
|
56
83
|
end
|
|
57
84
|
|
|
58
|
-
# Returns all elements that can be placed on the current page.
|
|
59
|
-
# The elements will be grouped by cell.
|
|
60
|
-
#
|
|
61
|
-
# @param [Array] elements
|
|
62
|
-
# collection of element objects
|
|
63
|
-
# @param [String] object_method
|
|
64
|
-
# method that is called on the element objects used for the select option value
|
|
65
|
-
#
|
|
66
|
-
def grouped_elements_for_select(elements, object_method = 'name')
|
|
67
|
-
return [] if elements.blank?
|
|
68
|
-
cells_definition = @page.cell_definitions
|
|
69
|
-
return [] if cells_definition.blank?
|
|
70
|
-
options = {}
|
|
71
|
-
cells_definition.each do |cell|
|
|
72
|
-
cell_elements = elements_for_cell(elements, cell)
|
|
73
|
-
optgroup_label = Cell.translated_label_for(cell['name'])
|
|
74
|
-
options[optgroup_label] = cell_elements.map do |e|
|
|
75
|
-
element_array_for_options(e, object_method, cell)
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
options[Alchemy.t(:main_content)] = elements_for_main_content(elements).map do |e|
|
|
79
|
-
element_array_for_options(e, object_method)
|
|
80
|
-
end
|
|
81
|
-
# Remove empty cells
|
|
82
|
-
options.delete_if { |_c, e| e.blank? }
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def element_array_for_options(element, object_method, cell = nil)
|
|
86
|
-
case element
|
|
87
|
-
when Alchemy::Element
|
|
88
|
-
[
|
|
89
|
-
element.display_name_with_preview_text,
|
|
90
|
-
element.send(object_method).to_s + (cell ? "##{cell['name']}" : "")
|
|
91
|
-
]
|
|
92
|
-
else
|
|
93
|
-
[
|
|
94
|
-
Element.display_name_for(element['name']),
|
|
95
|
-
element[object_method] + (cell ? "##{cell['name']}" : "")
|
|
96
|
-
]
|
|
97
|
-
end
|
|
98
|
-
end
|
|
99
|
-
|
|
100
85
|
# CSS classes for the element editor partial.
|
|
101
|
-
def element_editor_classes(element
|
|
86
|
+
def element_editor_classes(element)
|
|
102
87
|
[
|
|
103
88
|
'element-editor',
|
|
104
89
|
element.content_definitions.present? ? 'with-contents' : 'without-contents',
|
|
105
90
|
element.nestable_elements.any? ? 'nestable' : 'not-nestable',
|
|
106
91
|
element.taggable? ? 'taggable' : 'not-taggable',
|
|
107
92
|
element.folded ? 'folded' : 'expanded',
|
|
108
|
-
|
|
93
|
+
element.compact? ? 'compact' : nil,
|
|
94
|
+
element.fixed? ? 'is-fixed' : 'not-fixed'
|
|
109
95
|
].join(' ')
|
|
110
96
|
end
|
|
111
97
|
|
|
@@ -118,22 +104,6 @@ module Alchemy
|
|
|
118
104
|
element.nestable_elements.empty?
|
|
119
105
|
end
|
|
120
106
|
end
|
|
121
|
-
|
|
122
|
-
private
|
|
123
|
-
|
|
124
|
-
def elements_for_main_content(elements)
|
|
125
|
-
page_definition = @page.definition['elements']
|
|
126
|
-
elements.select do |e|
|
|
127
|
-
page_definition.include?(e.class.name == 'Element' ? e.name : e['name'])
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
def elements_for_cell(elements, cell)
|
|
132
|
-
cell_elements = cell['elements']
|
|
133
|
-
elements.select do |e|
|
|
134
|
-
cell_elements.include?(e.class.name == 'Element' ? e.name : e['name'])
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
107
|
end
|
|
138
108
|
end
|
|
139
109
|
end
|