alchemy_cms 2.1.5 → 2.1.6
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.
- data/.travis.yml +1 -0
- data/app/assets/javascripts/alchemy/alchemy.base.js +1 -1
- data/app/assets/javascripts/alchemy/alchemy.buttons.js +5 -5
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js +1 -1
- data/app/assets/javascripts/alchemy/alchemy.element_editor_selector.js +2 -2
- data/app/assets/javascripts/alchemy/alchemy.windows.js +1 -1
- data/app/assets/stylesheets/alchemy/base.css.scss +22 -13
- data/app/assets/stylesheets/alchemy/buttons.css.scss +14 -14
- data/app/assets/stylesheets/alchemy/elements.css.scss +79 -46
- data/app/controllers/alchemy/admin/elements_controller.rb +1 -1
- data/app/helpers/alchemy/admin/base_helper.rb +4 -3
- data/app/helpers/alchemy/admin/elements_helper.rb +2 -2
- data/app/helpers/alchemy/admin/essences_helper.rb +7 -14
- data/app/models/alchemy/element.rb +13 -10
- data/app/models/alchemy/message.rb +2 -2
- data/app/models/alchemy/page.rb +1 -1
- data/app/views/alchemy/admin/clipboard/index.html.erb +4 -3
- data/app/views/alchemy/admin/clipboard/insert.js.erb +2 -2
- data/app/views/alchemy/admin/contents/create.js.erb +48 -13
- data/app/views/alchemy/admin/contents/new.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_elements_select.html.erb +1 -1
- data/app/views/alchemy/admin/elements/create.js.erb +9 -5
- data/app/views/alchemy/admin/elements/fold.js.erb +9 -7
- data/app/views/alchemy/admin/elements/trash.js.erb +13 -11
- data/app/views/alchemy/admin/elements/update.js.erb +10 -7
- data/app/views/alchemy/admin/essence_files/edit.html.erb +1 -1
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +3 -3
- data/app/views/alchemy/admin/pages/_contactform_links.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_external_link.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_file_link.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_internal_link.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
- data/app/views/alchemy/admin/partials/_upload_form.html.erb +2 -2
- data/app/views/alchemy/admin/resources/destroy.js.erb +1 -1
- data/app/views/alchemy/admin/users/_table.html.erb +3 -3
- data/app/views/alchemy/elements/_contactform_editor.html.erb +1 -4
- data/app/views/alchemy/essences/_essence_date_editor.html.erb +2 -3
- data/app/views/alchemy/essences/_essence_date_view.html.erb +4 -6
- data/app/views/alchemy/essences/_essence_text_editor.html.erb +2 -2
- data/app/views/layouts/alchemy/admin.html.erb +1 -1
- data/config/alchemy/elements.yml +2 -0
- data/config/locales/alchemy.de.yml +8 -3
- data/config/locales/alchemy.en.yml +4 -3
- data/lib/alchemy/capistrano.rb +6 -6
- data/lib/alchemy/essence.rb +9 -4
- data/lib/alchemy/version.rb +1 -1
- data/spec/helpers/admin/elements_helper_spec.rb +1 -1
- data/spec/integration/security_spec.rb +2 -2
- data/spec/models/page_spec.rb +28 -1
- data/spec/support/alchemy/specs_helpers.rb +1 -1
- metadata +33 -34
- data/app/views/alchemy/admin/elements/destroy.js.erb +0 -6
data/.travis.yml
CHANGED
@@ -133,7 +133,7 @@ if (typeof(Alchemy) === 'undefined') {
|
|
133
133
|
setElementSaved : function(selector) {
|
134
134
|
var $element = $(selector);
|
135
135
|
Alchemy.setElementClean(selector);
|
136
|
-
Alchemy.enableButton(
|
136
|
+
Alchemy.enableButton('button.button', $element);
|
137
137
|
},
|
138
138
|
|
139
139
|
resizeFrame : function() {
|
@@ -7,17 +7,17 @@ if (typeof(Alchemy) === 'undefined') {
|
|
7
7
|
$.extend(Alchemy, {
|
8
8
|
|
9
9
|
ButtonObserver: function (selector) {
|
10
|
-
$(selector).click(function(event) {
|
10
|
+
$(selector).not('.no-spinner').click(function(event) {
|
11
11
|
Alchemy.disableButton(this);
|
12
12
|
});
|
13
13
|
},
|
14
14
|
|
15
15
|
disableButton: function (button) {
|
16
16
|
var $button = $(button), $clone = $button.clone(), width = $button.outerWidth(), text = $button.text();
|
17
|
-
$button.hide();
|
17
|
+
$button.hide().addClass('disabled');
|
18
18
|
$button.parent().append($clone);
|
19
19
|
$clone.attr({disabled: true, href: 'javascript:void(0)'})
|
20
|
-
.addClass('
|
20
|
+
.addClass('cloned-button')
|
21
21
|
.css({width: width})
|
22
22
|
.html('<img src="/assets/alchemy/ajax_loader.gif" style="width: 16px; height: 16px">')
|
23
23
|
.show();
|
@@ -25,8 +25,8 @@ if (typeof(Alchemy) === 'undefined') {
|
|
25
25
|
},
|
26
26
|
|
27
27
|
enableButton: function (button) {
|
28
|
-
var $button = $(button);
|
29
|
-
$button.show();
|
28
|
+
var $button = $(button).not('.no-spinner');
|
29
|
+
$button.show().removeClass('disabled');
|
30
30
|
$button.parent().find('.cloned-button').remove();
|
31
31
|
return true;
|
32
32
|
}
|
@@ -22,7 +22,7 @@ if (typeof(Alchemy) === 'undefined') {
|
|
22
22
|
return $(child).attr('data-element-id');
|
23
23
|
});
|
24
24
|
var params_string = '';
|
25
|
-
var cell_id = $(
|
25
|
+
var cell_id = $(this).attr('data-cell-id');
|
26
26
|
// Is the trash window open?
|
27
27
|
if ($('#alchemyTrashWindow').length > 0) {
|
28
28
|
// updating the trash icon
|
@@ -18,8 +18,8 @@ if (typeof(Alchemy) === 'undefined') {
|
|
18
18
|
reinit : function(elements) {
|
19
19
|
var self = Alchemy.ElementEditorSelector;
|
20
20
|
var $elements = $(elements);
|
21
|
-
$elements.each(function
|
22
|
-
self.bindEvent(this
|
21
|
+
$elements.each(function() {
|
22
|
+
self.bindEvent(this);
|
23
23
|
});
|
24
24
|
$elements.find('.element_head').click(self.onClickElement);
|
25
25
|
$elements.find('.element_head').dblclick(function() {
|
@@ -170,7 +170,7 @@ if (typeof(Alchemy) === 'undefined') {
|
|
170
170
|
Alchemy.AjaxErrorHandler($dialog, XMLHttpRequest.status, textStatus, errorThrown);
|
171
171
|
},
|
172
172
|
complete: function(jqXHR, textStatus) {
|
173
|
-
Alchemy.enableButton('.button');
|
173
|
+
Alchemy.enableButton('.disabled.button');
|
174
174
|
}
|
175
175
|
});
|
176
176
|
},
|
@@ -1469,19 +1469,28 @@ div#overlay_toolbar a.button:active {
|
|
1469
1469
|
margin: 1px 0 0 -12px;
|
1470
1470
|
}
|
1471
1471
|
|
1472
|
-
#clipboard_items
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1484
|
-
|
1472
|
+
#clipboard_items {
|
1473
|
+
|
1474
|
+
ul {
|
1475
|
+
list-style-type: none;
|
1476
|
+
margin: 0 0 8px;
|
1477
|
+
padding: 0;
|
1478
|
+
height: 220px;
|
1479
|
+
overflow-y: auto;
|
1480
|
+
overflow-x: hidden;
|
1481
|
+
|
1482
|
+
li {
|
1483
|
+
padding: 2*$default-padding;
|
1484
|
+
border: $default-border;
|
1485
|
+
background-color: white;
|
1486
|
+
@include rounded-corner;
|
1487
|
+
&.element {
|
1488
|
+
background-color: #E5DCCA;
|
1489
|
+
border: 1px solid #BBA589;
|
1490
|
+
}
|
1491
|
+
}
|
1492
|
+
}
|
1493
|
+
}
|
1485
1494
|
|
1486
1495
|
.mceEditor table {
|
1487
1496
|
border-spacing: 0 !important;
|
@@ -1,6 +1,6 @@
|
|
1
1
|
@import "alchemy/defaults";
|
2
2
|
|
3
|
-
a.button.small.
|
3
|
+
a.button.small.cloned-button img {
|
4
4
|
display: inline-block;
|
5
5
|
float: none;
|
6
6
|
position: relative;
|
@@ -82,15 +82,15 @@ a.button:active {
|
|
82
82
|
background-color: #e5e5e5;
|
83
83
|
}
|
84
84
|
|
85
|
-
a.button.
|
86
|
-
a.button.
|
87
|
-
a.button.
|
88
|
-
input.button.
|
89
|
-
input.button.
|
90
|
-
input.button.
|
91
|
-
button.button.
|
92
|
-
button.button.
|
93
|
-
button.button.
|
85
|
+
a.button.cloned-button,
|
86
|
+
a.button.cloned-button:hover,
|
87
|
+
a.button.cloned-button:active,
|
88
|
+
input.button.cloned-button,
|
89
|
+
input.button.cloned-button:hover,
|
90
|
+
input.button.cloned-button:active,
|
91
|
+
button.button.cloned-button,
|
92
|
+
button.button.cloned-button:hover,
|
93
|
+
button.button.cloned-button:active {
|
94
94
|
color: $text-color;
|
95
95
|
text-shadow: none;
|
96
96
|
border-color: #ccc;
|
@@ -101,15 +101,15 @@ button.button.disabled:active {
|
|
101
101
|
line-height: 15px;
|
102
102
|
}
|
103
103
|
|
104
|
-
a.button.
|
105
|
-
a.button.
|
106
|
-
a.button.
|
104
|
+
a.button.cloned-button,
|
105
|
+
a.button.cloned-button:hover,
|
106
|
+
a.button.cloned-button:active {
|
107
107
|
padding: 2px 0 !important;
|
108
108
|
line-height: 13px !important;
|
109
109
|
text-align: center;
|
110
110
|
}
|
111
111
|
|
112
|
-
a.button.
|
112
|
+
a.button.cloned-button img {
|
113
113
|
display: inline-block;
|
114
114
|
float: none;
|
115
115
|
}
|
@@ -437,6 +437,17 @@ a.icon_button.linked {
|
|
437
437
|
cursor: default;
|
438
438
|
}
|
439
439
|
|
440
|
+
div.content_editor.essence_date {
|
441
|
+
float: none;
|
442
|
+
display: inline;
|
443
|
+
display: inline-block;
|
444
|
+
vertical-align: top;
|
445
|
+
|
446
|
+
input.date {
|
447
|
+
width: 154px;
|
448
|
+
}
|
449
|
+
}
|
450
|
+
|
440
451
|
div.essence_picture_editor {
|
441
452
|
float: left;
|
442
453
|
height: 126px;
|
@@ -613,12 +624,6 @@ table.content_editor_table {
|
|
613
624
|
width: 210px;
|
614
625
|
}
|
615
626
|
|
616
|
-
div.content_editor label.inline {
|
617
|
-
display: inline-block;
|
618
|
-
min-width: 90px;
|
619
|
-
margin-right: 4px;
|
620
|
-
}
|
621
|
-
|
622
627
|
a.new_content_link {
|
623
628
|
float: none;
|
624
629
|
display: inline-block;
|
@@ -649,10 +654,6 @@ div.content_text_editor.text_short {
|
|
649
654
|
display: inline;
|
650
655
|
}
|
651
656
|
|
652
|
-
div.content_editor input.thin_border {
|
653
|
-
width: 97%;
|
654
|
-
}
|
655
|
-
|
656
657
|
input.long,
|
657
658
|
input.text_long {
|
658
659
|
width: 363px;
|
@@ -671,53 +672,85 @@ div.content_text_editor input.text_short {
|
|
671
672
|
padding: 2px;
|
672
673
|
}
|
673
674
|
|
675
|
+
#alchemy .ui-dialog-content div.content_editor input.auto_resize {
|
676
|
+
width: 100%;
|
677
|
+
}
|
678
|
+
|
679
|
+
// div.element_content {
|
680
|
+
// white-space: nowrap;
|
681
|
+
|
682
|
+
// p, div {
|
683
|
+
// white-space: normal;
|
684
|
+
// }
|
685
|
+
// }
|
686
|
+
|
674
687
|
div.content_editor {
|
675
688
|
margin-bottom: 8px;
|
676
689
|
margin-top: 8px;
|
677
690
|
position: relative;
|
678
|
-
}
|
679
691
|
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
border: 1px solid #f5b04e;
|
684
|
-
background-color: #f5dea9;
|
685
|
-
@include rounded-corner;
|
686
|
-
font-size: 11px;
|
687
|
-
}
|
692
|
+
input.thin_border {
|
693
|
+
width: 97%;
|
694
|
+
}
|
688
695
|
|
689
|
-
|
690
|
-
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
696
|
+
&.missing p {
|
697
|
+
line-height: 25px;
|
698
|
+
padding: 2*$default-padding;
|
699
|
+
border: 1px solid #f5b04e;
|
700
|
+
background-color: #f5dea9;
|
701
|
+
@include rounded-corner;
|
702
|
+
font-size: 11px;
|
703
|
+
|
704
|
+
span.icon.warning {
|
705
|
+
position: relative;
|
706
|
+
top: 2px;
|
707
|
+
left: 2px;
|
708
|
+
margin-right: 8px;
|
709
|
+
}
|
710
|
+
}
|
695
711
|
|
696
|
-
|
697
|
-
|
698
|
-
|
712
|
+
&.display_inline {
|
713
|
+
display: inline;
|
714
|
+
display: inline-block;
|
715
|
+
margin-right: 4px;
|
716
|
+
vertical-align: top;
|
717
|
+
|
718
|
+
input.thin_border {
|
719
|
+
width: 170px;
|
720
|
+
}
|
721
|
+
}
|
699
722
|
|
700
|
-
|
701
|
-
color: #931f23;
|
702
|
-
}
|
723
|
+
&.validation_failed {
|
703
724
|
|
704
|
-
|
705
|
-
|
706
|
-
|
707
|
-
}
|
725
|
+
label {
|
726
|
+
color: #931f23;
|
727
|
+
}
|
708
728
|
|
709
|
-
|
710
|
-
|
711
|
-
|
712
|
-
|
713
|
-
|
714
|
-
line-height: 15px;
|
715
|
-
text-indent: 1px;
|
716
|
-
}
|
729
|
+
input {
|
730
|
+
border: 1px solid #931f23;
|
731
|
+
background-color: #f9e8e9;
|
732
|
+
}
|
733
|
+
}
|
717
734
|
|
718
|
-
|
719
|
-
|
720
|
-
|
735
|
+
label {
|
736
|
+
display: block;
|
737
|
+
margin-bottom: 0.5em;
|
738
|
+
font-size: 10px;
|
739
|
+
text-shadow: #fff5e1 1px 1px 0;
|
740
|
+
line-height: 15px;
|
741
|
+
text-indent: 1px;
|
742
|
+
|
743
|
+
span.warning.icon {
|
744
|
+
position: relative;
|
745
|
+
top: 2px;
|
746
|
+
}
|
747
|
+
|
748
|
+
&.inline {
|
749
|
+
display: inline-block;
|
750
|
+
min-width: 90px;
|
751
|
+
margin-right: 4px;
|
752
|
+
}
|
753
|
+
}
|
721
754
|
}
|
722
755
|
|
723
756
|
.element_editor div.error {
|
@@ -70,7 +70,7 @@ module Alchemy
|
|
70
70
|
else
|
71
71
|
@element_validated = false
|
72
72
|
@notice = t('Validation failed')
|
73
|
-
@error_message = "<h2>#{@notice}</h2><p>#{t(
|
73
|
+
@error_message = "<h2>#{@notice}</h2><p>#{t(:content_validations_headline)}</p>".html_safe
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
@@ -189,7 +189,8 @@ module Alchemy
|
|
189
189
|
select_options = options_for_select(select_options, content.essence.content)
|
190
190
|
select_tag(
|
191
191
|
"contents[content_#{content.id}]",
|
192
|
-
select_options
|
192
|
+
select_options,
|
193
|
+
:class => 'alchemy_selectbox'
|
193
194
|
)
|
194
195
|
end
|
195
196
|
|
@@ -301,13 +302,13 @@ module Alchemy
|
|
301
302
|
def clipboard_select_tag(items, html_options = {})
|
302
303
|
options = [[t('Please choose'), ""]]
|
303
304
|
items.each do |item|
|
304
|
-
options << [item.class.to_s == 'Element' ? item.display_name_with_preview_text : item.name, item.id]
|
305
|
+
options << [item.class.to_s == 'Alchemy::Element' ? item.display_name_with_preview_text : item.name, item.id]
|
305
306
|
end
|
306
307
|
select_tag(
|
307
308
|
'paste_from_clipboard',
|
308
309
|
!@page.new_record? && @page.can_have_cells? ? grouped_elements_for_select(items, :id) : options_for_select(options),
|
309
310
|
{
|
310
|
-
:class => html_options[:class],
|
311
|
+
:class => [html_options[:class], 'alchemy_selectbox'].join(' '),
|
311
312
|
:style => html_options[:style]
|
312
313
|
}
|
313
314
|
)
|
@@ -99,14 +99,14 @@ module Alchemy
|
|
99
99
|
end
|
100
100
|
|
101
101
|
def element_array_for_options(e, object_method, cell = nil)
|
102
|
-
if e.class.name == 'Element'
|
102
|
+
if e.class.name == 'Alchemy::Element'
|
103
103
|
[
|
104
104
|
e.display_name_with_preview_text,
|
105
105
|
e.send(object_method).to_s + (cell ? "##{cell['name']}" : "")
|
106
106
|
]
|
107
107
|
else
|
108
108
|
[
|
109
|
-
t(e['name'], :scope => :element_names),
|
109
|
+
Alchemy::I18n.t(e['name'], :scope => :element_names),
|
110
110
|
e[object_method] + (cell ? "##{cell['name']}" : "")
|
111
111
|
]
|
112
112
|
end
|
@@ -78,28 +78,21 @@ module Alchemy
|
|
78
78
|
end
|
79
79
|
|
80
80
|
# Renders the EssenceText editor partial with a form select for storing page urlnames
|
81
|
-
#
|
82
|
-
#
|
83
|
-
#
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
# ** :page_attribute (Symbol) - The Page attribute which will be stored.
|
81
|
+
#
|
82
|
+
# === Options:
|
83
|
+
#
|
84
|
+
# :only [Hash] # Pagelayout names. Only pages with this page_layout will be displayed inside the select.
|
85
|
+
# :page_attribute [Symbol] # The Page attribute which will be stored.
|
86
|
+
#
|
88
87
|
def page_selector(element, content_name, options = {}, select_options = {})
|
89
88
|
default_options = {
|
90
|
-
:except => {
|
91
|
-
:page_layout => [""]
|
92
|
-
},
|
93
|
-
:only => {
|
94
|
-
:page_layout => [""]
|
95
|
-
},
|
96
89
|
:page_attribute => :id,
|
97
90
|
:prompt => t('Choose page')
|
98
91
|
}
|
99
92
|
options = default_options.merge(options)
|
100
93
|
pages = Page.where({
|
101
94
|
:language_id => session[:language_id],
|
102
|
-
:page_layout => options[:only]
|
95
|
+
:page_layout => options[:only],
|
103
96
|
:public => true
|
104
97
|
})
|
105
98
|
content = element.content_by_name(content_name)
|
@@ -372,7 +372,7 @@ module Alchemy
|
|
372
372
|
end
|
373
373
|
|
374
374
|
def has_ingredient?(name)
|
375
|
-
|
375
|
+
self.ingredient(name).present?
|
376
376
|
end
|
377
377
|
|
378
378
|
def save_contents(params)
|
@@ -400,14 +400,17 @@ module Alchemy
|
|
400
400
|
def essence_errors
|
401
401
|
essence_errors = {}
|
402
402
|
essences.each do |essence|
|
403
|
-
unless essence.
|
404
|
-
essence_errors[essence.content.name] = essence.
|
403
|
+
unless essence.errors.blank?
|
404
|
+
essence_errors[essence.content.name] = essence.validation_errors
|
405
405
|
end
|
406
406
|
end
|
407
407
|
essence_errors
|
408
408
|
end
|
409
409
|
|
410
|
-
# Essence validation errors
|
410
|
+
# Essence validation errors
|
411
|
+
#
|
412
|
+
# Messages are translated via I18n.
|
413
|
+
#
|
411
414
|
# Inside your translation file add translations like:
|
412
415
|
#
|
413
416
|
# alchemy:
|
@@ -422,12 +425,12 @@ module Alchemy
|
|
422
425
|
# * taken
|
423
426
|
# * wrong_format
|
424
427
|
#
|
425
|
-
# Example:
|
428
|
+
# === Example:
|
426
429
|
#
|
427
430
|
# de:
|
428
431
|
# alchemy:
|
429
432
|
# content_validations:
|
430
|
-
#
|
433
|
+
# contactform:
|
431
434
|
# email:
|
432
435
|
# wrong_format: 'Die Email hat nicht das richtige Format'
|
433
436
|
#
|
@@ -435,11 +438,11 @@ module Alchemy
|
|
435
438
|
messages = []
|
436
439
|
essence_errors.each do |content_name, errors|
|
437
440
|
errors.each do |error|
|
438
|
-
messages << I18n.t(
|
439
|
-
|
441
|
+
messages << I18n.t(error,
|
442
|
+
:scope => [:content_validations, self.name, content_name],
|
440
443
|
:default => [
|
441
|
-
"content_validations.fields.#{content_name}.#{error}".to_sym,
|
442
|
-
"content_validations.errors.#{error}".to_sym
|
444
|
+
"alchemy.content_validations.fields.#{content_name}.#{error}".to_sym,
|
445
|
+
"alchemy.content_validations.errors.#{error}".to_sym
|
443
446
|
],
|
444
447
|
:field => Content.translated_label_for(content_name)
|
445
448
|
)
|