alchemy_cms 2.7.0 → 2.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.dragndrop.js.coffee +12 -6
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +6 -1
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +7 -5
- data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee.erb +45 -47
- data/app/assets/stylesheets/alchemy/base.scss +18 -9
- data/app/assets/stylesheets/alchemy/elements.scss +35 -31
- data/app/assets/stylesheets/alchemy/menubar.css.scss +12 -6
- data/app/assets/stylesheets/alchemy/tables.scss +1 -1
- data/app/controllers/alchemy/admin/pages_controller.rb +10 -2
- data/app/helpers/alchemy/admin/contents_helper.rb +0 -5
- data/app/helpers/alchemy/admin/navigation_helper.rb +2 -1
- data/app/helpers/alchemy/elements_helper.rb +5 -2
- data/app/helpers/alchemy/pages_helper.rb +2 -2
- data/app/models/alchemy/element.rb +6 -0
- data/app/models/alchemy/page/elements.rb +5 -6
- data/app/models/alchemy/page/scopes.rb +1 -1
- data/app/views/alchemy/admin/contents/create.js.erb +1 -1
- data/app/views/alchemy/admin/elements/_refresh_editor.js.erb +3 -5
- data/app/views/alchemy/admin/elements/create.js.erb +1 -3
- data/app/views/alchemy/admin/elements/fold.js.erb +2 -12
- data/app/views/alchemy/admin/elements/update.js.erb +3 -1
- data/app/views/alchemy/admin/essence_files/assign.js.erb +2 -3
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +5 -5
- data/app/views/alchemy/admin/languages/_form.html.erb +6 -1
- data/app/views/alchemy/admin/languages/_language.html.erb +1 -1
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +2 -2
- data/app/views/alchemy/admin/pages/edit.html.erb +2 -2
- data/app/views/alchemy/essences/_essence_file_editor.html.erb +1 -1
- data/app/views/alchemy/essences/_essence_richtext_editor.html.erb +2 -1
- data/app/views/alchemy/essences/shared/_essence_picture_tools.html.erb +6 -5
- data/config/locales/alchemy.de.yml +1 -1
- data/config/locales/alchemy.en.yml +1 -1
- data/lib/alchemy/modules.rb +53 -16
- data/lib/alchemy/version.rb +1 -1
- data/spec/controllers/admin/pages_controller_spec.rb +19 -6
- data/spec/helpers/admin/contents_helper_spec.rb +0 -11
- data/spec/helpers/admin/navigation_helper_spec.rb +23 -14
- data/spec/libraries/modules_spec.rb +50 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2e25191bd90849e3276a03f409875bcd05a49ce5
|
4
|
+
data.tar.gz: ce85ab765e70be9351d4d6c69a7a5aaf84b174bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4d0b6f298b7b9ccb71f4a539a329dc5b3e485f3c02a029ea248214b694634112b19712270009d5fe0f2f3e367972a10876d88be2e9508b72a116528d35e664cb
|
7
|
+
data.tar.gz: 45bed619a0e65bb9427fe91c76ee8077c261c7c969ac3d07e455e9cdc50e02393ad40e07952c7f54bdfbb8a3360652621e703bcc7cd37f270ecb46c64c6a884f
|
data/Gemfile
CHANGED
@@ -29,9 +29,9 @@ group :assets do
|
|
29
29
|
gem 'uglifier', '>= 1.0.3'
|
30
30
|
end
|
31
31
|
|
32
|
-
group :development do
|
32
|
+
group :development, :test do
|
33
33
|
unless ENV['CI']
|
34
|
-
gem '
|
34
|
+
gem 'pry'
|
35
35
|
gem 'quiet_assets' # Mute assets loggin
|
36
36
|
gem 'thin' # Get rid off 'Could not determine content-length of response body' Warning. Start with 'rails s thin'
|
37
37
|
end
|
@@ -72,7 +72,7 @@ $.extend Alchemy,
|
|
72
72
|
$element = $(selector)
|
73
73
|
Alchemy.setElementClean selector
|
74
74
|
Alchemy.Buttons.enable $element
|
75
|
-
return
|
75
|
+
return true
|
76
76
|
|
77
77
|
# Initializes all select tag with .alchemy_selectbox class as selectBoxIt instance
|
78
78
|
# Pass a jQuery scope to only init a subset of selectboxes.
|
@@ -2,8 +2,16 @@ window.Alchemy = {} if typeof (window.Alchemy) is "undefined"
|
|
2
2
|
|
3
3
|
$.extend Alchemy,
|
4
4
|
|
5
|
-
SortableElements: (page_id, form_token, selector) ->
|
6
|
-
|
5
|
+
SortableElements: (page_id, form_token, selector = '#element_area .sortable_cell') ->
|
6
|
+
|
7
|
+
getTinymceIDs = (ui) ->
|
8
|
+
ids = []
|
9
|
+
$textareas = ui.item.find('textarea.default_tinymce, textarea.custom_tinymce')
|
10
|
+
$($textareas).each ->
|
11
|
+
id = this.id.replace(/tinymce_/, '')
|
12
|
+
ids.push parseInt(id, 10)
|
13
|
+
return ids
|
14
|
+
|
7
15
|
$(selector).sortable
|
8
16
|
items: "div.element_editor"
|
9
17
|
handle: ".element_handle"
|
@@ -37,12 +45,10 @@ $.extend Alchemy,
|
|
37
45
|
Alchemy.TrashWindow.refresh page_id
|
38
46
|
|
39
47
|
start: (event, ui) ->
|
40
|
-
|
41
|
-
Alchemy.Tinymce.removeEditor $textareas
|
48
|
+
Alchemy.Tinymce.remove getTinymceIDs(ui)
|
42
49
|
|
43
50
|
stop: (event, ui) ->
|
44
|
-
|
45
|
-
Alchemy.Tinymce.addEditor $textareas
|
51
|
+
Alchemy.Tinymce.init getTinymceIDs(ui)
|
46
52
|
|
47
53
|
SortableContents: (selector, token) ->
|
48
54
|
$(selector).sortable
|
@@ -44,8 +44,13 @@ Alchemy.ElementEditors =
|
|
44
44
|
$("#element_area .element_editor").removeClass "selected"
|
45
45
|
$element.addClass "selected"
|
46
46
|
self.scrollToElement this
|
47
|
+
self.selectElementInPreview id
|
48
|
+
|
49
|
+
# Selcts and scrolls to element with given id in the preview window.
|
50
|
+
#
|
51
|
+
selectElementInPreview: (id) ->
|
47
52
|
$frame_elements = document.getElementById("alchemyPreviewWindow").contentWindow.jQuery("[data-alchemy-element]")
|
48
|
-
$selected_element = $frame_elements.closest("[data-alchemy-element
|
53
|
+
$selected_element = $frame_elements.closest("[data-alchemy-element='#{id}']")
|
49
54
|
$selected_element.trigger "Alchemy.SelectElement"
|
50
55
|
|
51
56
|
# Binds the custom 'Alchemy.SelectElementEditor' event.
|
@@ -13,10 +13,10 @@ Alchemy.PreviewWindow =
|
|
13
13
|
Alchemy.PreviewWindow.currentWindow = $iframe.dialog(
|
14
14
|
modal: false
|
15
15
|
title: title
|
16
|
-
|
17
|
-
height: $(window).height() - 76
|
18
|
-
minWidth: 600
|
16
|
+
minWidth: 320
|
19
17
|
minHeight: 300
|
18
|
+
width: $(window).width() - 482
|
19
|
+
height: $(window).height() - 76
|
20
20
|
show: "fade"
|
21
21
|
hide: "fade"
|
22
22
|
position: [70, 84]
|
@@ -43,15 +43,17 @@ Alchemy.PreviewWindow =
|
|
43
43
|
else
|
44
44
|
$("#alchemyPreviewWindow").dialog "open"
|
45
45
|
|
46
|
-
refresh: ->
|
46
|
+
refresh: (callback) ->
|
47
47
|
$iframe = $("#alchemyPreviewWindow")
|
48
48
|
$spinner = $(".preview-refresh-spinner")
|
49
49
|
$refresh = $('.ui-dialog-titlebar-refresh')
|
50
50
|
$spinner.show()
|
51
51
|
$refresh.hide()
|
52
|
-
$iframe.load ->
|
52
|
+
$iframe.load (e) ->
|
53
53
|
$spinner.hide()
|
54
54
|
$refresh.show()
|
55
|
+
if callback
|
56
|
+
callback.call(e, $iframe)
|
55
57
|
$iframe.attr("src", $iframe.attr("src"))
|
56
58
|
true
|
57
59
|
|
@@ -21,71 +21,69 @@ window.Alchemy.Tinymce =
|
|
21
21
|
#
|
22
22
|
customConfigs: {}
|
23
23
|
|
24
|
-
# Returns default config for tinymce
|
24
|
+
# Returns default config for a tinymce editor.
|
25
25
|
#
|
26
|
-
getDefaultConfig: ->
|
26
|
+
getDefaultConfig: (id) ->
|
27
27
|
config = @defaults
|
28
28
|
config.language = Alchemy.locale
|
29
|
-
config.mode =
|
30
|
-
config.
|
31
|
-
config.init_instance_callback =
|
32
|
-
$this = $("##{inst.editorId}")
|
33
|
-
parent = $this.parents('.element_editor')
|
34
|
-
parent.find('.spinner').remove()
|
35
|
-
inst.onChange.add ->
|
36
|
-
Alchemy.setElementDirty(parent)
|
29
|
+
config.mode = 'exact'
|
30
|
+
config.elements = "tinymce_#{id}"
|
31
|
+
config.init_instance_callback = @initInstanceCallback
|
37
32
|
return config
|
38
33
|
|
39
34
|
# Returns configuration for given custom tinymce editor selector.
|
40
35
|
#
|
41
36
|
# It uses the +.getDefaultConfig+ and merges the custom parts.
|
42
37
|
#
|
43
|
-
getCustomConfig: (
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
config.editor_selector = new RegExp("custom_tinymce #{editor}")
|
48
|
-
return config
|
38
|
+
getCustomConfig: (id, selector) ->
|
39
|
+
editor_config = @customConfigs[selector]
|
40
|
+
if editor_config
|
41
|
+
$.extend({}, @getDefaultConfig(id), editor_config)
|
49
42
|
|
50
|
-
# Initializes all
|
43
|
+
# Initializes all TinyMCE editors with given ids
|
51
44
|
#
|
52
|
-
|
53
|
-
|
54
|
-
$('.tinymce_container').prepend spinner.spin().el
|
55
|
-
tinymce.init @getDefaultConfig()
|
56
|
-
|
57
|
-
# Initializes all tinymce editors with custom configuration.
|
58
|
-
#
|
59
|
-
# @param editors [Array]
|
60
|
-
# - Editor selectors that should be initialized. The selector has to be in format of:
|
61
|
-
# "element_name_content_name"
|
45
|
+
# @param ids [Array]
|
46
|
+
# - Editor ids that should be initialized.
|
62
47
|
#
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
if custom_editor_config = @getCustomConfig(editor)
|
67
|
-
tinymce.init custom_editor_config
|
48
|
+
init: (ids) ->
|
49
|
+
for id in ids
|
50
|
+
@initEditor(id)
|
68
51
|
|
69
|
-
#
|
52
|
+
# Initializes one specific TinyMCE editor
|
70
53
|
#
|
71
|
-
#
|
72
|
-
#
|
54
|
+
# @param id [Number]
|
55
|
+
# - Editor id that should be initialized.
|
73
56
|
#
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
57
|
+
initEditor: (id) ->
|
58
|
+
textarea = $("textarea#tinymce_#{id}")
|
59
|
+
return if textarea.length == 0
|
60
|
+
if selector = textarea[0].classList[1]
|
61
|
+
config = @getCustomConfig(id, selector)
|
62
|
+
else
|
63
|
+
config = @getDefaultConfig(id)
|
64
|
+
if config
|
65
|
+
spinner = Alchemy.Spinner.small()
|
66
|
+
textarea.parents('.tinymce_container').prepend spinner.spin().el
|
81
67
|
tinymce.init(config)
|
82
|
-
|
68
|
+
else
|
69
|
+
Alchemy.debug('No tinymce configuration found for', id)
|
70
|
+
|
71
|
+
# Gets called after an editor instance gets intialized
|
72
|
+
#
|
73
|
+
initInstanceCallback: (inst) ->
|
74
|
+
$this = $("##{inst.editorId}")
|
75
|
+
parent = $this.parents('.element_editor')
|
76
|
+
parent.find('.spinner').remove()
|
77
|
+
inst.onChange.add ->
|
78
|
+
Alchemy.setElementDirty(parent)
|
83
79
|
|
84
|
-
# Removes the TinyMCE editor from given dom
|
80
|
+
# Removes the TinyMCE editor from given dom ids.
|
85
81
|
#
|
86
|
-
|
87
|
-
|
88
|
-
tinymce.get(
|
82
|
+
remove: (ids) ->
|
83
|
+
for id in ids
|
84
|
+
editor = tinymce.get("tinymce_#{id}")
|
85
|
+
if editor
|
86
|
+
editor.remove()
|
89
87
|
|
90
88
|
# Populate custom tinymce configurations
|
91
89
|
<% Alchemy::Tinymce.custom_config_contents.each do |content| %>
|
@@ -269,10 +269,6 @@ ul.list li.legend {
|
|
269
269
|
font-weight: bold;
|
270
270
|
}
|
271
271
|
|
272
|
-
#layoutpages li img.site_status {
|
273
|
-
float: left;
|
274
|
-
}
|
275
|
-
|
276
272
|
ul.list span.right {
|
277
273
|
float: right;
|
278
274
|
}
|
@@ -428,6 +424,13 @@ p.foot_note {
|
|
428
424
|
position: relative;
|
429
425
|
}
|
430
426
|
|
427
|
+
.info.message {
|
428
|
+
float: right;
|
429
|
+
width: 134px;
|
430
|
+
margin-left: 8px;
|
431
|
+
padding: 0 8px 0 32px;
|
432
|
+
}
|
433
|
+
|
431
434
|
.jcrop-holder { @include inline-block }
|
432
435
|
|
433
436
|
img {
|
@@ -437,13 +440,19 @@ p.foot_note {
|
|
437
440
|
|
438
441
|
form {
|
439
442
|
padding: 0;
|
440
|
-
text-align: right;
|
441
443
|
position: absolute;
|
442
|
-
width: 800px;
|
443
444
|
bottom: 2 * $default-padding;
|
444
|
-
|
445
|
-
|
446
|
-
|
445
|
+
right: 2 * $default-padding;
|
446
|
+
width: 176px;
|
447
|
+
margin-left: 8px;
|
448
|
+
|
449
|
+
.reset_mask, button {
|
450
|
+
display: block;
|
451
|
+
margin-bottom: 0;
|
452
|
+
text-align: center;
|
453
|
+
}
|
454
|
+
.reset_mask { padding-top: 4px }
|
455
|
+
button { width: 100% }
|
447
456
|
}
|
448
457
|
}
|
449
458
|
|
@@ -488,50 +488,54 @@ div.file_icon {
|
|
488
488
|
float: left;
|
489
489
|
height: 24px;
|
490
490
|
width: 24px;
|
491
|
-
}
|
492
491
|
|
493
|
-
|
494
|
-
|
495
|
-
}
|
492
|
+
span.icon {
|
493
|
+
margin: $default-margin;
|
494
|
+
}
|
496
495
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
496
|
+
a.assign_file {
|
497
|
+
display: block;
|
498
|
+
height: 16px;
|
499
|
+
background: image-url('alchemy/icons.png') no-repeat -480px -40px;
|
500
|
+
width: 16px;
|
501
|
+
margin: $default-margin;
|
502
|
+
}
|
503
503
|
}
|
504
504
|
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
510
|
-
|
511
|
-
|
505
|
+
.content_editor.essence_file {
|
506
|
+
|
507
|
+
.file_name {
|
508
|
+
white-space: nowrap;
|
509
|
+
overflow: hidden;
|
510
|
+
float: left;
|
511
|
+
max-width: 80%;
|
512
|
+
line-height: 25px;
|
513
|
+
font-size: 10px;
|
514
|
+
text-overflow: ellipsis;
|
515
|
+
}
|
512
516
|
}
|
513
517
|
|
514
|
-
|
518
|
+
.essence_file_tools {
|
515
519
|
height: 24px;
|
516
520
|
float: right;
|
517
521
|
background-color: white;
|
518
522
|
width: 48px;
|
519
|
-
}
|
520
523
|
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
}
|
524
|
+
a {
|
525
|
+
text-decoration: none;
|
526
|
+
width: 16px;
|
527
|
+
height: 16px;
|
528
|
+
margin: $default-margin;
|
529
|
+
float: left;
|
528
530
|
|
529
|
-
|
530
|
-
|
531
|
-
}
|
531
|
+
&.assign_file {
|
532
|
+
background: image-url('alchemy/icons.png') -512px -40px;
|
533
|
+
}
|
532
534
|
|
533
|
-
|
534
|
-
|
535
|
+
&.edit_file {
|
536
|
+
background: image-url('alchemy/icons.png') -160px -167px;
|
537
|
+
}
|
538
|
+
}
|
535
539
|
}
|
536
540
|
|
537
541
|
a.new_content_link {
|
@@ -38,7 +38,7 @@
|
|
38
38
|
box-shadow: $shadow;
|
39
39
|
}
|
40
40
|
|
41
|
-
@mixin box-sizing($box-sizing-type:
|
41
|
+
@mixin box-sizing($box-sizing-type: border-box) {
|
42
42
|
-webkit-box-sizing: $box-sizing-type;
|
43
43
|
-moz-box-sizing: $box-sizing-type;
|
44
44
|
box-sizing: $box-sizing-type;
|
@@ -47,8 +47,8 @@
|
|
47
47
|
#alchemy_menubar {
|
48
48
|
position: fixed;
|
49
49
|
top: 0;
|
50
|
-
left: -
|
51
|
-
width:
|
50
|
+
left: -356px;
|
51
|
+
width: 400px;
|
52
52
|
z-index: 10000;
|
53
53
|
background: $light-gray;
|
54
54
|
@include transition;
|
@@ -58,7 +58,7 @@
|
|
58
58
|
@include box-sizing;
|
59
59
|
border-right: $default-border;
|
60
60
|
border-bottom: $default-border;
|
61
|
-
height:
|
61
|
+
height: 44px;
|
62
62
|
padding: 4px 40px 4px 8px;
|
63
63
|
overflow: hidden;
|
64
64
|
font: $default-font-style;
|
@@ -90,15 +90,21 @@
|
|
90
90
|
height: auto;
|
91
91
|
|
92
92
|
li {
|
93
|
+
width: 32%;
|
93
94
|
height: 35px;
|
94
|
-
margin: 0 $default-
|
95
|
+
margin: 0 $default-margin 0 0;
|
95
96
|
padding: 0;
|
96
97
|
@include inline-block;
|
97
98
|
list-style-type: none;
|
99
|
+
text-align: center;
|
98
100
|
|
99
101
|
a, button {
|
100
|
-
line-height: 14px;
|
101
102
|
@extend %button-defaults;
|
103
|
+
padding-left: $default-padding;
|
104
|
+
padding-right: $default-padding;
|
105
|
+
width: 100%;
|
106
|
+
display: block;
|
107
|
+
line-height: 14px;
|
102
108
|
font-weight: normal;
|
103
109
|
text-decoration: none !important;
|
104
110
|
color: $text-color !important;
|
@@ -62,7 +62,7 @@ module Alchemy
|
|
62
62
|
@page.set_language_from_parent_or_default_language
|
63
63
|
end
|
64
64
|
if @page.save
|
65
|
-
redirect_path =
|
65
|
+
redirect_path = redirect_path_after_page_create
|
66
66
|
else
|
67
67
|
# TODO: Make a rollback, because the page is already persisted here.
|
68
68
|
redirect_path = admin_pages_path
|
@@ -238,7 +238,7 @@ module Alchemy
|
|
238
238
|
end
|
239
239
|
end
|
240
240
|
|
241
|
-
|
241
|
+
private
|
242
242
|
|
243
243
|
def load_page
|
244
244
|
@page = Page.find(params[:id])
|
@@ -259,6 +259,14 @@ module Alchemy
|
|
259
259
|
end
|
260
260
|
end
|
261
261
|
|
262
|
+
def redirect_path_after_page_create
|
263
|
+
if @page.redirects_to_external?
|
264
|
+
admin_pages_path
|
265
|
+
else
|
266
|
+
params[:redirect_to] || edit_admin_page_path(@page)
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
262
270
|
end
|
263
271
|
end
|
264
272
|
end
|
@@ -15,11 +15,6 @@ module Alchemy
|
|
15
15
|
"#{c.essence_type.demodulize.underscore}_#{c.id}"
|
16
16
|
end
|
17
17
|
|
18
|
-
# Returns a jquery selector string of form field ids from given contents
|
19
|
-
def contents_form_field_ids_string(contents)
|
20
|
-
contents.collect { |c| "##{c.form_field_id}" }.join(', ')
|
21
|
-
end
|
22
|
-
|
23
18
|
# Renders the name of elements content or the default name defined in elements.yml
|
24
19
|
def render_content_name(content)
|
25
20
|
if content.blank?
|
@@ -88,13 +88,14 @@ module Alchemy
|
|
88
88
|
#
|
89
89
|
def url_for_module_sub_navigation(navigation)
|
90
90
|
alchemy_module = module_definition_for(navigation)
|
91
|
+
return if alchemy_module.nil?
|
91
92
|
route_from_engine_or_main_app(
|
92
93
|
alchemy_module['engine_name'],
|
93
94
|
url_options_for_navigation_entry(navigation)
|
94
95
|
)
|
95
96
|
end
|
96
97
|
|
97
|
-
|
98
|
+
private
|
98
99
|
|
99
100
|
# Calls +url_for+ helper on engine if present or on host app.
|
100
101
|
#
|
@@ -70,6 +70,8 @@ module Alchemy
|
|
70
70
|
# Reverse the rendering order
|
71
71
|
# @option options [String] :sort_by
|
72
72
|
# The name of a {Alchemy::Content} to sort the elements by
|
73
|
+
# @option options [String] :separator
|
74
|
+
# A string that will be used to join the element partials. Default nil
|
73
75
|
#
|
74
76
|
def render_elements(options = {})
|
75
77
|
default_options = {
|
@@ -114,10 +116,11 @@ module Alchemy
|
|
114
116
|
end
|
115
117
|
end
|
116
118
|
end
|
119
|
+
element_string = []
|
117
120
|
all_elements.each_with_index do |element, i|
|
118
|
-
element_string
|
121
|
+
element_string << render_element(element, :view, options, i+1)
|
119
122
|
end
|
120
|
-
element_string.html_safe
|
123
|
+
element_string.join(options[:separator]).html_safe
|
121
124
|
end
|
122
125
|
end
|
123
126
|
|
@@ -155,7 +155,7 @@ module Alchemy
|
|
155
155
|
# :submenu => true # Shows the nested children
|
156
156
|
# :level => 2 # Normally there is no need to change the level parameter, just in a few special cases
|
157
157
|
#
|
158
|
-
def render_subnavigation(options = {})
|
158
|
+
def render_subnavigation(options = {}, html_options = {})
|
159
159
|
default_options = {
|
160
160
|
:from_page => @page,
|
161
161
|
:submenu => true,
|
@@ -166,7 +166,7 @@ module Alchemy
|
|
166
166
|
while options[:from_page].level > options[:level] do
|
167
167
|
options[:from_page] = options[:from_page].parent
|
168
168
|
end
|
169
|
-
render_navigation(options)
|
169
|
+
render_navigation(options, html_options)
|
170
170
|
else
|
171
171
|
return nil
|
172
172
|
end
|
@@ -358,6 +358,12 @@ module Alchemy
|
|
358
358
|
end
|
359
359
|
alias_method :richtext_contents, :rtf_contents
|
360
360
|
|
361
|
+
# Returns an array of all EssenceRichtext contents ids
|
362
|
+
#
|
363
|
+
def richtext_contents_ids
|
364
|
+
contents.essence_richtexts.pluck('alchemy_contents.id')
|
365
|
+
end
|
366
|
+
|
361
367
|
# The names of all cells from given page this element could be placed in.
|
362
368
|
def belonging_cellnames(page)
|
363
369
|
cellnames = page.cells.select { |c| c.available_elements.include?(self.name) }.collect(&:name).flatten.uniq
|
@@ -166,14 +166,13 @@ module Alchemy
|
|
166
166
|
elements.named(definition['feed_elements'])
|
167
167
|
end
|
168
168
|
|
169
|
-
# Returns an array of
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
end
|
169
|
+
# Returns an array of all EssenceRichtext contents ids
|
170
|
+
#
|
171
|
+
def richtext_contents_ids
|
172
|
+
contents.essence_richtexts.pluck('alchemy_contents.id')
|
174
173
|
end
|
175
174
|
|
176
|
-
|
175
|
+
private
|
177
176
|
|
178
177
|
# Looks in the page_layout descripion, if there are elements to autogenerate.
|
179
178
|
#
|
@@ -1,10 +1,8 @@
|
|
1
|
-
<%- rtfs = element.
|
1
|
+
<%- rtfs = element.richtext_contents_ids -%>
|
2
2
|
(function() {
|
3
3
|
var $element = $('.element_content', '#element_<%= element.id %>');
|
4
|
-
|
5
|
-
tinymce.get('contents_content_<%= content.id %>_body').remove();
|
6
|
-
<% end %>
|
4
|
+
Alchemy.Tinymce.remove(<%= rtfs.to_json %>);
|
7
5
|
$element.html('<%= escape_javascript render_editor(element) %>');
|
8
6
|
Alchemy.GUI.init($element);
|
9
|
-
Alchemy.Tinymce.
|
7
|
+
Alchemy.Tinymce.init(<%= rtfs.to_json %>);
|
10
8
|
})();
|
@@ -30,9 +30,7 @@
|
|
30
30
|
|
31
31
|
Alchemy.growl('<%= _t(:successfully_added_element) -%>');
|
32
32
|
Alchemy.closeCurrentWindow();
|
33
|
-
|
34
|
-
Alchemy.Tinymce.addEditor('<%= contents_form_field_ids_string(rtfs) %>');
|
35
|
-
<% end %>
|
33
|
+
Alchemy.Tinymce.init(<%= @element.richtext_contents_ids.to_json %>);
|
36
34
|
Alchemy.PreviewWindow.refresh();
|
37
35
|
Alchemy.ElementEditors.init();
|
38
36
|
|
@@ -1,5 +1,3 @@
|
|
1
|
-
<% rtfs = @element.contents.essence_richtexts %>
|
2
|
-
|
3
1
|
(function($) {
|
4
2
|
var $el = $('.element_editor[data-element-id="<%= @element.id %>"]');
|
5
3
|
|
@@ -16,21 +14,13 @@
|
|
16
14
|
|
17
15
|
<% if @element.folded %>
|
18
16
|
|
19
|
-
|
20
|
-
|
21
|
-
Alchemy.Tinymce.removeEditor('<%= contents_form_field_ids_string(rtfs) %>');
|
22
|
-
|
23
|
-
<% end %>
|
17
|
+
Alchemy.Tinymce.remove(<%= @element.richtext_contents_ids.to_json %>);
|
24
18
|
|
25
19
|
<% else %>
|
26
20
|
|
27
21
|
$el.trigger('Alchemy.SelectElementEditor');
|
28
22
|
Alchemy.SelectBox($el);
|
29
|
-
|
30
|
-
<% if rtfs.any? %>
|
31
|
-
Alchemy.Tinymce.addEditor('<%= contents_form_field_ids_string(rtfs) %>');
|
32
|
-
<% end %>
|
33
|
-
|
23
|
+
Alchemy.Tinymce.init(<%= @element.richtext_contents_ids.to_json %>);
|
34
24
|
Alchemy.GUI.initElement($el);
|
35
25
|
|
36
26
|
<% end %>
|
@@ -8,7 +8,9 @@
|
|
8
8
|
$("#element_<%= @element.id %>_errors").hide();
|
9
9
|
Alchemy.setElementSaved($el);
|
10
10
|
Alchemy.growl('<%= _t(:element_saved) %>');
|
11
|
-
Alchemy.PreviewWindow.refresh()
|
11
|
+
Alchemy.PreviewWindow.refresh(function() {
|
12
|
+
Alchemy.ElementEditors.selectElementInPreview(<%= @element.id %>);
|
13
|
+
});
|
12
14
|
<%= update_essence_select_elements(@page, @element) -%>
|
13
15
|
<%- else -%>
|
14
16
|
Alchemy.growl('<%= escape_javascript(@notice) %>', 'warn');
|
@@ -1,5 +1,4 @@
|
|
1
1
|
(function($) {
|
2
|
-
var $el = $('#element_<%= @content.element.id %>');
|
3
2
|
$('#<%= content_dom_id(@content) %>').replaceWith('<%= escape_javascript(
|
4
3
|
render partial: "alchemy/essences/essence_file_editor",
|
5
4
|
formats: [:html],
|
@@ -10,6 +9,6 @@
|
|
10
9
|
) %>');
|
11
10
|
Alchemy.closeCurrentWindow();
|
12
11
|
Alchemy.reloadPreview();
|
13
|
-
Alchemy.setElementDirty($
|
14
|
-
Alchemy.overlayObserver($
|
12
|
+
Alchemy.setElementDirty($('#element_<%= @content.element.id %>'));
|
13
|
+
Alchemy.overlayObserver($('#<%= content_dom_id(@content) %>'));
|
15
14
|
})(jQuery);
|
@@ -5,7 +5,7 @@
|
|
5
5
|
<% end %>
|
6
6
|
<% else %>
|
7
7
|
<%= render_message do %>
|
8
|
-
<%= _t(
|
8
|
+
<%= simple_format _t(:explain_cropping) %>
|
9
9
|
<% end %>
|
10
10
|
<div class="thumbnail_background">
|
11
11
|
<%= image_tag(
|
@@ -22,11 +22,11 @@
|
|
22
22
|
<%= f.hidden_field :crop_from %>
|
23
23
|
<%= f.hidden_field :crop_size %>
|
24
24
|
<%= hidden_field_tag :content_id, @content.id %>
|
25
|
-
<%=
|
25
|
+
<%= f.button "#{render_icon(:true)} #{_t(:apply)}".html_safe, class: 'with_icon' %>
|
26
|
+
<%= link_to _t('Reset Imagemask'), '#', {
|
26
27
|
onclick: 'Alchemy.ImageCropper.reset()',
|
27
|
-
class: '
|
28
|
-
}
|
29
|
-
<%= f.button _t(:apply), class: 'button' %>
|
28
|
+
class: 'reset_mask'
|
29
|
+
} %>
|
30
30
|
<% end %>
|
31
31
|
</div>
|
32
32
|
<% end %>
|
@@ -26,7 +26,12 @@
|
|
26
26
|
</tr>
|
27
27
|
<tr>
|
28
28
|
<td class="label"><%= f.label :page_layout %></td>
|
29
|
-
<td class="
|
29
|
+
<td class="select">
|
30
|
+
<%= f.select :page_layout,
|
31
|
+
Alchemy::PageLayout.all.map { |p| [Alchemy::PageLayout.human_layout_name(p['name']), p['name']] },
|
32
|
+
{prompt: _t('Please choose')},
|
33
|
+
{class: 'alchemy_selectbox long'} %>
|
34
|
+
</td>
|
30
35
|
</tr>
|
31
36
|
<tr>
|
32
37
|
<td></td>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<li class="page_level_<%= layoutpage.level %>" id="page_<%= layoutpage.id %>">
|
2
|
-
<div class="sitemap_page">
|
2
|
+
<div class="sitemap_page<%= layoutpage.locked ? ' locked' : '' %>">
|
3
3
|
<div class="sitemap_left_images">
|
4
|
-
<span class="site_status
|
4
|
+
<span class="site_status"></span>
|
5
5
|
</div>
|
6
6
|
<div class="sitemap_right_tools">
|
7
7
|
<%- permitted_to?(:configure, :alchemy_admin_pages) do -%>
|
@@ -165,8 +165,7 @@
|
|
165
165
|
Alchemy.SortableElements(<%= @page.id %>, '<%= form_authenticity_token %>');
|
166
166
|
Alchemy.ElementEditors.init();
|
167
167
|
Alchemy.SelectBox('.element_editor');
|
168
|
-
Alchemy.Tinymce.init();
|
169
|
-
Alchemy.Tinymce.initCustomEditors(<%= raw @page.custom_tinymce_contents_selectors.to_json %>);
|
168
|
+
Alchemy.Tinymce.init(<%= @page.richtext_contents_ids.to_json %>);
|
170
169
|
jQuery('#cells').tabs().tabs('paging', { follow: true, followOnSelect: true } );
|
171
170
|
Alchemy.ElementDirtyObserver('#element_area');
|
172
171
|
if (window.location.hash) {
|
@@ -201,6 +200,7 @@
|
|
201
200
|
width = Alchemy.PreviewWindow.currentWidth;
|
202
201
|
}
|
203
202
|
Alchemy.PreviewWindow.currentWindow.dialog('widget').css('width', width);
|
203
|
+
Alchemy.PreviewWindow.currentWindow.dialog('moveToTop');
|
204
204
|
});
|
205
205
|
});
|
206
206
|
|
@@ -1,14 +1,15 @@
|
|
1
1
|
<% if options[:crop] && content.ingredient %>
|
2
2
|
<%= link_to_overlay_window(
|
3
3
|
render_icon('crop'),
|
4
|
-
alchemy.crop_admin_essence_picture_path(content.essence, :
|
4
|
+
alchemy.crop_admin_essence_picture_path(content.essence, options: options.to_json),
|
5
5
|
{
|
6
|
-
:
|
7
|
-
:
|
8
|
-
:
|
6
|
+
size: "1000x653",
|
7
|
+
title: _t('Edit Picturemask'),
|
8
|
+
image_loader: false,
|
9
|
+
modal: false
|
9
10
|
},
|
10
11
|
{
|
11
|
-
:
|
12
|
+
title: _t('Edit Picturemask')
|
12
13
|
}
|
13
14
|
) %>
|
14
15
|
<%- else -%>
|
@@ -399,7 +399,7 @@ de:
|
|
399
399
|
element_of_type: "Element"
|
400
400
|
element_saved: "Element wurde gespeichert."
|
401
401
|
enter_external_link: "Geben Sie hier die Adresse der Seite ein zu der Sie einen Link setzen wollen."
|
402
|
-
|
402
|
+
explain_cropping: "<p>Sie können den Rahmen verschieben und in der Größe verändern um den Bildausschnitt festzulegen.</p><p>Wenn Sie zufrieden sind, dann klicken Sie bitte auf speichern.</p>"
|
403
403
|
explain_publishing: "Die gecachte Version vom Server löschen und die aktuellen Änderungen veröffentlichen"
|
404
404
|
explain_sitemap_dragndrop_sorting: "Tip: Halten Sie zum Sortieren der Seiten das Seitensymbol mit der Maus fest und bewegen Sie sie an ihre neue Position."
|
405
405
|
explain_unlocking: "Die Seite verlassen und für andere Benutzer zum Bearbeiten freigeben."
|
@@ -237,7 +237,7 @@ en:
|
|
237
237
|
element_of_type: "Element"
|
238
238
|
element_saved: "Saved element."
|
239
239
|
enter_external_link: "Please enter the URL you want to link with"
|
240
|
-
|
240
|
+
explain_cropping: "<p>Move the frame and change its size to adjust the image section.</p><p>Click on apply when you are satisfied.</p>"
|
241
241
|
explain_publishing: "Publish the page and remove the cached version from the server."
|
242
242
|
explain_sitemap_dragndrop_sorting: "Tip: Drag the pages at the icon in order to sort them."
|
243
243
|
explain_unlocking: "Leave page and unlock it for other users."
|
data/lib/alchemy/modules.rb
CHANGED
@@ -1,38 +1,75 @@
|
|
1
1
|
module Alchemy
|
2
2
|
module Modules
|
3
|
+
mattr_accessor :alchemy_modules
|
3
4
|
|
4
|
-
@@alchemy_modules = YAML.load_file(File.
|
5
|
+
@@alchemy_modules = YAML.load_file(File.expand_path('../../../config/alchemy/modules.yml', __FILE__))
|
5
6
|
|
6
7
|
def self.included(base)
|
7
8
|
base.send :helper_method, :alchemy_modules, :module_definition_for
|
8
9
|
end
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
# Get the module definition for given module name
|
12
|
+
#
|
13
|
+
# You can also pass a hash of an module definition.
|
14
|
+
# It then tries to find the module defintion from controller name and action name
|
15
|
+
#
|
14
16
|
def module_definition_for(name)
|
15
|
-
|
16
|
-
|
17
|
-
|
17
|
+
case name
|
18
|
+
when String
|
19
|
+
alchemy_modules.detect { |p| p['name'] == name }
|
20
|
+
when Hash
|
18
21
|
alchemy_modules.detect do |alchemy_module|
|
19
|
-
alchemy_module.
|
20
|
-
name.symbolize_keys!
|
21
|
-
module_navi = alchemy_module["navigation"].stringify_keys
|
22
|
-
if module_navi["sub_navigation"]
|
23
|
-
module_navi["sub_navigation"].map(&:stringify_keys).detect do |subnavi|
|
24
|
-
subnavi["controller"].gsub(/^\//, '') == name[:controller] && subnavi["action"] == name[:action]
|
25
|
-
end
|
26
|
-
end
|
22
|
+
definition_from_subnavi(alchemy_module, name.symbolize_keys)
|
27
23
|
end
|
28
24
|
else
|
29
25
|
raise "Could not find module definition for #{name}"
|
30
26
|
end
|
31
27
|
end
|
32
28
|
|
29
|
+
# Register a Alchemy module.
|
30
|
+
#
|
31
|
+
# A module is a Hash that must have at least a name and a navigation key
|
32
|
+
# that has a controller and action name.
|
33
|
+
#
|
34
|
+
# == Example:
|
35
|
+
#
|
36
|
+
# name: 'module',
|
37
|
+
# navigation: {
|
38
|
+
# controller: 'admin/controller_name',
|
39
|
+
# action: 'index'
|
40
|
+
# }
|
41
|
+
#
|
33
42
|
def self.register_module(module_definition)
|
34
43
|
@@alchemy_modules << module_definition.stringify_keys
|
35
44
|
end
|
36
45
|
|
46
|
+
private
|
47
|
+
|
48
|
+
def alchemy_module_navigation(alchemy_module)
|
49
|
+
alchemy_module.stringify_keys!
|
50
|
+
alchemy_module.fetch('navigation', {}).stringify_keys
|
51
|
+
end
|
52
|
+
|
53
|
+
def definition_from_subnavi(alchemy_module, name)
|
54
|
+
module_navi = alchemy_module_navigation(alchemy_module)
|
55
|
+
subnavi = module_navi['sub_navigation']
|
56
|
+
return if subnavi.nil?
|
57
|
+
subnavi.map(&:stringify_keys).detect do |subnavi|
|
58
|
+
controller_matches?(subnavi, name) && action_matches?(subnavi, name)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
def controller_matches?(subnavi, name)
|
63
|
+
remove_slash(subnavi['controller']) == remove_slash(name[:controller])
|
64
|
+
end
|
65
|
+
|
66
|
+
def action_matches?(subnavi, name)
|
67
|
+
subnavi['action'] == name[:action]
|
68
|
+
end
|
69
|
+
|
70
|
+
def remove_slash(name)
|
71
|
+
name.gsub(/^\//, '')
|
72
|
+
end
|
73
|
+
|
37
74
|
end
|
38
75
|
end
|
data/lib/alchemy/version.rb
CHANGED
@@ -73,13 +73,13 @@ module Alchemy
|
|
73
73
|
let(:language) { mock_model('Language', code: 'kl') }
|
74
74
|
let(:parent) { mock_model('Page', language: language) }
|
75
75
|
let(:page_params) do
|
76
|
-
{parent_id: parent.id, name: 'new Page'}
|
76
|
+
{parent_id: parent.id, name: 'new Page'}
|
77
77
|
end
|
78
78
|
|
79
79
|
context "" do
|
80
80
|
before do
|
81
81
|
Page.any_instance.stub(:set_language_from_parent_or_default_language)
|
82
|
-
Page.any_instance.stub(:
|
82
|
+
Page.any_instance.stub(save: true)
|
83
83
|
end
|
84
84
|
|
85
85
|
it "nests a new page under given parent" do
|
@@ -88,6 +88,13 @@ module Alchemy
|
|
88
88
|
expect(assigns(:page).parent_id).to eq(parent.id)
|
89
89
|
end
|
90
90
|
|
91
|
+
it "redirects to edit page template" do
|
92
|
+
page = mock_model('Page')
|
93
|
+
controller.should_receive(:edit_admin_page_path).and_return('bla')
|
94
|
+
post :create, page: page_params
|
95
|
+
response.should redirect_to('bla')
|
96
|
+
end
|
97
|
+
|
91
98
|
context "if new page can not be saved" do
|
92
99
|
it "should redirect to admin_pages_path" do
|
93
100
|
Page.any_instance.stub(:save).and_return(false)
|
@@ -114,6 +121,14 @@ module Alchemy
|
|
114
121
|
end
|
115
122
|
end
|
116
123
|
end
|
124
|
+
|
125
|
+
context 'with page redirecting to external' do
|
126
|
+
it "redirects to sitemap" do
|
127
|
+
Page.any_instance.should_receive(:redirects_to_external?).and_return(true)
|
128
|
+
post :create, page: page_params
|
129
|
+
response.should redirect_to(admin_pages_path)
|
130
|
+
end
|
131
|
+
end
|
117
132
|
end
|
118
133
|
|
119
134
|
context "with paste_from_clipboard in parameters" do
|
@@ -130,13 +145,11 @@ module Alchemy
|
|
130
145
|
parent,
|
131
146
|
'pasted Page'
|
132
147
|
).and_return(
|
133
|
-
mock_model('Page', save: true, name: 'pasted Page')
|
148
|
+
mock_model('Page', save: true, name: 'pasted Page', redirects_to_external?: false)
|
134
149
|
)
|
135
150
|
post :create, {paste_from_clipboard: page_in_clipboard.id, page: {parent_id: parent.id, name: 'pasted Page'}, format: :js}
|
136
151
|
end
|
137
|
-
|
138
152
|
end
|
139
|
-
|
140
153
|
end
|
141
154
|
|
142
155
|
describe '#copy_language_tree' do
|
@@ -283,7 +296,7 @@ module Alchemy
|
|
283
296
|
end
|
284
297
|
end
|
285
298
|
end
|
286
|
-
|
299
|
+
|
287
300
|
end
|
288
301
|
|
289
302
|
end
|
@@ -7,17 +7,6 @@ describe Alchemy::Admin::ContentsHelper do
|
|
7
7
|
helper.content_dom_id(element.content_by_type('EssenceText')).should match(/essence_text_\d{1,}/)
|
8
8
|
end
|
9
9
|
|
10
|
-
describe '#contents_form_field_ids_string' do
|
11
|
-
let(:content_1) { double('Alchemy::Content', form_field_id: 'contents_content_1_body') }
|
12
|
-
let(:content_2) { double('Alchemy::Content', form_field_id: 'contents_content_2_body') }
|
13
|
-
|
14
|
-
it "renders a jquery selector string of form field ids from given contents" do
|
15
|
-
expect(
|
16
|
-
helper.contents_form_field_ids_string([content_1, content_2])
|
17
|
-
).to eq('#contents_content_1_body, #contents_content_2_body')
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
10
|
it "should render the content name" do
|
22
11
|
helper.render_content_name(element.content_by_type('EssenceText')).should == "Intro"
|
23
12
|
end
|
@@ -18,10 +18,10 @@ describe Alchemy::Admin::NavigationHelper do
|
|
18
18
|
|
19
19
|
let(:event_module) { {
|
20
20
|
'navigation' => {
|
21
|
-
'controller' => 'admin/events',
|
21
|
+
'controller' => '/admin/events',
|
22
22
|
'action' => 'index',
|
23
23
|
'sub_navigation' => [{
|
24
|
-
'controller' => 'admin/events',
|
24
|
+
'controller' => '/admin/events',
|
25
25
|
'action' => 'index'
|
26
26
|
}]
|
27
27
|
}
|
@@ -176,29 +176,38 @@ describe Alchemy::Admin::NavigationHelper do
|
|
176
176
|
end
|
177
177
|
|
178
178
|
describe '#url_for_module_sub_navigation' do
|
179
|
-
|
180
|
-
let(:navigation) { alchemy_module['navigation']['sub_navigation'].first }
|
179
|
+
subject { helper.url_for_module_sub_navigation(navigation) }
|
181
180
|
|
182
|
-
|
183
|
-
|
184
|
-
|
181
|
+
let(:current_module) { alchemy_module }
|
182
|
+
let(:navigation) { current_module['navigation']['sub_navigation'].first }
|
183
|
+
|
184
|
+
before do
|
185
|
+
helper.stub(module_definition_for: current_module)
|
186
|
+
end
|
187
|
+
|
188
|
+
context "with module within an engine" do
|
189
|
+
let(:current_module) { alchemy_module }
|
185
190
|
|
186
191
|
it "returns correct url string" do
|
187
|
-
|
192
|
+
should == '/admin/layoutpages'
|
188
193
|
end
|
189
194
|
end
|
190
195
|
|
191
196
|
context "with module within host app" do
|
192
|
-
let(:
|
193
|
-
|
194
|
-
before {
|
195
|
-
helper.stub(:module_definition_for).and_return(event_module)
|
196
|
-
}
|
197
|
+
let(:current_module) { event_module }
|
197
198
|
|
198
199
|
it "returns correct url string" do
|
199
|
-
|
200
|
+
should == '/admin/events'
|
200
201
|
end
|
201
202
|
end
|
203
|
+
|
204
|
+
context 'without module found' do
|
205
|
+
before do
|
206
|
+
helper.stub(module_definition_for: nil)
|
207
|
+
end
|
208
|
+
|
209
|
+
it { should be_nil }
|
210
|
+
end
|
202
211
|
end
|
203
212
|
|
204
213
|
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Alchemy
|
4
|
+
class ModulesTestController < ApplicationController
|
5
|
+
include Modules
|
6
|
+
end
|
7
|
+
|
8
|
+
describe Modules do
|
9
|
+
let(:controller) { ModulesTestController.new }
|
10
|
+
let(:alchemy_modules) { YAML.load_file(File.expand_path('../../../config/alchemy/modules.yml', __FILE__)) }
|
11
|
+
|
12
|
+
describe '#module_definition_for' do
|
13
|
+
subject { controller.module_definition_for(name) }
|
14
|
+
|
15
|
+
let(:dashboard_module) { alchemy_modules.first }
|
16
|
+
|
17
|
+
context 'with a string given as name' do
|
18
|
+
let(:name) { 'dashboard' }
|
19
|
+
|
20
|
+
it "returns the module definition" do
|
21
|
+
should == dashboard_module
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context 'with a hash given as name' do
|
26
|
+
let(:controller_name) { 'alchemy/admin/dashboard' }
|
27
|
+
let(:name) { {controller: controller_name, action: 'index'} }
|
28
|
+
|
29
|
+
it "returns the module definition" do
|
30
|
+
should == dashboard_module
|
31
|
+
end
|
32
|
+
|
33
|
+
context 'with leading slash in controller name' do
|
34
|
+
let(:controller_name) { '/alchemy/admin/dashboard' }
|
35
|
+
|
36
|
+
it "returns the module definition" do
|
37
|
+
should == dashboard_module
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context 'with nil given as name' do
|
43
|
+
let(:name) { nil }
|
44
|
+
it 'raises an error' do
|
45
|
+
expect { subject }.to raise_error('Could not find module definition for ')
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: alchemy_cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.7.
|
4
|
+
version: 2.7.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thomas von Deyen
|
@@ -12,7 +12,7 @@ authors:
|
|
12
12
|
autorequire:
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
|
-
date: 2013-
|
15
|
+
date: 2013-11-18 00:00:00.000000000 Z
|
16
16
|
dependencies:
|
17
17
|
- !ruby/object:Gem::Dependency
|
18
18
|
name: rails
|
@@ -966,6 +966,7 @@ files:
|
|
966
966
|
- spec/javascripts/spec.js
|
967
967
|
- spec/libraries/config_spec.rb
|
968
968
|
- spec/libraries/essence_spec.rb
|
969
|
+
- spec/libraries/modules_spec.rb
|
969
970
|
- spec/libraries/mount_point_spec.rb
|
970
971
|
- spec/libraries/page_layout_spec.rb
|
971
972
|
- spec/libraries/resource_spec.rb
|
@@ -1145,7 +1146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
1145
1146
|
requirements:
|
1146
1147
|
- ImageMagick (libmagick), v6.6 or greater.
|
1147
1148
|
rubyforge_project:
|
1148
|
-
rubygems_version: 2.
|
1149
|
+
rubygems_version: 2.1.10
|
1149
1150
|
signing_key:
|
1150
1151
|
specification_version: 4
|
1151
1152
|
summary: A powerful, userfriendly and flexible CMS for Rails 3
|
@@ -1257,6 +1258,7 @@ test_files:
|
|
1257
1258
|
- spec/javascripts/spec.js
|
1258
1259
|
- spec/libraries/config_spec.rb
|
1259
1260
|
- spec/libraries/essence_spec.rb
|
1261
|
+
- spec/libraries/modules_spec.rb
|
1260
1262
|
- spec/libraries/mount_point_spec.rb
|
1261
1263
|
- spec/libraries/page_layout_spec.rb
|
1262
1264
|
- spec/libraries/resource_spec.rb
|