cms42 0.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.
Files changed (145) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README.md +299 -0
  4. data/Rakefile +10 -0
  5. data/app/assets/stylesheets/cms/application.css +3 -0
  6. data/app/controllers/cms/admin/api_keys_controller.rb +52 -0
  7. data/app/controllers/cms/admin/base_controller.rb +54 -0
  8. data/app/controllers/cms/admin/documents_controller.rb +56 -0
  9. data/app/controllers/cms/admin/form_fields_controller.rb +70 -0
  10. data/app/controllers/cms/admin/form_submissions_controller.rb +36 -0
  11. data/app/controllers/cms/admin/images_controller.rb +67 -0
  12. data/app/controllers/cms/admin/pages_controller.rb +188 -0
  13. data/app/controllers/cms/admin/sections_controller.rb +177 -0
  14. data/app/controllers/cms/admin/sites_controller.rb +60 -0
  15. data/app/controllers/cms/admin/webhook_deliveries_controller.rb +19 -0
  16. data/app/controllers/cms/admin/webhooks_controller.rb +51 -0
  17. data/app/controllers/cms/api/base_controller.rb +45 -0
  18. data/app/controllers/cms/api/v1/base_controller.rb +29 -0
  19. data/app/controllers/cms/api/v1/pages_controller.rb +21 -0
  20. data/app/controllers/cms/api/v1/sites_controller.rb +18 -0
  21. data/app/controllers/cms/application_controller.rb +11 -0
  22. data/app/controllers/cms/public/base_controller.rb +23 -0
  23. data/app/controllers/cms/public/form_submissions_controller.rb +63 -0
  24. data/app/controllers/cms/public/previews_controller.rb +21 -0
  25. data/app/controllers/cms/public/sites_controller.rb +37 -0
  26. data/app/controllers/concerns/cms/admin/page_scoped_sections.rb +42 -0
  27. data/app/controllers/concerns/cms/current_site_resolver.rb +17 -0
  28. data/app/controllers/concerns/cms/public/page_paths.rb +31 -0
  29. data/app/controllers/concerns/cms/public/page_rendering.rb +23 -0
  30. data/app/controllers/concerns/cms/site_resolvable.rb +27 -0
  31. data/app/helpers/cms/admin/pages_helper.rb +29 -0
  32. data/app/helpers/cms/admin/sections_helper.rb +86 -0
  33. data/app/helpers/cms/admin/sites_helper.rb +8 -0
  34. data/app/helpers/cms/application_helper.rb +51 -0
  35. data/app/helpers/cms/media_helper.rb +28 -0
  36. data/app/helpers/cms/pages_helper.rb +16 -0
  37. data/app/helpers/cms/sections_helper.rb +25 -0
  38. data/app/helpers/cms/sites_helper.rb +11 -0
  39. data/app/javascript/cms/controllers/sortable_controller.js +38 -0
  40. data/app/jobs/cms/application_job.rb +6 -0
  41. data/app/jobs/cms/deliver_webhook_job.rb +66 -0
  42. data/app/mailers/cms/application_mailer.rb +9 -0
  43. data/app/mailers/cms/form_submission_mailer.rb +16 -0
  44. data/app/models/cms/api_key.rb +27 -0
  45. data/app/models/cms/application_record.rb +7 -0
  46. data/app/models/cms/document.rb +48 -0
  47. data/app/models/cms/form_field.rb +27 -0
  48. data/app/models/cms/form_submission.rb +42 -0
  49. data/app/models/cms/image.rb +61 -0
  50. data/app/models/cms/image_translation.rb +22 -0
  51. data/app/models/cms/page.rb +228 -0
  52. data/app/models/cms/page_section.rb +43 -0
  53. data/app/models/cms/page_translation.rb +22 -0
  54. data/app/models/cms/section/block_base.rb +32 -0
  55. data/app/models/cms/section/blocks/call_to_action_block.rb +16 -0
  56. data/app/models/cms/section/blocks/hero_block.rb +14 -0
  57. data/app/models/cms/section/blocks/image_block.rb +13 -0
  58. data/app/models/cms/section/blocks/rich_text_block.rb +12 -0
  59. data/app/models/cms/section/kind_registry.rb +66 -0
  60. data/app/models/cms/section.rb +94 -0
  61. data/app/models/cms/section_image.rb +10 -0
  62. data/app/models/cms/section_translation.rb +25 -0
  63. data/app/models/cms/site.rb +87 -0
  64. data/app/models/cms/webhook.rb +41 -0
  65. data/app/models/cms/webhook_delivery.rb +12 -0
  66. data/app/serializers/cms/api/base_serializer.rb +51 -0
  67. data/app/serializers/cms/api/page_serializer.rb +145 -0
  68. data/app/serializers/cms/api/site_serializer.rb +45 -0
  69. data/app/services/cms/locale_resolver.rb +30 -0
  70. data/app/services/cms/page_resolver.rb +73 -0
  71. data/app/services/cms/public_page_context.rb +49 -0
  72. data/app/views/cms/admin/api_keys/_form.html.erb +23 -0
  73. data/app/views/cms/admin/api_keys/create.html.erb +9 -0
  74. data/app/views/cms/admin/api_keys/edit.html.erb +5 -0
  75. data/app/views/cms/admin/api_keys/index.html.erb +36 -0
  76. data/app/views/cms/admin/api_keys/new.html.erb +5 -0
  77. data/app/views/cms/admin/documents/_form.html.erb +24 -0
  78. data/app/views/cms/admin/documents/edit.html.erb +2 -0
  79. data/app/views/cms/admin/documents/index.html.erb +37 -0
  80. data/app/views/cms/admin/documents/new.html.erb +2 -0
  81. data/app/views/cms/admin/form_fields/_form.html.erb +46 -0
  82. data/app/views/cms/admin/form_fields/edit.html.erb +2 -0
  83. data/app/views/cms/admin/form_fields/index.html.erb +41 -0
  84. data/app/views/cms/admin/form_fields/new.html.erb +2 -0
  85. data/app/views/cms/admin/form_submissions/index.html.erb +38 -0
  86. data/app/views/cms/admin/images/_form.html.erb +36 -0
  87. data/app/views/cms/admin/images/edit.html.erb +2 -0
  88. data/app/views/cms/admin/images/index.html.erb +25 -0
  89. data/app/views/cms/admin/images/new.html.erb +2 -0
  90. data/app/views/cms/admin/pages/_attach_section_panel.html.erb +20 -0
  91. data/app/views/cms/admin/pages/_form.html.erb +116 -0
  92. data/app/views/cms/admin/pages/_section_editor_frame.html.erb +3 -0
  93. data/app/views/cms/admin/pages/_sections_list.html.erb +9 -0
  94. data/app/views/cms/admin/pages/edit.html.erb +2 -0
  95. data/app/views/cms/admin/pages/index.html.erb +62 -0
  96. data/app/views/cms/admin/pages/new.html.erb +2 -0
  97. data/app/views/cms/admin/pages/show.html.erb +111 -0
  98. data/app/views/cms/admin/sections/_form.html.erb +128 -0
  99. data/app/views/cms/admin/sections/_section.html.erb +22 -0
  100. data/app/views/cms/admin/sections/edit.html.erb +9 -0
  101. data/app/views/cms/admin/sections/index.html.erb +47 -0
  102. data/app/views/cms/admin/sections/new.html.erb +9 -0
  103. data/app/views/cms/admin/sections/page_update.turbo_stream.erb +17 -0
  104. data/app/views/cms/admin/sections/show.html.erb +97 -0
  105. data/app/views/cms/admin/sites/_form.html.erb +44 -0
  106. data/app/views/cms/admin/sites/edit.html.erb +3 -0
  107. data/app/views/cms/admin/sites/new.html.erb +5 -0
  108. data/app/views/cms/admin/sites/show.html.erb +22 -0
  109. data/app/views/cms/admin/webhook_deliveries/index.html.erb +29 -0
  110. data/app/views/cms/admin/webhooks/_form.html.erb +38 -0
  111. data/app/views/cms/admin/webhooks/edit.html.erb +5 -0
  112. data/app/views/cms/admin/webhooks/index.html.erb +34 -0
  113. data/app/views/cms/admin/webhooks/new.html.erb +5 -0
  114. data/app/views/cms/form_submission_mailer/notify.html.erb +14 -0
  115. data/app/views/cms/form_submission_mailer/notify.text.erb +7 -0
  116. data/app/views/cms/public/pages/_content.html.erb +48 -0
  117. data/app/views/cms/public/pages/show.html.erb +44 -0
  118. data/app/views/cms/public/pages/templates/_custom.html.erb +3 -0
  119. data/app/views/cms/public/pages/templates/_form.html.erb +3 -0
  120. data/app/views/cms/public/pages/templates/_landing.html.erb +3 -0
  121. data/app/views/cms/public/pages/templates/_standard.html.erb +3 -0
  122. data/app/views/cms/sections/kinds/_cta.html.erb +13 -0
  123. data/app/views/cms/sections/kinds/_hero.html.erb +14 -0
  124. data/app/views/cms/sections/kinds/_image.html.erb +19 -0
  125. data/app/views/cms/sections/kinds/_rich_text.html.erb +6 -0
  126. data/app/views/layouts/cms/application.html.erb +13 -0
  127. data/app/views/layouts/cms/public.html.erb +14 -0
  128. data/bin/rails +19 -0
  129. data/bin/rubocop +9 -0
  130. data/cms.gemspec +29 -0
  131. data/config/importmap.rb +4 -0
  132. data/config/locales/activerecord.cms.en.yml +65 -0
  133. data/config/locales/en.yml +390 -0
  134. data/config/routes.rb +56 -0
  135. data/lib/cms/engine.rb +45 -0
  136. data/lib/cms/version.rb +5 -0
  137. data/lib/cms.rb +75 -0
  138. data/lib/cms42.rb +3 -0
  139. data/lib/generators/cms/install/install_generator.rb +26 -0
  140. data/lib/generators/cms/install/templates/create_cms_tables.rb +194 -0
  141. data/lib/generators/cms/install/templates/initializer.rb +21 -0
  142. data/lib/generators/cms/views/views_generator.rb +79 -0
  143. data/lib/tasks/cms_tasks.rake +6 -0
  144. data/lib/tasks/version.rake +8 -0
  145. metadata +281 -0
