alchemy_cms 3.3.3 → 3.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/CHANGELOG.md +42 -4
- data/README.md +7 -3
- data/alchemy_cms.gemspec +1 -0
- data/app/assets/javascripts/alchemy/{alchemy.js → admin.js} +1 -2
- data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +28 -25
- data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +1 -0
- data/app/assets/javascripts/alchemy/alchemy.i18n.js.coffee +7 -1
- data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +1 -1
- data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +26 -0
- data/app/assets/javascripts/alchemy/alchemy.translations.js.coffee +56 -1
- data/app/assets/stylesheets/alchemy/_variables.scss +1 -0
- data/app/assets/stylesheets/alchemy/admin.scss +2 -1
- data/app/assets/stylesheets/alchemy/archive.scss +7 -0
- data/app/assets/stylesheets/alchemy/base.scss +0 -42
- data/app/assets/stylesheets/alchemy/buttons.scss +2 -1
- data/app/assets/stylesheets/alchemy/form_fields.scss +9 -0
- data/app/assets/stylesheets/alchemy/forms.scss +36 -10
- data/app/assets/stylesheets/alchemy/frame.scss +12 -1
- data/app/assets/stylesheets/alchemy/icons.scss +1 -1
- data/app/assets/stylesheets/alchemy/jquery-ui.scss +0 -260
- data/app/assets/stylesheets/alchemy/jquery.datetimepicker.scss +507 -0
- data/app/assets/stylesheets/alchemy/lists.scss +62 -0
- data/app/assets/stylesheets/alchemy/selects.scss +9 -2
- data/app/assets/stylesheets/alchemy/sitemap.scss +28 -51
- data/app/assets/stylesheets/alchemy/toolbar.scss +0 -2
- data/app/controllers/alchemy/admin/attachments_controller.rb +4 -6
- data/app/controllers/alchemy/admin/base_controller.rb +2 -2
- data/app/controllers/alchemy/admin/dashboard_controller.rb +2 -2
- data/app/controllers/alchemy/admin/languages_controller.rb +5 -0
- data/app/controllers/alchemy/admin/pages_controller.rb +14 -5
- data/app/controllers/alchemy/admin/resources_controller.rb +17 -1
- data/app/controllers/alchemy/base_controller.rb +1 -0
- data/app/controllers/alchemy/messages_controller.rb +1 -1
- data/app/controllers/alchemy/pages_controller.rb +16 -26
- data/app/controllers/alchemy/pictures_controller.rb +23 -10
- data/app/controllers/concerns/alchemy/page_redirects.rb +7 -7
- data/app/helpers/alchemy/admin/base_helper.rb +22 -19
- data/app/helpers/alchemy/admin/essences_helper.rb +26 -11
- data/app/helpers/alchemy/admin/pages_helper.rb +2 -1
- data/app/helpers/alchemy/essences_helper.rb +0 -35
- data/app/helpers/alchemy/url_helper.rb +1 -1
- data/app/mailers/alchemy/base_mailer.rb +18 -0
- data/app/mailers/alchemy/{messages.rb → messages_mailer.rb} +1 -1
- data/app/models/alchemy/attachment.rb +9 -0
- data/app/models/alchemy/cell.rb +1 -1
- data/app/models/alchemy/essence_picture.rb +4 -1
- data/app/models/alchemy/essence_picture_view.rb +68 -0
- data/app/models/alchemy/language.rb +8 -10
- data/app/models/alchemy/language/code.rb +4 -1
- data/app/models/alchemy/page.rb +69 -26
- data/app/models/alchemy/page/page_natures.rb +22 -0
- data/app/models/alchemy/page/page_scopes.rb +20 -6
- data/app/models/alchemy/picture.rb +37 -4
- data/app/models/alchemy/site.rb +8 -0
- data/app/serializers/alchemy/page_tree_serializer.rb +1 -1
- data/app/views/alchemy/admin/attachments/_archive_overlay.html.erb +9 -6
- data/app/views/alchemy/admin/attachments/_file_to_assign.html.erb +11 -9
- data/app/views/alchemy/admin/attachments/_filter_bar.html.erb +32 -0
- data/app/views/alchemy/admin/attachments/_overlay_file_list.html.erb +14 -2
- data/app/views/alchemy/admin/attachments/index.html.erb +10 -9
- data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +20 -9
- data/app/views/alchemy/admin/dashboard/_recent_pages.html.erb +11 -1
- data/app/views/alchemy/admin/languages/_form.html.erb +1 -0
- data/app/views/alchemy/admin/languages/index.html.erb +7 -8
- data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +1 -1
- data/app/views/alchemy/admin/layoutpages/index.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_current_page.html.erb +4 -0
- data/app/views/alchemy/admin/pages/_form.html.erb +16 -1
- data/app/views/alchemy/admin/pages/_locked_page.html.erb +2 -12
- data/app/views/alchemy/admin/pages/_page.html.erb +1 -1
- data/app/views/alchemy/admin/pages/_page_for_links.html.erb +2 -2
- data/app/views/alchemy/admin/pages/_page_status.html.erb +23 -11
- data/app/views/alchemy/admin/pages/edit.html.erb +2 -1
- data/app/views/alchemy/admin/pages/index.html.erb +2 -2
- data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +3 -0
- data/app/views/alchemy/admin/partials/_site_select.html.erb +9 -0
- data/app/views/alchemy/admin/pictures/_picture.html.erb +6 -1
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +2 -1
- data/app/views/alchemy/admin/pictures/show.html.erb +1 -1
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +31 -0
- data/app/views/alchemy/admin/resources/_form.html.erb +6 -0
- data/app/views/alchemy/admin/resources/_tag_list.html.erb +16 -0
- data/app/views/alchemy/admin/resources/index.html.erb +13 -1
- data/app/views/alchemy/essences/_essence_file_view.html.erb +2 -5
- data/app/views/alchemy/essences/_essence_picture_view.html.erb +5 -3
- data/app/views/alchemy/{messages → messages_mailer}/contact_form_mail.de.text.erb +0 -0
- data/app/views/alchemy/{messages → messages_mailer}/contact_form_mail.en.text.erb +0 -0
- data/app/views/alchemy/{messages → messages_mailer}/contact_form_mail.es.text.erb +0 -0
- data/app/views/alchemy/{messages → messages_mailer}/new.html.erb +0 -0
- data/app/views/layouts/alchemy/admin.html.erb +3 -8
- data/config/alchemy/config.yml +4 -3
- data/config/initializers/assets.rb +2 -2
- data/config/initializers/dragonfly.rb +3 -0
- data/config/initializers/mime_types.rb +1 -0
- data/config/locales/alchemy.de.yml +10 -2
- data/config/locales/alchemy.en.yml +6 -2
- data/config/locales/alchemy.es.yml +6 -3
- data/config/locales/alchemy.fr.yml +6 -2
- data/config/locales/alchemy.it.yml +937 -0
- data/config/locales/alchemy.nl.yml +6 -2
- data/config/locales/alchemy.ru.yml +3 -2
- data/config/locales/simple_form.it.yml +25 -0
- data/db/migrate/20160108174834_add_timebased_publishing_columns_to_pages.rb +32 -0
- data/db/migrate/20160422195310_add_image_file_format_to_alchemy_pictures.rb +21 -0
- data/db/migrate/20160617224938_change_alchemy_pages_locked_to_locked_at.rb +22 -0
- data/lib/alchemy/ability_helper.rb +23 -0
- data/lib/alchemy/configuration_methods.rb +2 -2
- data/lib/alchemy/controller_actions.rb +4 -33
- data/lib/alchemy/engine.rb +1 -0
- data/lib/alchemy/resource.rb +30 -13
- data/lib/alchemy/resources_helper.rb +17 -0
- data/lib/alchemy/test_support/factories/page_factory.rb +7 -2
- data/lib/alchemy/upgrader.rb +1 -0
- data/lib/alchemy/upgrader/tasks/install_asset_manifests.rb +15 -0
- data/lib/alchemy/upgrader/three_point_four.rb +16 -0
- data/lib/alchemy/version.rb +1 -1
- data/lib/rails/generators/alchemy/elements/elements_generator.rb +8 -7
- data/lib/rails/generators/alchemy/essence/essence_generator.rb +2 -6
- data/lib/rails/generators/alchemy/install/files/all.css +11 -0
- data/lib/rails/generators/alchemy/install/files/all.js +11 -0
- data/lib/rails/generators/alchemy/install/files/{alchemy.elements.css.scss → article.scss} +0 -0
- data/lib/rails/generators/alchemy/install/install_generator.rb +20 -19
- data/lib/rails/generators/alchemy/module/module_generator.rb +3 -5
- data/lib/rails/generators/alchemy/page_layouts/page_layouts_generator.rb +7 -6
- data/lib/rails/generators/alchemy/site_layouts/site_layouts_generator.rb +7 -6
- data/vendor/assets/javascripts/date-formatter.js +161 -0
- data/vendor/assets/javascripts/jquery_plugins/jquery.datetimepicker.full.min.js +2 -0
- data/vendor/assets/javascripts/tinymce/langs/it.js +219 -0
- metadata +48 -13
- data/app/assets/javascripts/alchemy/alchemy.custom.js +0 -1
- data/app/assets/stylesheets/alchemy/custom.scss +0 -1
@@ -68,7 +68,7 @@ module Alchemy
|
|
68
68
|
@page = @element.page
|
69
69
|
@root_page = @page.get_language_root
|
70
70
|
if @message.valid?
|
71
|
-
|
71
|
+
MessagesMailer.contact_form_mail(@message, mail_to, mail_from, subject).deliver
|
72
72
|
redirect_to_success_page
|
73
73
|
else
|
74
74
|
render template: 'alchemy/pages/show'
|
@@ -26,6 +26,8 @@ module Alchemy
|
|
26
26
|
if: :run_on_page_layout_callbacks?,
|
27
27
|
only: [:index, :show]
|
28
28
|
|
29
|
+
before_action :set_expiration_headers, only: [:index, :show], if: -> { @page }
|
30
|
+
|
29
31
|
rescue_from ActionController::UnknownFormat, with: :page_not_found!
|
30
32
|
|
31
33
|
# == The index action gets invoked if one requests '/' or '/:locale'
|
@@ -35,7 +37,7 @@ module Alchemy
|
|
35
37
|
# Loads the current language root page. The current language is either loaded via :locale
|
36
38
|
# parameter or, if that's missing, the default language is used.
|
37
39
|
#
|
38
|
-
# If this page is not published then it
|
40
|
+
# If this page is not published then it redirects to the first published descendant it finds.
|
39
41
|
#
|
40
42
|
# If no public page can be found it renders a 404 error.
|
41
43
|
#
|
@@ -45,8 +47,7 @@ module Alchemy
|
|
45
47
|
raise "Remove deprecated `redirect_index` configuration!" if Alchemy.version == "4.0.0.rc1"
|
46
48
|
redirect_permanently_to page_redirect_url
|
47
49
|
else
|
48
|
-
|
49
|
-
render_page if render_fresh_page?
|
50
|
+
show
|
50
51
|
end
|
51
52
|
end
|
52
53
|
|
@@ -84,13 +85,13 @@ module Alchemy
|
|
84
85
|
#
|
85
86
|
# Loads the current public language root page.
|
86
87
|
#
|
87
|
-
# If the root page is not public it
|
88
|
+
# If the root page is not public it redirects to the first published child.
|
88
89
|
# This can be configured via +redirect_to_public_child+ [default: true]
|
89
90
|
#
|
90
91
|
# If no index page and no admin users are present we show the "Welcome to Alchemy" page.
|
91
92
|
#
|
92
93
|
def load_index_page
|
93
|
-
@page ||=
|
94
|
+
@page ||= Language.current_root_page
|
94
95
|
render template: 'alchemy/welcome', layout: false if signup_required?
|
95
96
|
end
|
96
97
|
|
@@ -110,26 +111,6 @@ module Alchemy
|
|
110
111
|
)
|
111
112
|
end
|
112
113
|
|
113
|
-
# Returns the current language root page, if it's published.
|
114
|
-
#
|
115
|
-
# Otherwise it returns nil.
|
116
|
-
#
|
117
|
-
def public_root_page
|
118
|
-
@root_page ||= Language.current_root_page
|
119
|
-
@root_page if @root_page && @root_page.public?
|
120
|
-
end
|
121
|
-
|
122
|
-
# Returns the first public child of the current language root page.
|
123
|
-
#
|
124
|
-
# If +redirect_to_public_child+ is configured to +false+ it returns +nil+.
|
125
|
-
#
|
126
|
-
def first_public_child
|
127
|
-
if Alchemy::Config.get(:redirect_to_public_child)
|
128
|
-
return unless @root_page
|
129
|
-
@root_page.descendants.published.first
|
130
|
-
end
|
131
|
-
end
|
132
|
-
|
133
114
|
# Redirects to given url with 301 status
|
134
115
|
def redirect_permanently_to(url)
|
135
116
|
redirect_to url, status: :moved_permanently
|
@@ -170,6 +151,14 @@ module Alchemy
|
|
170
151
|
end
|
171
152
|
end
|
172
153
|
|
154
|
+
def set_expiration_headers
|
155
|
+
if @page.cache_page?
|
156
|
+
expires_in @page.expiration_time, public: !@page.restricted
|
157
|
+
else
|
158
|
+
expires_now
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
173
162
|
def set_root_page
|
174
163
|
@root_page ||= Language.current_root_page
|
175
164
|
end
|
@@ -200,7 +189,8 @@ module Alchemy
|
|
200
189
|
def render_fresh_page?
|
201
190
|
!@page.cache_page? || stale?(etag: page_etag,
|
202
191
|
last_modified: @page.published_at,
|
203
|
-
public: !@page.restricted
|
192
|
+
public: !@page.restricted,
|
193
|
+
template: 'pages/show')
|
204
194
|
end
|
205
195
|
|
206
196
|
def page_not_found!
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Alchemy
|
2
2
|
class PicturesController < Alchemy::BaseController
|
3
|
-
ALLOWED_IMAGE_TYPES = %w(png jpeg gif)
|
3
|
+
ALLOWED_IMAGE_TYPES = %w(png jpeg gif svg)
|
4
4
|
|
5
5
|
caches_page :show, :thumbnail, :zoom
|
6
6
|
|
@@ -25,7 +25,7 @@ module Alchemy
|
|
25
25
|
@size = params[:size]
|
26
26
|
end
|
27
27
|
|
28
|
-
respond_to { |format| send_image(processed_image, format) }
|
28
|
+
respond_to { |format| send_image(processed_image, format, flatten: true) }
|
29
29
|
end
|
30
30
|
|
31
31
|
def zoom
|
@@ -45,20 +45,29 @@ module Alchemy
|
|
45
45
|
false
|
46
46
|
end
|
47
47
|
|
48
|
-
def send_image(image, format)
|
48
|
+
def send_image(image, format, opts = {})
|
49
49
|
request.session_options[:skip] = true
|
50
50
|
ALLOWED_IMAGE_TYPES.each do |type|
|
51
|
+
# Flatten animated gifs, only if converting to a different format.
|
52
|
+
# Can be overwritten via +options[:flatten]+.
|
53
|
+
options = {
|
54
|
+
flatten: type != "gif" && image.ext == 'gif'
|
55
|
+
}.merge(opts)
|
56
|
+
|
51
57
|
format.send(type) do
|
52
|
-
|
58
|
+
encoding_options = []
|
53
59
|
if type == 'jpeg'
|
54
60
|
quality = params[:quality] || Config.get(:output_image_jpg_quality)
|
55
|
-
|
61
|
+
encoding_options << "-quality #{quality}"
|
62
|
+
end
|
63
|
+
if options[:flatten]
|
64
|
+
encoding_options << "-flatten"
|
56
65
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
66
|
+
if @picture.has_convertible_format?
|
67
|
+
render text: image.encode(type, encoding_options.join(' ')).data
|
68
|
+
else
|
69
|
+
render text: image.data
|
60
70
|
end
|
61
|
-
render text: image.encode(type, options.join(' ')).data
|
62
71
|
end
|
63
72
|
end
|
64
73
|
end
|
@@ -70,7 +79,7 @@ module Alchemy
|
|
70
79
|
if @image.nil?
|
71
80
|
raise MissingImageFileError, "Missing image file for #{@picture.inspect}"
|
72
81
|
end
|
73
|
-
if
|
82
|
+
if resizable?
|
74
83
|
if params[:crop_size].present? && params[:crop_from].present? || params[:crop].present?
|
75
84
|
@picture.crop(@size, params[:crop_from], params[:crop_size], @upsample)
|
76
85
|
else
|
@@ -80,5 +89,9 @@ module Alchemy
|
|
80
89
|
@image
|
81
90
|
end
|
82
91
|
end
|
92
|
+
|
93
|
+
def resizable?
|
94
|
+
@size.present? && @picture.has_convertible_format?
|
95
|
+
end
|
83
96
|
end
|
84
97
|
end
|
@@ -36,10 +36,14 @@ module Alchemy
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def public_child_redirect_url
|
39
|
-
return
|
39
|
+
return if @page.public?
|
40
40
|
|
41
|
-
|
42
|
-
|
41
|
+
if configuration(:redirect_to_public_child)
|
42
|
+
@page = @page.descendants.published.not_restricted.first
|
43
|
+
@page ? page_redirect_url : page_not_found!
|
44
|
+
else
|
45
|
+
page_not_found!
|
46
|
+
end
|
43
47
|
end
|
44
48
|
|
45
49
|
def controller_and_action_url
|
@@ -65,9 +69,5 @@ module Alchemy
|
|
65
69
|
def locale_prefix_missing?
|
66
70
|
multi_language? && params[:locale].blank? && !default_locale?
|
67
71
|
end
|
68
|
-
|
69
|
-
def redirect_to_public_child?
|
70
|
-
configuration(:redirect_to_public_child) && !@page.public?
|
71
|
-
end
|
72
72
|
end
|
73
73
|
end
|
@@ -332,38 +332,41 @@ module Alchemy
|
|
332
332
|
|
333
333
|
# Renders a textfield ready to display a datepicker
|
334
334
|
#
|
335
|
-
# Uses a HTML5
|
335
|
+
# Uses a HTML5 +<input type="date">+ field.
|
336
|
+
# A Javascript observer converts this into a fancy Datepicker.
|
337
|
+
# If you pass +'datetime'+ as +:type+ the datepicker will also have a Time select.
|
336
338
|
#
|
337
|
-
#
|
339
|
+
# The date value gets localized via +I18n.l+. The format on Time and Date is +datepicker+
|
340
|
+
# or +datetimepicker+, if you pass another +type+.
|
341
|
+
#
|
342
|
+
# === Date Example
|
338
343
|
#
|
339
344
|
# <%= alchemy_datepicker(@person, :birthday) %>
|
340
345
|
#
|
346
|
+
# === Datetime Example
|
347
|
+
#
|
348
|
+
# <%= alchemy_datepicker(@page, :public_on, type: 'datetime') %>
|
349
|
+
#
|
341
350
|
# @param [ActiveModel::Base] object
|
342
351
|
# An instance of a model
|
343
352
|
# @param [String or Symbol] method
|
344
353
|
# The attribute method to be called for the date value
|
345
354
|
#
|
346
|
-
# @option html_options [String] :type (
|
355
|
+
# @option html_options [String] :type (date)
|
347
356
|
# The type of text field
|
348
|
-
# @option html_options [String] :class (
|
357
|
+
# @option html_options [String] :class (type)
|
349
358
|
# CSS classes of the input field
|
350
|
-
# @option html_options [String] :value (
|
351
|
-
# The value the input displays
|
359
|
+
# @option html_options [String] :value (value of method on object)
|
360
|
+
# The value the input displays. If you pass a String its parsed with +Time.parse+
|
352
361
|
#
|
353
362
|
def alchemy_datepicker(object, method, html_options = {})
|
354
|
-
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
end
|
362
|
-
text_field object.class.name.underscore.to_sym, method.to_sym, html_options.merge({
|
363
|
-
type: 'date',
|
364
|
-
class: 'date',
|
365
|
-
value: value
|
366
|
-
})
|
363
|
+
type = html_options.delete(:type) || 'date'
|
364
|
+
date = html_options.delete(:value) || object.send(method.to_sym).presence
|
365
|
+
date = Time.zone.parse(date) if date.is_a?(String)
|
366
|
+
value = date ? l(date, format: "#{type}picker".to_sym) : nil
|
367
|
+
|
368
|
+
text_field object.class.name.demodulize.underscore.to_sym,
|
369
|
+
method.to_sym, {type: type, class: type, value: value}.merge(html_options)
|
367
370
|
end
|
368
371
|
|
369
372
|
# Merges the params-hash with the given hash
|
@@ -57,25 +57,40 @@ module Alchemy
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def essence_picture_thumbnail(content, options)
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
ingredient = content.ingredient
|
61
|
+
essence = content.essence
|
62
|
+
return if ingredient.blank?
|
63
|
+
|
64
|
+
crop = !(essence.crop_size.blank? && essence.crop_from.blank?) ||
|
65
|
+
(
|
66
|
+
content.settings_value(:crop, options) == true ||
|
67
|
+
content.settings_value(:crop, options) == "true"
|
68
|
+
)
|
69
|
+
|
70
|
+
size = if essence.render_size.blank?
|
71
|
+
content.settings_value(:size, options)
|
72
|
+
else
|
73
|
+
essence.render_size
|
74
|
+
end
|
75
|
+
|
63
76
|
image_options = {
|
64
|
-
size:
|
65
|
-
crop_from:
|
66
|
-
crop_size:
|
77
|
+
size: essence.thumbnail_size(size, crop),
|
78
|
+
crop_from: essence.crop_from.blank? ? nil : essence.crop_from,
|
79
|
+
crop_size: essence.crop_size.blank? ? nil : essence.crop_size,
|
67
80
|
crop: crop ? 'crop' : nil,
|
68
81
|
upsample: content.settings_value(:upsample, options)
|
69
82
|
}
|
83
|
+
|
70
84
|
image_tag(
|
71
85
|
alchemy.thumbnail_path({
|
72
|
-
id:
|
73
|
-
name:
|
74
|
-
sh:
|
86
|
+
id: ingredient.id,
|
87
|
+
name: ingredient.urlname,
|
88
|
+
sh: ingredient.security_token(image_options),
|
89
|
+
format: ingredient.image_file_format
|
75
90
|
}.merge(image_options)),
|
76
|
-
alt:
|
91
|
+
alt: ingredient.name,
|
77
92
|
class: 'img_paddingtop',
|
78
|
-
title: Alchemy.t(:image_name) + ": #{
|
93
|
+
title: Alchemy.t(:image_name) + ": #{ingredient.name}"
|
79
94
|
)
|
80
95
|
end
|
81
96
|
|
@@ -22,7 +22,8 @@ module Alchemy
|
|
22
22
|
def combined_page_status(page)
|
23
23
|
page.status.map do |state, _value|
|
24
24
|
next if state == :locked
|
25
|
-
|
25
|
+
css_class = page.send("#{state}?") ? "page_status #{state}" : "page_status not_#{state}"
|
26
|
+
val = content_tag(:span, '', class: css_class)
|
26
27
|
val + page.status_title(state)
|
27
28
|
end.delete_if(&:blank?).join("<br>").html_safe
|
28
29
|
end
|
@@ -86,40 +86,5 @@ module Alchemy
|
|
86
86
|
def render_essence_view(content, options = {}, html_options = {})
|
87
87
|
render_essence(content, :view, {for_view: options}, html_options)
|
88
88
|
end
|
89
|
-
|
90
|
-
# Renders a essence picture
|
91
|
-
#
|
92
|
-
def render_essence_picture_view(content, options, html_options)
|
93
|
-
options = {
|
94
|
-
show_caption: true,
|
95
|
-
disable_link: false
|
96
|
-
}.update(content.settings).update(options)
|
97
|
-
return if content.ingredient.blank?
|
98
|
-
if content.essence.caption.present? && options[:show_caption]
|
99
|
-
caption = content_tag(:figcaption, content.essence.caption, id: "#{dom_id(content.ingredient)}_caption", class: "image_caption")
|
100
|
-
end
|
101
|
-
img_tag = image_tag(
|
102
|
-
content.essence.picture_url(options), {
|
103
|
-
alt: (content.essence.alt_tag.blank? ? nil : content.essence.alt_tag),
|
104
|
-
title: (content.essence.title.blank? ? nil : content.essence.title),
|
105
|
-
class: (caption || content.essence.css_class.blank? ? nil : content.essence.css_class)
|
106
|
-
}.merge(caption ? {} : html_options)
|
107
|
-
)
|
108
|
-
output = caption ? img_tag + caption : img_tag
|
109
|
-
if content.essence.link.present? && !options[:disable_link]
|
110
|
-
output = link_to(url_for(content.essence.link), {
|
111
|
-
title: content.essence.link_title.blank? ? nil : content.essence.link_title,
|
112
|
-
target: (content.essence.link_target == "blank" ? "_blank" : nil),
|
113
|
-
'data-link-target' => content.essence.link_target.blank? ? nil : content.essence.link_target
|
114
|
-
}) do
|
115
|
-
output
|
116
|
-
end
|
117
|
-
end
|
118
|
-
if caption
|
119
|
-
content_tag(:figure, output, {class: content.essence.css_class.blank? ? nil : content.essence.css_class}.merge(html_options))
|
120
|
-
else
|
121
|
-
output
|
122
|
-
end
|
123
|
-
end
|
124
89
|
end
|
125
90
|
end
|
@@ -43,7 +43,7 @@ module Alchemy
|
|
43
43
|
url_params = {
|
44
44
|
id: picture.id,
|
45
45
|
name: picture.urlname,
|
46
|
-
format:
|
46
|
+
format: picture.default_render_format,
|
47
47
|
sh: picture.security_token(optional_params)
|
48
48
|
}
|
49
49
|
url_params.update(optional_params.update(crop: optional_params[:crop] ? 'crop' : nil))
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Alchemy
|
2
|
+
begin
|
3
|
+
base_class = Object.const_get('::ApplicationMailer')
|
4
|
+
rescue NameError
|
5
|
+
base_class = ActionMailer::Base
|
6
|
+
end
|
7
|
+
|
8
|
+
# The +BaseMailer+ is the class all Alchemy mailers inherit from.
|
9
|
+
#
|
10
|
+
# Itself inherits from +ApplicationMailer+ when it is defined, or
|
11
|
+
# as a fallback from +ActionMailer::Base+.
|
12
|
+
#
|
13
|
+
# +ApplicationMailer+ is the Rails standard for registering helpers and
|
14
|
+
# setting the default layout. It is only generated though, when you
|
15
|
+
# +rails generate+ a mailer.
|
16
|
+
#
|
17
|
+
class BaseMailer < base_class; end
|
18
|
+
end
|
@@ -39,6 +39,13 @@ module Alchemy
|
|
39
39
|
def allowed_filetypes
|
40
40
|
Config.get(:uploader).fetch('allowed_filetypes', {}).fetch('alchemy/attachments', [])
|
41
41
|
end
|
42
|
+
|
43
|
+
def file_types_for_select
|
44
|
+
file_types = Alchemy::Attachment.pluck(:file_mime_type).uniq.map do |type|
|
45
|
+
[Alchemy.t(type, scope: 'mime_types'), type]
|
46
|
+
end
|
47
|
+
file_types.sort_by(&:first)
|
48
|
+
end
|
42
49
|
end
|
43
50
|
|
44
51
|
validates_presence_of :file
|
@@ -56,6 +63,8 @@ module Alchemy
|
|
56
63
|
|
57
64
|
after_update :touch_contents
|
58
65
|
|
66
|
+
scope :with_file_type, ->(file_type) { where(file_mime_type: file_type) }
|
67
|
+
|
59
68
|
# Instance methods
|
60
69
|
|
61
70
|
def to_jq_upload
|
data/app/models/alchemy/cell.rb
CHANGED
@@ -28,7 +28,7 @@ module Alchemy
|
|
28
28
|
belongs_to :page
|
29
29
|
validates_uniqueness_of :name, scope: 'page_id'
|
30
30
|
validates_format_of :name, with: /\A[a-z0-9_-]+\z/
|
31
|
-
has_many :elements, -> {
|
31
|
+
has_many :elements, -> { order(:position) }, dependent: :destroy
|
32
32
|
|
33
33
|
class << self
|
34
34
|
def definitions
|
@@ -126,11 +126,13 @@ module Alchemy
|
|
126
126
|
#
|
127
127
|
def picture_params(options = {})
|
128
128
|
return {} if picture.nil?
|
129
|
+
|
129
130
|
params = {
|
130
131
|
id: picture.id,
|
131
132
|
name: picture.urlname,
|
132
|
-
format:
|
133
|
+
format: picture.default_render_format
|
133
134
|
}.merge(options)
|
135
|
+
|
134
136
|
if options[:crop] && crop_from.present? && crop_size.present?
|
135
137
|
params = {
|
136
138
|
crop: true,
|
@@ -138,6 +140,7 @@ module Alchemy
|
|
138
140
|
crop_size: crop_size
|
139
141
|
}.merge(params)
|
140
142
|
end
|
143
|
+
|
141
144
|
params = clean_picture_params(params)
|
142
145
|
params.merge(sh: picture.security_token(params))
|
143
146
|
end
|