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