iron-cms 0.1.2 → 0.2.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 +26 -0
- data/app/assets/builds/iron.css +9 -0
- data/app/controllers/iron/contents_controller.rb +33 -0
- data/app/models/concerns/iron/instance_scoped.rb +25 -0
- data/app/models/iron/account.rb +2 -0
- data/app/models/iron/archive.rb +69 -0
- data/app/models/iron/block_definition.rb +8 -0
- data/app/models/iron/content_export.rb +73 -0
- data/app/models/iron/content_import/entry_builder.rb +77 -0
- data/app/models/iron/content_import/entry_snapshot.rb +23 -0
- data/app/models/iron/content_import/field_reconstructor.rb +276 -0
- data/app/models/iron/content_import/field_snapshot.rb +33 -0
- data/app/models/iron/content_import/registry.rb +32 -0
- data/app/models/iron/content_import/session.rb +89 -0
- data/app/models/iron/content_import.rb +15 -0
- data/app/models/iron/content_type.rb +8 -0
- data/app/models/iron/current.rb +2 -1
- data/app/models/iron/entry/portable.rb +35 -0
- data/app/models/iron/entry.rb +1 -1
- data/app/models/iron/field/portable.rb +33 -0
- data/app/models/iron/field.rb +1 -1
- data/app/models/iron/field_definition/portable.rb +12 -6
- data/app/models/iron/fields/block.rb +22 -8
- data/app/models/iron/fields/block_list.rb +10 -0
- data/app/models/iron/fields/boolean.rb +10 -0
- data/app/models/iron/fields/date.rb +10 -0
- data/app/models/iron/fields/file.rb +8 -0
- data/app/models/iron/fields/number.rb +10 -0
- data/app/models/iron/fields/reference.rb +10 -0
- data/app/models/iron/fields/reference_list.rb +14 -0
- data/app/models/iron/fields/rich_text_area.rb +26 -0
- data/app/models/iron/fields/text_area.rb +10 -0
- data/app/models/iron/fields/text_field.rb +8 -0
- data/app/models/iron/locale.rb +1 -1
- data/app/models/iron/schema_importer/import_strategy.rb +59 -0
- data/app/models/iron/schema_importer/merge_strategy.rb +52 -0
- data/app/models/iron/schema_importer/replace_strategy.rb +51 -0
- data/app/models/iron/schema_importer/safe_strategy.rb +55 -0
- data/app/models/iron/schema_importer.rb +29 -199
- data/app/views/iron/contents/new.html.erb +34 -0
- data/app/views/iron/settings/show.html.erb +19 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20250908203158_add_instance_token_to_iron_accounts.rb +6 -0
- data/lib/iron/engine.rb +9 -0
- data/lib/iron/global_id/instance_scoped_locator.rb +29 -0
- data/lib/iron/version.rb +1 -1
- data/lib/iron-cms.rb +1 -1
- data/lib/iron.rb +1 -0
- metadata +21 -1
@@ -0,0 +1,51 @@
|
|
1
|
+
module Iron
|
2
|
+
class SchemaImporter::ReplaceStrategy < SchemaImporter::ImportStrategy
|
3
|
+
def import_block_definition(row)
|
4
|
+
BlockDefinition.create!(
|
5
|
+
handle: row["handle"],
|
6
|
+
name: row["name"],
|
7
|
+
description: row["description"]
|
8
|
+
)
|
9
|
+
end
|
10
|
+
|
11
|
+
def import_content_type(row)
|
12
|
+
content_type_class(row["type"]).create!(
|
13
|
+
handle: row["handle"],
|
14
|
+
name: row["name"],
|
15
|
+
description: row["description"],
|
16
|
+
icon: row["icon"],
|
17
|
+
web_publishing_enabled: row["web_publishing_enabled"] == "true",
|
18
|
+
base_path: row["base_path"]
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
def import_field_definition(row)
|
23
|
+
raise "Field type is required" unless row["type"].present?
|
24
|
+
return unless row["parent_type"].present? && row["parent_handle"].present? && row["handle"].present?
|
25
|
+
|
26
|
+
parent = find_parent(row["parent_type"], row["parent_handle"])
|
27
|
+
return unless parent
|
28
|
+
|
29
|
+
parent.field_definitions.find_by(handle: row["handle"])&.destroy!
|
30
|
+
|
31
|
+
klass = field_definition_class(row["type"])
|
32
|
+
attributes = {
|
33
|
+
schemable: parent,
|
34
|
+
handle: row["handle"],
|
35
|
+
name: row["name"],
|
36
|
+
rank: row["rank"],
|
37
|
+
metadata: parse_metadata(row["metadata"])
|
38
|
+
}
|
39
|
+
|
40
|
+
if klass <= FieldDefinitions::Block || klass <= FieldDefinitions::BlockList
|
41
|
+
attributes[:supported_block_definition_ids] = parse_supported_block_definitions(row["supported_block_definitions"]).pluck(:id)
|
42
|
+
end
|
43
|
+
|
44
|
+
if klass <= FieldDefinitions::Reference || klass <= FieldDefinitions::ReferenceList
|
45
|
+
attributes[:supported_content_type_ids] = parse_supported_content_types(row["supported_content_types"]).pluck(:id)
|
46
|
+
end
|
47
|
+
|
48
|
+
klass.create!(attributes)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module Iron
|
2
|
+
class SchemaImporter::SafeStrategy < SchemaImporter::ImportStrategy
|
3
|
+
def import_block_definition(row)
|
4
|
+
return if BlockDefinition.exists?(handle: row["handle"])
|
5
|
+
|
6
|
+
BlockDefinition.create!(
|
7
|
+
handle: row["handle"],
|
8
|
+
name: row["name"],
|
9
|
+
description: row["description"]
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
def import_content_type(row)
|
14
|
+
return if ContentType.exists?(handle: row["handle"])
|
15
|
+
|
16
|
+
content_type_class(row["type"]).create!(
|
17
|
+
handle: row["handle"],
|
18
|
+
name: row["name"],
|
19
|
+
description: row["description"],
|
20
|
+
icon: row["icon"],
|
21
|
+
web_publishing_enabled: row["web_publishing_enabled"] == "true",
|
22
|
+
base_path: row["base_path"]
|
23
|
+
)
|
24
|
+
end
|
25
|
+
|
26
|
+
def import_field_definition(row)
|
27
|
+
raise "Field type is required" unless row["type"].present?
|
28
|
+
return unless row["parent_type"].present? && row["parent_handle"].present? && row["handle"].present?
|
29
|
+
|
30
|
+
parent = find_parent(row["parent_type"], row["parent_handle"])
|
31
|
+
return unless parent
|
32
|
+
|
33
|
+
return if parent.field_definitions.exists?(handle: row["handle"])
|
34
|
+
|
35
|
+
klass = field_definition_class(row["type"])
|
36
|
+
attributes = {
|
37
|
+
schemable: parent,
|
38
|
+
handle: row["handle"],
|
39
|
+
name: row["name"],
|
40
|
+
rank: row["rank"],
|
41
|
+
metadata: parse_metadata(row["metadata"])
|
42
|
+
}
|
43
|
+
|
44
|
+
if klass <= FieldDefinitions::Block || klass <= FieldDefinitions::BlockList
|
45
|
+
attributes[:supported_block_definition_ids] = parse_supported_block_definitions(row["supported_block_definitions"]).pluck(:id)
|
46
|
+
end
|
47
|
+
|
48
|
+
if klass <= FieldDefinitions::Reference || klass <= FieldDefinitions::ReferenceList
|
49
|
+
attributes[:supported_content_type_ids] = parse_supported_content_types(row["supported_content_types"]).pluck(:id)
|
50
|
+
end
|
51
|
+
|
52
|
+
klass.create!(attributes)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -11,16 +11,16 @@ module Iron
|
|
11
11
|
end
|
12
12
|
|
13
13
|
def initialize(file, mode: "merge")
|
14
|
+
raise ArgumentError, "Missing import file" unless file.present?
|
15
|
+
raise ArgumentError, "Invalid import mode: #{mode}. Must be one of: #{IMPORT_MODES.join(', ')}" unless IMPORT_MODES.include?(mode)
|
16
|
+
|
14
17
|
@file = file
|
15
18
|
@mode = mode.to_s
|
16
19
|
@errors = []
|
17
|
-
|
18
|
-
validate_mode!
|
20
|
+
@strategy = build_strategy(mode)
|
19
21
|
end
|
20
22
|
|
21
23
|
def import
|
22
|
-
return ImportResult.new(false, errors) unless valid?
|
23
|
-
|
24
24
|
ActiveRecord::Base.transaction do
|
25
25
|
Account.clear_schema! if mode == "replace"
|
26
26
|
|
@@ -31,205 +31,45 @@ module Iron
|
|
31
31
|
return ImportResult.new(false, errors)
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
update_content_type_references(archive["content_types.csv"])
|
39
|
-
|
40
|
-
ImportResult.new(true, [])
|
41
|
-
end
|
42
|
-
rescue StandardError => e
|
43
|
-
errors << "Import failed: #{e.message}"
|
44
|
-
ImportResult.new(false, errors)
|
45
|
-
end
|
46
|
-
|
47
|
-
private
|
48
|
-
|
49
|
-
def valid?
|
50
|
-
validate_file_presence
|
51
|
-
errors.empty?
|
52
|
-
end
|
53
|
-
|
54
|
-
def validate_mode!
|
55
|
-
unless IMPORT_MODES.include?(mode)
|
56
|
-
raise ArgumentError, "Invalid import mode: #{mode}. Must be one of: #{IMPORT_MODES.join(', ')}"
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def validate_file_presence
|
61
|
-
errors << "No file provided" unless file
|
62
|
-
end
|
63
|
-
|
64
|
-
def import_block_definitions(csv_content)
|
65
|
-
return unless csv_content
|
66
|
-
|
67
|
-
CSV.parse(csv_content, headers: true) do |row|
|
68
|
-
handle = row["handle"]
|
69
|
-
next unless handle.present?
|
70
|
-
|
71
|
-
case mode
|
72
|
-
when "merge"
|
73
|
-
block_def = BlockDefinition.find_or_initialize_by(handle: handle)
|
74
|
-
block_def.assign_attributes(
|
75
|
-
name: row["name"],
|
76
|
-
description: row["description"]
|
77
|
-
)
|
78
|
-
block_def.save!
|
79
|
-
when "replace"
|
80
|
-
BlockDefinition.create!(
|
81
|
-
handle: handle,
|
82
|
-
name: row["name"],
|
83
|
-
description: row["description"]
|
84
|
-
)
|
85
|
-
when "safe"
|
86
|
-
next if BlockDefinition.exists?(handle: handle)
|
87
|
-
|
88
|
-
BlockDefinition.create!(
|
89
|
-
handle: handle,
|
90
|
-
name: row["name"],
|
91
|
-
description: row["description"]
|
92
|
-
)
|
34
|
+
if archive["block_definitions.csv"]
|
35
|
+
CSV.parse(archive["block_definitions.csv"], headers: true) do |row|
|
36
|
+
next unless row["handle"].present?
|
37
|
+
@strategy.import_block_definition(row)
|
93
38
|
end
|
94
39
|
end
|
95
|
-
end
|
96
40
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
handle = row["handle"]
|
102
|
-
next unless handle.present?
|
103
|
-
|
104
|
-
case mode
|
105
|
-
when "merge"
|
106
|
-
content_type = ContentType.find_or_initialize_by(handle: handle)
|
107
|
-
update_content_type(content_type, row)
|
108
|
-
when "replace"
|
109
|
-
content_type = build_content_type(row)
|
110
|
-
content_type.save!
|
111
|
-
when "safe"
|
112
|
-
next if ContentType.exists?(handle: handle)
|
113
|
-
|
114
|
-
content_type = build_content_type(row)
|
115
|
-
content_type.save!
|
41
|
+
if archive["content_types.csv"]
|
42
|
+
CSV.parse(archive["content_types.csv"], headers: true) do |row|
|
43
|
+
next unless row["handle"].present?
|
44
|
+
@strategy.import_content_type(row)
|
116
45
|
end
|
117
46
|
end
|
118
|
-
end
|
119
|
-
|
120
|
-
def import_field_definitions(csv_content)
|
121
|
-
return unless csv_content
|
122
|
-
|
123
|
-
CSV.parse(csv_content, headers: true) do |row|
|
124
|
-
parent_type = row["parent_type"]
|
125
|
-
parent_handle = row["parent_handle"]
|
126
|
-
handle = row["handle"]
|
127
47
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
next unless parent
|
132
|
-
|
133
|
-
case mode
|
134
|
-
when "merge"
|
135
|
-
field_def = parent.field_definitions.find_or_initialize_by(handle: handle)
|
136
|
-
update_field_definition(field_def, row)
|
137
|
-
when "replace"
|
138
|
-
field_def = build_field_definition(parent, row)
|
139
|
-
field_def.save!
|
140
|
-
when "safe"
|
141
|
-
next if parent.field_definitions.exists?(handle: handle)
|
142
|
-
|
143
|
-
field_def = build_field_definition(parent, row)
|
144
|
-
field_def.save!
|
48
|
+
if archive["field_definitions.csv"]
|
49
|
+
CSV.parse(archive["field_definitions.csv"], headers: true) do |row|
|
50
|
+
@strategy.import_field_definition(row)
|
145
51
|
end
|
146
52
|
end
|
147
|
-
end
|
148
|
-
|
149
|
-
def find_parent(parent_type, parent_handle)
|
150
|
-
case parent_type
|
151
|
-
when "content_type"
|
152
|
-
ContentType.find_by(handle: parent_handle)
|
153
|
-
when "block"
|
154
|
-
BlockDefinition.find_by(handle: parent_handle)
|
155
|
-
end
|
156
|
-
end
|
157
|
-
|
158
|
-
def build_content_type(row)
|
159
|
-
klass = case row["type"]
|
160
|
-
when "single" then ContentTypes::Single
|
161
|
-
when "collection" then ContentTypes::Collection
|
162
|
-
else ContentType
|
163
|
-
end
|
164
|
-
|
165
|
-
klass.new(
|
166
|
-
handle: row["handle"],
|
167
|
-
name: row["name"],
|
168
|
-
description: row["description"],
|
169
|
-
icon: row["icon"],
|
170
|
-
web_publishing_enabled: row["web_publishing_enabled"] == "true",
|
171
|
-
base_path: row["base_path"]
|
172
|
-
)
|
173
|
-
end
|
174
|
-
|
175
|
-
def update_content_type(content_type, row)
|
176
|
-
content_type.assign_attributes(
|
177
|
-
name: row["name"],
|
178
|
-
description: row["description"],
|
179
|
-
icon: row["icon"],
|
180
|
-
web_publishing_enabled: row["web_publishing_enabled"] == "true",
|
181
|
-
base_path: row["base_path"]
|
182
|
-
)
|
183
|
-
|
184
|
-
# Update type if changed
|
185
|
-
if row["type"] && content_type.type != "Iron::ContentTypes::#{row['type'].camelize}"
|
186
|
-
content_type.type = "Iron::ContentTypes::#{row['type'].camelize}"
|
187
|
-
end
|
188
|
-
|
189
|
-
content_type.save!
|
190
|
-
end
|
191
|
-
|
192
|
-
def build_field_definition(parent, row)
|
193
|
-
klass = "Iron::FieldDefinitions::#{row['type'].camelize}".constantize
|
194
53
|
|
195
|
-
|
196
|
-
schemable: parent,
|
197
|
-
handle: row["handle"],
|
198
|
-
name: row["name"],
|
199
|
-
rank: row["rank"],
|
200
|
-
metadata: parse_metadata(row["metadata"])
|
201
|
-
)
|
202
|
-
|
203
|
-
# Set supported block definitions before saving
|
204
|
-
set_supported_block_definitions(field_def, row["supported_block_definitions"])
|
54
|
+
update_content_type_references(archive["content_types.csv"])
|
205
55
|
|
206
|
-
|
56
|
+
ImportResult.new(true, [])
|
207
57
|
end
|
58
|
+
rescue StandardError => e
|
59
|
+
errors << "Import failed: #{e.message}"
|
60
|
+
ImportResult.new(false, errors)
|
61
|
+
end
|
208
62
|
|
209
|
-
|
210
|
-
field_def.assign_attributes(
|
211
|
-
name: row["name"],
|
212
|
-
rank: row["rank"],
|
213
|
-
metadata: parse_metadata(row["metadata"])
|
214
|
-
)
|
63
|
+
private
|
215
64
|
|
216
|
-
|
217
|
-
|
218
|
-
|
65
|
+
def build_strategy(mode)
|
66
|
+
case mode.to_s
|
67
|
+
when "merge" then SchemaImporter::MergeStrategy.new
|
68
|
+
when "replace" then SchemaImporter::ReplaceStrategy.new
|
69
|
+
when "safe" then SchemaImporter::SafeStrategy.new
|
70
|
+
else
|
71
|
+
raise ArgumentError, "Invalid import mode: #{mode}"
|
219
72
|
end
|
220
|
-
|
221
|
-
# Set supported block definitions before saving
|
222
|
-
set_supported_block_definitions(field_def, row["supported_block_definitions"])
|
223
|
-
|
224
|
-
field_def.save!
|
225
|
-
end
|
226
|
-
|
227
|
-
def parse_metadata(metadata_string)
|
228
|
-
return {} if metadata_string.blank?
|
229
|
-
|
230
|
-
JSON.parse(metadata_string)
|
231
|
-
rescue JSON::ParserError
|
232
|
-
{}
|
233
73
|
end
|
234
74
|
|
235
75
|
def update_content_type_references(content_types_csv)
|
@@ -252,16 +92,6 @@ module Iron
|
|
252
92
|
end
|
253
93
|
end
|
254
94
|
|
255
|
-
def set_supported_block_definitions(field_def, supported_handles_string)
|
256
|
-
return unless supported_handles_string.present?
|
257
|
-
return unless field_def.respond_to?(:supported_block_definitions)
|
258
|
-
|
259
|
-
handles = supported_handles_string.split("|")
|
260
|
-
block_definitions = BlockDefinition.where(handle: handles)
|
261
|
-
|
262
|
-
field_def.supported_block_definitions = block_definitions
|
263
|
-
end
|
264
|
-
|
265
95
|
class ImportResult
|
266
96
|
attr_reader :errors
|
267
97
|
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<% content_for :title, "Import Content" %>
|
2
|
+
|
3
|
+
<div class="">
|
4
|
+
<%= back_button_to "Settings", settings_path %>
|
5
|
+
<h1 class="page-title">Import Content</h1>
|
6
|
+
<p class="mt-2 text-sm text-stone-500">Upload a content archive exported from another Iron instance.</p>
|
7
|
+
|
8
|
+
<%= form_with url: import_content_path, multipart: true, class: "mt-8 max-w-2xl", data: { turbo: false } do |form| %>
|
9
|
+
<div class="field-group">
|
10
|
+
<div class="field">
|
11
|
+
<%= form.label :content_file, "Content Archive" %>
|
12
|
+
<div>
|
13
|
+
<%= form.file_field :content_file,
|
14
|
+
accept: ".tar",
|
15
|
+
required: true,
|
16
|
+
class: "input" %>
|
17
|
+
<p class="mt-2 text-sm text-stone-500">Select a .tar file exported using Iron's content export.</p>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div class="field">
|
22
|
+
<label class="text-sm font-medium text-stone-700">Import behaviour</label>
|
23
|
+
<p class="text-sm text-stone-500 mt-1">
|
24
|
+
Entries with matching IDs and instance tokens are updated. Other records are created.
|
25
|
+
</p>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
|
29
|
+
<div class="mt-6 flex items-center gap-x-3">
|
30
|
+
<%= form.submit "Import Content", class: "btn" %>
|
31
|
+
<%= link_to "Cancel", settings_path, class: "btn", data: { variant: "plain" } %>
|
32
|
+
</div>
|
33
|
+
<% end %>
|
34
|
+
</div>
|
@@ -35,4 +35,23 @@
|
|
35
35
|
</div>
|
36
36
|
<% end %>
|
37
37
|
</div>
|
38
|
+
|
39
|
+
<div class="bg-white dark:bg-stone-800/50 rounded-lg shadow-sm p-6 max-w-96">
|
40
|
+
<h2 class="text-lg font-semibold mb-4">Content Management</h2>
|
41
|
+
<p class="text-sm text-stone-600 dark:text-stone-400 mb-4">
|
42
|
+
Export content entries and their files or import an archive from another instance.
|
43
|
+
</p>
|
44
|
+
<div class="flex flex-col gap-2">
|
45
|
+
<%= link_to "Export Content",
|
46
|
+
export_content_path,
|
47
|
+
class: "btn",
|
48
|
+
data: {
|
49
|
+
turbo: false,
|
50
|
+
} %>
|
51
|
+
<%= link_to "Import Content",
|
52
|
+
new_content_path,
|
53
|
+
class: "btn",
|
54
|
+
data: { variant: "secondary" } %>
|
55
|
+
</div>
|
56
|
+
</div>
|
38
57
|
</div>
|
data/config/routes.rb
CHANGED
@@ -22,6 +22,11 @@ Iron::Engine.routes.draw do
|
|
22
22
|
post :import, on: :member
|
23
23
|
end
|
24
24
|
|
25
|
+
resource :content, only: [ :new ] do
|
26
|
+
get :export, on: :collection
|
27
|
+
post :import, on: :collection
|
28
|
+
end
|
29
|
+
|
25
30
|
resources :block_definitions do
|
26
31
|
resources :field_definitions, shallow: true, module: :block_definitions
|
27
32
|
end
|
data/lib/iron/engine.rb
CHANGED
@@ -31,6 +31,15 @@ module Iron
|
|
31
31
|
app.config.active_storage.analyzers.prepend Iron::ImageAnalyzer
|
32
32
|
end
|
33
33
|
|
34
|
+
initializer "iron.global_id_locator" do |app|
|
35
|
+
app.config.after_initialize do
|
36
|
+
global_id_app = ::GlobalID.app || ::Rails.application.config.try(:global_id)&.app
|
37
|
+
next unless global_id_app
|
38
|
+
|
39
|
+
::GlobalID::Locator.use(global_id_app, Iron::GlobalID::InstanceScopedLocator.new)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
34
43
|
config.to_prepare do
|
35
44
|
ActionView::Base.include(Module.new do
|
36
45
|
def attachment_url(attachment, **options)
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require "globalid"
|
2
|
+
|
3
|
+
module Iron
|
4
|
+
module GlobalID
|
5
|
+
class InstanceScopedLocator < ::GlobalID::Locator::UnscopedLocator
|
6
|
+
def locate(gid, options = {})
|
7
|
+
return unless instance_matches?(gid)
|
8
|
+
|
9
|
+
super
|
10
|
+
end
|
11
|
+
|
12
|
+
def locate_many(gids, options = {})
|
13
|
+
filtered_gids = gids.select { |candidate| instance_matches?(candidate) }
|
14
|
+
return [] if filtered_gids.empty?
|
15
|
+
|
16
|
+
super(filtered_gids, options)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def instance_matches?(gid)
|
22
|
+
instance_token = gid.params[:instance]
|
23
|
+
return true if instance_token.blank?
|
24
|
+
|
25
|
+
Current.account&.instance_token == instance_token
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/iron/version.rb
CHANGED
data/lib/iron-cms.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require "iron"
|
1
|
+
require "iron"
|
data/lib/iron.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: iron-cms
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Massimo De Marchi
|
@@ -198,6 +198,7 @@ files:
|
|
198
198
|
- app/controllers/iron/blocks_controller.rb
|
199
199
|
- app/controllers/iron/content_types/field_definitions_controller.rb
|
200
200
|
- app/controllers/iron/content_types_controller.rb
|
201
|
+
- app/controllers/iron/contents_controller.rb
|
201
202
|
- app/controllers/iron/entries_controller.rb
|
202
203
|
- app/controllers/iron/field_definitions_controller.rb
|
203
204
|
- app/controllers/iron/first_runs_controller.rb
|
@@ -239,11 +240,21 @@ files:
|
|
239
240
|
- app/mailers/iron/application_mailer.rb
|
240
241
|
- app/mailers/passwords_mailer.rb
|
241
242
|
- app/models/concerns/iron/csv_serializable.rb
|
243
|
+
- app/models/concerns/iron/instance_scoped.rb
|
242
244
|
- app/models/iron/account.rb
|
243
245
|
- app/models/iron/account/joinable.rb
|
244
246
|
- app/models/iron/application_record.rb
|
247
|
+
- app/models/iron/archive.rb
|
245
248
|
- app/models/iron/block_definition.rb
|
246
249
|
- app/models/iron/block_definition/portable.rb
|
250
|
+
- app/models/iron/content_export.rb
|
251
|
+
- app/models/iron/content_import.rb
|
252
|
+
- app/models/iron/content_import/entry_builder.rb
|
253
|
+
- app/models/iron/content_import/entry_snapshot.rb
|
254
|
+
- app/models/iron/content_import/field_reconstructor.rb
|
255
|
+
- app/models/iron/content_import/field_snapshot.rb
|
256
|
+
- app/models/iron/content_import/registry.rb
|
257
|
+
- app/models/iron/content_import/session.rb
|
247
258
|
- app/models/iron/content_type.rb
|
248
259
|
- app/models/iron/content_type/field_queryable.rb
|
249
260
|
- app/models/iron/content_type/portable.rb
|
@@ -254,12 +265,14 @@ files:
|
|
254
265
|
- app/models/iron/current.rb
|
255
266
|
- app/models/iron/entry.rb
|
256
267
|
- app/models/iron/entry/deep_validation.rb
|
268
|
+
- app/models/iron/entry/portable.rb
|
257
269
|
- app/models/iron/entry/presentable.rb
|
258
270
|
- app/models/iron/entry/schemable.rb
|
259
271
|
- app/models/iron/entry/titlable.rb
|
260
272
|
- app/models/iron/entry/web_publishable.rb
|
261
273
|
- app/models/iron/field.rb
|
262
274
|
- app/models/iron/field/belongs_to_entry.rb
|
275
|
+
- app/models/iron/field/portable.rb
|
263
276
|
- app/models/iron/field_definition.rb
|
264
277
|
- app/models/iron/field_definition/portable.rb
|
265
278
|
- app/models/iron/field_definitions/block.rb
|
@@ -291,6 +304,10 @@ files:
|
|
291
304
|
- app/models/iron/schema_archive.rb
|
292
305
|
- app/models/iron/schema_exporter.rb
|
293
306
|
- app/models/iron/schema_importer.rb
|
307
|
+
- app/models/iron/schema_importer/import_strategy.rb
|
308
|
+
- app/models/iron/schema_importer/merge_strategy.rb
|
309
|
+
- app/models/iron/schema_importer/replace_strategy.rb
|
310
|
+
- app/models/iron/schema_importer/safe_strategy.rb
|
294
311
|
- app/models/iron/session.rb
|
295
312
|
- app/models/iron/user.rb
|
296
313
|
- app/models/iron/user/role.rb
|
@@ -308,6 +325,7 @@ files:
|
|
308
325
|
- app/views/iron/content_types/index.html.erb
|
309
326
|
- app/views/iron/content_types/new.html.erb
|
310
327
|
- app/views/iron/content_types/show.html.erb
|
328
|
+
- app/views/iron/contents/new.html.erb
|
311
329
|
- app/views/iron/entries/_entry.html.erb
|
312
330
|
- app/views/iron/entries/_entry_option.html.erb
|
313
331
|
- app/views/iron/entries/_form.html.erb
|
@@ -390,6 +408,7 @@ files:
|
|
390
408
|
- db/migrate/20250601080146_add_icon_to_iron_content_types.rb
|
391
409
|
- db/migrate/20250609091605_add_web_publishing_to_iron_content_types.rb
|
392
410
|
- db/migrate/20250609091813_add_route_to_iron_entries.rb
|
411
|
+
- db/migrate/20250908203158_add_instance_token_to_iron_accounts.rb
|
393
412
|
- lib/generators/iron/pages/pages_generator.rb
|
394
413
|
- lib/generators/iron/pages/templates/pages_controller.rb
|
395
414
|
- lib/generators/iron/pages/templates/show.html.erb
|
@@ -399,6 +418,7 @@ files:
|
|
399
418
|
- lib/iron.rb
|
400
419
|
- lib/iron/cva.rb
|
401
420
|
- lib/iron/engine.rb
|
421
|
+
- lib/iron/global_id/instance_scoped_locator.rb
|
402
422
|
- lib/iron/image_analyzer.rb
|
403
423
|
- lib/iron/lexorank.rb
|
404
424
|
- lib/iron/lexorank/exceptions.rb
|