alchemy_cms 3.5.0 → 3.6.0
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.
- 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
|