alchemy_cms 3.5.0 → 3.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +82 -26
- data/.travis.yml +1 -1
- data/CHANGELOG.md +23 -1
- data/README.md +14 -5
- data/Rakefile +0 -1
- data/alchemy_cms.gemspec +2 -5
- data/app/assets/images/alchemy/alchemy-logo.png +0 -0
- data/app/assets/javascripts/alchemy/admin.js +1 -1
- data/app/assets/javascripts/alchemy/alchemy.base.js.coffee +4 -8
- data/app/assets/javascripts/alchemy/alchemy.buttons.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +18 -27
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +3 -8
- data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +0 -1
- data/app/assets/javascripts/alchemy/alchemy.page_sorter.js +22 -46
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +2 -2
- data/app/assets/javascripts/alchemy/alchemy.spinner.js +32 -0
- data/app/assets/javascripts/alchemy/alchemy.tinymce.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/templates/index.js +1 -0
- data/app/assets/javascripts/alchemy/templates/spinner.hbs +7 -0
- data/app/assets/stylesheets/alchemy/_extends.scss +1 -0
- data/app/assets/stylesheets/alchemy/admin.scss +1 -0
- data/app/assets/stylesheets/alchemy/base.scss +1 -7
- data/app/assets/stylesheets/alchemy/buttons.scss +1 -5
- data/app/assets/stylesheets/alchemy/dialogs.scss +0 -4
- data/app/assets/stylesheets/alchemy/elements.scss +2 -6
- data/app/assets/stylesheets/alchemy/frame.scss +0 -5
- data/app/assets/stylesheets/alchemy/image_library.scss +0 -13
- data/app/assets/stylesheets/alchemy/sitemap.scss +5 -34
- data/app/assets/stylesheets/alchemy/spinner.scss +52 -0
- data/app/controllers/alchemy/admin/attachments_controller.rb +12 -11
- data/app/controllers/alchemy/admin/base_controller.rb +3 -7
- data/app/controllers/alchemy/admin/essence_pictures_controller.rb +2 -1
- data/app/controllers/alchemy/admin/languages_controller.rb +3 -8
- data/app/controllers/alchemy/admin/pictures_controller.rb +11 -7
- data/app/controllers/alchemy/admin/resources_controller.rb +1 -1
- data/app/controllers/alchemy/attachments_controller.rb +2 -0
- data/app/controllers/alchemy/base_controller.rb +4 -5
- data/app/controllers/concerns/alchemy/admin/uploader_responses.rb +1 -1
- data/app/helpers/alchemy/admin/base_helper.rb +17 -8
- data/app/helpers/alchemy/admin/tags_helper.rb +31 -18
- data/app/helpers/alchemy/base_helper.rb +1 -1
- data/app/helpers/alchemy/pages_helper.rb +4 -7
- data/app/models/alchemy/attachment.rb +4 -0
- data/app/models/alchemy/cell.rb +1 -1
- data/app/models/alchemy/element.rb +6 -12
- data/app/models/alchemy/element/definitions.rb +2 -2
- data/app/models/alchemy/element/element_contents.rb +1 -1
- data/app/models/alchemy/essence_picture_view.rb +14 -2
- data/app/models/alchemy/language.rb +4 -4
- data/app/models/alchemy/page.rb +25 -28
- data/app/models/alchemy/page/page_elements.rb +1 -1
- data/app/models/alchemy/page/page_natures.rb +1 -1
- data/app/models/alchemy/picture.rb +5 -1
- data/app/models/alchemy/site.rb +27 -12
- data/app/views/alchemy/admin/attachments/_tag_list.html.erb +14 -13
- data/app/views/alchemy/admin/dashboard/info.html.erb +1 -1
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_sitemap.html.erb +2 -2
- data/app/views/alchemy/admin/pages/configure_external.html.erb +1 -1
- data/app/views/alchemy/admin/pages/index.html.erb +5 -7
- data/app/views/alchemy/admin/pages/sort.html.erb +19 -0
- data/app/views/alchemy/admin/pages/update.js.erb +1 -1
- data/app/views/alchemy/admin/pictures/_archive.html.erb +19 -19
- data/app/views/alchemy/admin/pictures/_tag_list.html.erb +3 -4
- data/app/views/alchemy/admin/resources/_tag_list.html.erb +3 -4
- data/app/views/alchemy/admin/resources/edit.html.erb +1 -1
- data/app/views/alchemy/admin/resources/new.html.erb +1 -1
- data/app/views/alchemy/pages/_meta_data.html.erb +1 -1
- data/app/views/alchemy/pages/show.rss.builder +0 -2
- data/app/views/alchemy/welcome.html.erb +1 -1
- data/app/views/layouts/alchemy/admin.html.erb +1 -1
- data/config/locales/alchemy.de.yml +4 -4
- data/config/locales/alchemy.en.yml +4 -4
- data/config/locales/alchemy.es.yml +3 -3
- data/config/locales/alchemy.fr.yml +4 -4
- data/config/locales/alchemy.it.yml +3 -3
- data/config/locales/alchemy.nl.yml +4 -4
- data/config/locales/alchemy.ru.yml +3 -3
- data/lib/alchemy/auth_accessors.rb +6 -6
- data/lib/alchemy/cache_digests/template_tracker.rb +5 -5
- data/lib/alchemy/controller_actions.rb +1 -6
- data/lib/alchemy/engine.rb +0 -53
- data/lib/alchemy/errors.rb +12 -3
- data/lib/alchemy/i18n.rb +1 -1
- data/lib/alchemy/logger.rb +1 -1
- data/lib/alchemy/page_layout.rb +5 -5
- data/lib/alchemy/seeder.rb +16 -49
- data/lib/alchemy/tasks/helpers.rb +1 -1
- data/lib/alchemy/test_support/config_stubbing.rb +28 -0
- data/lib/alchemy/test_support/essence_shared_examples.rb +6 -6
- data/lib/alchemy/test_support/factories/language_factory.rb +1 -1
- data/lib/alchemy/test_support/factories/page_factory.rb +7 -0
- data/lib/alchemy/test_support/factories/site_factory.rb +6 -0
- data/lib/alchemy/test_support/shared_contexts.rb +14 -0
- data/lib/alchemy/test_support/shared_uploader_examples.rb +10 -0
- data/lib/alchemy/touching.rb +1 -1
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +56 -1
- data/lib/{alchemy/kaminari → kaminari}/scoped_pagination_url_helper.rb +0 -0
- data/lib/rails/generators/alchemy/base.rb +1 -1
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +2 -1
- data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +2 -1
- data/lib/rails/generators/alchemy/site_layouts/site_layouts_generator.rb +2 -1
- data/lib/tasks/alchemy/tidy.rake +91 -89
- data/lib/tasks/alchemy/upgrade.rake +15 -15
- metadata +29 -14
- data/app/assets/javascripts/alchemy/alchemy.spinner.js.coffee +0 -49
- data/app/views/alchemy/admin/pages/sort.js.erb +0 -4
- data/vendor/assets/javascripts/handlebars.js +0 -4608
- data/vendor/assets/javascripts/spin.min.js +0 -1
@@ -44,11 +44,7 @@ module Alchemy
|
|
44
44
|
else
|
45
45
|
render_errors_or_redirect(
|
46
46
|
@attachment,
|
47
|
-
admin_attachments_path(
|
48
|
-
per_page: params[:per_page],
|
49
|
-
page: params[:page],
|
50
|
-
q: params[:q]
|
51
|
-
),
|
47
|
+
admin_attachments_path(search_params),
|
52
48
|
Alchemy.t("File successfully updated")
|
53
49
|
)
|
54
50
|
end
|
@@ -57,11 +53,7 @@ module Alchemy
|
|
57
53
|
def destroy
|
58
54
|
name = @attachment.name
|
59
55
|
@attachment.destroy
|
60
|
-
@url = admin_attachments_url(
|
61
|
-
per_page: params[:per_page],
|
62
|
-
page: params[:page],
|
63
|
-
q: params[:q]
|
64
|
-
)
|
56
|
+
@url = admin_attachments_url(search_params)
|
65
57
|
flash[:notice] = Alchemy.t('File deleted successfully', name: name)
|
66
58
|
end
|
67
59
|
|
@@ -75,9 +67,18 @@ module Alchemy
|
|
75
67
|
|
76
68
|
private
|
77
69
|
|
70
|
+
def search_params
|
71
|
+
params.except(:attachment, :id).permit(
|
72
|
+
:file_type,
|
73
|
+
:page,
|
74
|
+
{q: resource_handler.search_field_name},
|
75
|
+
:tagged_with
|
76
|
+
)
|
77
|
+
end
|
78
|
+
|
78
79
|
def handle_uploader_response(status:)
|
79
80
|
if @attachment.valid?
|
80
|
-
render
|
81
|
+
render successful_uploader_response(file: @attachment, status: status)
|
81
82
|
else
|
82
83
|
render failed_uploader_response(file: @attachment)
|
83
84
|
end
|
@@ -138,17 +138,13 @@ module Alchemy
|
|
138
138
|
#
|
139
139
|
def options_from_params
|
140
140
|
case params[:options]
|
141
|
-
when ''
|
141
|
+
when '', nil
|
142
142
|
{}
|
143
143
|
when String
|
144
144
|
JSON.parse(params[:options])
|
145
|
-
when Hash
|
146
|
-
params[:options]
|
147
|
-
when Array
|
148
|
-
params[:options]
|
149
145
|
else
|
150
|
-
|
151
|
-
end.
|
146
|
+
params[:options].permit!.to_h
|
147
|
+
end.deep_symbolize_keys
|
152
148
|
end
|
153
149
|
|
154
150
|
# This method decides if we want to raise an exception or not.
|
@@ -1,6 +1,7 @@
|
|
1
1
|
module Alchemy
|
2
2
|
module Admin
|
3
3
|
class EssencePicturesController < Alchemy::Admin::BaseController
|
4
|
+
FLOAT_REGEX = /\A\d+(\.\d+)?\z/
|
4
5
|
authorize_resource class: Alchemy::EssencePicture
|
5
6
|
|
6
7
|
before_action :load_essence_picture, only: [:edit, :crop, :update]
|
@@ -92,7 +93,7 @@ module Alchemy
|
|
92
93
|
# aspect ratio, don't specify a size or only width or height.
|
93
94
|
#
|
94
95
|
def ratio_from_size_or_params
|
95
|
-
if @min_size.value?(0) && @options[:fixed_ratio]
|
96
|
+
if @min_size.value?(0) && @options[:fixed_ratio].to_s =~ FLOAT_REGEX
|
96
97
|
@options[:fixed_ratio].to_f
|
97
98
|
elsif !@min_size[:width].zero? && !@min_size[:height].zero?
|
98
99
|
@min_size[:width].to_f / @min_size[:height].to_f
|
@@ -7,14 +7,9 @@ module Alchemy
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def new
|
10
|
-
@language = Language.new
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
private
|
15
|
-
|
16
|
-
def configured_page_layout
|
17
|
-
Config.get(:default_language).try('[]', 'page_layout')
|
10
|
+
@language = Language.new(
|
11
|
+
page_layout: Config.get(:default_language)['page_layout']
|
12
|
+
)
|
18
13
|
end
|
19
14
|
end
|
20
15
|
end
|
@@ -31,7 +31,7 @@ module Alchemy
|
|
31
31
|
@picture = Picture.new(picture_params)
|
32
32
|
@picture.name = @picture.humanized_name
|
33
33
|
if @picture.save
|
34
|
-
render
|
34
|
+
render successful_uploader_response(file: @picture)
|
35
35
|
else
|
36
36
|
render failed_uploader_response(file: @picture)
|
37
37
|
end
|
@@ -136,12 +136,16 @@ module Alchemy
|
|
136
136
|
end
|
137
137
|
|
138
138
|
def redirect_to_index
|
139
|
-
do_redirect_to admin_pictures_path(
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
139
|
+
do_redirect_to admin_pictures_path(search_params)
|
140
|
+
end
|
141
|
+
|
142
|
+
def search_params
|
143
|
+
params.except(:id, :picture_ids).permit(
|
144
|
+
:filter,
|
145
|
+
:page,
|
146
|
+
{q: resource_handler.search_field_name},
|
147
|
+
:size,
|
148
|
+
:tagged_with
|
145
149
|
)
|
146
150
|
end
|
147
151
|
|
@@ -97,7 +97,7 @@ module Alchemy
|
|
97
97
|
when :destroy
|
98
98
|
verb = "removed"
|
99
99
|
end
|
100
|
-
flash[:notice] = Alchemy.t("#{resource_handler.resource_name.classify} successfully #{verb}", default: Alchemy.t("
|
100
|
+
flash[:notice] = Alchemy.t("#{resource_handler.resource_name.classify} successfully #{verb}", default: Alchemy.t("Successfully #{verb}"))
|
101
101
|
end
|
102
102
|
|
103
103
|
def is_alchemy_module?
|
@@ -5,6 +5,7 @@ module Alchemy
|
|
5
5
|
|
6
6
|
# sends file inline. i.e. for viewing pdfs/movies in browser
|
7
7
|
def show
|
8
|
+
response.headers['Content-Length'] = @attachment.file.size.to_s
|
8
9
|
send_file(
|
9
10
|
@attachment.file.path,
|
10
11
|
{
|
@@ -17,6 +18,7 @@ module Alchemy
|
|
17
18
|
|
18
19
|
# sends file as attachment. aka download
|
19
20
|
def download
|
21
|
+
response.headers['Content-Length'] = @attachment.file.size.to_s
|
20
22
|
send_file(
|
21
23
|
@attachment.file.path, {
|
22
24
|
filename: @attachment.file_name,
|
@@ -51,11 +51,10 @@ module Alchemy
|
|
51
51
|
|
52
52
|
def permission_denied(exception = nil)
|
53
53
|
if exception
|
54
|
-
Rails.logger.debug <<-WARN
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
WARN
|
54
|
+
Rails.logger.debug <<-WARN.strip_heredoc
|
55
|
+
/!\\ Failed to permit #{exception.action} on #{exception.subject.inspect} for:
|
56
|
+
#{current_alchemy_user.inspect}
|
57
|
+
WARN
|
59
58
|
end
|
60
59
|
if current_alchemy_user
|
61
60
|
handle_redirect_for_user
|
@@ -3,7 +3,7 @@ module Alchemy
|
|
3
3
|
module UploaderResponses
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
|
-
def
|
6
|
+
def successful_uploader_response(file:, status: :created)
|
7
7
|
message = Alchemy.t(:upload_success,
|
8
8
|
scope: [:uploader, file.class.model_name.i18n_key],
|
9
9
|
name: file.name
|
@@ -312,9 +312,9 @@ module Alchemy
|
|
312
312
|
}
|
313
313
|
options = defaults.merge(options)
|
314
314
|
content_for(:toolbar) do
|
315
|
-
content = <<-CONTENT
|
316
|
-
#{options[:buttons].map { |button_options| toolbar_button(button_options) }.join}
|
317
|
-
|
315
|
+
content = <<-CONTENT.strip_heredoc
|
316
|
+
#{options[:buttons].map { |button_options| toolbar_button(button_options) }.join}
|
317
|
+
#{render('alchemy/admin/partials/search_form', url: options[:search_url]) if options[:search]}
|
318
318
|
CONTENT
|
319
319
|
content.html_safe
|
320
320
|
end
|
@@ -332,13 +332,18 @@ module Alchemy
|
|
332
332
|
|
333
333
|
# Renders a textfield ready to display a datepicker
|
334
334
|
#
|
335
|
-
# Uses a HTML5 +<input type="date">+ field.
|
336
335
|
# A Javascript observer converts this into a fancy Datepicker.
|
337
336
|
# If you pass +'datetime'+ as +:type+ the datepicker will also have a Time select.
|
337
|
+
# If you pass +'time'+ as +:type+ the datepicker will only have a Time select.
|
338
338
|
#
|
339
|
-
# The date value gets localized via +I18n.l+. The format on Time and Date is +datepicker+
|
339
|
+
# The date value gets localized via +I18n.l+. The format on Time and Date is +datepicker+, +timepicker+
|
340
340
|
# or +datetimepicker+, if you pass another +type+.
|
341
341
|
#
|
342
|
+
# This helper always renders "text" as input type because:
|
343
|
+
# HTML5 supports input types like 'date' but Browsers are using the users OS settings
|
344
|
+
# to validate the input format. Since Alchemy is localized in the backend the date formats
|
345
|
+
# should be aligned with the users locale setting in the backend but not the OS settings.
|
346
|
+
#
|
342
347
|
# === Date Example
|
343
348
|
#
|
344
349
|
# <%= alchemy_datepicker(@person, :birthday) %>
|
@@ -347,13 +352,17 @@ module Alchemy
|
|
347
352
|
#
|
348
353
|
# <%= alchemy_datepicker(@page, :public_on, type: 'datetime') %>
|
349
354
|
#
|
355
|
+
# === Time Example
|
356
|
+
#
|
357
|
+
# <%= alchemy_datepicker(@meeting, :starts_at, type: 'time') %>
|
358
|
+
#
|
350
359
|
# @param [ActiveModel::Base] object
|
351
360
|
# An instance of a model
|
352
361
|
# @param [String or Symbol] method
|
353
362
|
# The attribute method to be called for the date value
|
354
363
|
#
|
355
|
-
# @option html_options [String] :type (
|
356
|
-
# The
|
364
|
+
# @option html_options [String] :data-datepicker-type (type)
|
365
|
+
# The value of the data attribute for the type
|
357
366
|
# @option html_options [String] :class (type)
|
358
367
|
# CSS classes of the input field
|
359
368
|
# @option html_options [String] :value (value of method on object)
|
@@ -366,7 +375,7 @@ module Alchemy
|
|
366
375
|
value = date ? l(date, format: "#{type}picker".to_sym) : nil
|
367
376
|
|
368
377
|
text_field object.class.name.demodulize.underscore.to_sym,
|
369
|
-
method.to_sym, {type:
|
378
|
+
method.to_sym, {type: "text", class: type, "data-datepicker-type" => type, value: value}.merge(html_options)
|
370
379
|
end
|
371
380
|
|
372
381
|
# Merges the params-hash with the given hash
|
@@ -9,16 +9,16 @@ module Alchemy
|
|
9
9
|
# @return [String]
|
10
10
|
# A HTML string containing <tt><li></tt> tags
|
11
11
|
#
|
12
|
-
def render_tag_list(class_name
|
12
|
+
def render_tag_list(class_name)
|
13
13
|
raise ArgumentError, 'Please provide a String as class_name' if class_name.nil?
|
14
14
|
li_s = []
|
15
15
|
class_name.constantize.tag_counts.sort { |x, y| x.name.downcase <=> y.name.downcase }.each do |tag|
|
16
16
|
tags = filtered_by_tag?(tag) ? tag_filter(remove: tag) : tag_filter(add: tag)
|
17
|
-
li_s << content_tag('li', name: tag.name, class: tag_list_tag_active?(tag
|
17
|
+
li_s << content_tag('li', name: tag.name, class: tag_list_tag_active?(tag) ? 'active' : nil) do
|
18
18
|
link_to(
|
19
19
|
"#{tag.name} (#{tag.count})",
|
20
20
|
url_for(
|
21
|
-
|
21
|
+
tag_list_params.reject { |k, _v| k == "page" }.merge(
|
22
22
|
action: 'index',
|
23
23
|
tagged_with: tags
|
24
24
|
)
|
@@ -39,14 +39,14 @@ module Alchemy
|
|
39
39
|
# url params
|
40
40
|
# @return [Boolean]
|
41
41
|
#
|
42
|
-
def tag_list_tag_active?(tag
|
43
|
-
|
42
|
+
def tag_list_tag_active?(tag)
|
43
|
+
tag_list_params[:tagged_with].to_s.split(',').include?(tag.name)
|
44
44
|
end
|
45
45
|
|
46
46
|
# Checks if the tagged_with param contains the given tag
|
47
47
|
def filtered_by_tag?(tag)
|
48
|
-
if
|
49
|
-
tags =
|
48
|
+
if tag_list_params[:tagged_with].present?
|
49
|
+
tags = tag_list_params[:tagged_with].split(',')
|
50
50
|
tags.include?(tag.name)
|
51
51
|
else
|
52
52
|
false
|
@@ -55,8 +55,8 @@ module Alchemy
|
|
55
55
|
|
56
56
|
# Adds the given tag to the tag filter.
|
57
57
|
def add_to_tag_filter(tag)
|
58
|
-
if
|
59
|
-
tags =
|
58
|
+
if tag_list_params[:tagged_with].present?
|
59
|
+
tags = tag_list_params[:tagged_with].split(',')
|
60
60
|
tags << tag.name
|
61
61
|
else
|
62
62
|
[tag.name]
|
@@ -65,8 +65,8 @@ module Alchemy
|
|
65
65
|
|
66
66
|
# Removes the given tag from the tag filter.
|
67
67
|
def remove_from_tag_filter(tag)
|
68
|
-
if
|
69
|
-
tags =
|
68
|
+
if tag_list_params[:tagged_with].present?
|
69
|
+
tags = tag_list_params[:tagged_with].split(',')
|
70
70
|
tags.delete_if { |t| t == tag.name }
|
71
71
|
else
|
72
72
|
[]
|
@@ -84,17 +84,30 @@ module Alchemy
|
|
84
84
|
# ** :remove (ActsAsTaggableOn::Tag) - The tag that should be removed from the tag-filter
|
85
85
|
#
|
86
86
|
def tag_filter(options = {})
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
return params[:tagged_with]
|
87
|
+
if options[:add]
|
88
|
+
taglist = add_to_tag_filter(options[:add])
|
89
|
+
elsif options[:remove]
|
90
|
+
taglist = remove_from_tag_filter(options[:remove])
|
91
|
+
else
|
92
|
+
return tag_list_params[:tagged_with]
|
94
93
|
end
|
95
94
|
return nil if taglist.blank?
|
96
95
|
taglist.uniq.join(',')
|
97
96
|
end
|
97
|
+
|
98
|
+
def tag_list_params
|
99
|
+
params.permit(
|
100
|
+
:controller,
|
101
|
+
:content_id,
|
102
|
+
:element_id,
|
103
|
+
:options,
|
104
|
+
:swap,
|
105
|
+
:use_route,
|
106
|
+
:tagged_with,
|
107
|
+
:filter,
|
108
|
+
q: params.fetch(:q, {}).keys
|
109
|
+
)
|
110
|
+
end
|
98
111
|
end
|
99
112
|
end
|
100
113
|
end
|
@@ -14,7 +14,7 @@ module Alchemy
|
|
14
14
|
# Logs a message in the Rails logger (warn level)
|
15
15
|
# and optionally displays an error message to the user.
|
16
16
|
def warning(message, text = nil)
|
17
|
-
Logger.warn(message, caller
|
17
|
+
Logger.warn(message, caller(0..0))
|
18
18
|
unless text.nil?
|
19
19
|
warning = content_tag('p', class: 'content_editor_error') do
|
20
20
|
render_icon('warning') + text
|
@@ -166,7 +166,7 @@ module Alchemy
|
|
166
166
|
pages = page.children.accessible_by(current_ability, :see)
|
167
167
|
pages = pages.restricted if options.delete(:restricted_only)
|
168
168
|
if depth = options[:deepness]
|
169
|
-
pages = pages.where(
|
169
|
+
pages = pages.where('depth <= ?', depth)
|
170
170
|
end
|
171
171
|
if options[:reverse]
|
172
172
|
pages.reverse!
|
@@ -246,15 +246,12 @@ module Alchemy
|
|
246
246
|
end
|
247
247
|
|
248
248
|
if options.delete(:reverse)
|
249
|
-
pages.
|
249
|
+
pages = pages.reorder('lft DESC')
|
250
250
|
end
|
251
251
|
|
252
252
|
if options[:without].present?
|
253
|
-
|
254
|
-
|
255
|
-
else
|
256
|
-
pages.to_a.delete(options[:without])
|
257
|
-
end
|
253
|
+
without = options.delete(:without)
|
254
|
+
pages = pages.where.not(id: without.try(:collect, &:id) || without.id)
|
258
255
|
end
|
259
256
|
|
260
257
|
render 'alchemy/breadcrumb/wrapper', pages: pages, options: options
|
@@ -36,6 +36,10 @@ module Alchemy
|
|
36
36
|
|
37
37
|
# We need to define this method here to have it available in the validations below.
|
38
38
|
class << self
|
39
|
+
def searchable_alchemy_resource_attributes
|
40
|
+
%w(name file_name)
|
41
|
+
end
|
42
|
+
|
39
43
|
def allowed_filetypes
|
40
44
|
Config.get(:uploader).fetch('allowed_filetypes', {}).fetch('alchemy/attachments', [])
|
41
45
|
end
|
data/app/models/alchemy/cell.rb
CHANGED
@@ -211,7 +211,8 @@ module Alchemy
|
|
211
211
|
# Pass an element name to get next of this kind.
|
212
212
|
#
|
213
213
|
def next(name = nil)
|
214
|
-
|
214
|
+
elements = page.elements.published.where('position > ?', position)
|
215
|
+
select_element(elements, name, :asc)
|
215
216
|
end
|
216
217
|
|
217
218
|
# Returns previous public element from same page.
|
@@ -219,7 +220,8 @@ module Alchemy
|
|
219
220
|
# Pass an element name to get previous of this kind.
|
220
221
|
#
|
221
222
|
def prev(name = nil)
|
222
|
-
|
223
|
+
elements = page.elements.published.where('position < ?', position)
|
224
|
+
select_element(elements, name, :desc)
|
223
225
|
end
|
224
226
|
|
225
227
|
# Stores the page into +touchable_pages+ (Pages that have to be touched after updating the element).
|
@@ -313,17 +315,9 @@ module Alchemy
|
|
313
315
|
|
314
316
|
private
|
315
317
|
|
316
|
-
|
317
|
-
#
|
318
|
-
# @param [String]
|
319
|
-
# Pass '>' or '<' to find next or previous public element.
|
320
|
-
# @param [String]
|
321
|
-
# Pass an element name to get previous of this kind.
|
322
|
-
#
|
323
|
-
def previous_or_next(dir, name = nil)
|
324
|
-
elements = page.elements.published.where("#{self.class.table_name}.position #{dir} #{position}")
|
318
|
+
def select_element(elements, name, order)
|
325
319
|
elements = elements.named(name) if name.present?
|
326
|
-
elements.reorder(
|
320
|
+
elements.reorder(position: order).limit(1).first
|
327
321
|
end
|
328
322
|
|
329
323
|
# Returns all cells from given page this element could be placed in.
|
@@ -26,7 +26,7 @@ module Alchemy
|
|
26
26
|
#
|
27
27
|
def read_definitions_file
|
28
28
|
if ::File.exist?(definitions_file_path)
|
29
|
-
::YAML.
|
29
|
+
::YAML.safe_load(ERB.new(File.read(definitions_file_path)).result, [Regexp, Date], [], true) || []
|
30
30
|
else
|
31
31
|
raise LoadError, "Could not find elements.yml file! Please run `rails generate alchemy:scaffold`"
|
32
32
|
end
|
@@ -46,7 +46,7 @@ module Alchemy
|
|
46
46
|
definition
|
47
47
|
else
|
48
48
|
log_warning "Could not find element definition for #{name}. Please check your elements.yml file!"
|
49
|
-
|
49
|
+
{}
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|