trusty-cms 4.1.2 → 4.1.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +3 -3
- data/Gemfile.lock +104 -104
- data/README.md +1 -1
- data/Rakefile +7 -7
- data/app/assets/javascripts/admin/assets.js +1 -1
- data/app/assets/javascripts/rad_social/rad_ajax_form.js +3 -0
- data/app/assets/javascripts/rad_social/rad_email.js +0 -1
- data/app/assets/javascripts/rad_social/rad_email_form.js +2 -7
- data/app/assets/stylesheets/admin/partials/_content.scss +1 -2
- data/app/assets/stylesheets/rad_social/rad_screen.scss +0 -4
- data/app/controllers/admin/assets_controller.rb +22 -21
- data/app/controllers/admin/configuration_controller.rb +9 -11
- data/app/controllers/admin/extensions_controller.rb +3 -3
- data/app/controllers/admin/layouts_controller.rb +3 -4
- data/app/controllers/admin/page_attachments_controller.rb +5 -5
- data/app/controllers/admin/page_fields_controller.rb +3 -4
- data/app/controllers/admin/page_parts_controller.rb +4 -5
- data/app/controllers/admin/pages_controller.rb +55 -56
- data/app/controllers/admin/references_controller.rb +1 -1
- data/app/controllers/admin/resource_controller.rb +132 -130
- data/app/controllers/admin/sites_controller.rb +4 -4
- data/app/controllers/admin/snippets_controller.rb +3 -4
- data/app/controllers/admin/users_controller.rb +16 -16
- data/app/controllers/application_controller.rb +47 -48
- data/app/controllers/site_controller.rb +51 -48
- data/app/controllers/social_mailer_controller.rb +12 -22
- data/app/helpers/admin/configuration_helper.rb +19 -20
- data/app/helpers/admin/layouts_helper.rb +0 -1
- data/app/helpers/admin/node_helper.rb +27 -24
- data/app/helpers/admin/pages_helper.rb +2 -2
- data/app/helpers/admin/preferences_helper.rb +0 -1
- data/app/helpers/admin/references_helper.rb +9 -10
- data/app/helpers/admin/regions_helper.rb +3 -3
- data/app/helpers/application_helper.rb +32 -33
- data/app/helpers/rad_social_helper.rb +8 -11
- data/app/helpers/scoped_helper.rb +1 -3
- data/app/helpers/sites_helper.rb +4 -4
- data/app/mailers/devise_mailer.rb +3 -4
- data/app/mailers/rad_social_mailer.rb +8 -8
- data/app/models/asset.rb +62 -63
- data/app/models/asset_type.rb +38 -39
- data/app/models/deprecated_tags.rb +3 -4
- data/app/models/file_not_found_page.rb +1 -3
- data/app/models/haml_filter.rb +1 -1
- data/app/models/layout.rb +4 -5
- data/app/models/legacy_user.rb +2 -2
- data/app/models/menu_renderer.rb +16 -18
- data/app/models/page.rb +96 -93
- data/app/models/page_attachment.rb +1 -2
- data/app/models/page_context.rb +11 -12
- data/app/models/page_part.rb +3 -4
- data/app/models/rails_page.rb +10 -12
- data/app/models/site.rb +22 -21
- data/app/models/snippet.rb +6 -8
- data/app/models/snippet_finder.rb +3 -3
- data/app/models/snippet_tags.rb +4 -4
- data/app/models/standard_tags.rb +258 -252
- data/app/models/status.rb +8 -8
- data/app/models/trusty_cms/config.rb +25 -25
- data/app/models/trusty_cms/page_response_cache_director.rb +2 -3
- data/app/models/user.rb +15 -14
- data/app/models/user_action_observer.rb +3 -3
- data/app/views/admin/assets/edit.html.haml +3 -0
- data/app/views/rad_social_mailer/social_mail_form.html.haml +1 -3
- data/app/views/widget/_email_form.html.haml +0 -5
- data/bin/rails +4 -4
- data/bin/trusty_cms +3 -5
- data/config.ru +1 -1
- data/config/application.rb +14 -15
- data/config/boot.rb +1 -2
- data/config/environment.rb +1 -1
- data/config/environments/production.rb +0 -1
- data/config/environments/test.rb +1 -2
- data/config/initializers/devise.rb +1 -1
- data/config/initializers/kraken.rb +2 -2
- data/config/initializers/tmp.rb +1 -1
- data/config/initializers/trusty_cms_config.rb +48 -48
- data/config/locales/en.yml +1 -0
- data/config/routes.rb +6 -6
- data/lib/active_record_extensions/active_record_extensions.rb +1 -2
- data/lib/annotatable.rb +3 -5
- data/lib/configuration_extensions/configuration_extensions.rb +1 -1
- data/lib/inheritable_class_attributes.rb +13 -9
- data/lib/login_system.rb +73 -73
- data/lib/method_observer.rb +13 -12
- data/lib/ostruct.rb +7 -10
- data/lib/simpleton.rb +0 -4
- data/lib/string_extensions/string_extensions.rb +3 -3
- data/lib/symbol_extensions/symbol_extensions.rb +1 -1
- data/lib/tasks/database.rake +28 -28
- data/lib/tasks/extensions.rake +18 -18
- data/lib/tasks/framework.rake +68 -68
- data/lib/tasks/radiant_config.rake +4 -4
- data/lib/tasks/snippets_extension_tasks.rake +11 -11
- data/lib/tasks/translate.rake +14 -14
- data/lib/tasks/upgrade_to_devise.rake +1 -1
- data/lib/translation_support.rb +22 -22
- data/lib/trusty_cms.rb +2 -2
- data/lib/trusty_cms/admin_ui.rb +19 -16
- data/lib/trusty_cms/admin_ui/region_partials.rb +4 -3
- data/lib/trusty_cms/admin_ui/region_set.rb +4 -5
- data/lib/trusty_cms/available_locales.rb +2 -4
- data/lib/trusty_cms/config/definition.rb +11 -8
- data/lib/trusty_cms/engine.rb +13 -14
- data/lib/trusty_cms/extension.rb +14 -16
- data/lib/trusty_cms/extension_loader.rb +6 -6
- data/lib/trusty_cms/extension_migrator.rb +42 -41
- data/lib/trusty_cms/extension_path.rb +20 -19
- data/lib/trusty_cms/initializer.rb +5 -8
- data/lib/trusty_cms/pagination/controller.rb +7 -10
- data/lib/trusty_cms/pagination/link_renderer.rb +2 -2
- data/lib/trusty_cms/resource_responses.rb +3 -3
- data/lib/trusty_cms/setup.rb +130 -132
- data/lib/trusty_cms/taggable.rb +19 -22
- data/lib/trusty_cms/task_support.rb +9 -6
- data/public/dispatch.fcgi +1 -1
- data/public/dispatch.rb +2 -2
- data/script/extension +1 -1
- data/script/rails +2 -2
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/core.js +126 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/failsafe/index.js +4 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/failsafe/map.js +56 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/failsafe/seq.js +43 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/failsafe/string.js +28 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/index.js +36 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/json.js +76 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/options.js +23 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/yaml-1.1/binary.js +87 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/yaml-1.1/index.js +157 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/yaml-1.1/omap.js +142 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/yaml-1.1/pairs.js +81 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/yaml-1.1/set.js +114 -0
- data/spec/spec/dummy/node_modules/yaml/browser/dist/tags/yaml-1.1/timestamp.js +97 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/core.js +114 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/failsafe/index.js +17 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/failsafe/map.js +37 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/failsafe/seq.js +34 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/failsafe/string.js +40 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/index.js +62 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/json.js +60 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/options.js +35 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/yaml-1.1/binary.js +97 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/yaml-1.1/index.js +131 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/yaml-1.1/omap.js +105 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/yaml-1.1/pairs.js +80 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/yaml-1.1/set.js +91 -0
- data/spec/spec/dummy/node_modules/yaml/dist/tags/yaml-1.1/timestamp.js +93 -0
- data/trusty_cms.gemspec +24 -24
- data/yarn.lock +3 -3
- metadata +7602 -103
- data/app/assets/javascripts/rad_social/captcha.js +0 -42
data/app/models/asset_type.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class AssetType
|
2
|
-
|
3
2
|
# The Asset Type encapsulates a type of attachment.
|
4
3
|
# Conventionally this would a sensible category like 'image' or 'video'
|
5
4
|
# that should be processed and presented in a particular way.
|
@@ -34,10 +33,10 @@ class AssetType
|
|
34
33
|
Asset.send :define_method, "#{name}?".intern do this.mime_types.include?(asset_content_type) end
|
35
34
|
Asset.send :define_class_method, "#{name}_condition".intern do this.condition; end
|
36
35
|
Asset.send :define_class_method, "not_#{name}_condition".intern do this.non_condition; end
|
37
|
-
Asset.send :scope, plural.to_sym, -> {where(:
|
38
|
-
Asset.send :scope, "not_#{plural}".to_sym, -> {where(:
|
36
|
+
Asset.send :scope, plural.to_sym, -> { where(conditions: condition) }
|
37
|
+
Asset.send :scope, "not_#{plural}".to_sym, -> { where(conditions: non_condition) }
|
39
38
|
|
40
|
-
|
39
|
+
define_radius_tags
|
41
40
|
@@types.push self
|
42
41
|
@@type_lookup[@name] = self
|
43
42
|
end
|
@@ -46,21 +45,21 @@ class AssetType
|
|
46
45
|
name.to_s.pluralize
|
47
46
|
end
|
48
47
|
|
49
|
-
def icon(style_name='icon')
|
50
|
-
if File.exist?(Rails.root + "public/images/admin/assets/#{icon_name}_#{style_name
|
51
|
-
|
48
|
+
def icon(style_name = 'icon')
|
49
|
+
if File.exist?(Rails.root + "public/images/admin/assets/#{icon_name}_#{style_name}.png")
|
50
|
+
"/assets/admin/#{icon_name}_#{style_name}.png"
|
52
51
|
else
|
53
|
-
|
52
|
+
"/assets/admin/#{icon_name}_icon.png"
|
54
53
|
end
|
55
54
|
end
|
56
55
|
|
57
|
-
def icon_path(style_name='icon')
|
56
|
+
def icon_path(style_name = 'icon')
|
58
57
|
Rails.root + "public#{icon(style_name)}"
|
59
58
|
end
|
60
59
|
|
61
60
|
def condition
|
62
61
|
if @mimes.any?
|
63
|
-
["asset_content_type IN (#{@mimes.map{'?'}.join(',')})", *@mimes]
|
62
|
+
["asset_content_type IN (#{@mimes.map { '?' }.join(',')})", *@mimes]
|
64
63
|
else
|
65
64
|
self.class.other_condition
|
66
65
|
end
|
@@ -72,7 +71,7 @@ class AssetType
|
|
72
71
|
|
73
72
|
def non_condition
|
74
73
|
if @mimes.any?
|
75
|
-
["NOT asset_content_type IN (#{@mimes.map{'?'}.join(',')})", *@mimes]
|
74
|
+
["NOT asset_content_type IN (#{@mimes.map { '?' }.join(',')})", *@mimes]
|
76
75
|
else
|
77
76
|
self.class.non_other_condition
|
78
77
|
end
|
@@ -98,23 +97,23 @@ class AssetType
|
|
98
97
|
def paperclip_styles
|
99
98
|
# Styles are not relevant if processors are not defined.
|
100
99
|
@paperclip_styles ||= if paperclip_processors.any?
|
101
|
-
|
102
|
-
|
103
|
-
|
100
|
+
normalize_style_rules(configured_styles.merge(styles))
|
101
|
+
else
|
102
|
+
{}
|
104
103
|
end
|
105
104
|
@paperclip_styles
|
106
105
|
end
|
107
106
|
|
108
107
|
# Takes a motley collection of differently-defined styles and renders them into the standard hash-of-hashes format.
|
109
108
|
# Solitary strings are assumed to be #
|
110
|
-
def normalize_style_rules(styles={})
|
109
|
+
def normalize_style_rules(styles = {})
|
111
110
|
styles.each_pair do |name, rule|
|
112
111
|
unless rule.is_a? Hash
|
113
112
|
if rule =~ /\=/
|
114
|
-
parameters = rule.split(',').collect{ |parameter| parameter.split('=') }
|
115
|
-
rule = Hash[parameters].symbolize_keys
|
113
|
+
parameters = rule.split(',').collect { |parameter| parameter.split('=') } # array of pairs
|
114
|
+
rule = Hash[parameters].symbolize_keys # into hash of :first => last
|
116
115
|
else
|
117
|
-
rule = {:
|
116
|
+
rule = { geometry: rule } # simplest case: name:geom|name:geom
|
118
117
|
end
|
119
118
|
end
|
120
119
|
rule[:geometry] ||= rule.delete(:size)
|
@@ -122,10 +121,10 @@ class AssetType
|
|
122
121
|
end
|
123
122
|
styles
|
124
123
|
end
|
125
|
-
|
124
|
+
|
126
125
|
def standard_styles
|
127
126
|
{
|
128
|
-
:
|
127
|
+
thumbnail: { geometry: '100x100#', format: :png },
|
129
128
|
}
|
130
129
|
end
|
131
130
|
|
@@ -140,17 +139,17 @@ class AssetType
|
|
140
139
|
#
|
141
140
|
def configured_styles
|
142
141
|
@configured_styles ||= if style_definitions = TrustyCms.config["assets.thumbnails.#{name}"]
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
142
|
+
style_definitions.split('|').each_with_object({}) do |definition, styles|
|
143
|
+
name, rule = definition.split(':')
|
144
|
+
styles[name.strip.to_sym] = rule.to_s.strip
|
145
|
+
end
|
146
|
+
else
|
147
|
+
{}
|
149
148
|
end
|
150
149
|
end
|
151
150
|
|
152
151
|
def legacy_styles
|
153
|
-
TrustyCms::config[
|
152
|
+
TrustyCms::config['assets.additional_thumbnails'].to_s.gsub(' ', '').split(',').collect { |s| s.split('=') }.inject({}) { |ha, (k, v)| ha[k.to_sym] = v; ha }
|
154
153
|
end
|
155
154
|
|
156
155
|
def style_dimensions(style_name)
|
@@ -160,21 +159,21 @@ class AssetType
|
|
160
159
|
end
|
161
160
|
|
162
161
|
def define_radius_tags
|
163
|
-
type =
|
164
|
-
Page.class_eval
|
162
|
+
type = name
|
163
|
+
Page.class_eval do
|
165
164
|
tag "asset:if_#{type}" do |tag|
|
166
165
|
tag.expand if find_asset(tag, tag.attr.dup).send("#{type}?".to_sym)
|
167
166
|
end
|
168
167
|
tag "asset:unless_#{type}" do |tag|
|
169
168
|
tag.expand unless find_asset(tag, tag.attr.dup).send("#{type}?".to_sym)
|
170
169
|
end
|
171
|
-
|
170
|
+
end
|
172
171
|
end
|
173
172
|
|
174
173
|
# class methods
|
175
174
|
|
176
175
|
def self.for(attachment)
|
177
|
-
extension = File.extname(attachment.original_filename).sub(/^\.+/,
|
176
|
+
extension = File.extname(attachment.original_filename).sub(/^\.+/, '')
|
178
177
|
from_extension(extension) || from_mimetype(attachment.instance_read(:content_type)) || catchall
|
179
178
|
end
|
180
179
|
|
@@ -187,20 +186,21 @@ class AssetType
|
|
187
186
|
end
|
188
187
|
|
189
188
|
def self.catchall
|
190
|
-
@@default_type ||=
|
189
|
+
@@default_type ||= find(:other)
|
191
190
|
end
|
192
191
|
|
193
192
|
def self.known?(name)
|
194
|
-
!
|
193
|
+
!find(name).nil?
|
195
194
|
end
|
196
195
|
|
197
196
|
def self.slice(*types)
|
198
|
-
@@type_lookup.slice(*types.map(&:to_sym)).values if types
|
197
|
+
@@type_lookup.slice(*types.map(&:to_sym)).values if types # Hash#slice is provided by will_paginate
|
199
198
|
end
|
200
199
|
|
201
200
|
def self.find(type)
|
202
201
|
@@type_lookup[type] if type
|
203
202
|
end
|
203
|
+
|
204
204
|
def self.[](type)
|
205
205
|
find(type)
|
206
206
|
end
|
@@ -218,19 +218,18 @@ class AssetType
|
|
218
218
|
end
|
219
219
|
|
220
220
|
def self.mime_types_for(*names)
|
221
|
-
names.collect{ |name| find(name).mime_types }.flatten
|
221
|
+
names.collect { |name| find(name).mime_types }.flatten
|
222
222
|
end
|
223
223
|
|
224
224
|
def self.conditions_for(*names)
|
225
|
-
names.collect{ |name|
|
225
|
+
names.collect { |name| find(name).sanitized_condition }.join(' OR ')
|
226
226
|
end
|
227
227
|
|
228
228
|
def self.non_other_condition
|
229
|
-
["asset_content_type IN (#{known_mimetypes.map{'?'}.join(',')})", *known_mimetypes]
|
229
|
+
["asset_content_type IN (#{known_mimetypes.map { '?' }.join(',')})", *known_mimetypes]
|
230
230
|
end
|
231
231
|
|
232
232
|
def self.other_condition
|
233
|
-
["NOT asset_content_type IN (#{known_mimetypes.map{'?'}.join(',')})", *known_mimetypes]
|
233
|
+
["NOT asset_content_type IN (#{known_mimetypes.map { '?' }.join(',')})", *known_mimetypes]
|
234
234
|
end
|
235
|
-
|
236
235
|
end
|
@@ -2,9 +2,9 @@ require 'trusty_cms/taggable'
|
|
2
2
|
module DeprecatedTags
|
3
3
|
include TrustyCms::Taggable
|
4
4
|
|
5
|
-
deprecated_tag
|
5
|
+
deprecated_tag 'comment', substitute: 'hide', deadline: '2.0'
|
6
6
|
|
7
|
-
deprecated_tag
|
7
|
+
deprecated_tag 'meta', deadline: '2.0' do |tag|
|
8
8
|
if tag.double?
|
9
9
|
tag.expand
|
10
10
|
else
|
@@ -12,11 +12,10 @@ module DeprecatedTags
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
deprecated_tag
|
15
|
+
deprecated_tag 'rfc1123_date', deadline: '2.0' do |tag|
|
16
16
|
page = tag.locals.page
|
17
17
|
if date = page.published_at || page.created_at
|
18
18
|
CGI.rfc1123_date(date.to_time)
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
21
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
class FileNotFoundPage < Page
|
2
|
-
|
3
2
|
def allowed_children
|
4
3
|
[]
|
5
4
|
end
|
@@ -13,7 +12,7 @@ class FileNotFoundPage < Page
|
|
13
12
|
page type.
|
14
13
|
}
|
15
14
|
|
16
|
-
tag
|
15
|
+
tag 'attempted_url' do |_tag|
|
17
16
|
CGI.escapeHTML(request.request_uri) unless request.nil?
|
18
17
|
end
|
19
18
|
|
@@ -28,5 +27,4 @@ class FileNotFoundPage < Page
|
|
28
27
|
def cache?
|
29
28
|
false
|
30
29
|
end
|
31
|
-
|
32
30
|
end
|
data/app/models/haml_filter.rb
CHANGED
data/app/models/layout.rb
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
class Layout < ActiveRecord::Base
|
2
|
-
|
3
2
|
# Default Order
|
4
|
-
default_scope {order(
|
3
|
+
default_scope { order('name') }
|
5
4
|
|
6
5
|
# Associations
|
7
6
|
has_many :pages
|
8
|
-
belongs_to :created_by, :
|
9
|
-
belongs_to :updated_by, :
|
7
|
+
belongs_to :created_by, class_name: 'User'
|
8
|
+
belongs_to :updated_by, class_name: 'User'
|
10
9
|
|
11
10
|
# Validations
|
12
11
|
validates_presence_of :name
|
13
12
|
validates_uniqueness_of :name
|
14
|
-
validates_length_of :name, :
|
13
|
+
validates_length_of :name, maximum: 100
|
15
14
|
end
|
data/app/models/legacy_user.rb
CHANGED
data/app/models/menu_renderer.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
module MenuRenderer
|
2
|
-
|
3
2
|
def exclude(*type_names)
|
4
3
|
@excluded_class_names ||= []
|
5
4
|
@excluded_class_names.concat(type_names).uniq!
|
@@ -26,7 +25,7 @@ module MenuRenderer
|
|
26
25
|
end
|
27
26
|
|
28
27
|
def menu_renderer_module_name
|
29
|
-
simple_name =
|
28
|
+
simple_name = class_name.to_s.sub('Page', '')
|
30
29
|
"#{simple_name}MenuRenderer"
|
31
30
|
end
|
32
31
|
|
@@ -38,19 +37,18 @@ module MenuRenderer
|
|
38
37
|
(allowed_children_cache.to_s.split(',') - Array(excluded_class_names)).map do |name|
|
39
38
|
begin
|
40
39
|
name.constantize
|
41
|
-
rescue LoadError, NameError =>
|
40
|
+
rescue LoadError, NameError => _e
|
42
41
|
nil
|
43
42
|
end
|
44
43
|
end.compact
|
45
44
|
end
|
46
45
|
|
47
|
-
|
48
46
|
def default_child_item
|
49
47
|
menu_item(default_child)
|
50
48
|
end
|
51
49
|
|
52
50
|
def separator_item
|
53
|
-
view.content_tag :li, '', :
|
51
|
+
view.content_tag :li, '', class: 'separator'
|
54
52
|
end
|
55
53
|
|
56
54
|
def child_items
|
@@ -64,11 +62,11 @@ module MenuRenderer
|
|
64
62
|
end
|
65
63
|
|
66
64
|
def menu_list
|
67
|
-
view.content_tag :ul, menu_items.join.html_safe, :
|
65
|
+
view.content_tag :ul, menu_items.join.html_safe, class: 'menu', id: "allowed_children_#{id}"
|
68
66
|
end
|
69
67
|
|
70
68
|
def remove_link
|
71
|
-
view.link_to(
|
69
|
+
view.link_to('<i class="fas fa-minus-circle"></i> '.html_safe + I18n.t('remove'), view.remove_admin_page_url(self), class: 'action')
|
72
70
|
end
|
73
71
|
|
74
72
|
def remove_option
|
@@ -80,15 +78,15 @@ module MenuRenderer
|
|
80
78
|
end
|
81
79
|
|
82
80
|
def disabled_add_child_link
|
83
|
-
view.content_tag :span, view.image('plus_disabled') + ' Add Child', :
|
81
|
+
view.content_tag :span, view.image('plus_disabled') + ' Add Child', class: 'action disabled'
|
84
82
|
end
|
85
83
|
|
86
84
|
def add_child_link
|
87
|
-
view.link_to(
|
85
|
+
view.link_to('<i class="fas fa-plus-circle"></i> Add Child'.html_safe, view.new_admin_page_child_path(self, page_class: default_child.name), class: 'action')
|
88
86
|
end
|
89
87
|
|
90
88
|
def add_child_link_with_menu_hook
|
91
|
-
view.link_to('<i class="fas fa-plus-circle"></i> Add Child'.html_safe, "#allowed_children_#{id}", :
|
89
|
+
view.link_to('<i class="fas fa-plus-circle"></i> Add Child'.html_safe, "#allowed_children_#{id}", class: 'action dropdown')
|
92
90
|
end
|
93
91
|
|
94
92
|
def add_child_menu
|
@@ -114,7 +112,7 @@ module MenuRenderer
|
|
114
112
|
private
|
115
113
|
|
116
114
|
def clean_page_description(page_class)
|
117
|
-
page_class.description.to_s.strip.gsub(/\t/,'').gsub(/\s+/,' ')
|
115
|
+
page_class.description.to_s.strip.gsub(/\t/, '').gsub(/\s+/, ' ')
|
118
116
|
end
|
119
117
|
|
120
118
|
def menu_item(child_class)
|
@@ -123,18 +121,18 @@ module MenuRenderer
|
|
123
121
|
|
124
122
|
def menu_link(child_class)
|
125
123
|
title = clean_page_description(child_class)
|
126
|
-
path = view.new_admin_page_child_path(self, :
|
124
|
+
path = view.new_admin_page_child_path(self, page_class: child_class.name)
|
127
125
|
text = link_text_for_child_class(child_class.name)
|
128
|
-
view.link_to(text, path, :
|
126
|
+
view.link_to(text, path, title: title)
|
129
127
|
end
|
130
128
|
|
131
129
|
def link_text_for_child_class(given_class_name)
|
132
130
|
translation_key = if given_class_name == 'Page' || given_class_name.blank?
|
133
|
-
|
134
|
-
|
135
|
-
|
131
|
+
'normal_page'
|
132
|
+
else
|
133
|
+
given_class_name.sub('Page', '').underscore
|
136
134
|
end
|
137
|
-
fallback = given_class_name == 'Page' ? 'Page' : given_class_name.sub('Page','').titleize
|
138
|
-
I18n.t(translation_key, :
|
135
|
+
fallback = given_class_name == 'Page' ? 'Page' : given_class_name.sub('Page', '').titleize
|
136
|
+
I18n.t(translation_key, default: fallback)
|
139
137
|
end
|
140
138
|
end
|
data/app/models/page.rb
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
class Page < ActiveRecord::Base
|
2
|
-
|
3
2
|
class MissingRootPageError < StandardError
|
4
3
|
def initialize(message = 'Database missing root page'); super end
|
5
4
|
end
|
@@ -8,24 +7,24 @@ class Page < ActiveRecord::Base
|
|
8
7
|
before_save :update_virtual, :update_status, :set_allowed_children_cache
|
9
8
|
|
10
9
|
# Associations
|
11
|
-
acts_as_tree :
|
12
|
-
has_many :parts, -> {order(:id)}, :
|
13
|
-
accepts_nested_attributes_for :parts, :
|
14
|
-
has_many :fields, -> {order(:id)}, :
|
15
|
-
accepts_nested_attributes_for :fields, :
|
10
|
+
acts_as_tree order: 'position ASC'
|
11
|
+
has_many :parts, -> { order(:id) }, class_name: 'PagePart', dependent: :destroy
|
12
|
+
accepts_nested_attributes_for :parts, allow_destroy: true
|
13
|
+
has_many :fields, -> { order(:id) }, class_name: 'PageField', dependent: :destroy
|
14
|
+
accepts_nested_attributes_for :fields, allow_destroy: true
|
16
15
|
belongs_to :layout
|
17
|
-
belongs_to :created_by, :
|
18
|
-
belongs_to :updated_by, :
|
16
|
+
belongs_to :created_by, class_name: 'User'
|
17
|
+
belongs_to :updated_by, class_name: 'User'
|
19
18
|
|
20
19
|
# Validations
|
21
20
|
validates_presence_of :title, :slug, :breadcrumb, :status_id
|
22
21
|
|
23
|
-
validates_length_of :title, :
|
24
|
-
validates_length_of :slug, :
|
25
|
-
validates_length_of :breadcrumb, :
|
22
|
+
validates_length_of :title, maximum: 255
|
23
|
+
validates_length_of :slug, maximum: 100
|
24
|
+
validates_length_of :breadcrumb, maximum: 160
|
26
25
|
|
27
|
-
validates_format_of :slug, :
|
28
|
-
validates_uniqueness_of :slug, :
|
26
|
+
validates_format_of :slug, with: %r{\A([-_.A-Za-z0-9]*|/)\z}
|
27
|
+
validates_uniqueness_of :slug, scope: :parent_id
|
29
28
|
|
30
29
|
validate :valid_class_name
|
31
30
|
|
@@ -42,10 +41,10 @@ class Page < ActiveRecord::Base
|
|
42
41
|
self.inheritance_column = 'class_name'
|
43
42
|
|
44
43
|
def layout_with_inheritance
|
45
|
-
|
46
|
-
parent.layout if parent?
|
47
|
-
else
|
44
|
+
if layout_without_inheritance
|
48
45
|
layout_without_inheritance
|
46
|
+
else
|
47
|
+
parent.layout if parent?
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
@@ -53,11 +52,11 @@ class Page < ActiveRecord::Base
|
|
53
52
|
alias_method :layout, :layout_with_inheritance
|
54
53
|
|
55
54
|
def description
|
56
|
-
self[
|
55
|
+
self['description']
|
57
56
|
end
|
58
57
|
|
59
58
|
def description=(value)
|
60
|
-
self[
|
59
|
+
self['description'] = value
|
61
60
|
end
|
62
61
|
|
63
62
|
def cache?
|
@@ -70,8 +69,8 @@ class Page < ActiveRecord::Base
|
|
70
69
|
alias_method :child_url, :child_path
|
71
70
|
|
72
71
|
def part(name)
|
73
|
-
if new_record?
|
74
|
-
parts.to_a.find {|p| p.name == name.to_s }
|
72
|
+
if new_record? || parts.to_a.any?(&:new_record?)
|
73
|
+
parts.to_a.find { |p| p.name == name.to_s }
|
75
74
|
else
|
76
75
|
parts.find_by_name name.to_s
|
77
76
|
end
|
@@ -86,11 +85,11 @@ class Page < ActiveRecord::Base
|
|
86
85
|
end
|
87
86
|
|
88
87
|
def inherits_part?(name)
|
89
|
-
!has_part?(name) &&
|
88
|
+
!has_part?(name) && ancestors.any? { |page| page.has_part?(name) }
|
90
89
|
end
|
91
90
|
|
92
91
|
def field(name)
|
93
|
-
if new_record?
|
92
|
+
if new_record? || fields.any?(&:new_record?)
|
94
93
|
fields.detect { |f| f.name.downcase == name.to_s.downcase }
|
95
94
|
else
|
96
95
|
fields.find_by_name name.to_s
|
@@ -106,7 +105,7 @@ class Page < ActiveRecord::Base
|
|
106
105
|
end
|
107
106
|
|
108
107
|
def status
|
109
|
-
|
108
|
+
Status.find(status_id)
|
110
109
|
end
|
111
110
|
|
112
111
|
def status=(value)
|
@@ -123,7 +122,8 @@ class Page < ActiveRecord::Base
|
|
123
122
|
alias_method :url, :path
|
124
123
|
|
125
124
|
def process(request, response)
|
126
|
-
@request
|
125
|
+
@request = request
|
126
|
+
@response = response
|
127
127
|
set_response_headers(@response)
|
128
128
|
@response.body = render
|
129
129
|
@response.status = response_code
|
@@ -131,12 +131,12 @@ class Page < ActiveRecord::Base
|
|
131
131
|
|
132
132
|
def headers
|
133
133
|
# Return a blank hash that child classes can override or merge
|
134
|
-
{
|
134
|
+
{}
|
135
135
|
end
|
136
136
|
|
137
137
|
def set_response_headers(response)
|
138
138
|
set_content_type(response)
|
139
|
-
headers.each { |k,v| response.headers[k] = v }
|
139
|
+
headers.each { |k, v| response.headers[k] = v }
|
140
140
|
end
|
141
141
|
|
142
142
|
def self.save_order(new_position)
|
@@ -187,11 +187,12 @@ class Page < ActiveRecord::Base
|
|
187
187
|
|
188
188
|
def find_by_path(path, live = true, clean = true)
|
189
189
|
return nil if virtual?
|
190
|
+
|
190
191
|
path = clean_path(path) if clean
|
191
192
|
my_path = self.path
|
192
|
-
if (my_path == path) && (not live
|
193
|
+
if (my_path == path) && ((not live) || published?)
|
193
194
|
return self
|
194
|
-
elsif
|
195
|
+
elsif path =~ /^#{Regexp.quote(my_path)}([^\/]*)/
|
195
196
|
slug_child = children.find_by_slug($1)
|
196
197
|
if slug_child
|
197
198
|
found = slug_child.find_by_path(path, live, clean)
|
@@ -202,6 +203,7 @@ class Page < ActiveRecord::Base
|
|
202
203
|
return found if found
|
203
204
|
end
|
204
205
|
end
|
206
|
+
|
205
207
|
unless slug_child
|
206
208
|
file_not_found_types = ([FileNotFoundPage] + FileNotFoundPage.descendants)
|
207
209
|
file_not_found_names = file_not_found_types.collect { |x| x.name }
|
@@ -214,11 +216,11 @@ class Page < ActiveRecord::Base
|
|
214
216
|
alias_method :find_by_url, :find_by_path
|
215
217
|
|
216
218
|
def update_status
|
217
|
-
self.published_at = Time.zone.now if published? &&
|
219
|
+
self.published_at = Time.zone.now if published? && published_at == nil
|
218
220
|
|
219
|
-
if
|
220
|
-
self[:status_id] = Status[:scheduled].id if
|
221
|
-
self[:status_id] = Status[:published].id if
|
221
|
+
if !published_at.nil? && (published? || scheduled?)
|
222
|
+
self[:status_id] = Status[:scheduled].id if published_at > Time.zone.now
|
223
|
+
self[:status_id] = Status[:published].id if published_at <= Time.zone.now
|
222
224
|
end
|
223
225
|
|
224
226
|
true
|
@@ -237,22 +239,23 @@ class Page < ActiveRecord::Base
|
|
237
239
|
end
|
238
240
|
|
239
241
|
class << self
|
240
|
-
|
241
242
|
def root
|
242
243
|
find_by_parent_id(nil)
|
243
244
|
end
|
244
245
|
|
245
246
|
def find_by_path(path, live = true)
|
246
247
|
raise MissingRootPageError unless root
|
248
|
+
|
247
249
|
root.find_by_path(path, live)
|
248
250
|
end
|
251
|
+
|
249
252
|
def find_by_url(*args)
|
250
253
|
ActiveSupport::Deprecation.warn("`find_by_url' has been deprecated; use `find_by_path' instead.", caller)
|
251
254
|
find_by_path(*args)
|
252
255
|
end
|
253
256
|
|
254
257
|
def date_column_names
|
255
|
-
|
258
|
+
columns.collect { |c| c.name if c.sql_type =~ /(date|time)/ }.compact
|
256
259
|
end
|
257
260
|
|
258
261
|
def display_name(string = nil)
|
@@ -266,7 +269,7 @@ class Page < ActiveRecord::Base
|
|
266
269
|
n.strip
|
267
270
|
end
|
268
271
|
end
|
269
|
-
@display_name = @display_name +
|
272
|
+
@display_name = @display_name + ' - not installed' if missing? && @display_name !~ /not installed/
|
270
273
|
@display_name
|
271
274
|
end
|
272
275
|
|
@@ -286,8 +289,8 @@ class Page < ActiveRecord::Base
|
|
286
289
|
begin
|
287
290
|
p.constantize
|
288
291
|
rescue NameError, LoadError
|
289
|
-
#Rubocop: The use of eval is a serious security risk.
|
290
|
-
#eval(%Q{class #{p} < Page; acts_as_tree; def self.missing?; true end end}, TOPLEVEL_BINDING)
|
292
|
+
# Rubocop: The use of eval is a serious security risk.
|
293
|
+
# eval(%Q{class #{p} < Page; acts_as_tree; def self.missing?; true end end}, TOPLEVEL_BINDING)
|
291
294
|
Rails.logger.error NameError
|
292
295
|
end
|
293
296
|
end
|
@@ -305,12 +308,13 @@ class Page < ActiveRecord::Base
|
|
305
308
|
end
|
306
309
|
|
307
310
|
def is_descendant_class_name?(class_name)
|
308
|
-
(Page.descendants.map(&:to_s) + [nil,
|
311
|
+
(Page.descendants.map(&:to_s) + [nil, '', 'Page']).include?(class_name)
|
309
312
|
end
|
310
313
|
|
311
314
|
def descendant_class(class_name)
|
312
|
-
raise ArgumentError.new(
|
313
|
-
|
315
|
+
raise ArgumentError.new('argument must be a valid descendant of Page') unless is_descendant_class_name?(class_name)
|
316
|
+
|
317
|
+
if ['', nil, 'Page'].include?(class_name)
|
314
318
|
Page
|
315
319
|
else
|
316
320
|
class_name.constantize
|
@@ -323,73 +327,72 @@ class Page < ActiveRecord::Base
|
|
323
327
|
|
324
328
|
private
|
325
329
|
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
end
|
330
|
+
def default_page_parts(config = TrustyCms::Config)
|
331
|
+
default_parts = config['defaults.page.parts'].to_s.strip.split(/\s*,\s*/)
|
332
|
+
default_parts.map do |name|
|
333
|
+
PagePart.new(name: name, filter_id: config['defaults.page.filter'])
|
331
334
|
end
|
335
|
+
end
|
332
336
|
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
end
|
337
|
+
def default_page_fields(config = TrustyCms::Config)
|
338
|
+
default_fields = config['defaults.page.fields'].to_s.strip.split(/\s*,\s*/)
|
339
|
+
default_fields.map do |name|
|
340
|
+
PageField.new(name: name)
|
338
341
|
end
|
342
|
+
end
|
339
343
|
end
|
340
344
|
|
341
345
|
private
|
342
346
|
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
end
|
347
|
-
end
|
348
|
-
|
349
|
-
def update_virtual
|
350
|
-
unless self.class == Page.descendant_class(class_name)
|
351
|
-
self.virtual = Page.descendant_class(class_name).new.virtual?
|
352
|
-
else
|
353
|
-
self.virtual = virtual?
|
354
|
-
end
|
355
|
-
true
|
347
|
+
def valid_class_name
|
348
|
+
unless Page.is_descendant_class_name?(class_name)
|
349
|
+
errors.add :class_name, 'must be set to a valid descendant of Page'
|
356
350
|
end
|
351
|
+
end
|
357
352
|
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
353
|
+
def update_virtual
|
354
|
+
self.virtual = if self.class == Page.descendant_class(class_name)
|
355
|
+
virtual?
|
356
|
+
else
|
357
|
+
Page.descendant_class(class_name).new.virtual?
|
358
|
+
end
|
359
|
+
true
|
360
|
+
end
|
362
361
|
|
363
|
-
|
364
|
-
|
365
|
-
|
362
|
+
def clean_path(path)
|
363
|
+
"/#{path.to_s.strip}".gsub(%r{//+}, '/')
|
364
|
+
end
|
365
|
+
alias_method :clean_url, :clean_path
|
366
366
|
|
367
|
-
|
368
|
-
|
369
|
-
|
370
|
-
false
|
371
|
-
else
|
372
|
-
true
|
373
|
-
end
|
367
|
+
def parent?
|
368
|
+
!parent.nil?
|
369
|
+
end
|
374
370
|
|
375
|
-
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
371
|
+
def database_exists?
|
372
|
+
ActiveRecord::Base.connection
|
373
|
+
rescue ActiveRecord::NoDatabaseError
|
374
|
+
false
|
375
|
+
else
|
376
|
+
true
|
377
|
+
end
|
382
378
|
|
383
|
-
|
384
|
-
|
385
|
-
|
379
|
+
def lazy_initialize_parser_and_context
|
380
|
+
unless @parser && @context
|
381
|
+
@context = PageContext.new(self)
|
382
|
+
@parser = Radius::Parser.new(@context, tag_prefix: 'r')
|
386
383
|
end
|
384
|
+
@parser
|
385
|
+
end
|
387
386
|
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
text
|
393
|
-
end
|
387
|
+
def parse(text)
|
388
|
+
text = '' if text.nil?
|
389
|
+
lazy_initialize_parser_and_context.parse(text)
|
390
|
+
end
|
394
391
|
|
392
|
+
def parse_object(object)
|
393
|
+
text = object.content || ''
|
394
|
+
text = parse(text)
|
395
|
+
text = object.filter.filter(text) if object.respond_to? :filter_id
|
396
|
+
text
|
397
|
+
end
|
395
398
|
end
|