alchemy_cms 5.0.1 → 5.1.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/.github/PULL_REQUEST_TEMPLATE.md +1 -1
- data/.github/workflows/ci.yml +126 -0
- data/.github/workflows/stale.yml +1 -1
- data/.gitignore +1 -0
- data/CHANGELOG.md +66 -2
- data/CONTRIBUTING.md +2 -2
- data/Gemfile +2 -2
- data/README.md +2 -2
- data/alchemy_cms.gemspec +3 -3
- data/app/assets/images/alchemy/missing-image.svg +1 -0
- data/app/assets/javascripts/alchemy/admin.js +0 -1
- data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -4
- data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +0 -3
- data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +29 -4
- data/app/assets/stylesheets/alchemy/_variables.scss +8 -0
- data/app/assets/stylesheets/alchemy/admin.scss +0 -1
- data/app/assets/stylesheets/alchemy/archive.scss +23 -17
- data/app/assets/stylesheets/alchemy/buttons.scss +26 -15
- data/app/assets/stylesheets/alchemy/elements.scss +58 -19
- data/app/assets/stylesheets/alchemy/errors.scss +1 -1
- data/app/assets/stylesheets/alchemy/frame.scss +0 -1
- data/app/assets/stylesheets/alchemy/hints.scss +2 -1
- data/app/assets/stylesheets/alchemy/navigation.scss +7 -10
- data/app/assets/stylesheets/alchemy/pagination.scss +1 -1
- data/app/assets/stylesheets/alchemy/search.scss +13 -3
- data/app/assets/stylesheets/alchemy/selects.scss +26 -20
- data/app/assets/stylesheets/alchemy/tables.scss +38 -9
- data/app/assets/stylesheets/alchemy/tags.scss +19 -31
- data/app/controllers/alchemy/admin/pages_controller.rb +58 -8
- data/app/controllers/alchemy/admin/pictures_controller.rb +13 -6
- data/app/controllers/alchemy/admin/resources_controller.rb +3 -3
- data/app/controllers/alchemy/pages_controller.rb +49 -14
- data/app/decorators/alchemy/element_editor.rb +1 -0
- data/app/helpers/alchemy/admin/base_helper.rb +0 -44
- data/app/helpers/alchemy/admin/navigation_helper.rb +2 -1
- data/app/models/alchemy/attachment.rb +20 -3
- data/app/models/alchemy/attachment/url.rb +40 -0
- data/app/models/alchemy/essence_picture.rb +3 -3
- data/app/models/alchemy/essence_picture_view.rb +5 -3
- data/app/models/alchemy/legacy_page_url.rb +1 -1
- data/app/models/alchemy/page.rb +24 -1
- data/app/models/alchemy/page/page_natures.rb +2 -0
- data/app/models/alchemy/page/url_path.rb +8 -6
- data/app/models/alchemy/picture.rb +58 -2
- data/app/models/alchemy/picture/calculations.rb +55 -0
- data/app/models/alchemy/picture/transformations.rb +5 -49
- data/app/models/alchemy/picture/url.rb +28 -77
- data/app/models/alchemy/picture_thumb.rb +57 -0
- data/app/models/alchemy/picture_thumb/create.rb +39 -0
- data/app/models/alchemy/picture_thumb/signature.rb +23 -0
- data/app/models/alchemy/picture_thumb/uid.rb +22 -0
- data/app/models/alchemy/picture_variant.rb +114 -0
- data/app/models/alchemy/site/layout.rb +30 -2
- data/app/serializers/alchemy/page_tree_serializer.rb +4 -4
- data/app/views/alchemy/admin/attachments/show.html.erb +8 -8
- data/app/views/alchemy/admin/dashboard/index.html.erb +13 -16
- data/app/views/alchemy/admin/elements/_element_footer.html.erb +1 -1
- data/app/views/alchemy/admin/elements/publish.js.erb +1 -0
- data/app/views/alchemy/admin/essence_pictures/crop.html.erb +1 -1
- data/app/views/alchemy/admin/essence_pictures/edit.html.erb +2 -2
- data/app/views/alchemy/admin/layoutpages/edit.html.erb +4 -6
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +19 -29
- data/app/views/alchemy/admin/pages/_form.html.erb +4 -6
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +12 -2
- data/app/views/alchemy/admin/pages/_page_layout_filter.html.erb +29 -0
- data/app/views/alchemy/admin/pages/_table.html.erb +27 -0
- data/app/views/alchemy/admin/pages/_table_row.html.erb +107 -0
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +77 -0
- data/app/views/alchemy/admin/pages/edit.html.erb +9 -1
- data/app/views/alchemy/admin/pages/index.html.erb +41 -74
- data/app/views/alchemy/admin/pages/list/_table.html.erb +31 -0
- data/app/views/alchemy/admin/pages/unlock.js.erb +2 -2
- data/app/views/alchemy/admin/pages/update.js.erb +19 -10
- data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +14 -13
- data/app/views/alchemy/admin/partials/_search_form.html.erb +8 -8
- data/app/views/alchemy/admin/pictures/_archive.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_form.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/_picture.html.erb +3 -3
- data/app/views/alchemy/admin/pictures/_picture_to_assign.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/index.html.erb +1 -1
- data/app/views/alchemy/admin/pictures/show.html.erb +3 -3
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +13 -11
- data/app/views/alchemy/admin/resources/_per_page_select.html.erb +3 -3
- data/app/views/alchemy/admin/resources/index.html.erb +4 -1
- data/app/views/alchemy/admin/tags/index.html.erb +14 -15
- data/app/views/alchemy/base/500.html.erb +11 -13
- data/app/views/alchemy/essences/_essence_file_view.html.erb +3 -3
- data/config/alchemy/config.yml +15 -11
- data/config/alchemy/modules.yml +12 -12
- data/config/locales/alchemy.en.yml +6 -4
- data/config/routes.rb +1 -1
- data/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb +22 -0
- data/db/migrate/20200907111332_remove_tri_state_booleans.rb +33 -0
- data/lib/alchemy.rb +66 -0
- data/lib/alchemy/admin/preview_url.rb +2 -0
- data/lib/alchemy/auth_accessors.rb +12 -5
- data/lib/alchemy/config.rb +1 -3
- data/lib/alchemy/engine.rb +7 -6
- data/lib/alchemy/modules.rb +11 -1
- data/lib/alchemy/permissions.rb +1 -0
- data/lib/alchemy/test_support/factories/picture_factory.rb +0 -1
- data/lib/alchemy/test_support/factories/picture_thumb_factory.rb +12 -0
- data/lib/alchemy/test_support/integration_helpers.rb +0 -7
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +2 -4
- data/lib/generators/alchemy/install/files/alchemy.en.yml +2 -2
- data/lib/generators/alchemy/install/templates/dragonfly.rb.tt +5 -5
- data/lib/tasks/alchemy/thumbnails.rake +37 -0
- data/vendor/assets/javascripts/jquery_plugins/select2.js +3729 -0
- data/vendor/assets/stylesheets/alchemy_admin/select2.scss +740 -0
- metadata +46 -37
- data/.github/workflows/greetings.yml +0 -13
- data/.travis.yml +0 -48
- data/app/controllers/concerns/alchemy/locale_redirects.rb +0 -40
- data/app/controllers/concerns/alchemy/page_redirects.rb +0 -68
- data/lib/alchemy/userstamp.rb +0 -12
|
@@ -11,16 +11,18 @@ module Alchemy
|
|
|
11
11
|
before_action :load_resource,
|
|
12
12
|
only: [:show, :edit, :update, :destroy, :info]
|
|
13
13
|
|
|
14
|
+
before_action :set_size, only: [:index, :show, :edit_multiple]
|
|
15
|
+
|
|
14
16
|
authorize_resource class: Alchemy::Picture
|
|
15
17
|
|
|
16
18
|
def index
|
|
17
|
-
@size = params[:size].present? ? params[:size] : "medium"
|
|
18
19
|
@query = Picture.ransack(search_filter_params[:q])
|
|
19
20
|
@pictures = Picture.search_by(
|
|
20
21
|
search_filter_params,
|
|
21
22
|
@query,
|
|
22
23
|
items_per_page,
|
|
23
24
|
)
|
|
25
|
+
@pictures = @pictures.includes(:thumbs)
|
|
24
26
|
|
|
25
27
|
if in_overlay?
|
|
26
28
|
archive_overlay
|
|
@@ -115,7 +117,7 @@ module Alchemy
|
|
|
115
117
|
|
|
116
118
|
def items_per_page
|
|
117
119
|
if in_overlay?
|
|
118
|
-
case
|
|
120
|
+
case @size
|
|
119
121
|
when "small" then 25
|
|
120
122
|
when "large" then 4
|
|
121
123
|
else
|
|
@@ -124,19 +126,24 @@ module Alchemy
|
|
|
124
126
|
else
|
|
125
127
|
cookies[:alchemy_pictures_per_page] = params[:per_page] ||
|
|
126
128
|
cookies[:alchemy_pictures_per_page] ||
|
|
127
|
-
pictures_per_page_for_size
|
|
129
|
+
pictures_per_page_for_size
|
|
128
130
|
end
|
|
129
131
|
end
|
|
130
132
|
|
|
131
133
|
def items_per_page_options
|
|
132
|
-
per_page = pictures_per_page_for_size
|
|
134
|
+
per_page = pictures_per_page_for_size
|
|
133
135
|
[per_page, per_page * 2, per_page * 4]
|
|
134
136
|
end
|
|
135
137
|
|
|
136
138
|
private
|
|
137
139
|
|
|
138
|
-
def
|
|
139
|
-
|
|
140
|
+
def set_size
|
|
141
|
+
@size = params[:size] || session[:alchemy_pictures_size] || "medium"
|
|
142
|
+
session[:alchemy_pictures_size] = @size
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def pictures_per_page_for_size
|
|
146
|
+
case @size
|
|
140
147
|
when "small" then 60
|
|
141
148
|
when "large" then 12
|
|
142
149
|
else
|
|
@@ -148,15 +148,15 @@ module Alchemy
|
|
|
148
148
|
|
|
149
149
|
def common_search_filter_includes
|
|
150
150
|
[
|
|
151
|
-
{q: [
|
|
151
|
+
{ q: [
|
|
152
152
|
resource_handler.search_field_name,
|
|
153
153
|
:s,
|
|
154
|
-
]},
|
|
154
|
+
] },
|
|
155
155
|
:tagged_with,
|
|
156
156
|
:filter,
|
|
157
157
|
:page,
|
|
158
158
|
:per_page,
|
|
159
|
-
]
|
|
159
|
+
]
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
def items_per_page
|
|
@@ -13,7 +13,10 @@ module Alchemy
|
|
|
13
13
|
|
|
14
14
|
# Redirecting concerns. Order is important here!
|
|
15
15
|
include SiteRedirects
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
before_action :enforce_no_locale,
|
|
18
|
+
if: :locale_prefix_not_allowed?,
|
|
19
|
+
only: [:index, :show]
|
|
17
20
|
|
|
18
21
|
before_action :load_index_page, only: [:index]
|
|
19
22
|
before_action :load_page, only: [:show]
|
|
@@ -21,11 +24,13 @@ module Alchemy
|
|
|
21
24
|
# Legacy page redirects need to run after the page was loaded and before we render 404.
|
|
22
25
|
include LegacyPageRedirects
|
|
23
26
|
|
|
24
|
-
# From here on, we need a +@page+ to work with!
|
|
25
|
-
before_action :page_not_found!,
|
|
27
|
+
# From here on, we need a published +@page+ to work with!
|
|
28
|
+
before_action :page_not_found!, unless: -> { @page&.public? }, only: [:index, :show]
|
|
26
29
|
|
|
27
|
-
# Page redirects need to run after the page was loaded and we're sure to have a +@page+ set.
|
|
28
|
-
|
|
30
|
+
# Page redirects need to run after the page was loaded and we're sure to have a public +@page+ set.
|
|
31
|
+
before_action :enforce_locale,
|
|
32
|
+
if: :locale_prefix_missing?,
|
|
33
|
+
only: [:index, :show]
|
|
29
34
|
|
|
30
35
|
# We only need to set the +@root_page+ if we are sure that no more redirects happen.
|
|
31
36
|
before_action :set_root_page, only: [:index, :show]
|
|
@@ -66,12 +71,8 @@ module Alchemy
|
|
|
66
71
|
# descendant it finds. If no public page can be found it renders a 404 error.
|
|
67
72
|
#
|
|
68
73
|
def show
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
else
|
|
72
|
-
authorize! :show, @page
|
|
73
|
-
render_page if render_fresh_page?
|
|
74
|
-
end
|
|
74
|
+
authorize! :show, @page
|
|
75
|
+
render_page if render_fresh_page?
|
|
75
76
|
end
|
|
76
77
|
|
|
77
78
|
# Renders a search engine compatible xml sitemap.
|
|
@@ -84,13 +85,25 @@ module Alchemy
|
|
|
84
85
|
|
|
85
86
|
private
|
|
86
87
|
|
|
88
|
+
# Redirects to requested action without locale prefixed
|
|
89
|
+
def enforce_no_locale
|
|
90
|
+
redirect_permanently_to additional_params.merge(locale: nil)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Is the requested locale allowed?
|
|
94
|
+
#
|
|
95
|
+
# If Alchemy is not in multi language mode or the requested locale is the default locale,
|
|
96
|
+
# then we want to redirect to a non prefixed url.
|
|
97
|
+
#
|
|
98
|
+
def locale_prefix_not_allowed?
|
|
99
|
+
params[:locale].present? && !multi_language? ||
|
|
100
|
+
params[:locale].presence == ::I18n.default_locale.to_s
|
|
101
|
+
end
|
|
102
|
+
|
|
87
103
|
# == Loads index page
|
|
88
104
|
#
|
|
89
105
|
# Loads the current public language root page.
|
|
90
106
|
#
|
|
91
|
-
# If the root page is not public it redirects to the first published child.
|
|
92
|
-
# This can be configured via +redirect_to_public_child+ [default: true]
|
|
93
|
-
#
|
|
94
107
|
# If no index page and no admin users are present we show the "Welcome to Alchemy" page.
|
|
95
108
|
#
|
|
96
109
|
def load_index_page
|
|
@@ -116,6 +129,28 @@ module Alchemy
|
|
|
116
129
|
)
|
|
117
130
|
end
|
|
118
131
|
|
|
132
|
+
def enforce_locale
|
|
133
|
+
redirect_permanently_to page_locale_redirect_url(locale: Language.current.code)
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def locale_prefix_missing?
|
|
137
|
+
multi_language? && params[:locale].blank? && !default_locale?
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def default_locale?
|
|
141
|
+
Language.current.code.to_sym == ::I18n.default_locale.to_sym
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# Page url with or without locale while keeping all additional params
|
|
145
|
+
def page_locale_redirect_url(options = {})
|
|
146
|
+
options = {
|
|
147
|
+
locale: prefix_locale? ? @page.language_code : nil,
|
|
148
|
+
urlname: @page.urlname,
|
|
149
|
+
}.merge(options)
|
|
150
|
+
|
|
151
|
+
alchemy.show_page_path additional_params.merge(options)
|
|
152
|
+
end
|
|
153
|
+
|
|
119
154
|
# Redirects to given url with 301 status
|
|
120
155
|
def redirect_permanently_to(url)
|
|
121
156
|
redirect_to url, status: :moved_permanently
|
|
@@ -272,50 +272,6 @@ module Alchemy
|
|
|
272
272
|
end
|
|
273
273
|
end
|
|
274
274
|
|
|
275
|
-
# Renders the toolbar shown on top of the records.
|
|
276
|
-
#
|
|
277
|
-
# == Example
|
|
278
|
-
#
|
|
279
|
-
# <% label_title = Alchemy.t("Create #{resource_name}", default: Alchemy.t('Create')) %>
|
|
280
|
-
# <% toolbar(
|
|
281
|
-
# buttons: [
|
|
282
|
-
# {
|
|
283
|
-
# icon: :plus,
|
|
284
|
-
# label: label_title,
|
|
285
|
-
# url: new_resource_path,
|
|
286
|
-
# title: label_title,
|
|
287
|
-
# hotkey: 'alt+n',
|
|
288
|
-
# dialog_options: {
|
|
289
|
-
# title: label_title,
|
|
290
|
-
# size: "430x400"
|
|
291
|
-
# },
|
|
292
|
-
# if_permitted_to: [:create, resource_model]
|
|
293
|
-
# }
|
|
294
|
-
# ]
|
|
295
|
-
# ) %>
|
|
296
|
-
#
|
|
297
|
-
# @option options [Array] :buttons ([])
|
|
298
|
-
# Pass an Array with button options. They will be passed to {#toolbar_button} helper.
|
|
299
|
-
# @option options [Boolean] :search (true)
|
|
300
|
-
# Show searchfield.
|
|
301
|
-
#
|
|
302
|
-
def toolbar(options = {})
|
|
303
|
-
defaults = {
|
|
304
|
-
buttons: [],
|
|
305
|
-
search: true,
|
|
306
|
-
}
|
|
307
|
-
options = defaults.merge(options)
|
|
308
|
-
content_for(:toolbar) do
|
|
309
|
-
content = <<-CONTENT.strip_heredoc
|
|
310
|
-
#{options[:buttons].map { |button_options| toolbar_button(button_options) }.join}
|
|
311
|
-
#{render("alchemy/admin/partials/search_form", url: options[:search_url]) if options[:search]}
|
|
312
|
-
CONTENT
|
|
313
|
-
content.html_safe
|
|
314
|
-
end
|
|
315
|
-
end
|
|
316
|
-
|
|
317
|
-
deprecate toolbar: "Please use `content_for(:toolbar)` instead", deprecator: Alchemy::Deprecation
|
|
318
|
-
|
|
319
275
|
# (internal) Used by upload form
|
|
320
276
|
def new_asset_path_with_session_information(asset_type)
|
|
321
277
|
session_key = Rails.application.config.session_options[:key]
|
|
@@ -175,7 +175,8 @@ module Alchemy
|
|
|
175
175
|
# Returns true if the given entry's controller is current controller
|
|
176
176
|
#
|
|
177
177
|
def is_entry_controller_active?(entry)
|
|
178
|
-
entry["controller"].gsub(/\A\//, "") == params[:controller]
|
|
178
|
+
entry["controller"].gsub(/\A\//, "") == params[:controller] ||
|
|
179
|
+
entry.fetch("nested_controllers", []).include?(params[:controller])
|
|
179
180
|
end
|
|
180
181
|
|
|
181
182
|
# Returns true if the given entry's action is current controllers action
|
|
@@ -37,6 +37,20 @@ module Alchemy
|
|
|
37
37
|
|
|
38
38
|
# We need to define this method here to have it available in the validations below.
|
|
39
39
|
class << self
|
|
40
|
+
# The class used to generate URLs for attachments
|
|
41
|
+
#
|
|
42
|
+
# @see Alchemy::Attachment::Url
|
|
43
|
+
def url_class
|
|
44
|
+
@_url_class ||= Alchemy::Attachment::Url
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Set a different attachment url class
|
|
48
|
+
#
|
|
49
|
+
# @see Alchemy::Attachment::Url
|
|
50
|
+
def url_class=(klass)
|
|
51
|
+
@_url_class = klass
|
|
52
|
+
end
|
|
53
|
+
|
|
40
54
|
def searchable_alchemy_resource_attributes
|
|
41
55
|
%w(name file_name)
|
|
42
56
|
end
|
|
@@ -76,14 +90,17 @@ module Alchemy
|
|
|
76
90
|
}
|
|
77
91
|
end
|
|
78
92
|
|
|
93
|
+
def url(options = {})
|
|
94
|
+
if file
|
|
95
|
+
self.class.url_class.new(self).call(options)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
79
99
|
# An url save filename without format suffix
|
|
80
100
|
def slug
|
|
81
101
|
CGI.escape(file_name.gsub(/\.#{extension}$/, "").tr(".", " "))
|
|
82
102
|
end
|
|
83
103
|
|
|
84
|
-
alias_method :urlname, :slug
|
|
85
|
-
deprecate urlname: :slug, deprecator: Alchemy::Deprecation
|
|
86
|
-
|
|
87
104
|
# Checks if the attachment is restricted, because it is attached on restricted pages only
|
|
88
105
|
def restricted?
|
|
89
106
|
pages.any? && pages.not_restricted.blank?
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Alchemy
|
|
4
|
+
class Attachment < BaseRecord
|
|
5
|
+
# The class representing an URL to an attachment
|
|
6
|
+
#
|
|
7
|
+
# Set a different one
|
|
8
|
+
#
|
|
9
|
+
# Alchemy::Attachment.url_class = MyRemoteUrlClass
|
|
10
|
+
#
|
|
11
|
+
class Url
|
|
12
|
+
def initialize(attachment)
|
|
13
|
+
@attachment = attachment
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# The attachment url
|
|
17
|
+
#
|
|
18
|
+
# @param [Hash] options
|
|
19
|
+
# @option options [Symbol] :download return a URL for downloading the attachment
|
|
20
|
+
# @option options [Symbol] :name The filename
|
|
21
|
+
# @option options [Symbol] :format The file extension
|
|
22
|
+
#
|
|
23
|
+
# @return [String]
|
|
24
|
+
#
|
|
25
|
+
def call(options = {})
|
|
26
|
+
if options.delete(:download)
|
|
27
|
+
routes.download_attachment_path(@attachment, options)
|
|
28
|
+
else
|
|
29
|
+
routes.show_attachment_path(@attachment, options)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def routes
|
|
36
|
+
Alchemy::Engine.routes.url_helpers
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -62,7 +62,7 @@ module Alchemy
|
|
|
62
62
|
def picture_url(options = {})
|
|
63
63
|
return if picture.nil?
|
|
64
64
|
|
|
65
|
-
picture.url
|
|
65
|
+
picture.url(picture_url_options.merge(options)) || "missing-image.png"
|
|
66
66
|
end
|
|
67
67
|
|
|
68
68
|
# Picture rendering options
|
|
@@ -103,7 +103,7 @@ module Alchemy
|
|
|
103
103
|
format: picture.image_file_format,
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
picture.url(options)
|
|
106
|
+
picture.url(options) || "alchemy/missing-image.svg"
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# The name of the picture used as preview text in element editor views.
|
|
@@ -140,7 +140,7 @@ module Alchemy
|
|
|
140
140
|
# Show image cropping link for content
|
|
141
141
|
def allow_image_cropping?
|
|
142
142
|
content && content.settings[:crop] && picture &&
|
|
143
|
-
picture.can_be_cropped_to(
|
|
143
|
+
picture.can_be_cropped_to?(
|
|
144
144
|
content.settings[:size],
|
|
145
145
|
content.settings[:upsample],
|
|
146
146
|
) && !!picture.image_file
|
|
@@ -44,17 +44,19 @@ module Alchemy
|
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
private
|
|
48
|
-
|
|
49
47
|
def caption
|
|
50
48
|
return unless show_caption?
|
|
51
49
|
|
|
52
50
|
@_caption ||= content_tag(:figcaption, essence.caption)
|
|
53
51
|
end
|
|
54
52
|
|
|
53
|
+
def src
|
|
54
|
+
essence.picture_url(options.except(*DEFAULT_OPTIONS.keys))
|
|
55
|
+
end
|
|
56
|
+
|
|
55
57
|
def img_tag
|
|
56
58
|
@_img_tag ||= image_tag(
|
|
57
|
-
|
|
59
|
+
src, {
|
|
58
60
|
alt: alt_text,
|
|
59
61
|
title: essence.title.presence,
|
|
60
62
|
class: caption ? nil : essence.css_class.presence,
|
data/app/models/alchemy/page.rb
CHANGED
|
@@ -149,6 +149,29 @@ module Alchemy
|
|
|
149
149
|
# Class methods
|
|
150
150
|
#
|
|
151
151
|
class << self
|
|
152
|
+
# The url_path class
|
|
153
|
+
# @see Alchemy::Page::UrlPath
|
|
154
|
+
def url_path_class
|
|
155
|
+
@_url_path_class ||= Alchemy::Page::UrlPath
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
# Set a custom url path class
|
|
159
|
+
#
|
|
160
|
+
# # config/initializers/alchemy.rb
|
|
161
|
+
# Alchemy::Page.url_path_class = MyPageUrlPathClass
|
|
162
|
+
#
|
|
163
|
+
def url_path_class=(klass)
|
|
164
|
+
@_url_path_class = klass
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def alchemy_resource_filters
|
|
168
|
+
%w[published not_public restricted]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def searchable_alchemy_resource_attributes
|
|
172
|
+
%w[name urlname title]
|
|
173
|
+
end
|
|
174
|
+
|
|
152
175
|
# Used to store the current page previewed in the edit page template.
|
|
153
176
|
#
|
|
154
177
|
def current_preview=(page)
|
|
@@ -298,7 +321,7 @@ module Alchemy
|
|
|
298
321
|
#
|
|
299
322
|
# @see Alchemy::Page::UrlPath#call
|
|
300
323
|
def url_path
|
|
301
|
-
|
|
324
|
+
self.class.url_path_class.new(self).call
|
|
302
325
|
end
|
|
303
326
|
|
|
304
327
|
# The page's view partial is dependent from its page layout
|
|
@@ -20,8 +20,6 @@ module Alchemy
|
|
|
20
20
|
# link_to page.url
|
|
21
21
|
#
|
|
22
22
|
class UrlPath
|
|
23
|
-
ROOT_PATH = "/"
|
|
24
|
-
|
|
25
23
|
def initialize(page)
|
|
26
24
|
@page = page
|
|
27
25
|
@language = @page.language
|
|
@@ -41,7 +39,7 @@ module Alchemy
|
|
|
41
39
|
private
|
|
42
40
|
|
|
43
41
|
def language_root_path
|
|
44
|
-
@language.default? ?
|
|
42
|
+
@language.default? ? root_path : language_path
|
|
45
43
|
end
|
|
46
44
|
|
|
47
45
|
def page_path_with_language_prefix
|
|
@@ -49,15 +47,19 @@ module Alchemy
|
|
|
49
47
|
end
|
|
50
48
|
|
|
51
49
|
def page_path_with_leading_slash
|
|
52
|
-
@page.language_root? ?
|
|
50
|
+
@page.language_root? ? root_path : page_path
|
|
53
51
|
end
|
|
54
52
|
|
|
55
53
|
def language_path
|
|
56
|
-
"
|
|
54
|
+
"#{root_path}#{@page.language_code}"
|
|
57
55
|
end
|
|
58
56
|
|
|
59
57
|
def page_path
|
|
60
|
-
"
|
|
58
|
+
"#{root_path}#{@page.urlname}"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def root_path
|
|
62
|
+
Engine.routes.url_helpers.root_path
|
|
61
63
|
end
|
|
62
64
|
end
|
|
63
65
|
end
|