katalyst-content 3.2.2 → 3.3.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/README.md +5 -227
- data/app/models/concerns/katalyst/content/duplicates_associations.rb +79 -0
- data/app/models/concerns/katalyst/content/duplicates_attachments.rb +81 -0
- data/app/models/concerns/katalyst/content/duplicates_rich_text.rb +40 -0
- data/app/models/katalyst/content/content.rb +0 -6
- data/app/models/katalyst/content/figure.rb +0 -11
- data/app/models/katalyst/content/item.rb +3 -0
- data/app/models/katalyst/content/table.rb +0 -10
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 67386b67c7add01c35e38a9a2615c09fb56dbc3a77f74289671e3df3539e82ef
|
|
4
|
+
data.tar.gz: efbadc3abde98aaf0591b9ac8566c982b1d3c3094f7375b2e4555d8e21a269a9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 74d3ac936c53778bee4c15cac9ced3ae219eb00f7338aba68d8ac713844e7a83fd74ee0a195b21fba03880fd8ad2a0d5e39f2e3d03f50931088de7134a263dba
|
|
7
|
+
data.tar.gz: 4649815a1c692d4b1d6ab7e30c99b4a76e605dbbe8f2771415a5e44eb90cbb716e55e3d46336e67a68530f33051f7e51e50781c5387a60438f930ebadad35377
|
data/README.md
CHANGED
|
@@ -1,232 +1,10 @@
|
|
|
1
|
-
# Katalyst
|
|
1
|
+
# Katalyst Content
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
applications.
|
|
3
|
+
A library for editing and publishing rich content in Ruby on Rails.
|
|
5
4
|
|
|
6
|
-
##
|
|
5
|
+
## Documentation
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
```ruby
|
|
11
|
-
gem "katalyst-content"
|
|
12
|
-
```
|
|
13
|
-
|
|
14
|
-
Mount the engine in your `routes.rb` file:
|
|
15
|
-
|
|
16
|
-
```ruby
|
|
17
|
-
mount Katalyst::Content::Engine, at: "content"
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
Add the Gem's migrations to your application:
|
|
21
|
-
|
|
22
|
-
```ruby
|
|
23
|
-
rake katalyst_content:install:migrations
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
Add the Gem's javascript and CSS to your build pipeline. This assumes that
|
|
27
|
-
you're using `propshaft` and `importmaps` to manage your assets.
|
|
28
|
-
|
|
29
|
-
```javascript
|
|
30
|
-
// app/javascript/controllers/application.js
|
|
31
|
-
import { application } from "controllers/application";
|
|
32
|
-
import content from "@katalyst/content";
|
|
33
|
-
application.load(content);
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
Import the editor styles as css:
|
|
37
|
-
|
|
38
|
-
```css
|
|
39
|
-
/** In your admin/editor */
|
|
40
|
-
@import url("/katalyst/content/editor.css");
|
|
41
|
-
/** In your frontend */
|
|
42
|
-
@import url("/katalyst/content/frontend.css");
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
Or, if you're using `dartsass-rails`:
|
|
46
|
-
|
|
47
|
-
```scss
|
|
48
|
-
// app/assets/stylesheets/admin.scss
|
|
49
|
-
@use "katalyst/content/editor";
|
|
50
|
-
// app/assets/stylesheets/application.scss
|
|
51
|
-
@use "katalyst/content/frontend";
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
## Usage
|
|
55
|
-
|
|
56
|
-
Content can be added to multiple models in your application. These examples
|
|
57
|
-
assume a `Page` model.
|
|
58
|
-
|
|
59
|
-
Assuming your model already exists, create a table for versions and add
|
|
60
|
-
published and draft version columns to your model. For example, if you have a
|
|
61
|
-
pages model:
|
|
62
|
-
|
|
63
|
-
```ruby
|
|
64
|
-
class CreatePageVersions < ActiveRecord::Migration[7.0]
|
|
65
|
-
def change
|
|
66
|
-
create_table :page_versions do |t|
|
|
67
|
-
t.references :parent, foreign_key: { to_table: :pages }, null: false
|
|
68
|
-
t.json :nodes
|
|
69
|
-
|
|
70
|
-
t.timestamps
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
change_table :pages do |t|
|
|
74
|
-
t.references :published_version, foreign_key: { to_table: :page_versions }
|
|
75
|
-
t.references :draft_version, foreign_key: { to_table: :page_versions }
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
If you don't have a pages model yet, add it before the page_versions change:
|
|
82
|
-
```ruby
|
|
83
|
-
class CreatePages < ActiveRecord::Migration[7.0]
|
|
84
|
-
def change
|
|
85
|
-
create_table :pages do |t|
|
|
86
|
-
t.string :title
|
|
87
|
-
t.string :slug
|
|
88
|
-
t.boolean :show_title, default: true, null: false
|
|
89
|
-
|
|
90
|
-
t.timestamps
|
|
91
|
-
end
|
|
92
|
-
add_index :pages, :slug, unique: true
|
|
93
|
-
|
|
94
|
-
create_table :page_versions do |t|
|
|
95
|
-
t.references :parent, foreign_key: { to_table: :pages }, null: false
|
|
96
|
-
t.json :nodes
|
|
97
|
-
|
|
98
|
-
t.timestamps
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
change_table :pages do |t|
|
|
102
|
-
t.references :published_version, foreign_key: { to_table: :page_versions }
|
|
103
|
-
t.references :draft_version, foreign_key: { to_table: :page_versions }
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
Next, include the `Katalyst::Content` concerns into your model, and add a nested
|
|
111
|
-
model for storing content version information:
|
|
112
|
-
|
|
113
|
-
```ruby
|
|
114
|
-
class Page < ApplicationRecord
|
|
115
|
-
include Katalyst::Content::Container
|
|
116
|
-
|
|
117
|
-
class Version < ApplicationRecord
|
|
118
|
-
include Katalyst::Content::Version
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
You may also want to configure your factory to add container information to
|
|
124
|
-
items:
|
|
125
|
-
|
|
126
|
-
```ruby
|
|
127
|
-
FactoryBot.define do
|
|
128
|
-
factory :page do
|
|
129
|
-
title { Faker::Beer.unique.name }
|
|
130
|
-
slug { title.parameterize }
|
|
131
|
-
|
|
132
|
-
after(:build) do |page, _context|
|
|
133
|
-
page.items.each { |item| item.container = page }
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
after(:create) do |page, _context|
|
|
137
|
-
page.items_attributes = page.items.map.with_index { |item, index| { id: item.id, index: index, depth: 0 } }
|
|
138
|
-
page.publish!
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
end
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
Create a controller for editing content. This example assumes you're rendering the editor on the 'show' route of an
|
|
145
|
-
admin controller.
|
|
146
|
-
|
|
147
|
-
```ruby
|
|
148
|
-
class Admin::PagesController < Admin::BaseController
|
|
149
|
-
before_action :set_page, only: %i[show update]
|
|
150
|
-
|
|
151
|
-
def show; end
|
|
152
|
-
|
|
153
|
-
def update
|
|
154
|
-
@page.attributes = page_params
|
|
155
|
-
|
|
156
|
-
unless @page.valid?
|
|
157
|
-
return respond_to do |format|
|
|
158
|
-
format.turbo_stream { render @editor.errors, status: :unprocessable_entity }
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
case params[:commit]
|
|
163
|
-
when "publish"
|
|
164
|
-
@page.save!
|
|
165
|
-
@page.publish!
|
|
166
|
-
when "save"
|
|
167
|
-
@page.save!
|
|
168
|
-
when "revert"
|
|
169
|
-
@page.revert!
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
redirect_to [:admin, @page], status: :see_other
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
private
|
|
176
|
-
|
|
177
|
-
def set_page
|
|
178
|
-
@page = Page.find(params[:id])
|
|
179
|
-
@editor = Katalyst::Content::EditorComponent.new(container: @page)
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
def page_params
|
|
183
|
-
params.require(:page).permit(items_attributes: %i[id index depth])
|
|
184
|
-
end
|
|
185
|
-
end
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
And the view:
|
|
189
|
-
|
|
190
|
-
```erb
|
|
191
|
-
<%# app/views/admin/pages/show.html.erb %>
|
|
192
|
-
<%= render @editor.status_bar %>
|
|
193
|
-
<%= render @editor %>
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### New items dialog customisation
|
|
197
|
-
|
|
198
|
-
The new items dialog can be customised by providing content to the ViewComponent slot:
|
|
199
|
-
|
|
200
|
-
```erb
|
|
201
|
-
<%# app/views/admin/pages/show.html.erb %>
|
|
202
|
-
<%= render @editor.status_bar %>
|
|
203
|
-
<%= render @editor do |editor_component| %>
|
|
204
|
-
<% editor_component.with_new_items do |component| %>
|
|
205
|
-
<h3>Layouts</h3>
|
|
206
|
-
<ul role="list" class="items-list">
|
|
207
|
-
<%= component.item(:section) %>
|
|
208
|
-
<%= component.item(:group) %>
|
|
209
|
-
<%= component.item(:column) %>
|
|
210
|
-
<%= component.item(:aside) %>
|
|
211
|
-
</ul>
|
|
212
|
-
<h3>Content</h3>
|
|
213
|
-
<ul role="list" class="items-list">
|
|
214
|
-
<%= component.item(:content) %>
|
|
215
|
-
<%= component.item(:figure) %>
|
|
216
|
-
<%= component.item(:table) %>
|
|
217
|
-
</ul>
|
|
218
|
-
<% end %>
|
|
219
|
-
<% end %>
|
|
220
|
-
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
## Development
|
|
224
|
-
|
|
225
|
-
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake` to run the tests.
|
|
226
|
-
|
|
227
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the
|
|
228
|
-
version number and run `bundle exec rake release`, which will create a git tag for the version, push git commits and
|
|
229
|
-
the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
7
|
+
See [katalyst.github.io/content](https://katalyst.github.io/content/) for documentation.
|
|
230
8
|
|
|
231
9
|
## Contributing
|
|
232
10
|
|
|
@@ -234,4 +12,4 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/kataly
|
|
|
234
12
|
|
|
235
13
|
## License
|
|
236
14
|
|
|
237
|
-
|
|
15
|
+
Katalyst Content is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Katalyst
|
|
4
|
+
module Content
|
|
5
|
+
# Copies declared associations when a record is duplicated, e.g. for
|
|
6
|
+
# copy-on-write. Intended for owned detail records that extend an STI
|
|
7
|
+
# item with attributes beyond the shared table:
|
|
8
|
+
#
|
|
9
|
+
# has_one :detail, as: :detailable, autosave: true, dependent: :destroy
|
|
10
|
+
# accepts_nested_attributes_for :detail, update_only: true
|
|
11
|
+
# duplicates_association :detail
|
|
12
|
+
#
|
|
13
|
+
# Unsaved changes on the source's association are carried over to the
|
|
14
|
+
# duplicate. Records marked for destruction are dropped.
|
|
15
|
+
module DuplicatesAssociations
|
|
16
|
+
extend ActiveSupport::Concern
|
|
17
|
+
|
|
18
|
+
included do
|
|
19
|
+
class_attribute :duplicated_associations, instance_writer: false, default: []
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
class_methods do
|
|
23
|
+
def duplicates_association(*names)
|
|
24
|
+
self.duplicated_associations += names.map(&:to_sym)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def initialize_dup(source)
|
|
29
|
+
super
|
|
30
|
+
|
|
31
|
+
duplicated_associations.each do |name|
|
|
32
|
+
macro = self.class.reflect_on_association(name).macro
|
|
33
|
+
DUPLICATORS.fetch(macro).new(name).apply(source, self)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Duplicates a has_one association from source to target.
|
|
38
|
+
# Public API: can be used directly for models that want to duplicate a
|
|
39
|
+
# specific association without including the concern, e.g.
|
|
40
|
+
# DuplicatesAssociations::DupOne.new(:detail).apply(source, self)
|
|
41
|
+
class DupOne
|
|
42
|
+
attr_reader :name
|
|
43
|
+
|
|
44
|
+
def initialize(name)
|
|
45
|
+
@name = name
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def apply(source, target)
|
|
49
|
+
record = source.public_send(name)
|
|
50
|
+
|
|
51
|
+
target.public_send("#{name}=", record.dup) unless record.nil? || record.marked_for_destruction?
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Duplicates a has_many association from source to target.
|
|
56
|
+
# Public API: can be used directly for models that want to duplicate a
|
|
57
|
+
# specific association without including the concern, e.g.
|
|
58
|
+
# DuplicatesAssociations::DupMany.new(:notes).apply(source, self)
|
|
59
|
+
class DupMany
|
|
60
|
+
attr_reader :name
|
|
61
|
+
|
|
62
|
+
def initialize(name)
|
|
63
|
+
@name = name
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def apply(source, target)
|
|
67
|
+
records = source.public_send(name).reject(&:marked_for_destruction?).map(&:dup)
|
|
68
|
+
|
|
69
|
+
target.public_send("#{name}=", records) if records.any?
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
DUPLICATORS = {
|
|
74
|
+
has_one: DupOne,
|
|
75
|
+
has_many: DupMany,
|
|
76
|
+
}.freeze
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Katalyst
|
|
4
|
+
module Content
|
|
5
|
+
# Copies ActiveStorage attachments when a record is duplicated, e.g. for
|
|
6
|
+
# copy-on-write. Pending changes on the source are carried over: new
|
|
7
|
+
# uploads are copied to the duplicate, while attachments that are being
|
|
8
|
+
# removed (either by assigning "" as govuk_attachment_field does, or via
|
|
9
|
+
# nested attributes with _destroy) are dropped from the duplicate.
|
|
10
|
+
module DuplicatesAttachments
|
|
11
|
+
extend ActiveSupport::Concern
|
|
12
|
+
|
|
13
|
+
def initialize_dup(source)
|
|
14
|
+
super
|
|
15
|
+
|
|
16
|
+
self.class.reflect_on_all_attachments.each do |reflection|
|
|
17
|
+
DUPLICATORS.fetch(reflection.macro).new(reflection.name).apply(source, self)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Duplicates a has_one_attached attachment from source to target.
|
|
22
|
+
# Public API: can be used directly for models that want to duplicate a
|
|
23
|
+
# specific attachment without including the concern, e.g.
|
|
24
|
+
# DuplicatesAttachments::DupOne.new(:image).apply(source, self)
|
|
25
|
+
class DupOne
|
|
26
|
+
attr_reader :name
|
|
27
|
+
|
|
28
|
+
def initialize(name)
|
|
29
|
+
@name = name.to_s
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def apply(source, target)
|
|
33
|
+
current = source.public_send(name)
|
|
34
|
+
change = source.attachment_changes[name]
|
|
35
|
+
|
|
36
|
+
# if attachment has changed, duplicate the change, otherwise attach the existing blob
|
|
37
|
+
if change.is_a?(ActiveStorage::Attached::Changes::CreateOne)
|
|
38
|
+
target.public_send("#{name}=", change.attachable)
|
|
39
|
+
elsif change.is_a?(ActiveStorage::Attached::Changes::DeleteOne) ||
|
|
40
|
+
current.attachment&.marked_for_destruction?
|
|
41
|
+
# no-op, drop the attachment, if any
|
|
42
|
+
elsif current.attached?
|
|
43
|
+
target.public_send("#{name}=", current.blob)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Duplicates has_many_attached attachments from source to target.
|
|
49
|
+
# Public API: can be used directly for models that want to duplicate a
|
|
50
|
+
# specific attachment without including the concern, e.g.
|
|
51
|
+
# DuplicatesAttachments::DupMany.new(:slides).apply(source, self)
|
|
52
|
+
class DupMany
|
|
53
|
+
attr_reader :name
|
|
54
|
+
|
|
55
|
+
def initialize(name)
|
|
56
|
+
@name = name.to_s
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def apply(source, target)
|
|
60
|
+
current = source.public_send(name)
|
|
61
|
+
change = source.attachment_changes[name]
|
|
62
|
+
|
|
63
|
+
# if attachments have changed, duplicate the change, otherwise attach the existing blobs
|
|
64
|
+
if change.is_a?(ActiveStorage::Attached::Changes::CreateMany)
|
|
65
|
+
target.public_send("#{name}=", change.attachables)
|
|
66
|
+
elsif change.is_a?(ActiveStorage::Attached::Changes::DeleteMany)
|
|
67
|
+
# no-op, drop the attachments, if any
|
|
68
|
+
elsif current.attached?
|
|
69
|
+
blobs = current.attachments.reject(&:marked_for_destruction?).map(&:blob)
|
|
70
|
+
target.public_send("#{name}=", blobs) if blobs.any?
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
DUPLICATORS = {
|
|
76
|
+
has_one_attached: DupOne,
|
|
77
|
+
has_many_attached: DupMany,
|
|
78
|
+
}.freeze
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Katalyst
|
|
4
|
+
module Content
|
|
5
|
+
# Copies ActionText rich text attributes when a record is duplicated,
|
|
6
|
+
# e.g. for copy-on-write. Unsaved changes on the source are carried over
|
|
7
|
+
# to the duplicate.
|
|
8
|
+
module DuplicatesRichText
|
|
9
|
+
extend ActiveSupport::Concern
|
|
10
|
+
|
|
11
|
+
def initialize_dup(source)
|
|
12
|
+
super
|
|
13
|
+
|
|
14
|
+
self.class.rich_text_association_names.each do |association|
|
|
15
|
+
DupRichText.new(association.to_s.delete_prefix("rich_text_")).apply(source, self)
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Duplicates a has_rich_text attribute from source to target.
|
|
20
|
+
# Public API: can be used directly for models that want to duplicate a
|
|
21
|
+
# specific rich text attribute without including the concern, e.g.
|
|
22
|
+
# DuplicatesRichText::DupRichText.new(:subtitle).apply(source, self)
|
|
23
|
+
class DupRichText
|
|
24
|
+
attr_reader :name
|
|
25
|
+
|
|
26
|
+
def initialize(name)
|
|
27
|
+
@name = name.to_s
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def apply(source, target)
|
|
31
|
+
rich_text = source.public_send("rich_text_#{name}")
|
|
32
|
+
|
|
33
|
+
# copy via body assignment so that custom attribute writers
|
|
34
|
+
# (e.g. Table#content=) are not re-run on the duplicate
|
|
35
|
+
target.public_send(name).body = rich_text.body if rich_text
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
@@ -9,12 +9,6 @@ module Katalyst
|
|
|
9
9
|
|
|
10
10
|
default_scope { with_rich_text_content }
|
|
11
11
|
|
|
12
|
-
def initialize_copy(source)
|
|
13
|
-
super
|
|
14
|
-
|
|
15
|
-
self.content = source.content&.body if source.content.is_a?(ActionText::RichText)
|
|
16
|
-
end
|
|
17
|
-
|
|
18
12
|
def self.permitted_params
|
|
19
13
|
super + %i[content]
|
|
20
14
|
end
|
|
@@ -12,17 +12,6 @@ module Katalyst
|
|
|
12
12
|
|
|
13
13
|
default_scope { with_attached_image }
|
|
14
14
|
|
|
15
|
-
def initialize_dup(source)
|
|
16
|
-
super
|
|
17
|
-
|
|
18
|
-
# if image has changed, duplicate the change, otherwise attach the existing blob
|
|
19
|
-
if source.attachment_changes["image"]
|
|
20
|
-
self.image = source.attachment_changes["image"].attachable
|
|
21
|
-
elsif source.image.attached? && !source.image.marked_for_destruction?
|
|
22
|
-
image.attach(source.image.blob)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
15
|
def self.permitted_params
|
|
27
16
|
super - %i[heading_style] + %i[image caption]
|
|
28
17
|
end
|
|
@@ -14,20 +14,10 @@ module Katalyst
|
|
|
14
14
|
|
|
15
15
|
after_initialize :set_defaults
|
|
16
16
|
|
|
17
|
-
def initialize_copy(source)
|
|
18
|
-
super
|
|
19
|
-
|
|
20
|
-
content.body = source.content&.body if source.content.is_a?(ActionText::RichText)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
17
|
def self.permitted_params
|
|
24
18
|
super + %i[content heading_rows heading_columns]
|
|
25
19
|
end
|
|
26
20
|
|
|
27
|
-
def valid?(context = nil)
|
|
28
|
-
super
|
|
29
|
-
end
|
|
30
|
-
|
|
31
21
|
def to_plain_text
|
|
32
22
|
content.to_plain_text if visible?
|
|
33
23
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: katalyst-content
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Katalyst Interactive
|
|
@@ -153,6 +153,9 @@ files:
|
|
|
153
153
|
- app/javascript/content/editor/status_bar_controller.js
|
|
154
154
|
- app/javascript/content/editor/table_controller.js
|
|
155
155
|
- app/models/concerns/katalyst/content/container.rb
|
|
156
|
+
- app/models/concerns/katalyst/content/duplicates_associations.rb
|
|
157
|
+
- app/models/concerns/katalyst/content/duplicates_attachments.rb
|
|
158
|
+
- app/models/concerns/katalyst/content/duplicates_rich_text.rb
|
|
156
159
|
- app/models/concerns/katalyst/content/garbage_collection.rb
|
|
157
160
|
- app/models/concerns/katalyst/content/has_style.rb
|
|
158
161
|
- app/models/concerns/katalyst/content/has_tree.rb
|