railspress-engine 0.1.2 → 1.0.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/LICENSE +20 -0
- data/README.md +193 -25
- data/app/assets/javascripts/railspress/admin.js +39 -0
- data/app/assets/javascripts/railspress/markdown_mode.js +343 -0
- data/app/assets/stylesheets/application.css +0 -0
- data/app/assets/stylesheets/railspress/admin/badges.css +70 -0
- data/app/assets/stylesheets/railspress/admin/base.css +25 -0
- data/app/assets/stylesheets/railspress/admin/buttons.css +140 -0
- data/app/assets/stylesheets/railspress/admin/cards.css +52 -0
- data/app/assets/stylesheets/railspress/admin/components/exports.css +55 -0
- data/app/assets/stylesheets/railspress/admin/components/focal_point.css +801 -0
- data/app/assets/stylesheets/railspress/admin/components/imports.css +144 -0
- data/app/assets/stylesheets/railspress/admin/components/lexxy.css +145 -0
- data/app/assets/stylesheets/railspress/admin/filters.css +73 -0
- data/app/assets/stylesheets/railspress/admin/flash.css +26 -0
- data/app/assets/stylesheets/railspress/admin/forms.css +459 -0
- data/app/assets/stylesheets/railspress/admin/layout.css +256 -0
- data/app/assets/stylesheets/railspress/admin/lists.css +24 -0
- data/app/assets/stylesheets/railspress/admin/page.css +111 -0
- data/app/assets/stylesheets/railspress/admin/responsive.css +174 -0
- data/app/assets/stylesheets/railspress/admin/stats.css +43 -0
- data/app/assets/stylesheets/railspress/admin/tables.css +163 -0
- data/app/assets/stylesheets/railspress/admin/utilities.css +202 -0
- data/app/assets/stylesheets/railspress/admin/variables.css +58 -0
- data/app/assets/stylesheets/railspress/application.css +44 -13
- data/app/controllers/railspress/admin/base_controller.rb +6 -3
- data/app/controllers/railspress/admin/categories_controller.rb +1 -1
- data/app/controllers/railspress/admin/cms_transfers_controller.rb +49 -0
- data/app/controllers/railspress/admin/content_element_versions_controller.rb +12 -0
- data/app/controllers/railspress/admin/content_elements_controller.rb +143 -0
- data/app/controllers/railspress/admin/content_groups_controller.rb +69 -0
- data/app/controllers/railspress/admin/dashboard_controller.rb +6 -0
- data/app/controllers/railspress/admin/entities_controller.rb +157 -0
- data/app/controllers/railspress/admin/exports_controller.rb +55 -0
- data/app/controllers/railspress/admin/focal_points_controller.rb +100 -0
- data/app/controllers/railspress/admin/imports_controller.rb +63 -0
- data/app/controllers/railspress/admin/posts_controller.rb +58 -4
- data/app/controllers/railspress/admin/prototypes_controller.rb +30 -0
- data/app/controllers/railspress/admin/tags_controller.rb +1 -1
- data/app/controllers/railspress/application_controller.rb +1 -0
- data/app/helpers/railspress/admin_helper.rb +733 -0
- data/app/helpers/railspress/application_helper.rb +23 -0
- data/app/helpers/railspress/cms_helper.rb +338 -0
- data/app/javascript/railspress/controllers/cms_inline_editor_controller.js +130 -0
- data/app/javascript/railspress/controllers/content_element_form_controller.js +15 -0
- data/app/javascript/railspress/controllers/crop_controller.js +224 -0
- data/app/javascript/railspress/controllers/dropzone_controller.js +261 -0
- data/app/javascript/railspress/controllers/focal_point_controller.js +124 -0
- data/app/javascript/railspress/controllers/image_section_controller.js +94 -0
- data/app/javascript/railspress/controllers/index.js +37 -0
- data/app/javascript/railspress/index.js +59 -0
- data/app/jobs/railspress/export_posts_job.rb +16 -0
- data/app/jobs/railspress/import_posts_job.rb +44 -0
- data/app/models/concerns/railspress/has_focal_point.rb +242 -0
- data/app/models/concerns/railspress/soft_deletable.rb +23 -0
- data/app/models/concerns/railspress/taggable.rb +23 -0
- data/app/models/railspress/content_element.rb +103 -0
- data/app/models/railspress/content_element_version.rb +32 -0
- data/app/models/railspress/content_group.rb +39 -0
- data/app/models/railspress/export.rb +67 -0
- data/app/models/railspress/focal_point.rb +70 -0
- data/app/models/railspress/import.rb +65 -0
- data/app/models/railspress/post.rb +102 -15
- data/app/models/railspress/post_export_processor.rb +162 -0
- data/app/models/railspress/post_import_processor.rb +382 -0
- data/app/models/railspress/tag.rb +7 -2
- data/app/models/railspress/tagging.rb +11 -0
- data/app/services/railspress/content_export_service.rb +122 -0
- data/app/services/railspress/content_import_service.rb +228 -0
- data/app/views/action_text/attachables/_remote_image.html.erb +8 -0
- data/app/views/active_storage/blobs/_blob.html.erb +1 -1
- data/app/views/layouts/railspress/admin.html.erb +3 -1
- data/app/views/railspress/admin/categories/index.html.erb +11 -15
- data/app/views/railspress/admin/cms_transfers/show.html.erb +167 -0
- data/app/views/railspress/admin/content_element_versions/show.html.erb +42 -0
- data/app/views/railspress/admin/content_elements/_form.html.erb +71 -0
- data/app/views/railspress/admin/content_elements/_inline_form.html.erb +32 -0
- data/app/views/railspress/admin/content_elements/_inline_form_frame.html.erb +6 -0
- data/app/views/railspress/admin/content_elements/edit.html.erb +6 -0
- data/app/views/railspress/admin/content_elements/index.html.erb +74 -0
- data/app/views/railspress/admin/content_elements/new.html.erb +6 -0
- data/app/views/railspress/admin/content_elements/show.html.erb +124 -0
- data/app/views/railspress/admin/content_groups/_form.html.erb +9 -0
- data/app/views/railspress/admin/content_groups/edit.html.erb +6 -0
- data/app/views/railspress/admin/content_groups/index.html.erb +42 -0
- data/app/views/railspress/admin/content_groups/new.html.erb +6 -0
- data/app/views/railspress/admin/content_groups/show.html.erb +92 -0
- data/app/views/railspress/admin/dashboard/index.html.erb +36 -1
- data/app/views/railspress/admin/entities/_form.html.erb +53 -0
- data/app/views/railspress/admin/entities/edit.html.erb +4 -0
- data/app/views/railspress/admin/entities/index.html.erb +74 -0
- data/app/views/railspress/admin/entities/new.html.erb +4 -0
- data/app/views/railspress/admin/entities/show.html.erb +117 -0
- data/app/views/railspress/admin/exports/show.html.erb +62 -0
- data/app/views/railspress/admin/imports/_instructions.html.erb +56 -0
- data/app/views/railspress/admin/imports/show.html.erb +137 -0
- data/app/views/railspress/admin/posts/_form.html.erb +102 -28
- data/app/views/railspress/admin/posts/_post_row.html.erb +40 -0
- data/app/views/railspress/admin/posts/index.html.erb +47 -36
- data/app/views/railspress/admin/posts/show.html.erb +55 -19
- data/app/views/railspress/admin/prototypes/image_section.html.erb +42 -0
- data/app/views/railspress/admin/shared/_dropzone.html.erb +84 -0
- data/app/views/railspress/admin/shared/_focal_point_editor.html.erb +102 -0
- data/app/views/railspress/admin/shared/_image_section.html.erb +159 -0
- data/app/views/railspress/admin/shared/_image_section_compact.html.erb +90 -0
- data/app/views/railspress/admin/shared/_image_section_editor.html.erb +171 -0
- data/app/views/railspress/admin/shared/_image_section_v2.html.erb +205 -0
- data/app/views/railspress/admin/shared/_sidebar.html.erb +73 -5
- data/app/views/railspress/admin/tags/index.html.erb +12 -16
- data/config/brakeman.ignore +18 -0
- data/config/importmap.rb +20 -0
- data/config/routes.rb +62 -1
- data/db/migrate/20241218000004_create_railspress_post_tags.rb +1 -1
- data/db/migrate/20241218000005_create_railspress_imports.rb +21 -0
- data/db/migrate/20241218000006_create_railspress_exports.rb +20 -0
- data/db/migrate/20241218000007_create_railspress_taggings.rb +20 -0
- data/db/migrate/20241218000008_drop_railspress_post_tags.rb +14 -0
- data/db/migrate/20241218000010_add_reading_time_to_railspress_posts.rb +5 -0
- data/db/migrate/20250105000002_create_railspress_focal_points.rb +20 -0
- data/db/migrate/20260206000001_create_railspress_content_groups.rb +18 -0
- data/db/migrate/20260206000002_create_railspress_content_elements.rb +21 -0
- data/db/migrate/20260206000003_create_railspress_content_element_versions.rb +20 -0
- data/db/migrate/20260207000001_add_unique_index_to_content_elements.rb +11 -0
- data/db/migrate/20260211112812_add_image_hint_to_railspress_content_elements.rb +7 -0
- data/db/migrate/20260211154040_add_required_to_railspress_content_elements.rb +5 -0
- data/lib/generators/railspress/entity/entity_generator.rb +89 -0
- data/lib/generators/railspress/entity/templates/migration.rb.tt +13 -0
- data/lib/generators/railspress/entity/templates/model.rb.tt +21 -0
- data/lib/generators/railspress/install/install_generator.rb +11 -20
- data/lib/generators/railspress/install/templates/initializer.rb +29 -0
- data/lib/railspress/engine.rb +38 -0
- data/lib/railspress/entity.rb +239 -0
- data/lib/railspress/version.rb +1 -1
- data/lib/railspress.rb +198 -8
- data/lib/tasks/railspress_tasks.rake +49 -4
- metadata +203 -14
- data/MIT-LICENSE +0 -20
- data/app/assets/stylesheets/railspress/admin.css +0 -1207
- data/app/models/railspress/post_tag.rb +0 -8
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class CreateRailspressImports < ActiveRecord::Migration[7.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :railspress_imports do |t|
|
|
4
|
+
t.string :import_type, null: false
|
|
5
|
+
t.string :filename
|
|
6
|
+
t.string :content_type
|
|
7
|
+
t.string :status, default: "pending", null: false
|
|
8
|
+
t.integer :total_count, default: 0
|
|
9
|
+
t.integer :success_count, default: 0
|
|
10
|
+
t.integer :error_count, default: 0
|
|
11
|
+
t.text :error_messages
|
|
12
|
+
t.bigint :user_id
|
|
13
|
+
|
|
14
|
+
t.timestamps
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
add_index :railspress_imports, :import_type
|
|
18
|
+
add_index :railspress_imports, :status
|
|
19
|
+
add_index :railspress_imports, :user_id
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class CreateRailspressExports < ActiveRecord::Migration[7.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :railspress_exports do |t|
|
|
4
|
+
t.string :export_type, null: false
|
|
5
|
+
t.string :filename
|
|
6
|
+
t.string :status, default: "pending", null: false
|
|
7
|
+
t.integer :total_count, default: 0
|
|
8
|
+
t.integer :success_count, default: 0
|
|
9
|
+
t.integer :error_count, default: 0
|
|
10
|
+
t.text :error_messages
|
|
11
|
+
t.bigint :user_id
|
|
12
|
+
|
|
13
|
+
t.timestamps
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
add_index :railspress_exports, :export_type
|
|
17
|
+
add_index :railspress_exports, :status
|
|
18
|
+
add_index :railspress_exports, :user_id
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
class CreateRailspressTaggings < ActiveRecord::Migration[8.0]
|
|
2
|
+
def change
|
|
3
|
+
create_table :railspress_taggings do |t|
|
|
4
|
+
t.references :tag, null: false, foreign_key: { to_table: :railspress_tags }
|
|
5
|
+
t.references :taggable, polymorphic: true, null: false
|
|
6
|
+
t.timestamps
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
# Unique constraint: one tag per taggable
|
|
10
|
+
add_index :railspress_taggings,
|
|
11
|
+
[ :tag_id, :taggable_type, :taggable_id ],
|
|
12
|
+
unique: true,
|
|
13
|
+
name: "index_taggings_unique"
|
|
14
|
+
|
|
15
|
+
# For "find all entities with tag X" queries
|
|
16
|
+
add_index :railspress_taggings,
|
|
17
|
+
[ :taggable_type, :taggable_id ],
|
|
18
|
+
name: "index_taggings_on_taggable"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
class DropRailspressPostTags < ActiveRecord::Migration[8.0]
|
|
2
|
+
def up
|
|
3
|
+
drop_table :railspress_post_tags
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
def down
|
|
7
|
+
create_table :railspress_post_tags do |t|
|
|
8
|
+
t.references :post, null: false, foreign_key: { to_table: :railspress_posts }
|
|
9
|
+
t.references :tag, null: false, foreign_key: { to_table: :railspress_tags }
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
add_index :railspress_post_tags, [ :post_id, :tag_id ], unique: true
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateRailspressFocalPoints < ActiveRecord::Migration[8.0]
|
|
4
|
+
def change
|
|
5
|
+
create_table :railspress_focal_points do |t|
|
|
6
|
+
t.references :record, polymorphic: true, null: false, index: false
|
|
7
|
+
t.string :attachment_name, null: false
|
|
8
|
+
t.decimal :focal_x, precision: 5, scale: 4, default: 0.5, null: false
|
|
9
|
+
t.decimal :focal_y, precision: 5, scale: 4, default: 0.5, null: false
|
|
10
|
+
t.json :overrides, default: {}
|
|
11
|
+
|
|
12
|
+
t.timestamps
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
add_index :railspress_focal_points,
|
|
16
|
+
[ :record_type, :record_id, :attachment_name ],
|
|
17
|
+
unique: true,
|
|
18
|
+
name: "idx_focal_points_record_attachment"
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateRailspressContentGroups < ActiveRecord::Migration[8.0]
|
|
4
|
+
def change
|
|
5
|
+
create_table :railspress_content_groups do |t|
|
|
6
|
+
t.string :name, null: false
|
|
7
|
+
t.text :description
|
|
8
|
+
t.bigint :author_id
|
|
9
|
+
t.datetime :deleted_at
|
|
10
|
+
|
|
11
|
+
t.timestamps
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
add_index :railspress_content_groups, :name, unique: true
|
|
15
|
+
add_index :railspress_content_groups, :deleted_at
|
|
16
|
+
add_index :railspress_content_groups, :author_id
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateRailspressContentElements < ActiveRecord::Migration[8.0]
|
|
4
|
+
def change
|
|
5
|
+
create_table :railspress_content_elements do |t|
|
|
6
|
+
t.string :name, null: false
|
|
7
|
+
t.integer :content_type, default: 0, null: false
|
|
8
|
+
t.text :text_content
|
|
9
|
+
t.references :content_group, null: false, foreign_key: { to_table: :railspress_content_groups }
|
|
10
|
+
t.bigint :author_id
|
|
11
|
+
t.integer :position
|
|
12
|
+
t.datetime :deleted_at
|
|
13
|
+
|
|
14
|
+
t.timestamps
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
add_index :railspress_content_elements, :deleted_at
|
|
18
|
+
add_index :railspress_content_elements, :author_id
|
|
19
|
+
add_index :railspress_content_elements, :content_type
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateRailspressContentElementVersions < ActiveRecord::Migration[8.0]
|
|
4
|
+
def change
|
|
5
|
+
create_table :railspress_content_element_versions do |t|
|
|
6
|
+
t.references :content_element, null: false, foreign_key: { to_table: :railspress_content_elements }
|
|
7
|
+
t.bigint :author_id
|
|
8
|
+
t.text :text_content
|
|
9
|
+
t.integer :version_number, null: false
|
|
10
|
+
|
|
11
|
+
t.timestamps
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
add_index :railspress_content_element_versions,
|
|
15
|
+
[ :content_element_id, :version_number ],
|
|
16
|
+
unique: true,
|
|
17
|
+
name: "idx_content_element_versions_unique"
|
|
18
|
+
add_index :railspress_content_element_versions, :author_id
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class AddUniqueIndexToContentElements < ActiveRecord::Migration[8.1]
|
|
4
|
+
def change
|
|
5
|
+
add_index :railspress_content_elements,
|
|
6
|
+
[ :content_group_id, :name ],
|
|
7
|
+
unique: true,
|
|
8
|
+
where: "deleted_at IS NULL",
|
|
9
|
+
name: "idx_content_elements_unique_name_per_group"
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rails/generators"
|
|
4
|
+
require "rails/generators/active_record"
|
|
5
|
+
|
|
6
|
+
module Railspress
|
|
7
|
+
module Generators
|
|
8
|
+
class EntityGenerator < Rails::Generators::NamedBase
|
|
9
|
+
include ActiveRecord::Generators::Migration
|
|
10
|
+
|
|
11
|
+
source_root File.expand_path("templates", __dir__)
|
|
12
|
+
|
|
13
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
|
14
|
+
|
|
15
|
+
desc "Generate a RailsPress-managed entity with model, migration, and registration"
|
|
16
|
+
|
|
17
|
+
def create_model_file
|
|
18
|
+
template "model.rb.tt", File.join("app/models", "#{file_name}.rb")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def create_migration
|
|
22
|
+
migration_template "migration.rb.tt", File.join(db_migrate_path, "create_#{table_name}.rb")
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def add_registration
|
|
26
|
+
initializer_file = "config/initializers/railspress.rb"
|
|
27
|
+
|
|
28
|
+
unless File.exist?(initializer_file)
|
|
29
|
+
create_file initializer_file, <<~RUBY
|
|
30
|
+
# frozen_string_literal: true
|
|
31
|
+
|
|
32
|
+
Railspress.configure do |config|
|
|
33
|
+
# Register your CMS-managed entities here
|
|
34
|
+
# config.register_entity Project
|
|
35
|
+
end
|
|
36
|
+
RUBY
|
|
37
|
+
say_status :created, "RailsPress initializer", :green
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
inject_into_file initializer_file, after: "Railspress.configure do |config|\n" do
|
|
41
|
+
" config.register_entity #{class_name}\n"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
say_status :registered, "#{class_name} entity", :green
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def show_next_steps
|
|
48
|
+
say ""
|
|
49
|
+
say "=" * 60, :green
|
|
50
|
+
say " Entity #{class_name} created!", :green
|
|
51
|
+
say "=" * 60, :green
|
|
52
|
+
say ""
|
|
53
|
+
say "Next steps:", :yellow
|
|
54
|
+
say ""
|
|
55
|
+
say " 1. Run the migration:"
|
|
56
|
+
say " $ rails db:migrate", :cyan
|
|
57
|
+
say ""
|
|
58
|
+
say " 2. Restart your Rails server"
|
|
59
|
+
say ""
|
|
60
|
+
say " 3. Access #{class_name} in the admin:"
|
|
61
|
+
say " /railspress/admin/entities/#{table_name}", :cyan
|
|
62
|
+
say ""
|
|
63
|
+
say "=" * 60, :green
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
private
|
|
67
|
+
|
|
68
|
+
def db_migrate_path
|
|
69
|
+
"db/migrate"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def rich_text_fields
|
|
73
|
+
attributes.select { |a| a.type == :rich_text }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def regular_attributes
|
|
77
|
+
attributes.reject { |a| a.type == :rich_text }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def railspress_field_names
|
|
81
|
+
attributes.map { |a| ":#{a.name}" }.join(", ")
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def migration_version
|
|
85
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class Create<%= class_name.pluralize %> < ActiveRecord::Migration<%= migration_version %>
|
|
4
|
+
def change
|
|
5
|
+
create_table :<%= table_name %> do |t|
|
|
6
|
+
<% regular_attributes.each do |attribute| -%>
|
|
7
|
+
t.<%= attribute.type %> :<%= attribute.name %>
|
|
8
|
+
<% end -%>
|
|
9
|
+
|
|
10
|
+
t.timestamps
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class <%= class_name %> < ApplicationRecord
|
|
4
|
+
include Railspress::Entity
|
|
5
|
+
<% rich_text_fields.each do |attribute| -%>
|
|
6
|
+
|
|
7
|
+
has_rich_text :<%= attribute.name %>
|
|
8
|
+
<% end -%>
|
|
9
|
+
|
|
10
|
+
# Declare which fields appear in the CMS admin
|
|
11
|
+
railspress_fields <%= railspress_field_names %>
|
|
12
|
+
<% rich_text_fields.each do |attribute| -%>
|
|
13
|
+
railspress_fields :<%= attribute.name %>, as: :rich_text
|
|
14
|
+
<% end -%>
|
|
15
|
+
|
|
16
|
+
# Optional: customize sidebar label (defaults to pluralized class name)
|
|
17
|
+
# railspress_label "Custom Label"
|
|
18
|
+
|
|
19
|
+
# Add your validations
|
|
20
|
+
# validates :title, presence: true
|
|
21
|
+
end
|
|
@@ -72,23 +72,14 @@ module Railspress
|
|
|
72
72
|
end
|
|
73
73
|
end
|
|
74
74
|
|
|
75
|
-
def
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
application_js = Rails.root.join("app", "javascript", "application.js")
|
|
79
|
-
return unless File.exist?(application_js)
|
|
80
|
-
|
|
81
|
-
js_content = File.read(application_js)
|
|
75
|
+
def generate_initializer
|
|
76
|
+
initializer_path = Rails.root.join("config", "initializers", "railspress.rb")
|
|
82
77
|
|
|
83
|
-
if
|
|
84
|
-
say_status :skip, "
|
|
78
|
+
if File.exist?(initializer_path)
|
|
79
|
+
say_status :skip, "config/initializers/railspress.rb already exists", :yellow
|
|
85
80
|
else
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// RailsPress rich text editor
|
|
89
|
-
import "lexxy"
|
|
90
|
-
JS
|
|
91
|
-
say_status :added, "Lexxy import to application.js", :green
|
|
81
|
+
template "initializer.rb", initializer_path
|
|
82
|
+
say_status :created, "config/initializers/railspress.rb", :green
|
|
92
83
|
end
|
|
93
84
|
end
|
|
94
85
|
|
|
@@ -109,11 +100,11 @@ module Railspress
|
|
|
109
100
|
say " 3. (Optional) Change the mount path in config/routes.rb:"
|
|
110
101
|
say " mount Railspress::Engine => \"/blog\"", :cyan
|
|
111
102
|
say ""
|
|
112
|
-
say "
|
|
113
|
-
say "
|
|
114
|
-
say "
|
|
115
|
-
say ""
|
|
116
|
-
say "
|
|
103
|
+
say "Optional features:", :yellow
|
|
104
|
+
say " Edit config/initializers/railspress.rb to enable:"
|
|
105
|
+
say " - CMS content elements (config.enable_cms)"
|
|
106
|
+
say " - Inline CMS editing (config.inline_editing_check)"
|
|
107
|
+
say " See docs/CONFIGURING.md and docs/INLINE_EDITING.md for details."
|
|
117
108
|
say ""
|
|
118
109
|
say "=" * 60, :green
|
|
119
110
|
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Railspress.configure do |config|
|
|
4
|
+
# === Blog Features (always available) ===
|
|
5
|
+
|
|
6
|
+
# Author tracking for posts and content elements.
|
|
7
|
+
# Uncomment to enable:
|
|
8
|
+
# config.enable_authors
|
|
9
|
+
# config.author_class_name = "User"
|
|
10
|
+
# config.current_author_method = :current_user
|
|
11
|
+
|
|
12
|
+
# === CMS Content Elements (opt-in) ===
|
|
13
|
+
# Adds content groups, content elements, and the cms_element/cms_value
|
|
14
|
+
# view helpers for managing structured content on your site.
|
|
15
|
+
# Image elements support dropzone upload and focal points when
|
|
16
|
+
# enable_focal_points is also active.
|
|
17
|
+
# See docs/CONFIGURING.md for details.
|
|
18
|
+
# Uncomment to enable:
|
|
19
|
+
# config.enable_cms
|
|
20
|
+
|
|
21
|
+
# === Inline CMS Editing (requires enable_cms) ===
|
|
22
|
+
# Right-click editing of CMS content on public pages.
|
|
23
|
+
# Also requires: import "railspress" in your application.js
|
|
24
|
+
# and yield :head in your layout. See docs/INLINE_EDITING.md.
|
|
25
|
+
# Uncomment to enable:
|
|
26
|
+
# config.inline_editing_check = ->(context) {
|
|
27
|
+
# context.controller.current_user&.admin?
|
|
28
|
+
# }
|
|
29
|
+
end
|
data/lib/railspress/engine.rb
CHANGED
|
@@ -6,8 +6,46 @@ module Railspress
|
|
|
6
6
|
initializer "railspress.assets" do |app|
|
|
7
7
|
if app.config.respond_to?(:assets)
|
|
8
8
|
app.config.assets.paths << root.join("app", "assets", "stylesheets").to_s
|
|
9
|
+
app.config.assets.paths << root.join("app", "assets", "stylesheets", "railspress").to_s
|
|
9
10
|
app.config.assets.paths << root.join("app", "assets", "javascripts").to_s
|
|
10
11
|
app.config.assets.paths << root.join("app", "assets", "images").to_s
|
|
12
|
+
app.config.assets.paths << root.join("app", "javascript").to_s
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Make CMS helper available to host application views (or stub when disabled)
|
|
17
|
+
initializer "railspress.cms_helper" do
|
|
18
|
+
ActiveSupport.on_load(:action_view) do
|
|
19
|
+
if Railspress.cms_enabled?
|
|
20
|
+
include Railspress::CmsHelper
|
|
21
|
+
else
|
|
22
|
+
include Railspress::CmsHelper::DisabledStub
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Clear CMS cache on each request in development
|
|
28
|
+
initializer "railspress.cms_cache" do |app|
|
|
29
|
+
if Railspress.cms_enabled?
|
|
30
|
+
app.config.to_prepare do
|
|
31
|
+
Railspress::CmsHelper.clear_cache
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Validate configuration after all initializers have run
|
|
37
|
+
initializer "railspress.validate_config" do
|
|
38
|
+
if Railspress.inline_editing_check && !Railspress.cms_enabled?
|
|
39
|
+
raise Railspress::ConfigurationError,
|
|
40
|
+
"Inline editing requires CMS. Add `config.enable_cms` to your initializer."
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Configure importmap for Stimulus controllers
|
|
45
|
+
initializer "railspress.importmap", before: "importmap" do |app|
|
|
46
|
+
if app.respond_to?(:importmap)
|
|
47
|
+
app.config.importmap.paths << root.join("config", "importmap.rb")
|
|
48
|
+
app.config.importmap.cache_sweepers << root.join("app", "javascript")
|
|
11
49
|
end
|
|
12
50
|
end
|
|
13
51
|
end
|