trusty-cms 7.0.39 → 7.0.40
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/Gemfile +1 -0
- data/Gemfile.lock +6 -7
- data/README.md +25 -0
- data/app/assets/builds/trusty_cms/ckeditor5.css +6966 -0
- data/app/assets/builds/trusty_cms/ckeditor5.css.map +7 -0
- data/app/assets/builds/trusty_cms/ckeditor5.js +105634 -0
- data/app/assets/builds/trusty_cms/ckeditor5.js.map +7 -0
- data/app/assets/config/trusty-cms-manifest.js +2 -0
- data/app/assets/javascripts/admin.js +0 -1
- data/app/assets/stylesheets/admin/_ckeditor.css +109 -0
- data/app/assets/stylesheets/admin/main.scss +1 -0
- data/app/assets/stylesheets/admin/partials/_content.scss +2 -0
- data/app/controllers/admin/assets_controller.rb +78 -23
- data/app/controllers/admin/pages_controller.rb +31 -0
- data/app/javascript/trusty_cms/ckeditor5.js +391 -0
- data/app/models/asset.rb +3 -1
- data/app/views/admin/page_parts/_page_part.html.haml +13 -9
- data/app/views/layouts/application.html.haml +6 -0
- data/config/routes.rb +3 -0
- data/lib/generators/trusty_cms/templates/application.rb.erb +0 -1
- data/lib/trusty_cms/engine.rb +5 -8
- data/lib/trusty_cms/version.rb +1 -1
- data/lib/trusty_cms.rb +2 -0
- data/package.json +20 -2
- data/spec/controllers/assets_controller.rb +66 -0
- data/spec/dummy/config/application.rb +1 -1
- data/spec/dummy/config/storage.yml +7 -0
- data/spec/dummy/db/schema.rb +24 -20
- data/spec/fixtures/files/sample.ics +10 -0
- data/spec/fixtures/files/sample.txt +1 -0
- data/spec/models/asset_spec.rb +39 -0
- data/trusty_cms.gemspec +1 -1
- data/yarn.lock +2213 -493
- metadata +21 -15
- data/app/assets/javascripts/ckeditor/config.js +0 -22
- data/app/assets/javascripts/ckeditor/contents.css +0 -0
@@ -17,7 +17,6 @@
|
|
17
17
|
//= require 'jquery-validation/dist/jquery.validate.min'
|
18
18
|
//= require jquery-treetable/jquery.treetable.js
|
19
19
|
//= require_tree './admin/validations'
|
20
|
-
//= require ckeditor/init
|
21
20
|
//= require 'admin/persist.min'
|
22
21
|
//= require 'admin/modernizr'
|
23
22
|
//= require 'admin/datecheck'
|
@@ -0,0 +1,109 @@
|
|
1
|
+
@import url('https://fonts.googleapis.com/css2?family=Oswald&family=PT+Serif:ital,wght@0,400;0,700;1,400&display=swap');
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Lato:ital,wght@0,400;0,700;1,400;1,700&display=swap');
|
3
|
+
|
4
|
+
@media print {
|
5
|
+
body {
|
6
|
+
margin: 0 !important;
|
7
|
+
}
|
8
|
+
}
|
9
|
+
|
10
|
+
:root {
|
11
|
+
--ck-content-font-family: 'Lato';
|
12
|
+
}
|
13
|
+
|
14
|
+
.main-container {
|
15
|
+
font-family: var(--ck-content-font-family);
|
16
|
+
width: fit-content;
|
17
|
+
/* margin-left: auto;
|
18
|
+
margin-right: auto; */
|
19
|
+
}
|
20
|
+
|
21
|
+
.editor-container_classic-editor .editor-container__editor {
|
22
|
+
min-width: 750px;
|
23
|
+
max-width: 1300px;
|
24
|
+
}
|
25
|
+
|
26
|
+
.ck-content {
|
27
|
+
height: 600px;
|
28
|
+
}
|
29
|
+
|
30
|
+
.ck-content h3.category {
|
31
|
+
font-family: 'Oswald';
|
32
|
+
font-size: 20px;
|
33
|
+
font-weight: bold;
|
34
|
+
color: #555;
|
35
|
+
letter-spacing: 10px;
|
36
|
+
margin: 0;
|
37
|
+
padding: 0;
|
38
|
+
}
|
39
|
+
|
40
|
+
.ck-content h2.document-title {
|
41
|
+
font-family: 'Oswald';
|
42
|
+
font-size: 50px;
|
43
|
+
font-weight: bold;
|
44
|
+
margin: 0;
|
45
|
+
padding: 0;
|
46
|
+
border: 0;
|
47
|
+
}
|
48
|
+
|
49
|
+
.ck-content h3.document-subtitle {
|
50
|
+
font-family: 'Oswald';
|
51
|
+
font-size: 20px;
|
52
|
+
color: #555;
|
53
|
+
margin: 0 0 1em;
|
54
|
+
font-weight: bold;
|
55
|
+
padding: 0;
|
56
|
+
}
|
57
|
+
|
58
|
+
.ck-content p.info-box {
|
59
|
+
--background-size: 30px;
|
60
|
+
--background-color: #e91e63;
|
61
|
+
padding: 1.2em 2em;
|
62
|
+
border: 1px solid var(--background-color);
|
63
|
+
background:
|
64
|
+
linear-gradient(135deg, var(--background-color) 0%, var(--background-color) var(--background-size), transparent var(--background-size)),
|
65
|
+
linear-gradient(
|
66
|
+
135deg,
|
67
|
+
transparent calc(100% - var(--background-size)),
|
68
|
+
var(--background-color) calc(100% - var(--background-size)),
|
69
|
+
var(--background-color)
|
70
|
+
);
|
71
|
+
border-radius: 10px;
|
72
|
+
margin: 1.5em 2em;
|
73
|
+
box-shadow: 5px 5px 0 #ffe6ef;
|
74
|
+
}
|
75
|
+
|
76
|
+
.ck-content span.marker {
|
77
|
+
background: yellow;
|
78
|
+
}
|
79
|
+
|
80
|
+
.ck-content span.spoiler {
|
81
|
+
background: #000;
|
82
|
+
color: #000;
|
83
|
+
}
|
84
|
+
|
85
|
+
.ck-content span.spoiler:hover {
|
86
|
+
background: #000;
|
87
|
+
color: #fff;
|
88
|
+
}
|
89
|
+
|
90
|
+
.ck-content .button {
|
91
|
+
display: inline-block;
|
92
|
+
width: 260px;
|
93
|
+
border-radius: 8px;
|
94
|
+
margin: 0 auto;
|
95
|
+
padding: 12px;
|
96
|
+
color: #ffffff;
|
97
|
+
font-size: 24px;
|
98
|
+
font-weight: 700;
|
99
|
+
text-align: center;
|
100
|
+
text-decoration: none;
|
101
|
+
}
|
102
|
+
|
103
|
+
.ck-content .button--green {
|
104
|
+
background-color: #406b1e;
|
105
|
+
}
|
106
|
+
|
107
|
+
.ck-content .button--black {
|
108
|
+
background-color: #141517;
|
109
|
+
}
|
@@ -1,6 +1,7 @@
|
|
1
1
|
class Admin::AssetsController < Admin::ResourceController
|
2
2
|
paginate_models(per_page: 50)
|
3
3
|
COMPRESS_FILE_TYPE = ['image/jpeg', 'image/png', 'image/gif', 'image/svg+xml'].freeze
|
4
|
+
APPROVED_CONTENT_TYPES = Asset::APPROVED_CONTENT_TYPES
|
4
5
|
|
5
6
|
def index
|
6
7
|
assets = Asset.order('created_at DESC')
|
@@ -28,27 +29,41 @@ class Admin::AssetsController < Admin::ResourceController
|
|
28
29
|
end
|
29
30
|
end
|
30
31
|
|
32
|
+
def uploader
|
33
|
+
@page_attachments = []
|
34
|
+
result = process_uploaded_asset(asset_params[:upload])
|
35
|
+
|
36
|
+
if result[:asset]
|
37
|
+
@asset = result[:asset]
|
38
|
+
if params[:for_attachment]
|
39
|
+
@page = Page.find_by_id(params[:page_id]) || Page.new
|
40
|
+
@page_attachments << (@page_attachment = @asset.page_attachments.build(page: @page))
|
41
|
+
end
|
42
|
+
|
43
|
+
render json: { url: @asset.asset.url }
|
44
|
+
else
|
45
|
+
flash[result.fetch(:flash_type, :error)] = result[:error]
|
46
|
+
render json: { error: result[:error] }, status: result.fetch(:status, :unprocessable_entity)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
31
50
|
def create
|
32
51
|
@assets = []
|
33
52
|
@page_attachments = []
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
@asset =
|
41
|
-
if
|
42
|
-
|
43
|
-
|
44
|
-
@page = Page.find_by_id(params[:page_id]) || Page.new
|
45
|
-
@page_attachments << @page_attachment = @asset.page_attachments.build(page: @page)
|
46
|
-
end
|
47
|
-
@assets << @asset
|
48
|
-
else
|
49
|
-
error = @asset.errors.first.message
|
50
|
-
flash[:error] = error
|
53
|
+
uploads = Array(asset_params.dig('asset', 'asset')).reject(&:blank?)
|
54
|
+
|
55
|
+
uploads.each do |uploaded_asset|
|
56
|
+
result = process_uploaded_asset(uploaded_asset)
|
57
|
+
|
58
|
+
if result[:asset]
|
59
|
+
@asset = result[:asset]
|
60
|
+
if params[:for_attachment]
|
61
|
+
@page = Page.find_by_id(params[:page_id]) || Page.new
|
62
|
+
@page_attachments << (@page_attachment = @asset.page_attachments.build(page: @page))
|
51
63
|
end
|
64
|
+
@assets << @asset
|
65
|
+
else
|
66
|
+
flash[result.fetch(:flash_type, :error)] = result[:error]
|
52
67
|
end
|
53
68
|
end
|
54
69
|
|
@@ -72,6 +87,44 @@ class Admin::AssetsController < Admin::ResourceController
|
|
72
87
|
|
73
88
|
private
|
74
89
|
|
90
|
+
def process_uploaded_asset(uploaded_asset)
|
91
|
+
return failure_response('No file uploaded.', :unprocessable_entity, :error) unless uploaded_asset.present?
|
92
|
+
|
93
|
+
if uploaded_asset.content_type == 'application/octet-stream'
|
94
|
+
return failure_response('Please only upload assets that have a valid extension in the name.', :unprocessable_entity, :notice)
|
95
|
+
end
|
96
|
+
|
97
|
+
unless APPROVED_CONTENT_TYPES.include?(uploaded_asset.content_type)
|
98
|
+
return failure_response('Unsupported file type.', :unsupported_media_type, :error)
|
99
|
+
end
|
100
|
+
|
101
|
+
processed_upload = maybe_compress(uploaded_asset)
|
102
|
+
asset = Asset.create(asset: processed_upload, caption: '')
|
103
|
+
|
104
|
+
if asset.valid?
|
105
|
+
set_owner_or_editor(asset)
|
106
|
+
{ asset: asset }
|
107
|
+
else
|
108
|
+
failure_response(asset.errors.full_messages.first, :unprocessable_entity, :error)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def maybe_compress(uploaded_asset)
|
113
|
+
should_compress?(uploaded_asset.content_type) ? compress(uploaded_asset) : uploaded_asset
|
114
|
+
end
|
115
|
+
|
116
|
+
def should_compress?(content_type)
|
117
|
+
$kraken.api_key.present? && COMPRESS_FILE_TYPE.include?(content_type) && compression_enabled?
|
118
|
+
end
|
119
|
+
|
120
|
+
def compression_enabled?
|
121
|
+
current_site.try(:compress).nil? ? true : current_site.compress
|
122
|
+
end
|
123
|
+
|
124
|
+
def failure_response(message, status, flash_type)
|
125
|
+
{ error: message, status: status, flash_type: flash_type }
|
126
|
+
end
|
127
|
+
|
75
128
|
def compress(uploaded_asset)
|
76
129
|
require 'open-uri'
|
77
130
|
data = $kraken.upload(uploaded_asset.tempfile.path, 'lossy' => true)
|
@@ -80,13 +133,15 @@ class Admin::AssetsController < Admin::ResourceController
|
|
80
133
|
uploaded_asset
|
81
134
|
end
|
82
135
|
|
83
|
-
def set_owner_or_editor
|
84
|
-
|
85
|
-
|
86
|
-
|
136
|
+
def set_owner_or_editor(asset = @asset)
|
137
|
+
return unless asset
|
138
|
+
|
139
|
+
asset.created_by_id = current_user.id
|
140
|
+
asset.updated_by_id = current_user.id
|
141
|
+
asset.save! if asset.id.present?
|
87
142
|
end
|
88
143
|
|
89
144
|
def asset_params
|
90
|
-
params.permit(:id, :for_attachment, asset: [:for_attachment, { asset: [] }])
|
145
|
+
params.permit(:id, :upload, :for_attachment, asset: [:for_attachment, { asset: [] }])
|
91
146
|
end
|
92
|
-
end
|
147
|
+
end
|
@@ -2,6 +2,7 @@ class Admin::PagesController < Admin::ResourceController
|
|
2
2
|
before_action :initialize_meta_rows_and_buttons, only: %i[new edit create update]
|
3
3
|
before_action :count_deleted_pages, only: [:destroy]
|
4
4
|
before_action :set_page, only: %i[edit restore]
|
5
|
+
before_action :append_editor_stylesheets, only: %i[new edit create update]
|
5
6
|
rescue_from ActiveRecord::RecordInvalid, with: :validation_error
|
6
7
|
include Admin::PagesHelper
|
7
8
|
include Admin::UrlHelper
|
@@ -181,6 +182,36 @@ class Admin::PagesController < Admin::ResourceController
|
|
181
182
|
raise PreviewStop
|
182
183
|
end
|
183
184
|
|
185
|
+
def append_editor_stylesheets
|
186
|
+
return unless TrustyCms.respond_to?(:editor_stylesheets)
|
187
|
+
|
188
|
+
@stylesheets ||= []
|
189
|
+
@stylesheets |= editor_stylesheets_for_current_site
|
190
|
+
@editor_style_definitions = TrustyCms.editor_style_definitions
|
191
|
+
end
|
192
|
+
|
193
|
+
def editor_stylesheets_for_current_site
|
194
|
+
stylesheets = TrustyCms.editor_stylesheets
|
195
|
+
return stylesheets unless respond_to?(:current_site) && current_site.present?
|
196
|
+
|
197
|
+
stylesheets.filter_map do |entry|
|
198
|
+
site_key, path =
|
199
|
+
case entry
|
200
|
+
when Hash
|
201
|
+
[entry[:site], entry[:path]]
|
202
|
+
else
|
203
|
+
[nil, entry] # backward compatibility with plain strings
|
204
|
+
end
|
205
|
+
|
206
|
+
next path if site_key.blank? # global stylesheet
|
207
|
+
next path if site_key.to_s == identifier_for(current_site)
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
def identifier_for(site)
|
212
|
+
current_site.try(:name)&.downcase.gsub(' ', '_')
|
213
|
+
end
|
214
|
+
|
184
215
|
def count_deleted_pages
|
185
216
|
@count = model.children.count + 1
|
186
217
|
end
|