@@ -0,0 +1,194 @@
1
+ # frozen_string_literal: true
2
+
3
+ class CreateCmsTables < ActiveRecord::Migration[7.1]
4
+ def change
5
+ enable_extension "unaccent" unless extension_enabled?("unaccent")
6
+
7
+ create_table :cms_sites do |t|
8
+ t.string :name, null: false
9
+ t.string :slug, null: false
10
+ t.boolean :published, null: false, default: false
11
+ t.string :default_locale, null: false, default: "en"
12
+ t.timestamps
13
+ end
14
+
15
+ add_index :cms_sites, :slug, unique: true
16
+
17
+ create_table :cms_pages do |t|
18
+ t.references :site, null: false, foreign_key: { to_table: :cms_sites }
19
+ t.bigint :parent_id
20
+ t.string :slug, null: false
21
+ t.integer :position, null: false, default: 0
22
+ t.boolean :home, null: false, default: false
23
+ t.string :template_key, null: false, default: "standard"
24
+ t.string :status, null: false, default: "draft"
25
+ t.boolean :show_in_header, null: false, default: true
26
+ t.boolean :show_in_footer, null: false, default: false
27
+ t.string :nav_group, null: false, default: "main"
28
+ t.integer :nav_order, null: false, default: 0
29
+ t.integer :footer_order, null: false, default: 0
30
+ t.integer :depth, null: false, default: 0
31
+ t.string :preview_token
32
+ t.datetime :discarded_at
33
+ t.timestamps
34
+ end
35
+
36
+ add_index :cms_pages, %i[site_id slug], unique: true
37
+ add_index :cms_pages, %i[site_id status position]
38
+ add_index :cms_pages, %i[site_id nav_group nav_order]
39
+ add_index :cms_pages, :parent_id
40
+ add_index :cms_pages, :preview_token, unique: true
41
+ add_index :cms_pages, :discarded_at
42
+
43
+ add_foreign_key :cms_pages, :cms_pages, column: :parent_id
44
+
45
+ create_table :cms_page_translations do |t|
46
+ t.references :page, null: false, foreign_key: { to_table: :cms_pages }
47
+ t.string :locale, null: false
48
+ t.string :title, null: false
49
+ t.string :seo_title
50
+ t.string :seo_description
51
+ t.timestamps
52
+ end
53
+
54
+ add_index :cms_page_translations, %i[page_id locale], unique: true
55
+
56
+ create_table :cms_images do |t|
57
+ t.references :site, null: false, foreign_key: { to_table: :cms_sites }
58
+ t.string :title, null: false
59
+ t.timestamps
60
+ end
61
+
62
+ create_table :cms_image_translations do |t|
63
+ t.references :image, null: false, foreign_key: { to_table: :cms_images }
64
+ t.string :locale, null: false
65
+ t.string :alt_text, null: false
66
+ t.string :caption
67
+ t.timestamps
68
+ end
69
+
70
+ add_index :cms_image_translations, %i[image_id locale], unique: true
71
+
72
+ create_table :cms_sections do |t|
73
+ t.references :site, null: false, foreign_key: { to_table: :cms_sites }
74
+ t.string :kind, null: false, default: "rich_text"
75
+ t.boolean :global, null: false, default: false
76
+ t.boolean :enabled, null: false, default: true
77
+ t.jsonb :settings, null: false, default: {}
78
+ t.datetime :discarded_at
79
+ t.timestamps
80
+ end
81
+
82
+ add_index :cms_sections, %i[site_id kind]
83
+ add_index :cms_sections, %i[site_id global kind]
84
+ add_index :cms_sections, :discarded_at
85
+
86
+ create_table :cms_section_translations do |t|
87
+ t.references :section, null: false, foreign_key: { to_table: :cms_sections }
88
+ t.string :locale, null: false
89
+ t.string :title, null: false
90
+ t.string :subtitle
91
+ t.timestamps
92
+ end
93
+
94
+ add_index :cms_section_translations, %i[section_id locale], unique: true
95
+
96
+ create_table :cms_section_images do |t|
97
+ t.references :section, null: false, foreign_key: { to_table: :cms_sections }
98
+ t.references :image, null: false, foreign_key: { to_table: :cms_images }
99
+ t.integer :position, null: false, default: 0
100
+ t.timestamps
101
+ end
102
+
103
+ add_index :cms_section_images, %i[section_id position]
104
+ add_index :cms_section_images, %i[section_id image_id], unique: true
105
+
106
+ create_table :cms_documents do |t|
107
+ t.references :site, null: false, foreign_key: { to_table: :cms_sites }
108
+ t.string :title, null: false
109
+ t.text :description
110
+ t.timestamps
111
+ end
112
+
113
+ create_table :cms_page_sections do |t|
114
+ t.references :page, null: false, foreign_key: { to_table: :cms_pages }
115
+ t.references :section, null: false, foreign_key: { to_table: :cms_sections }
116
+ t.integer :position, null: false, default: 0
117
+ t.timestamps
118
+ end
119
+
120
+ add_index :cms_page_sections, %i[page_id position]
121
+ add_index :cms_page_sections, %i[page_id section_id], unique: true
122
+
123
+ create_table :cms_form_fields do |t|
124
+ t.references :page, null: false, foreign_key: { to_table: :cms_pages }
125
+ t.string :kind, null: false, default: "text"
126
+ t.string :label, null: false
127
+ t.string :field_name, null: false
128
+ t.string :placeholder
129
+ t.string :hint
130
+ t.boolean :required, null: false, default: false
131
+ t.jsonb :options, null: false, default: []
132
+ t.integer :position, null: false, default: 0
133
+ t.timestamps
134
+ end
135
+
136
+ add_index :cms_form_fields, %i[page_id position]
137
+ add_index :cms_form_fields, %i[page_id field_name], unique: true
138
+
139
+ create_table :cms_form_submissions do |t|
140
+ t.references :page, null: false, foreign_key: { to_table: :cms_pages }
141
+ t.jsonb :data, null: false, default: {}
142
+ t.string :ip_address
143
+ t.datetime :created_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
144
+ end
145
+
146
+ add_index :cms_form_submissions, :created_at
147
+
148
+ create_table :cms_api_keys do |t|
149
+ t.references :site, null: false, foreign_key: { to_table: :cms_sites }
150
+ t.string :name, null: false
151
+ t.string :token, null: false
152
+ t.boolean :active, null: false, default: true
153
+ t.datetime :last_used_at
154
+ t.timestamps
155
+ end
156
+
157
+ add_index :cms_api_keys, :token, unique: true
158
+
159
+ create_table :cms_webhooks do |t|
160
+ t.references :site, null: false, foreign_key: { to_table: :cms_sites }
161
+ t.string :url, null: false
162
+ t.jsonb :events, null: false, default: []
163
+ t.string :secret
164
+ t.boolean :active, null: false, default: true
165
+ t.timestamps
166
+ end
167
+
168
+ create_table :cms_webhook_deliveries do |t|
169
+ t.references :webhook, null: false, foreign_key: { to_table: :cms_webhooks }
170
+ t.string :event, null: false
171
+ t.integer :response_code
172
+ t.text :response_body
173
+ t.boolean :success, null: false, default: false
174
+ t.string :error_message
175
+ t.datetime :delivered_at, null: false, default: -> { "CURRENT_TIMESTAMP" }
176
+ end
177
+
178
+ add_index :cms_webhook_deliveries, %i[webhook_id delivered_at]
179
+
180
+ return if table_exists?(:action_text_rich_texts)
181
+
182
+ create_table :action_text_rich_texts do |t|
183
+ t.string :name, null: false
184
+ t.text :body
185
+ t.references :record, null: false, polymorphic: true, index: false
186
+ t.timestamps
187
+ end
188
+
189
+ add_index :action_text_rich_texts,
190
+ %i[record_type record_id name],
191
+ unique: true,
192
+ name: "index_action_text_rich_texts_uniqueness"
193
+ end
194
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ Cms.setup do |config|
4
+ # Public/API controllers inherit from this host controller.
5
+ config.parent_controller = "ApplicationController"
6
+
7
+ # Required for admin in production: point this at a host controller that
8
+ # already enforces authentication and authorization for CMS access.
9
+ config.admin_parent_controller = "Admin::BaseController"
10
+
11
+ # Optional for public/API requests when you use site slugs, headers, or
12
+ # subdomains. Required for admin once any Cms::Site exists.
13
+ config.current_site_resolver = ->(controller) { controller.current_organization&.cms_site }
14
+
15
+ # Optional: replace the public/API page lookup service.
16
+ # config.page_resolver_class = "Cms::PageResolver"
17
+
18
+ # Optional: replace API serialization classes.
19
+ # config.api_site_serializer_class = "Cms::Api::SiteSerializer"
20
+ # config.api_page_serializer_class = "Cms::Api::PageSerializer"
21
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators/base"
4
+
5
+ module Cms
6
+ module Generators
7
+ class ViewsGenerator < Rails::Generators::Base
8
+ source_root Cms::Engine.root.join("app/views")
9
+ desc "Copies CMS views to your application."
10
+
11
+ argument :scope,
12
+ required: false,
13
+ default: nil,
14
+ desc: "Select a view scope (admin, public, mailer, all)"
15
+
16
+ class_option :views,
17
+ aliases: "-v",
18
+ type: :array,
19
+ desc: "Select specific view scopes to generate (admin, public, mailer)"
20
+
21
+ VIEW_GROUPS = {
22
+ "admin" => [
23
+ "cms/admin"
24
+ ],
25
+ "public" => [
26
+ "cms/sections",
27
+ "cms/public",
28
+ "layouts/cms"
29
+ ],
30
+ "mailer" => [
31
+ "cms/form_submission_mailer"
32
+ ],
33
+ "all" => [
34
+ "cms",
35
+ "layouts/cms"
36
+ ]
37
+ }.freeze
38
+
39
+ def copy_views
40
+ selected_groups.each do |group|
41
+ copy_group(group)
42
+ end
43
+ end
44
+
45
+ private
46
+
47
+ def selected_groups
48
+ groups =
49
+ if options[:views].present?
50
+ options[:views]
51
+ elsif scope.present?
52
+ [scope]
53
+ else
54
+ ["all"]
55
+ end
56
+
57
+ normalized = groups.map { |entry| entry.to_s.downcase }.uniq
58
+ invalid = normalized - VIEW_GROUPS.keys
59
+ return normalized if invalid.empty?
60
+
61
+ raise Thor::Error, "Unknown view scope(s): #{invalid.join(', ')}. " \
62
+ "Valid scopes: #{VIEW_GROUPS.keys.join(', ')}"
63
+ end
64
+
65
+ def copy_group(group)
66
+ VIEW_GROUPS.fetch(group).each do |relative_path|
67
+ source = Cms::Engine.root.join("app/views", relative_path)
68
+ target = File.join("app/views", relative_path)
69
+
70
+ if source.directory?
71
+ directory relative_path, target
72
+ else
73
+ copy_file relative_path, target
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ # desc "Explaining what the task does"
4
+ # task :cms do
5
+ # # Task goes here
6
+ # end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ namespace :cms do
4
+ desc "Print current gem version"
5
+ task :version do
6
+ puts Cms::VERSION
7
+ end
8
+ end
metadata ADDED
@@ -0,0 +1,281 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cms42
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - shift42
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: actiontext
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '7.1'
19
+ - - "<"
20
+ - !ruby/object:Gem::Version
21
+ version: '9.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ version: '7.1'
29
+ - - "<"
30
+ - !ruby/object:Gem::Version
31
+ version: '9.0'
32
+ - !ruby/object:Gem::Dependency
33
+ name: discard
34
+ requirement: !ruby/object:Gem::Requirement
35
+ requirements:
36
+ - - "~>"
37
+ - !ruby/object:Gem::Version
38
+ version: '1.4'
39
+ type: :runtime
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - "~>"
44
+ - !ruby/object:Gem::Version
45
+ version: '1.4'
46
+ - !ruby/object:Gem::Dependency
47
+ name: importmap-rails
48
+ requirement: !ruby/object:Gem::Requirement
49
+ requirements:
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: '1.2'
53
+ type: :runtime
54
+ prerelease: false
55
+ version_requirements: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '1.2'
60
+ - !ruby/object:Gem::Dependency
61
+ name: rails
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '7.1'
67
+ - - "<"
68
+ - !ruby/object:Gem::Version
69
+ version: '9.0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '7.1'
77
+ - - "<"
78
+ - !ruby/object:Gem::Version
79
+ version: '9.0'
80
+ - !ruby/object:Gem::Dependency
81
+ name: stimulus-rails
82
+ requirement: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: '1.3'
87
+ type: :runtime
88
+ prerelease: false
89
+ version_requirements: !ruby/object:Gem::Requirement
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ version: '1.3'
94
+ - !ruby/object:Gem::Dependency
95
+ name: turbo-rails
96
+ requirement: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '1.5'
101
+ type: :runtime
102
+ prerelease: false
103
+ version_requirements: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '1.5'
108
+ description: A mountable Rails CMS engine. Multi-site, multilingual, content blocks,
109
+ page tree, media management, forms, headless JSON API, and webhooks.
110
+ email:
111
+ - hello@shift42.io
112
+ executables: []
113
+ extensions: []
114
+ extra_rdoc_files: []
115
+ files:
116
+ - MIT-LICENSE
117
+ - README.md
118
+ - Rakefile
119
+ - app/assets/stylesheets/cms/application.css
120
+ - app/controllers/cms/admin/api_keys_controller.rb
121
+ - app/controllers/cms/admin/base_controller.rb
122
+ - app/controllers/cms/admin/documents_controller.rb
123
+ - app/controllers/cms/admin/form_fields_controller.rb
124
+ - app/controllers/cms/admin/form_submissions_controller.rb
125
+ - app/controllers/cms/admin/images_controller.rb
126
+ - app/controllers/cms/admin/pages_controller.rb
127
+ - app/controllers/cms/admin/sections_controller.rb
128
+ - app/controllers/cms/admin/sites_controller.rb
129
+ - app/controllers/cms/admin/webhook_deliveries_controller.rb
130
+ - app/controllers/cms/admin/webhooks_controller.rb
131
+ - app/controllers/cms/api/base_controller.rb
132
+ - app/controllers/cms/api/v1/base_controller.rb
133
+ - app/controllers/cms/api/v1/pages_controller.rb
134
+ - app/controllers/cms/api/v1/sites_controller.rb
135
+ - app/controllers/cms/application_controller.rb
136
+ - app/controllers/cms/public/base_controller.rb
137
+ - app/controllers/cms/public/form_submissions_controller.rb
138
+ - app/controllers/cms/public/previews_controller.rb
139
+ - app/controllers/cms/public/sites_controller.rb
140
+ - app/controllers/concerns/cms/admin/page_scoped_sections.rb
141
+ - app/controllers/concerns/cms/current_site_resolver.rb
142
+ - app/controllers/concerns/cms/public/page_paths.rb
143
+ - app/controllers/concerns/cms/public/page_rendering.rb
144
+ - app/controllers/concerns/cms/site_resolvable.rb
145
+ - app/helpers/cms/admin/pages_helper.rb
146
+ - app/helpers/cms/admin/sections_helper.rb
147
+ - app/helpers/cms/admin/sites_helper.rb
148
+ - app/helpers/cms/application_helper.rb
149
+ - app/helpers/cms/media_helper.rb
150
+ - app/helpers/cms/pages_helper.rb
151
+ - app/helpers/cms/sections_helper.rb
152
+ - app/helpers/cms/sites_helper.rb
153
+ - app/javascript/cms/controllers/sortable_controller.js
154
+ - app/jobs/cms/application_job.rb
155
+ - app/jobs/cms/deliver_webhook_job.rb
156
+ - app/mailers/cms/application_mailer.rb
157
+ - app/mailers/cms/form_submission_mailer.rb
158
+ - app/models/cms/api_key.rb
159
+ - app/models/cms/application_record.rb
160
+ - app/models/cms/document.rb
161
+ - app/models/cms/form_field.rb
162
+ - app/models/cms/form_submission.rb
163
+ - app/models/cms/image.rb
164
+ - app/models/cms/image_translation.rb
165
+ - app/models/cms/page.rb
166
+ - app/models/cms/page_section.rb
167
+ - app/models/cms/page_translation.rb
168
+ - app/models/cms/section.rb
169
+ - app/models/cms/section/block_base.rb
170
+ - app/models/cms/section/blocks/call_to_action_block.rb
171
+ - app/models/cms/section/blocks/hero_block.rb
172
+ - app/models/cms/section/blocks/image_block.rb
173
+ - app/models/cms/section/blocks/rich_text_block.rb
174
+ - app/models/cms/section/kind_registry.rb
175
+ - app/models/cms/section_image.rb
176
+ - app/models/cms/section_translation.rb
177
+ - app/models/cms/site.rb
178
+ - app/models/cms/webhook.rb
179
+ - app/models/cms/webhook_delivery.rb
180
+ - app/serializers/cms/api/base_serializer.rb
181
+ - app/serializers/cms/api/page_serializer.rb
182
+ - app/serializers/cms/api/site_serializer.rb
183
+ - app/services/cms/locale_resolver.rb
184
+ - app/services/cms/page_resolver.rb
185
+ - app/services/cms/public_page_context.rb
186
+ - app/views/cms/admin/api_keys/_form.html.erb
187
+ - app/views/cms/admin/api_keys/create.html.erb
188
+ - app/views/cms/admin/api_keys/edit.html.erb
189
+ - app/views/cms/admin/api_keys/index.html.erb
190
+ - app/views/cms/admin/api_keys/new.html.erb
191
+ - app/views/cms/admin/documents/_form.html.erb
192
+ - app/views/cms/admin/documents/edit.html.erb
193
+ - app/views/cms/admin/documents/index.html.erb
194
+ - app/views/cms/admin/documents/new.html.erb
195
+ - app/views/cms/admin/form_fields/_form.html.erb
196
+ - app/views/cms/admin/form_fields/edit.html.erb
197
+ - app/views/cms/admin/form_fields/index.html.erb
198
+ - app/views/cms/admin/form_fields/new.html.erb
199
+ - app/views/cms/admin/form_submissions/index.html.erb
200
+ - app/views/cms/admin/images/_form.html.erb
201
+ - app/views/cms/admin/images/edit.html.erb
202
+ - app/views/cms/admin/images/index.html.erb
203
+ - app/views/cms/admin/images/new.html.erb
204
+ - app/views/cms/admin/pages/_attach_section_panel.html.erb
205
+ - app/views/cms/admin/pages/_form.html.erb
206
+ - app/views/cms/admin/pages/_section_editor_frame.html.erb
207
+ - app/views/cms/admin/pages/_sections_list.html.erb
208
+ - app/views/cms/admin/pages/edit.html.erb
209
+ - app/views/cms/admin/pages/index.html.erb
210
+ - app/views/cms/admin/pages/new.html.erb
211
+ - app/views/cms/admin/pages/show.html.erb
212
+ - app/views/cms/admin/sections/_form.html.erb
213
+ - app/views/cms/admin/sections/_section.html.erb
214
+ - app/views/cms/admin/sections/edit.html.erb
215
+ - app/views/cms/admin/sections/index.html.erb
216
+ - app/views/cms/admin/sections/new.html.erb
217
+ - app/views/cms/admin/sections/page_update.turbo_stream.erb
218
+ - app/views/cms/admin/sections/show.html.erb
219
+ - app/views/cms/admin/sites/_form.html.erb
220
+ - app/views/cms/admin/sites/edit.html.erb
221
+ - app/views/cms/admin/sites/new.html.erb
222
+ - app/views/cms/admin/sites/show.html.erb
223
+ - app/views/cms/admin/webhook_deliveries/index.html.erb
224
+ - app/views/cms/admin/webhooks/_form.html.erb
225
+ - app/views/cms/admin/webhooks/edit.html.erb
226
+ - app/views/cms/admin/webhooks/index.html.erb
227
+ - app/views/cms/admin/webhooks/new.html.erb
228
+ - app/views/cms/form_submission_mailer/notify.html.erb
229
+ - app/views/cms/form_submission_mailer/notify.text.erb
230
+ - app/views/cms/public/pages/_content.html.erb
231
+ - app/views/cms/public/pages/show.html.erb
232
+ - app/views/cms/public/pages/templates/_custom.html.erb
233
+ - app/views/cms/public/pages/templates/_form.html.erb
234
+ - app/views/cms/public/pages/templates/_landing.html.erb
235
+ - app/views/cms/public/pages/templates/_standard.html.erb
236
+ - app/views/cms/sections/kinds/_cta.html.erb
237
+ - app/views/cms/sections/kinds/_hero.html.erb
238
+ - app/views/cms/sections/kinds/_image.html.erb
239
+ - app/views/cms/sections/kinds/_rich_text.html.erb
240
+ - app/views/layouts/cms/application.html.erb
241
+ - app/views/layouts/cms/public.html.erb
242
+ - bin/rails
243
+ - bin/rubocop
244
+ - cms.gemspec
245
+ - config/importmap.rb
246
+ - config/locales/activerecord.cms.en.yml
247
+ - config/locales/en.yml
248
+ - config/routes.rb
249
+ - lib/cms.rb
250
+ - lib/cms/engine.rb
251
+ - lib/cms/version.rb
252
+ - lib/cms42.rb
253
+ - lib/generators/cms/install/install_generator.rb
254
+ - lib/generators/cms/install/templates/create_cms_tables.rb
255
+ - lib/generators/cms/install/templates/initializer.rb
256
+ - lib/generators/cms/views/views_generator.rb
257
+ - lib/tasks/cms_tasks.rake
258
+ - lib/tasks/version.rake
259
+ homepage: https://github.com/shift42/cms
260
+ licenses:
261
+ - MIT
262
+ metadata:
263
+ rubygems_mfa_required: 'true'
264
+ rdoc_options: []
265
+ require_paths:
266
+ - lib
267
+ required_ruby_version: !ruby/object:Gem::Requirement
268
+ requirements:
269
+ - - ">="
270
+ - !ruby/object:Gem::Version
271
+ version: '3.2'
272
+ required_rubygems_version: !ruby/object:Gem::Requirement
273
+ requirements:
274
+ - - ">="
275
+ - !ruby/object:Gem::Version
276
+ version: '0'
277
+ requirements: []
278
+ rubygems_version: 4.0.3
279
+ specification_version: 4
280
+ summary: Modular, mountable CMS engine for Rails apps
281
+ test_files: []