alchemy_cms 4.1.2 → 4.2.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|