ruby_cms 0.2.1.0 → 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/CHANGELOG.md +31 -72
- data/README.md +308 -153
- data/Rakefile +0 -18
- data/SYNC_RULES.md +84 -0
- data/exe/ruby_cms +13 -18
- data/lib/generators/ruby_cms/admin_page_generator.rb +116 -60
- data/lib/generators/ruby_cms/templates/admin.html.erb +35 -17
- data/lib/generators/ruby_cms/templates/admin_page/_admin_table_content.html.erb.tt +25 -0
- data/lib/generators/ruby_cms/templates/admin_page/_form.html.erb.tt +36 -0
- data/lib/generators/ruby_cms/templates/admin_page/_row.html.erb.tt +20 -0
- data/lib/generators/ruby_cms/templates/admin_page/controller.rb.tt +74 -2
- data/lib/generators/ruby_cms/templates/admin_page/edit.html.erb.tt +14 -0
- data/lib/generators/ruby_cms/templates/admin_page/index.html.erb.tt +21 -10
- data/lib/generators/ruby_cms/templates/admin_page/new.html.erb.tt +14 -0
- data/lib/generators/ruby_cms/templates/assets/tailwind/application.css +225 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/accordion/accordion.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/accordion/accordion_content.rb +21 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/accordion/accordion_default_content.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/accordion/accordion_default_trigger.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/accordion/accordion_icon.rb +38 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/accordion/accordion_item.rb +28 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/accordion/accordion_trigger.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/admin_page/admin_page.rb +31 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/admin_page/admin_page_header.rb +65 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/admin_page/admin_resource_card.rb +28 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/admin_page/admin_table_content.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/alert/alert.rb +36 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/alert/alert_description.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/alert/alert_title.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/aspect_ratio/aspect_ratio.rb +33 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/avatar/avatar.rb +31 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/avatar/avatar_fallback.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/avatar/avatar_image.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/badge/badge.rb +60 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/base.rb +29 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/box/box.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/breadcrumb/breadcrumb.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/breadcrumb/breadcrumb_ellipsis.rb +39 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/breadcrumb/breadcrumb_item.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/breadcrumb/breadcrumb_link.rb +22 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/breadcrumb/breadcrumb_list.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/breadcrumb/breadcrumb_page.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/breadcrumb/breadcrumb_separator.rb +38 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_button.rb +82 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table.rb +133 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_actions.rb +104 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_body.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_checkbox_cell.rb +40 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_checkbox_head.rb +34 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_delete_modal.rb +43 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_header.rb +42 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_pagination.rb +115 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_action_table_row.rb +77 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/bulk_action_table/bulk_actions.rb +86 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/button/button.rb +113 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar.rb +39 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar_body.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar_days.rb +104 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar_header.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar_next.rb +43 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar_prev.rb +43 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar_title.rb +27 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/calendar/calendar_weekdays.rb +33 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/card/card.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/card/card_content.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/card/card_description.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/card/card_footer.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/card/card_header.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/card/card_title.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/carousel/carousel.rb +44 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/carousel/carousel_content.rb +23 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/carousel/carousel_item.rb +23 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/carousel/carousel_next.rb +48 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/carousel/carousel_previous.rb +49 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/checkbox/checkbox.rb +29 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/checkbox/checkbox_group.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/clipboard/clipboard.rb +42 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/clipboard/clipboard_popover.rb +40 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/clipboard/clipboard_source.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/clipboard/clipboard_trigger.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/codeblock/codeblock.rb +102 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/collapsible/collapsible.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/collapsible/collapsible_content.rb +18 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/collapsible/collapsible_trigger.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_checkbox.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_empty_state.rb +21 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_item.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_list.rb +18 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_list_group.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_popover.rb +30 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_radio.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_search_input.rb +53 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_toggle_all_checkbox.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/combobox/combobox_trigger.rb +57 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command.rb +9 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_dialog.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_dialog_content.rb +48 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_dialog_trigger.rb +29 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_empty.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_group.rb +40 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_input.rb +56 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_item.rb +32 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/command/command_list.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/container/container.rb +33 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/container/container_section.rb +31 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/context_menu/context_menu.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/context_menu/context_menu_content.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/context_menu/context_menu_item.rb +66 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/context_menu/context_menu_label.rb +24 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/context_menu/context_menu_separator.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/context_menu/context_menu_trigger.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table.rb +29 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_bulk_actions.rb +18 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_column_toggle.rb +62 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_expand_toggle.rb +53 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_form.rb +39 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_kaminari_adapter.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_manual_adapter.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_pagination.rb +100 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_pagination_bar.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_pagy_adapter.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_per_page_select.rb +35 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_row_checkbox.rb +30 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_search.rb +57 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_select_all_checkbox.rb +21 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_selection_summary.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_sort_head.rb +112 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/data_table/data_table_toolbar.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog_content.rb +78 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog_description.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog_footer.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog_header.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog_middle.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog_title.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dialog/dialog_trigger.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dropdown_menu/dropdown_menu.rb +35 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dropdown_menu/dropdown_menu_content.rb +44 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dropdown_menu/dropdown_menu_item.rb +28 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dropdown_menu/dropdown_menu_label.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dropdown_menu/dropdown_menu_separator.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/dropdown_menu/dropdown_menu_trigger.rb +18 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/empty_state/empty_state.rb +190 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/form/form.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/form/form_field.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/form/form_field_error.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/form/form_field_hint.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/form/form_field_label.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/hover_card/hover_card.rb +27 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/hover_card/hover_card_content.rb +22 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/hover_card/hover_card_trigger.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/input/input.rb +34 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/link/link.rb +106 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/masked_input/masked_input.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal_action.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal_cancel.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal_content.rb +68 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal_description.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal_footer.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal_header.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/modal/modal_title.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/native_select/native_select.rb +39 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/native_select/native_select_group.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/native_select/native_select_icon.rb +39 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/native_select/native_select_option.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/pagination/pagination.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/pagination/pagination_content.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/pagination/pagination_ellipsis.rb +42 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/pagination/pagination_item.rb +28 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/popover/popover.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/popover/popover_content.rb +27 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/popover/popover_trigger.rb +20 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/progress/progress.rb +37 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/radio_button/radio_button.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select.rb +23 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select_content.rb +32 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select_group.rb +15 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select_input.rb +22 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select_item.rb +52 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select_label.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select_trigger.rb +54 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/select/select_value.rb +27 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/separator/separator.rb +38 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet_content.rb +77 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet_description.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet_footer.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet_header.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet_middle.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet_title.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/sheet/sheet_trigger.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/shortcut_key/shortcut_key.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/skeleton/skeleton.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/switch/switch.rb +24 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table_body.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table_caption.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table_cell.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table_footer.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table_head.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table_header.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/table/table_row.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/tabs/tabs.rb +25 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/tabs/tabs_content.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/tabs/tabs_list.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/tabs/tabs_trigger.rb +28 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/textarea/textarea.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/theme_toggle/set_dark_mode.rb +16 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/theme_toggle/set_light_mode.rb +16 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/theme_toggle/theme_toggle.rb +9 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/tooltip/tooltip.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/tooltip/tooltip_content.rb +26 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/tooltip/tooltip_trigger.rb +19 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/typography/heading.rb +60 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/typography/inline_code.rb +17 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/typography/inline_link.rb +22 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/typography/text.rb +53 -0
- data/lib/generators/ruby_cms/templates/components/ruby_ui/typography/typography_blockquote.rb +17 -0
- data/lib/generators/ruby_cms/templates/{ruby_cms.rb → config/initializers/admin.rb} +15 -9
- data/lib/generators/ruby_cms/templates/config/initializers/admin_dashboard.rb +43 -0
- data/lib/generators/ruby_cms/templates/config/initializers/pagy.rb +7 -0
- data/lib/generators/ruby_cms/templates/config/initializers/ruby_cms_core.rb +25 -0
- data/lib/generators/ruby_cms/templates/config/initializers/ruby_cms_custom_settings.rb +35 -0
- data/lib/generators/ruby_cms/templates/config/initializers/webauthn.rb +28 -0
- data/lib/generators/ruby_cms/templates/config/locales/en.yml +277 -0
- data/lib/generators/ruby_cms/templates/config/locales/nl.yml +329 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/analytics_controller.rb +211 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/application_controller.rb +186 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/audit_log_entries_controller.rb +69 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/commands_controller.rb +146 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/content_block_versions_controller.rb +96 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/content_blocks_controller.rb +405 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/dashboard_controller.rb +114 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/invitations_controller.rb +64 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/locale_controller.rb +19 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/media_assets_controller.rb +186 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/notifications_controller.rb +37 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/passkey_credentials_controller.rb +17 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/passkey_registrations_controller.rb +50 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/permissions_controller.rb +132 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/redirects_controller.rb +175 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/security_controller.rb +146 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/settings_controller.rb +298 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/system_health_controller.rb +11 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/trash_controller.rb +61 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/user_permissions_controller.rb +91 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/users_controller.rb +220 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/visitor_errors_controller.rb +114 -0
- data/lib/generators/ruby_cms/templates/controllers/admin/visual_editor_controller.rb +384 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/.keep +0 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/admin_bulk_actions.rb +59 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/admin_pagination.rb +106 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/admin_turbo_table.rb +46 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/audit_loggable.rb +28 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/authentication.rb +63 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/page_tracking.rb +45 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/security_monitoring.rb +102 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/sudo_mode.rb +29 -0
- data/lib/generators/ruby_cms/templates/controllers/concerns/visitor_error_capture.rb +35 -0
- data/lib/generators/ruby_cms/templates/controllers/errors_controller.rb +36 -0
- data/lib/generators/ruby_cms/templates/controllers/passkey_sessions_controller.rb +69 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20251121085414_create_email_blocklists.rb +12 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20251121161828_create_ip_blocklists.rb +12 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20251205120000_add_analytics_indices.rb +48 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20251216064753_backfill_security_fields_in_ahoy_events.rb +49 -0
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260125000001_create_ruby_cms_permissions.rb +2 -2
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260125000002_create_ruby_cms_user_permissions.rb +2 -2
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260125000003_create_ruby_cms_content_blocks.rb +3 -3
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260125000010_add_indexes_to_ruby_cms_tables.rb +1 -1
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260127000001_add_locale_to_ruby_cms_content_blocks.rb +8 -6
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260129000001_create_ruby_cms_visitor_errors.rb +4 -4
- data/lib/generators/ruby_cms/templates/db/migrate/20260130000001_add_referer_and_query_to_ruby_cms_visitor_errors.rb +10 -0
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260130000002_create_ruby_cms_preferences.rb +2 -2
- data/lib/generators/ruby_cms/templates/db/migrate/20260130000003_add_category_to_ruby_cms_preferences.rb +10 -0
- data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260328000001_create_content_block_versions.rb +2 -2
- data/lib/generators/ruby_cms/templates/db/migrate/20260525120000_create_audit_log_entries.rb +24 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260525130000_create_redirects.rb +28 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260525140000_create_media_assets.rb +25 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260525150000_create_invitations.rb +22 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260525160000_create_command_runs.rb +22 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260525190000_add_state_to_visitor_errors.rb +20 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260527165017_add_discarded_at_to_visitor_errors.rb +10 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260527165728_add_discarded_at_to_cms_tables.rb +12 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260605151935_create_passkey_credentials.rb +15 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260605151936_add_webauthn_id_to_users.rb +22 -0
- data/lib/generators/ruby_cms/templates/db/migrate/20260606000001_add_authenticated_at_to_sessions.rb +14 -0
- data/lib/generators/ruby_cms/templates/helpers/admin/admin_page_helper.rb +9 -0
- data/lib/generators/ruby_cms/templates/helpers/admin/dashboard_helper.rb +16 -0
- data/lib/generators/ruby_cms/templates/helpers/admin/media_assets_helper.rb +38 -0
- data/lib/generators/ruby_cms/templates/helpers/admin/relative_time_helper.rb +37 -0
- data/lib/generators/ruby_cms/templates/helpers/admin/ui_helper.rb +48 -0
- data/lib/generators/ruby_cms/templates/helpers/cms_application_helpers.rb +70 -0
- data/lib/generators/ruby_cms/templates/helpers/content_blocks_helper.rb +382 -0
- data/lib/generators/ruby_cms/templates/helpers/settings_helper.rb +192 -0
- data/lib/generators/ruby_cms/templates/javascript/admin.js +6 -0
- data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/admin}/admin_commands_controller.js +2 -2
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/autosearch_controller.js +18 -0
- data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/admin}/clickable_row_controller.js +11 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/clipboard_controller.js +34 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/command_palette_controller.js +189 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/commands_controller.js +300 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/content_block_history_controller.js +167 -0
- data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/admin}/flash_messages_controller.js +1 -1
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/inline_rich_editor_controller.js +157 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/media_selection_controller.js +76 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/media_uploader_controller.js +23 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/mobile_menu_controller.js +125 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/nav_order_sortable_controller.js +296 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/nav_shortcuts_controller.js +47 -0
- data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/admin}/page_preview_controller.js +64 -3
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/permission_matrix_controller.js +49 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/search_shortcut_controller.js +24 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/settings_rail_search_controller.js +17 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/shortcuts_overlay_controller.js +39 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/sidebar_collapse_controller.js +135 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/sidebar_nav_persist_controller.js +48 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/sidebar_toggle_trigger_controller.js +10 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/topbar_controller.js +88 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/visual_editor_controller.js +721 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/admin/visual_editor_page_select_controller.js +174 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/application.js +10 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/index.js +2 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/accordion_controller.js +97 -0
- data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui}/bulk_action_table_controller.js +86 -233
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/calendar_controller.js +249 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/calendar_input_controller.js +8 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/carousel_controller.js +60 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/checkbox_group_controller.js +21 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/clipboard_controller.js +54 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/collapsible_controller.js +47 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/combobox_controller.js +190 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/command_controller.js +138 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/context_menu_controller.js +144 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/data_table_column_visibility_controller.js +14 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/data_table_controller.js +109 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/data_table_search_controller.js +62 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/dialog_controller.js +32 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/dropdown_menu_controller.js +149 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/form_field_controller.js +61 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/hover_card_controller.js +153 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/masked_input_controller.js +9 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/modal_controller.js +45 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/popover_controller.js +107 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/select_controller.js +192 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/select_item_controller.js +11 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/sheet_content_controller.js +7 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/sheet_controller.js +9 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/tabs_controller.js +67 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/theme_toggle_controller.js +30 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/ruby_ui/tooltip_controller.js +38 -0
- data/lib/generators/ruby_cms/templates/javascript/controllers/webauthn_controller.js +153 -0
- data/lib/generators/ruby_cms/templates/lib/ruby_cms/cli.rb +170 -0
- data/lib/generators/ruby_cms/templates/lib/ruby_cms/commands_registry.rb +76 -0
- data/lib/{ruby_cms → generators/ruby_cms/templates/lib/ruby_cms}/content_blocks_grouping.rb +2 -6
- data/lib/{ruby_cms → generators/ruby_cms/templates/lib/ruby_cms}/content_blocks_sync.rb +6 -8
- data/lib/{ruby_cms → generators/ruby_cms/templates/lib/ruby_cms}/dashboard_blocks.rb +5 -5
- data/lib/{ruby_cms → generators/ruby_cms/templates/lib/ruby_cms}/icons.rb +41 -10
- data/lib/{ruby_cms → generators/ruby_cms/templates/lib/ruby_cms}/settings.rb +60 -10
- data/lib/{ruby_cms → generators/ruby_cms/templates/lib/ruby_cms}/settings_registry.rb +79 -3
- data/lib/generators/ruby_cms/templates/lib/ruby_cms.rb +342 -0
- data/lib/{tasks → generators/ruby_cms/templates/lib/tasks}/admin.rake +16 -16
- data/lib/generators/ruby_cms/templates/lib/tasks/ruby_cms.rake +158 -0
- data/lib/generators/ruby_cms/templates/models/audit_log_entry.rb +56 -0
- data/lib/generators/ruby_cms/templates/models/command_run.rb +29 -0
- data/lib/generators/ruby_cms/templates/models/concerns/content_block/searchable.rb +18 -0
- data/{app → lib/generators/ruby_cms/templates}/models/concerns/content_block/versionable.rb +1 -1
- data/lib/generators/ruby_cms/templates/models/concerns/ransackable.rb +32 -0
- data/{app → lib/generators/ruby_cms/templates}/models/content_block.rb +13 -5
- data/lib/generators/ruby_cms/templates/models/email_blocklist.rb +21 -0
- data/lib/generators/ruby_cms/templates/models/invitation.rb +86 -0
- data/lib/generators/ruby_cms/templates/models/ip_blocklist.rb +34 -0
- data/lib/generators/ruby_cms/templates/models/media_asset.rb +90 -0
- data/lib/generators/ruby_cms/templates/models/passkey_credential.rb +6 -0
- data/lib/generators/ruby_cms/templates/models/permission.rb +71 -0
- data/lib/generators/ruby_cms/templates/models/permittable.rb +69 -0
- data/lib/generators/ruby_cms/templates/models/preference.rb +109 -0
- data/lib/generators/ruby_cms/templates/models/redirect.rb +100 -0
- data/lib/generators/ruby_cms/templates/models/user_permission.rb +25 -0
- data/lib/generators/ruby_cms/templates/models/visitor_error.rb +157 -0
- data/lib/generators/ruby_cms/templates/nav/analytics.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/audit_log.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/commands.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/content_blocks.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/core.rb +13 -0
- data/lib/generators/ruby_cms/templates/nav/media.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/permissions.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/redirects.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/security.rb +4 -0
- data/lib/generators/ruby_cms/templates/nav/system_health.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/trash.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/users.rb +3 -0
- data/lib/generators/ruby_cms/templates/nav/visual_editor.rb +3 -0
- data/lib/generators/ruby_cms/templates/routes/analytics.rb +5 -0
- data/lib/generators/ruby_cms/templates/routes/audit_log.rb +3 -0
- data/lib/generators/ruby_cms/templates/routes/auth.public.rb +4 -0
- data/lib/generators/ruby_cms/templates/routes/auth.rb +6 -0
- data/lib/generators/ruby_cms/templates/routes/commands.rb +4 -0
- data/lib/generators/ruby_cms/templates/routes/content_blocks.rb +12 -0
- data/lib/generators/ruby_cms/templates/routes/core.public.rb +5 -0
- data/lib/generators/ruby_cms/templates/routes/core.rb +16 -0
- data/lib/generators/ruby_cms/templates/routes/media.rb +9 -0
- data/lib/generators/ruby_cms/templates/routes/passkeys.public.rb +4 -0
- data/lib/generators/ruby_cms/templates/routes/passkeys.rb +5 -0
- data/lib/generators/ruby_cms/templates/routes/permissions.rb +5 -0
- data/lib/generators/ruby_cms/templates/routes/redirects.rb +10 -0
- data/lib/generators/ruby_cms/templates/routes/security.rb +20 -0
- data/lib/generators/ruby_cms/templates/routes/system_health.rb +3 -0
- data/lib/generators/ruby_cms/templates/routes/trash.rb +5 -0
- data/lib/generators/ruby_cms/templates/routes/users.rb +10 -0
- data/lib/generators/ruby_cms/templates/routes/visual_editor.rb +5 -0
- data/lib/generators/ruby_cms/templates/services/admin/health_check.rb +362 -0
- data/lib/generators/ruby_cms/templates/services/analytics/report.rb +503 -0
- data/lib/generators/ruby_cms/templates/services/analytics_service.rb +305 -0
- data/lib/generators/ruby_cms/templates/services/audit_log.rb +60 -0
- data/lib/generators/ruby_cms/templates/services/command_runner.rb +79 -0
- data/lib/generators/ruby_cms/templates/services/security_service.rb +203 -0
- data/lib/generators/ruby_cms/templates/services/security_tracker.rb +90 -0
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/index.html.erb +61 -50
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/page_details.html.erb +15 -10
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_browser_device.html.erb +2 -2
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_conversions.html.erb +3 -3
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_daily_activity_chart.html.erb +18 -17
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_exit_pages.html.erb +4 -4
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_hourly_activity_chart.html.erb +18 -17
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_landing_pages.html.erb +3 -3
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_os_stats.html.erb +2 -2
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_popular_pages.html.erb +4 -4
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_recent_activity.html.erb +4 -4
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_top_referrers.html.erb +3 -3
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_top_visitors.html.erb +4 -4
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_utm_sources.html.erb +2 -2
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/visitor_details.html.erb +15 -10
- data/lib/generators/ruby_cms/templates/views/admin/audit_log_entries/_admin_table_content.html.erb +55 -0
- data/lib/generators/ruby_cms/templates/views/admin/audit_log_entries/_row.html.erb +84 -0
- data/lib/generators/ruby_cms/templates/views/admin/audit_log_entries/index.html.erb +33 -0
- data/lib/generators/ruby_cms/templates/views/admin/audit_log_entries/show.html.erb +89 -0
- data/lib/generators/ruby_cms/templates/views/admin/commands/index.html.erb +393 -0
- data/lib/generators/ruby_cms/templates/views/admin/content_block_versions/index.html.erb +63 -0
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/content_block_versions/show.html.erb +2 -2
- data/lib/generators/ruby_cms/templates/views/admin/content_blocks/_audits.html.erb +49 -0
- data/lib/generators/ruby_cms/templates/views/admin/content_blocks/_form.html.erb +79 -0
- data/lib/generators/ruby_cms/templates/views/admin/content_blocks/_rich_field.html.erb +44 -0
- data/lib/generators/ruby_cms/templates/views/admin/content_blocks/_row.html.erb +60 -0
- data/lib/generators/ruby_cms/templates/views/admin/content_blocks/index.html.erb +84 -0
- data/lib/generators/ruby_cms/templates/views/admin/content_blocks/new.html.erb +18 -0
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/content_blocks/show.html.erb +67 -61
- data/lib/generators/ruby_cms/templates/views/admin/dashboard/_gmail_token_status.html.erb +69 -0
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/dashboard/blocks/_analytics_overview.html.erb +11 -11
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/dashboard/blocks/_content_blocks_stats.html.erb +3 -3
- data/lib/generators/ruby_cms/templates/views/admin/dashboard/blocks/_notifications.html.erb +50 -0
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/dashboard/blocks/_permissions_stats.html.erb +3 -3
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/dashboard/blocks/_quick_actions.html.erb +15 -15
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/dashboard/blocks/_recent_errors.html.erb +8 -8
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/dashboard/blocks/_users_stats.html.erb +3 -3
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/dashboard/blocks/_visitor_errors_stats.html.erb +3 -3
- data/lib/generators/ruby_cms/templates/views/admin/dashboard/index.html.erb +34 -0
- data/lib/generators/ruby_cms/templates/views/admin/media_assets/_admin_table_content.html.erb +107 -0
- data/lib/generators/ruby_cms/templates/views/admin/media_assets/_form.html.erb +33 -0
- data/lib/generators/ruby_cms/templates/views/admin/media_assets/_grid.html.erb +58 -0
- data/lib/generators/ruby_cms/templates/views/admin/media_assets/_list.html.erb +43 -0
- data/lib/generators/ruby_cms/templates/views/admin/media_assets/edit.html.erb +13 -0
- data/lib/generators/ruby_cms/templates/views/admin/media_assets/index.html.erb +36 -0
- data/lib/generators/ruby_cms/templates/views/admin/media_assets/show.html.erb +97 -0
- data/lib/generators/ruby_cms/templates/views/admin/passkey_credentials/index.html.erb +30 -0
- data/lib/generators/ruby_cms/templates/views/admin/passkey_registrations/new.html.erb +23 -0
- data/lib/generators/ruby_cms/templates/views/admin/permissions/_admin_table_content.html.erb +45 -0
- data/lib/generators/ruby_cms/templates/views/admin/permissions/_matrix.html.erb +75 -0
- data/lib/generators/ruby_cms/templates/views/admin/permissions/_row.html.erb +62 -0
- data/lib/generators/ruby_cms/templates/views/admin/permissions/index.html.erb +65 -0
- data/lib/generators/ruby_cms/templates/views/admin/redirects/_admin_table_content.html.erb +77 -0
- data/lib/generators/ruby_cms/templates/views/admin/redirects/_form.html.erb +97 -0
- data/lib/generators/ruby_cms/templates/views/admin/redirects/_row.html.erb +82 -0
- data/lib/generators/ruby_cms/templates/views/admin/redirects/edit.html.erb +21 -0
- data/lib/generators/ruby_cms/templates/views/admin/redirects/index.html.erb +40 -0
- data/lib/generators/ruby_cms/templates/views/admin/redirects/new.html.erb +12 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/index.html.erb +88 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/ip_blocklist_content.html.erb +3 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/partials/_events_by_type.html.erb +24 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/partials/_ip_blocklist.html.erb +37 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/partials/_ip_blocklist_content.html.erb +41 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/partials/_ip_management.html.erb +11 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/partials/_recent_events.html.erb +59 -0
- data/lib/generators/ruby_cms/templates/views/admin/security/partials/_top_threat_ips.html.erb +21 -0
- data/lib/generators/ruby_cms/templates/views/admin/settings/index.html.erb +509 -0
- data/lib/generators/ruby_cms/templates/views/admin/shared/_add_button.html.erb +15 -0
- data/lib/generators/ruby_cms/templates/views/admin/shared/_data_table.html.erb +255 -0
- data/lib/generators/ruby_cms/templates/views/admin/shared/_turbo_pagination.html.erb +53 -0
- data/lib/generators/ruby_cms/templates/views/admin/system_health/index.html.erb +248 -0
- data/lib/generators/ruby_cms/templates/views/admin/trash/index.html.erb +58 -0
- data/lib/generators/ruby_cms/templates/views/admin/user_permissions/_row.html.erb +29 -0
- data/lib/generators/ruby_cms/templates/views/admin/user_permissions/index.html.erb +78 -0
- data/lib/generators/ruby_cms/templates/views/admin/users/_admin_table_content.html.erb +50 -0
- data/lib/generators/ruby_cms/templates/views/admin/users/_invite_form.html.erb +43 -0
- data/lib/generators/ruby_cms/templates/views/admin/users/_invites_panel.html.erb +91 -0
- data/lib/generators/ruby_cms/templates/views/admin/users/_row.html.erb +109 -0
- data/lib/generators/ruby_cms/templates/views/admin/users/index.html.erb +43 -0
- data/lib/generators/ruby_cms/templates/views/admin/users/show.html.erb +343 -0
- data/lib/generators/ruby_cms/templates/views/admin/visitor_errors/_admin_table_content.html.erb +61 -0
- data/lib/generators/ruby_cms/templates/views/admin/visitor_errors/_row.html.erb +90 -0
- data/lib/generators/ruby_cms/templates/views/admin/visitor_errors/index.html.erb +18 -0
- data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/visitor_errors/show.html.erb +4 -4
- data/lib/generators/ruby_cms/templates/views/admin/visual_editor/index.html.erb +383 -0
- data/{app/views/layouts/ruby_cms → lib/generators/ruby_cms/templates/views/layouts/admin}/_admin_flash_messages.html.erb +3 -3
- data/lib/generators/ruby_cms/templates/views/layouts/admin/_admin_sidebar.html.erb +239 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/_command_palette.html.erb +65 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/_shortcuts_overlay.html.erb +81 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/_topbar_widgets.html.erb +9 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/minimal.html.erb +71 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/topbar/_bell.html.erb +81 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/topbar/_profile_menu.html.erb +86 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/topbar/_search_trigger.html.erb +9 -0
- data/lib/generators/ruby_cms/templates/views/layouts/admin/topbar/_shortcuts_button.html.erb +8 -0
- data/lib/generators/ruby_cms/templates/views/shared/_maintenance_banner.html.erb +10 -0
- data/lib/ruby_cms/app_wiring.rb +56 -0
- data/lib/ruby_cms/auth_wiring.rb +64 -0
- data/lib/ruby_cms/cli.rb +181 -121
- data/lib/ruby_cms/excludes.rb +41 -0
- data/lib/ruby_cms/file_installer.rb +41 -0
- data/lib/ruby_cms/gem_setup.rb +84 -0
- data/lib/ruby_cms/helper_wiring.rb +32 -0
- data/lib/ruby_cms/importmap_wiring.rb +41 -0
- data/lib/ruby_cms/installer.rb +128 -0
- data/lib/ruby_cms/lockfile.rb +49 -0
- data/lib/ruby_cms/manifest.rb +88 -0
- data/lib/ruby_cms/manifest_data.rb +233 -0
- data/lib/ruby_cms/migration_installer.rb +64 -0
- data/lib/ruby_cms/nav_assembler.rb +43 -0
- data/lib/ruby_cms/passkey_wiring.rb +42 -0
- data/lib/ruby_cms/path_map.rb +26 -0
- data/lib/ruby_cms/routes_assembler.rb +103 -0
- data/lib/ruby_cms/syncer.rb +81 -0
- data/lib/ruby_cms/updater.rb +76 -0
- data/lib/ruby_cms/version.rb +1 -1
- data/lib/ruby_cms.rb +4 -245
- metadata +606 -169
- data/.cursor/dhh.mdc +0 -698
- data/app/components/ruby_cms/admin/admin_page/admin_table_content.rb +0 -32
- data/app/components/ruby_cms/admin/admin_page.rb +0 -345
- data/app/components/ruby_cms/admin/admin_page_header.rb +0 -79
- data/app/components/ruby_cms/admin/admin_resource_card.rb +0 -55
- data/app/components/ruby_cms/admin/base_component.rb +0 -78
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table.rb +0 -157
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_actions.rb +0 -127
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_body.rb +0 -15
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_checkbox_cell.rb +0 -43
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_checkbox_head.rb +0 -35
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_delete_modal.rb +0 -174
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_header.rb +0 -59
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_header_bar.rb +0 -169
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_pagination.rb +0 -192
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_action_table_row.rb +0 -96
- data/app/components/ruby_cms/admin/bulk_action_table/bulk_actions.rb +0 -196
- data/app/controllers/concerns/ruby_cms/admin_pagination.rb +0 -120
- data/app/controllers/concerns/ruby_cms/admin_turbo_table.rb +0 -68
- data/app/controllers/concerns/ruby_cms/page_tracking.rb +0 -67
- data/app/controllers/concerns/ruby_cms/visitor_error_capture.rb +0 -39
- data/app/controllers/ruby_cms/admin/analytics_controller.rb +0 -213
- data/app/controllers/ruby_cms/admin/base_controller.rb +0 -132
- data/app/controllers/ruby_cms/admin/commands_controller.rb +0 -122
- data/app/controllers/ruby_cms/admin/content_block_versions_controller.rb +0 -62
- data/app/controllers/ruby_cms/admin/content_blocks_controller.rb +0 -391
- data/app/controllers/ruby_cms/admin/dashboard_controller.rb +0 -89
- data/app/controllers/ruby_cms/admin/locale_controller.rb +0 -21
- data/app/controllers/ruby_cms/admin/permissions_controller.rb +0 -66
- data/app/controllers/ruby_cms/admin/settings_controller.rb +0 -223
- data/app/controllers/ruby_cms/admin/user_permissions_controller.rb +0 -77
- data/app/controllers/ruby_cms/admin/users_controller.rb +0 -107
- data/app/controllers/ruby_cms/admin/visitor_errors_controller.rb +0 -89
- data/app/controllers/ruby_cms/admin/visual_editor_controller.rb +0 -345
- data/app/controllers/ruby_cms/errors_controller.rb +0 -35
- data/app/helpers/ruby_cms/admin/admin_page_helper.rb +0 -21
- data/app/helpers/ruby_cms/admin/bulk_action_table_helper.rb +0 -159
- data/app/helpers/ruby_cms/admin/dashboard_helper.rb +0 -20
- data/app/helpers/ruby_cms/application_helper.rb +0 -41
- data/app/helpers/ruby_cms/bulk_action_table_helper.rb +0 -151
- data/app/helpers/ruby_cms/content_blocks_helper.rb +0 -399
- data/app/helpers/ruby_cms/settings_helper.rb +0 -172
- data/app/javascript/controllers/ruby_cms/content_block_history_controller.js +0 -91
- data/app/javascript/controllers/ruby_cms/index.js +0 -117
- data/app/javascript/controllers/ruby_cms/mobile_menu_controller.js +0 -55
- data/app/javascript/controllers/ruby_cms/nav_order_sortable_controller.js +0 -192
- data/app/javascript/controllers/ruby_cms/visual_editor_controller.js +0 -325
- data/app/models/concerns/content_block/searchable.rb +0 -22
- data/app/models/ruby_cms/content_block.rb +0 -8
- data/app/models/ruby_cms/permission.rb +0 -57
- data/app/models/ruby_cms/permittable.rb +0 -37
- data/app/models/ruby_cms/preference.rb +0 -111
- data/app/models/ruby_cms/user_permission.rb +0 -12
- data/app/models/ruby_cms/visitor_error.rb +0 -109
- data/app/services/ruby_cms/analytics/report.rb +0 -512
- data/app/services/ruby_cms/command_runner.rb +0 -42
- data/app/services/ruby_cms/security_tracker.rb +0 -92
- data/app/views/admin/content_block_versions/index.html.erb +0 -52
- data/app/views/admin/content_block_versions/show.html.erb +0 -37
- data/app/views/layouts/ruby_cms/_admin_sidebar.html.erb +0 -122
- data/app/views/layouts/ruby_cms/admin.html.erb +0 -77
- data/app/views/layouts/ruby_cms/minimal.html.erb +0 -181
- data/app/views/ruby_cms/admin/commands/index.html.erb +0 -104
- data/app/views/ruby_cms/admin/content_block_versions/index.html.erb +0 -52
- data/app/views/ruby_cms/admin/content_blocks/_form.html.erb +0 -92
- data/app/views/ruby_cms/admin/content_blocks/_row.html.erb +0 -25
- data/app/views/ruby_cms/admin/content_blocks/index.html.erb +0 -62
- data/app/views/ruby_cms/admin/content_blocks/new.html.erb +0 -10
- data/app/views/ruby_cms/admin/dashboard/index.html.erb +0 -31
- data/app/views/ruby_cms/admin/permissions/_row.html.erb +0 -11
- data/app/views/ruby_cms/admin/permissions/index.html.erb +0 -62
- data/app/views/ruby_cms/admin/settings/index.html.erb +0 -268
- data/app/views/ruby_cms/admin/shared/_bulk_action_table_index.html.erb +0 -56
- data/app/views/ruby_cms/admin/user_permissions/index.html.erb +0 -85
- data/app/views/ruby_cms/admin/users/_row.html.erb +0 -17
- data/app/views/ruby_cms/admin/users/index.html.erb +0 -70
- data/app/views/ruby_cms/admin/visitor_errors/_row.html.erb +0 -35
- data/app/views/ruby_cms/admin/visitor_errors/index.html.erb +0 -57
- data/app/views/ruby_cms/admin/visual_editor/index.html.erb +0 -157
- data/app/views/ruby_cms/errors/not_found.html.erb +0 -92
- data/config/database.yml +0 -6
- data/config/importmap.rb +0 -40
- data/config/locales/en.yml +0 -198
- data/config/locales/nl.yml +0 -156
- data/config/routes.rb +0 -76
- data/db/migrate/20260130000001_add_referer_and_query_to_ruby_cms_visitor_errors.rb +0 -8
- data/db/migrate/20260130000003_add_category_to_ruby_cms_preferences.rb +0 -8
- data/docs/assets/ruby_cms_logo.png +0 -0
- data/lib/generators/ruby_cms/install_generator.rb +0 -1080
- data/lib/ruby_cms/app_integration.rb +0 -82
- data/lib/ruby_cms/commands_registry.rb +0 -40
- data/lib/ruby_cms/css_compiler.rb +0 -35
- data/lib/ruby_cms/engine/admin_permissions.rb +0 -69
- data/lib/ruby_cms/engine/content_blocks_tasks.rb +0 -66
- data/lib/ruby_cms/engine/css.rb +0 -14
- data/lib/ruby_cms/engine/dashboard_registration.rb +0 -66
- data/lib/ruby_cms/engine/navigation_registration.rb +0 -89
- data/lib/ruby_cms/engine.rb +0 -273
- /data/{app → lib/generators/ruby_cms/templates}/assets/images/ruby_cms/logo.png +0 -0
- /data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260211000001_add_ruby_cms_analytics_fields_to_ahoy_events.rb +0 -0
- /data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260212000001_use_unprefixed_cms_tables.rb +0 -0
- /data/{db → lib/generators/ruby_cms/templates/db}/migrate/20260409000001_add_analytics_performance_indexes.rb +0 -0
- /data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/admin}/auto_save_preference_controller.js +0 -0
- /data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/admin}/locale_tabs_controller.js +0 -0
- /data/{app/javascript/controllers/ruby_cms → lib/generators/ruby_cms/templates/javascript/controllers/admin}/toggle_controller.js +0 -0
- /data/{app → lib/generators/ruby_cms/templates}/models/concerns/content_block/publishable.rb +0 -0
- /data/{app → lib/generators/ruby_cms/templates}/models/content_block_version.rb +0 -0
- /data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_back_button.html.erb +0 -0
- /data/{app/views/ruby_cms → lib/generators/ruby_cms/templates/views}/admin/analytics/partials/_security_alert.html.erb +0 -0
data/README.md
CHANGED
|
@@ -1,21 +1,44 @@
|
|
|
1
1
|
# RubyCMS
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Standalone CLI gem for a modular CMS-style admin: content blocks, visual editor, versioning, pluggable dashboard, permissions, analytics, and visitor error tracking.
|
|
4
4
|
|
|
5
|
-
Your app owns product features (pages, models, business logic)
|
|
5
|
+
Your app owns product features (pages, models, business logic). RubyCMS scaffolds the admin layer into your codebase so you can customize everything without a runtime engine dependency.
|
|
6
|
+
|
|
7
|
+
## How it works
|
|
8
|
+
|
|
9
|
+
RubyCMS is **install-only**. Running `ruby_cms install` (the CLI) copies controllers, views, models, helpers, JavaScript, and `lib/ruby_cms/` into your host app for whichever modules you select. After install you can remove the gem from your `Gemfile` — the app runs entirely on copied code.
|
|
10
|
+
|
|
11
|
+
| Layer | Location after install |
|
|
12
|
+
|-------|------------------------|
|
|
13
|
+
| Registries (nav, permissions, dashboard, settings, icons) | `lib/ruby_cms/` |
|
|
14
|
+
| Core configuration (`RubyCms.configure`, visual-editor preview) | `config/initializers/admin.rb` |
|
|
15
|
+
| Sidebar nav (generated from module fragments; user-editable) | `config/initializers/admin_nav.rb` |
|
|
16
|
+
| Dashboard blocks | `config/initializers/admin_dashboard.rb` |
|
|
17
|
+
| Admin controllers & views | `app/controllers/admin/`, `app/views/admin/` |
|
|
18
|
+
| UI components (Phlex / RubyUI) | `app/components/ruby_ui/admin_page/` |
|
|
19
|
+
| Rake tasks | `lib/tasks/ruby_cms.rake` |
|
|
20
|
+
| Module manifest / lockfile | `.ruby_cms.yml` |
|
|
21
|
+
|
|
22
|
+
Keep the gem in your `Gemfile` only when you need install/update commands:
|
|
23
|
+
|
|
24
|
+
```ruby
|
|
25
|
+
# Uncomment temporarily for install or updates:
|
|
26
|
+
# gem "ruby_cms", path: "../gems/ruby_cms"
|
|
27
|
+
```
|
|
6
28
|
|
|
7
29
|
## Features
|
|
8
30
|
|
|
9
|
-
- **Content blocks**
|
|
10
|
-
- **Content block versioning**
|
|
11
|
-
- **Visual editor**
|
|
12
|
-
- **Pluggable dashboard**
|
|
13
|
-
- **Permissions**
|
|
14
|
-
- **Admin page generator**
|
|
15
|
-
- **Named icon registry**
|
|
16
|
-
- **Settings**
|
|
17
|
-
- **Analytics**
|
|
18
|
-
- **Visitor error tracking**
|
|
31
|
+
- **Content blocks** — rich text, plain text, images, links, and lists with locale support
|
|
32
|
+
- **Content block versioning** — automatic version history with rollback and side-by-side diffs
|
|
33
|
+
- **Visual editor** — inline editing on live page previews
|
|
34
|
+
- **Pluggable dashboard** — registry-based blocks with permission gating and host-app extensibility
|
|
35
|
+
- **Permissions** — key-based access control with templates and per-user assignment
|
|
36
|
+
- **Admin page generator** — one command to scaffold a new admin page with nav, permission, and route
|
|
37
|
+
- **Named icon registry** — 20+ Heroicons by name, no SVG copy-pasting
|
|
38
|
+
- **Settings** — DB-backed admin settings with categories and UI
|
|
39
|
+
- **Analytics** — Ahoy-powered visit/event tracking with dashboard drill-downs
|
|
40
|
+
- **Visitor error tracking** — automatic 404/500 capture with admin overview
|
|
41
|
+
- **Admin UI components** — reusable `AdminPage`, `AdminPageHeader`, `AdminTableContent`, and `AdminResourceCard` (RubyUI / Phlex)
|
|
19
42
|
|
|
20
43
|
## Quick Start
|
|
21
44
|
|
|
@@ -23,17 +46,89 @@ Your app owns product features (pages, models, business logic); RubyCMS manages
|
|
|
23
46
|
# Add to Gemfile
|
|
24
47
|
gem "ruby_cms"
|
|
25
48
|
|
|
26
|
-
|
|
27
|
-
|
|
49
|
+
bundle install
|
|
50
|
+
ruby_cms install # interactive module picker
|
|
51
|
+
ruby_cms install --modules media,redirects # non-interactive
|
|
28
52
|
rails db:migrate
|
|
29
53
|
rails ruby_cms:seed_permissions
|
|
30
54
|
rails ruby_cms:setup_admin
|
|
31
55
|
```
|
|
32
56
|
|
|
33
|
-
The install
|
|
57
|
+
The `ruby_cms install` CLI:
|
|
58
|
+
|
|
59
|
+
- Copies admin scaffold into `app/` and `lib/ruby_cms/` for selected modules
|
|
60
|
+
- Creates `config/initializers/admin.rb` (`RubyCms.configure` block + visual-editor preview setup)
|
|
61
|
+
- Generates `config/initializers/admin_nav.rb` (sidebar nav assembled from per-module fragments)
|
|
62
|
+
- Creates `config/initializers/admin_dashboard.rb` (dashboard blocks)
|
|
63
|
+
- Seeds module permissions from the manifest — no manual `register_permission_keys` needed
|
|
64
|
+
- Adds `namespace :admin` routes (no engine mount)
|
|
65
|
+
- Configures Tailwind, Stimulus, Action Text, and Ahoy
|
|
66
|
+
- Records installed modules in `.ruby_cms.yml`
|
|
34
67
|
|
|
35
68
|
Visit `/admin` and sign in with the admin user you configured.
|
|
36
69
|
|
|
70
|
+
### Adding a module later
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
ruby_cms install --add media
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
This copies the module files, seeds its permissions, and appends its nav fragment to `config/initializers/admin_nav.rb`.
|
|
77
|
+
|
|
78
|
+
### Pulling updates from the gem
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Re-add gem to Gemfile, then:
|
|
82
|
+
ruby_cms update # updates only modules in .ruby_cms.yml
|
|
83
|
+
ruby_cms update --only=mod1,mod2
|
|
84
|
+
ruby_cms update --dry-run
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Only changed files are overwritten. Review diffs before committing. `config/initializers/admin_nav.rb` is regenerated on every install/update, so custom sidebar entries belong in `config/initializers/admin_pages.rb` (where `rails g ruby_cms:admin_page` writes them) — that file is never touched by the gem.
|
|
88
|
+
|
|
89
|
+
## Admin UI components
|
|
90
|
+
|
|
91
|
+
Admin views use Phlex components under `app/components/ruby_ui/admin_page/` (registered as `AdminPage`, `AdminPageHeader`, etc. via the RubyUI kit).
|
|
92
|
+
|
|
93
|
+
| Component | Purpose |
|
|
94
|
+
|-----------|---------|
|
|
95
|
+
| `RubyUI::AdminPage` | White card wrapper; optional `turbo_frame:` for full-page Turbo updates |
|
|
96
|
+
| `RubyUI::AdminPageHeader` | Breadcrumbs, title, subtitle, action slot |
|
|
97
|
+
| `RubyUI::AdminTableContent` | Turbo Frame (`id: "admin_table_content"`) for pagination, filters, search |
|
|
98
|
+
| `RubyUI::AdminResourceCard` | Layout constants for show/edit pages (grid, sidebar, form classes) |
|
|
99
|
+
|
|
100
|
+
### Usage in views
|
|
101
|
+
|
|
102
|
+
```erb
|
|
103
|
+
<%= AdminPage do %>
|
|
104
|
+
<%= AdminPageHeader(
|
|
105
|
+
title: "Users",
|
|
106
|
+
breadcrumbs: [
|
|
107
|
+
{ label: "Admin", url: admin_root_path },
|
|
108
|
+
{ label: "Users" }
|
|
109
|
+
]
|
|
110
|
+
) do %>
|
|
111
|
+
<%= link_to "New user", new_admin_user_path, class: "..." %>
|
|
112
|
+
<% end %>
|
|
113
|
+
|
|
114
|
+
<%= admin_table_content do %>
|
|
115
|
+
<%# table rows, pagination — replaces frame on Turbo navigation %>
|
|
116
|
+
<% end %>
|
|
117
|
+
<% end %>
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
`admin_table_content` is provided by `Admin::AdminPageHelper`.
|
|
121
|
+
|
|
122
|
+
For resource show pages, use `RubyUI::AdminResourceCard` constants:
|
|
123
|
+
|
|
124
|
+
```erb
|
|
125
|
+
<div class="<%= RubyUI::AdminResourceCard::CARD_CLASS %>">
|
|
126
|
+
<div class="<%= RubyUI::AdminResourceCard::GRID_CLASS %>">
|
|
127
|
+
...
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
```
|
|
131
|
+
|
|
37
132
|
## Content Blocks
|
|
38
133
|
|
|
39
134
|
Use the `content_block` helper in any view:
|
|
@@ -133,12 +228,13 @@ POST /admin/content_blocks/:id/versions/:vid/rollback
|
|
|
133
228
|
|
|
134
229
|
## Visual Editor
|
|
135
230
|
|
|
136
|
-
Configure preview templates in `config/initializers/
|
|
231
|
+
Configure preview templates in `config/initializers/admin.rb`:
|
|
137
232
|
|
|
138
233
|
```ruby
|
|
139
234
|
RubyCms.configure do |c|
|
|
140
235
|
c.preview_templates = { "home" => "pages/home", "about" => "pages/about" }
|
|
141
|
-
c.preview_data = ->(page_key, view) { { products: Product.limit(5) } }
|
|
236
|
+
c.preview_data = ->(page_key, view, variant = nil) { { products: Product.limit(5) } }
|
|
237
|
+
c.preview_variants = ->(page_key) { [] }
|
|
142
238
|
end
|
|
143
239
|
```
|
|
144
240
|
|
|
@@ -150,67 +246,71 @@ The dashboard uses a registry-based block system. Each block is a partial with o
|
|
|
150
246
|
|
|
151
247
|
### Default Blocks
|
|
152
248
|
|
|
249
|
+
Register defaults in `config/initializers/admin_dashboard.rb` (generated at install with CMS stats blocks; customize for your app):
|
|
250
|
+
|
|
153
251
|
| Block | Section | Permission |
|
|
154
252
|
|-------|---------|------------|
|
|
155
253
|
| Content blocks stats | stats | `manage_content_blocks` |
|
|
156
254
|
| Users stats | stats | `manage_permissions` |
|
|
157
255
|
| Permissions stats | stats | `manage_permissions` |
|
|
158
256
|
| Visitor errors stats | stats | `manage_visitor_errors` |
|
|
159
|
-
| Quick actions | main |
|
|
257
|
+
| Quick actions | main | — |
|
|
160
258
|
| Recent errors | main | `manage_visitor_errors` |
|
|
161
259
|
| Analytics overview | main | `manage_analytics` |
|
|
162
260
|
|
|
163
261
|
### Adding Custom Blocks
|
|
164
262
|
|
|
165
263
|
```ruby
|
|
166
|
-
# config/initializers/
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
)
|
|
180
|
-
end
|
|
264
|
+
# config/initializers/admin_dashboard.rb
|
|
265
|
+
RubyCms.dashboard_register(
|
|
266
|
+
key: :orders_stats,
|
|
267
|
+
label: "Orders",
|
|
268
|
+
section: :stats, # :stats (top row) or :main (bottom grid)
|
|
269
|
+
order: 5,
|
|
270
|
+
partial: "admin/dashboard/blocks/orders_stats",
|
|
271
|
+
permission: :manage_orders,
|
|
272
|
+
span: :single, # :single or :double (grid width)
|
|
273
|
+
data: ->(controller) {
|
|
274
|
+
{ count: Order.count, today: Order.where("created_at > ?", Date.today).count }
|
|
275
|
+
}
|
|
276
|
+
)
|
|
181
277
|
```
|
|
182
278
|
|
|
183
|
-
Then create the partial `app/views/admin/dashboard/_orders_stats.html.erb`. The `block` local contains the registration data and any computed `data`.
|
|
279
|
+
Then create the partial `app/views/admin/dashboard/blocks/_orders_stats.html.erb`. The `block` local contains the registration data and any computed `data`.
|
|
184
280
|
|
|
185
281
|
### Overriding Default Blocks
|
|
186
282
|
|
|
187
|
-
Re-register with the same key to override:
|
|
283
|
+
Re-register with the same key to override (in `config/initializers/admin_dashboard.rb`):
|
|
188
284
|
|
|
189
285
|
```ruby
|
|
190
286
|
RubyCms.dashboard_register(
|
|
191
287
|
key: :quick_actions,
|
|
192
288
|
label: "Quick actions",
|
|
193
289
|
section: :main,
|
|
194
|
-
partial: "admin/dashboard/my_quick_actions"
|
|
290
|
+
partial: "admin/dashboard/my_quick_actions"
|
|
195
291
|
)
|
|
196
292
|
```
|
|
197
293
|
|
|
198
294
|
## Navigation and Permissions
|
|
199
295
|
|
|
296
|
+
Navigation registration lives in **`config/initializers/admin_nav.rb`** (generated at install/add from per-module fragments; safe to edit manually). Permission keys are declared in the gem's manifest (`lib/ruby_cms/manifest.rb`) and seeded automatically at install — you do not need to call `register_permission_keys` for built-in modules. Register additional app-specific keys in `config/initializers/admin_nav.rb` or any initializer.
|
|
297
|
+
|
|
200
298
|
### register_page (recommended)
|
|
201
299
|
|
|
202
|
-
One call to register a nav item and its permission:
|
|
300
|
+
One call to register a nav item and its permission. Place in `config/initializers/admin_nav.rb` (or any initializer):
|
|
203
301
|
|
|
204
302
|
```ruby
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
303
|
+
Rails.application.config.to_prepare do
|
|
304
|
+
RubyCms.register_page(
|
|
305
|
+
key: :backups,
|
|
306
|
+
label: "Backups",
|
|
307
|
+
path: ->(view) { view.admin_backups_path },
|
|
308
|
+
icon: :archive_box,
|
|
309
|
+
section: :main,
|
|
310
|
+
permission: :manage_backups,
|
|
311
|
+
order: 10
|
|
312
|
+
)
|
|
313
|
+
end
|
|
214
314
|
```
|
|
215
315
|
|
|
216
316
|
### nav_register (low-level)
|
|
@@ -229,12 +329,28 @@ RubyCms.nav_register(
|
|
|
229
329
|
)
|
|
230
330
|
```
|
|
231
331
|
|
|
332
|
+
### nav_group (accordion)
|
|
333
|
+
|
|
334
|
+
```ruby
|
|
335
|
+
RubyCms.nav_group(
|
|
336
|
+
key: :operations,
|
|
337
|
+
label: "Operations",
|
|
338
|
+
icon: :folder,
|
|
339
|
+
section: "main",
|
|
340
|
+
order: 20,
|
|
341
|
+
path: ->(view) { view.admin_operations_path },
|
|
342
|
+
children: %i[backups reports]
|
|
343
|
+
)
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
Groups are hidden automatically when they have no visible children and no `path`.
|
|
347
|
+
|
|
232
348
|
### Path Options
|
|
233
349
|
|
|
234
350
|
| Format | Example | Behavior |
|
|
235
351
|
|--------|---------|----------|
|
|
236
352
|
| Symbol | `:admin_backups_path` | Auto-wrapped: `view.main_app.send(:admin_backups_path)` |
|
|
237
|
-
| Lambda | `->
|
|
353
|
+
| Lambda | `->(view) { view.admin_backups_path }` | Called with view context |
|
|
238
354
|
| String | `"/admin/backups"` | Used as-is |
|
|
239
355
|
|
|
240
356
|
### Named Icons
|
|
@@ -243,19 +359,16 @@ Use symbol keys from `RubyCms::Icons`:
|
|
|
243
359
|
|
|
244
360
|
```ruby
|
|
245
361
|
RubyCms::Icons.available
|
|
246
|
-
# => [:home, :pencil_square, :document_duplicate, :chart_bar, :shield_check,
|
|
247
|
-
# :exclamation_triangle, :user_group, :cog_6_tooth, :archive_box, :folder,
|
|
248
|
-
# :bell, :clock, :tag, :cube, :envelope, :wrench, :globe, :photograph,
|
|
249
|
-
# :list_bullet, :plus_circle, :trash, :eye, :lock_closed, :currency_dollar]
|
|
362
|
+
# => [:home, :pencil_square, :document_duplicate, :chart_bar, :shield_check, ...]
|
|
250
363
|
```
|
|
251
364
|
|
|
252
365
|
Raw SVG strings are also accepted for custom icons.
|
|
253
366
|
|
|
254
367
|
### Permission Keys
|
|
255
368
|
|
|
256
|
-
|
|
369
|
+
Built-in module permission keys (e.g. `manage_admin`, `manage_permissions`, `manage_content_blocks`, `manage_visitor_errors`, `manage_analytics`) are declared in the gem manifest and seeded automatically at install.
|
|
257
370
|
|
|
258
|
-
Register additional keys:
|
|
371
|
+
Register additional app-specific keys in any initializer (e.g. `config/initializers/admin_nav.rb`):
|
|
259
372
|
|
|
260
373
|
```ruby
|
|
261
374
|
RubyCms.register_permission_keys(:manage_orders, :manage_reports)
|
|
@@ -263,8 +376,6 @@ RubyCms.register_permission_keys(:manage_orders, :manage_reports)
|
|
|
263
376
|
|
|
264
377
|
### Permission Templates
|
|
265
378
|
|
|
266
|
-
Group permission keys into reusable templates:
|
|
267
|
-
|
|
268
379
|
```ruby
|
|
269
380
|
RubyCms.register_permission_template(:editor,
|
|
270
381
|
label: "Editor",
|
|
@@ -272,17 +383,16 @@ RubyCms.register_permission_template(:editor,
|
|
|
272
383
|
description: "Can manage content but not users"
|
|
273
384
|
)
|
|
274
385
|
|
|
275
|
-
# Apply to a user:
|
|
276
386
|
RubyCms::Permission.apply_template!(user, :editor)
|
|
277
387
|
```
|
|
278
388
|
|
|
279
389
|
### cms_page Macro
|
|
280
390
|
|
|
281
|
-
In controllers
|
|
391
|
+
In controllers under `Admin::ApplicationController`, use `cms_page` to enforce the permission from `register_page`:
|
|
282
392
|
|
|
283
393
|
```ruby
|
|
284
|
-
class Admin::BackupsController <
|
|
285
|
-
cms_page :backups
|
|
394
|
+
class Admin::BackupsController < Admin::ApplicationController
|
|
395
|
+
cms_page :backups
|
|
286
396
|
|
|
287
397
|
def index
|
|
288
398
|
@backups = Backup.recent
|
|
@@ -292,49 +402,50 @@ end
|
|
|
292
402
|
|
|
293
403
|
## Admin Page Generator
|
|
294
404
|
|
|
295
|
-
Scaffold a complete admin page
|
|
405
|
+
Scaffold a complete admin page — controller, data-table index, form and routes —
|
|
406
|
+
that follows the same conventions as the built-in modules. Pass optional
|
|
407
|
+
`field:type` pairs (type defaults to `string`) to scaffold the columns:
|
|
296
408
|
|
|
297
409
|
```bash
|
|
298
|
-
rails g ruby_cms:admin_page
|
|
410
|
+
rails g ruby_cms:admin_page product name:string price:decimal published:boolean
|
|
299
411
|
```
|
|
300
412
|
|
|
301
413
|
This generates:
|
|
302
414
|
|
|
303
415
|
| File | Description |
|
|
304
416
|
|------|-------------|
|
|
305
|
-
| `app/controllers/admin/
|
|
306
|
-
| `app/views/admin/
|
|
307
|
-
| `
|
|
308
|
-
| `
|
|
417
|
+
| `app/controllers/admin/products_controller.rb` | Full CRUD controller on the shared concern stack (pagination, turbo tables, bulk delete, audit) |
|
|
418
|
+
| `app/views/admin/products/index.html.erb` | `AdminPage` + `AdminPageHeader` with a `data_table` |
|
|
419
|
+
| `app/views/admin/products/_admin_table_content.html.erb` | The data-table partial (headers from your fields) |
|
|
420
|
+
| `app/views/admin/products/_row.html.erb` | Row cells per field |
|
|
421
|
+
| `app/views/admin/products/_form.html.erb`, `new`, `edit` | Form scaffolded from your fields |
|
|
422
|
+
| `config/routes.rb` | `resources :products` (with `bulk_delete`) in `namespace :admin` |
|
|
423
|
+
| `config/initializers/admin_pages.rb` | Sidebar registration via `RubyCms.register_page` (host-owned — never overwritten by `ruby_cms update`) |
|
|
309
424
|
|
|
310
425
|
### Options
|
|
311
426
|
|
|
312
427
|
```bash
|
|
313
|
-
rails g ruby_cms:admin_page
|
|
314
|
-
--permission=manage_backups \
|
|
315
|
-
--icon=archive_box \
|
|
316
|
-
--section=settings \
|
|
317
|
-
--order=15
|
|
428
|
+
rails g ruby_cms:admin_page report --read-only --section=settings --icon=chart_bar --order=15
|
|
318
429
|
```
|
|
319
430
|
|
|
320
431
|
| Option | Default | Description |
|
|
321
432
|
|--------|---------|-------------|
|
|
322
|
-
| `--permission` | `manage_<
|
|
323
|
-
| `--icon` | `folder` | Icon from `RubyCms::Icons` |
|
|
433
|
+
| `--permission` | `manage_<plural>` | Permission key |
|
|
434
|
+
| `--icon` | `folder` | Icon from `RubyCms::Icons` (`RubyCms::Icons.available`) |
|
|
324
435
|
| `--section` | `main` | `main` or `settings` |
|
|
325
436
|
| `--order` | `10` | Sort order in nav |
|
|
437
|
+
| `--read-only` | `false` | Index-only page (no form/create/update/destroy) |
|
|
438
|
+
| `--skip-route` | `false` | Don't touch `config/routes.rb` |
|
|
439
|
+
| `--skip-nav` | `false` | Don't register the page in the sidebar |
|
|
326
440
|
|
|
327
441
|
After generating, run `rails ruby_cms:seed_permissions` to create the permission row in the database.
|
|
328
442
|
|
|
329
443
|
## Settings
|
|
330
444
|
|
|
331
|
-
|
|
445
|
+
DB-backed settings with a registry for defaults and types:
|
|
332
446
|
|
|
333
447
|
```ruby
|
|
334
|
-
# Read
|
|
335
448
|
RubyCms::Settings.get(:analytics_default_period, default: "week")
|
|
336
|
-
|
|
337
|
-
# Write (admin UI or programmatic)
|
|
338
449
|
RubyCms::Settings.set(:analytics_default_period, "month")
|
|
339
450
|
```
|
|
340
451
|
|
|
@@ -354,7 +465,7 @@ Settings are managed in **Admin > Settings** with tabs per category.
|
|
|
354
465
|
|
|
355
466
|
## Visitor Error Tracking
|
|
356
467
|
|
|
357
|
-
Public exceptions are
|
|
468
|
+
Public exceptions are captured when `VisitorErrorCapture` is included in your `ApplicationController` (added by the install generator).
|
|
358
469
|
|
|
359
470
|
View captured errors in **Admin > Visitor errors** with status codes, paths, timestamps, and resolution tracking.
|
|
360
471
|
|
|
@@ -362,22 +473,20 @@ View captured errors in **Admin > Visitor errors** with status codes, paths, tim
|
|
|
362
473
|
|
|
363
474
|
RubyCMS integrates with Ahoy for server-side page view and event tracking.
|
|
364
475
|
|
|
365
|
-
Include `
|
|
476
|
+
Include `PageTracking` in public controllers:
|
|
366
477
|
|
|
367
478
|
```ruby
|
|
368
479
|
class PagesController < ApplicationController
|
|
369
|
-
include
|
|
480
|
+
include PageTracking
|
|
370
481
|
end
|
|
371
482
|
```
|
|
372
483
|
|
|
373
|
-
View analytics in **Admin > Analytics** with
|
|
374
|
-
- Visit and event counts
|
|
375
|
-
- Popular pages
|
|
376
|
-
- Top visitors
|
|
377
|
-
- Configurable date ranges and periods
|
|
484
|
+
View analytics in **Admin > Analytics** with visit/event counts, popular pages, top visitors, and configurable date ranges.
|
|
378
485
|
|
|
379
486
|
### Customization Hooks
|
|
380
487
|
|
|
488
|
+
Place these in `config/initializers/admin.rb` inside the `RubyCms.configure` block:
|
|
489
|
+
|
|
381
490
|
```ruby
|
|
382
491
|
RubyCms.configure do |c|
|
|
383
492
|
c.analytics_visit_scope = ->(scope) { scope.where.not(ip: ["127.0.0.1"]) }
|
|
@@ -390,147 +499,193 @@ end
|
|
|
390
499
|
|
|
391
500
|
## Seeding Content Blocks from YAML
|
|
392
501
|
|
|
393
|
-
Set the translation namespace:
|
|
394
|
-
|
|
395
502
|
```ruby
|
|
503
|
+
# config/initializers/admin.rb
|
|
396
504
|
RubyCms.configure do |c|
|
|
397
505
|
c.content_blocks_translation_namespace = "content_blocks"
|
|
398
506
|
end
|
|
399
507
|
```
|
|
400
508
|
|
|
401
|
-
Create locale files:
|
|
402
|
-
|
|
403
509
|
```yaml
|
|
404
510
|
# config/locales/en.yml
|
|
405
511
|
en:
|
|
406
512
|
content_blocks:
|
|
407
513
|
hero_title: "Welcome to my site"
|
|
408
|
-
footer_text: "Copyright 2026"
|
|
409
514
|
```
|
|
410
515
|
|
|
411
|
-
Import:
|
|
412
|
-
|
|
413
516
|
```bash
|
|
414
517
|
rails ruby_cms:content_blocks:import
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
Export DB content blocks back to YAML:
|
|
418
|
-
|
|
419
|
-
```bash
|
|
420
518
|
rails ruby_cms:content_blocks:export
|
|
421
519
|
```
|
|
422
520
|
|
|
423
521
|
## Configuration
|
|
424
522
|
|
|
425
|
-
All
|
|
523
|
+
Configuration is split across three generated files. All are plain Ruby initializers — edit them freely.
|
|
524
|
+
|
|
525
|
+
### `config/initializers/admin.rb`
|
|
526
|
+
|
|
527
|
+
`RubyCms.configure` options plus visual-editor preview setup:
|
|
426
528
|
|
|
427
529
|
```ruby
|
|
530
|
+
# config/initializers/admin.rb
|
|
531
|
+
|
|
428
532
|
RubyCms.configure do |c|
|
|
429
|
-
# Base controller (must provide current_user + authentication)
|
|
430
533
|
c.admin_base_controller = "ApplicationController"
|
|
431
|
-
|
|
432
|
-
# Admin layout
|
|
433
534
|
c.admin_layout = "admin/admin"
|
|
434
|
-
|
|
435
|
-
# User model class name
|
|
436
535
|
c.user_class_name = "User"
|
|
437
|
-
|
|
438
|
-
# Allow user.admin? bypass when no Permission records exist
|
|
439
536
|
c.bootstrap_admin_with_role = true
|
|
440
|
-
|
|
441
|
-
# Redirect path for unauthenticated/unauthorized users
|
|
442
537
|
c.unauthorized_redirect_path = "/"
|
|
443
|
-
|
|
444
|
-
# Visual editor
|
|
445
538
|
c.preview_templates = { "home" => "pages/home" }
|
|
446
|
-
c.preview_data = ->(page_key,
|
|
447
|
-
|
|
448
|
-
# Content blocks
|
|
539
|
+
c.preview_data = ->(page_key, _view, _variant = nil) { {} }
|
|
449
540
|
c.content_blocks_translation_namespace = "content_blocks"
|
|
450
541
|
c.image_content_types = %w[image/png image/jpeg image/gif image/webp]
|
|
451
542
|
c.image_max_size = 5 * 1024 * 1024
|
|
452
543
|
end
|
|
453
544
|
```
|
|
454
545
|
|
|
546
|
+
### `config/initializers/admin_nav.rb`
|
|
547
|
+
|
|
548
|
+
Sidebar nav entries. Generated from per-module nav fragments at `ruby_cms install` / `ruby_cms install --add`. Safe to edit by hand; note it is **regenerated** (fragments appended) when you add a new module.
|
|
549
|
+
|
|
550
|
+
```ruby
|
|
551
|
+
# config/initializers/admin_nav.rb
|
|
552
|
+
|
|
553
|
+
Rails.application.config.to_prepare do
|
|
554
|
+
RubyCms.register_page(key: :dashboard, ...)
|
|
555
|
+
RubyCms.nav_group(key: :content, ...)
|
|
556
|
+
# app-specific extra pages:
|
|
557
|
+
RubyCms.register_permission_keys(:manage_orders)
|
|
558
|
+
RubyCms.register_page(key: :orders, ...)
|
|
559
|
+
end
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
### `config/initializers/admin_dashboard.rb`
|
|
563
|
+
|
|
564
|
+
Dashboard block registrations:
|
|
565
|
+
|
|
566
|
+
```ruby
|
|
567
|
+
# config/initializers/admin_dashboard.rb
|
|
568
|
+
|
|
569
|
+
RubyCms.dashboard_register(key: :orders_stats, ...)
|
|
570
|
+
```
|
|
571
|
+
|
|
572
|
+
### Boot initializers
|
|
573
|
+
|
|
574
|
+
| File | Role |
|
|
575
|
+
|------|------|
|
|
576
|
+
| `config/initializers/admin.rb` | `RubyCms.configure` + visual-editor preview (generated at install) |
|
|
577
|
+
| `config/initializers/admin_nav.rb` | Sidebar nav (generated from module fragments at install/add) |
|
|
578
|
+
| `config/initializers/admin_dashboard.rb` | Dashboard block registrations |
|
|
579
|
+
| `config/initializers/ruby_cms_core.rb` | Boot hooks: versionable concern, settings import, permission rows |
|
|
580
|
+
|
|
581
|
+
### `config/application.rb`
|
|
582
|
+
|
|
583
|
+
After install, require the runtime module before the application class:
|
|
584
|
+
|
|
585
|
+
```ruby
|
|
586
|
+
require_relative "../lib/ruby_cms"
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
`lib/ruby_cms.rb` eager-loads `lib/ruby_cms/*.rb` so registries are available during boot.
|
|
590
|
+
|
|
455
591
|
## Rake Tasks
|
|
456
592
|
|
|
593
|
+
Copied to `lib/tasks/ruby_cms.rake` in the host app:
|
|
594
|
+
|
|
457
595
|
| Task | Description |
|
|
458
596
|
|------|-------------|
|
|
459
597
|
| `ruby_cms:seed_permissions` | Create default permission rows + settings |
|
|
460
598
|
| `ruby_cms:setup_admin` | Interactive first admin user setup |
|
|
461
|
-
| `ruby_cms:grant_manage_admin` | Grant all permissions to a user by email |
|
|
599
|
+
| `ruby_cms:grant_manage_admin[email]` | Grant all permissions to a user by email |
|
|
462
600
|
| `ruby_cms:content_blocks:export` | Export DB content blocks to YAML |
|
|
463
601
|
| `ruby_cms:content_blocks:import` | Import content blocks from YAML |
|
|
464
602
|
| `ruby_cms:content_blocks:sync` | Export + optional import |
|
|
465
603
|
| `ruby_cms:import_initializer_settings` | Import initializer values into DB settings |
|
|
466
|
-
| `ruby_cms:css:compile` | Compile admin CSS to host app |
|
|
467
|
-
| `ruby_cms:css:compile_gem` | Compile admin CSS within the gem |
|
|
468
604
|
|
|
469
605
|
## Development
|
|
470
606
|
|
|
471
|
-
###
|
|
607
|
+
### Gem repository
|
|
608
|
+
|
|
609
|
+
This repository holds **generator templates** under `lib/generators/ruby_cms/templates/`. The published gem defines only `RubyCms::VERSION` in `lib/ruby_cms.rb` — no runtime engine.
|
|
472
610
|
|
|
473
611
|
```bash
|
|
474
612
|
git clone https://github.com/jobhammer00/ruby_cms.git
|
|
475
613
|
cd ruby_cms
|
|
476
614
|
bundle install
|
|
477
|
-
```
|
|
478
|
-
|
|
479
|
-
### Running Tests
|
|
480
|
-
|
|
481
|
-
```bash
|
|
482
615
|
bundle exec rspec
|
|
483
616
|
```
|
|
484
617
|
|
|
485
|
-
|
|
618
|
+
### Syncing changes from a host app
|
|
486
619
|
|
|
487
|
-
|
|
620
|
+
When developing against a reference app (e.g. portfolio), push host-app edits back into gem templates using the `ruby_cms sync` CLI (run from the gem repo):
|
|
488
621
|
|
|
489
622
|
```bash
|
|
490
|
-
|
|
623
|
+
ruby_cms sync # default source: ../portfolio
|
|
624
|
+
ruby_cms sync --from ../gvexcelsior
|
|
625
|
+
ruby_cms sync --from ../gvexcelsior --dry-run
|
|
626
|
+
ruby_cms sync --from ../gvexcelsior --include-new # also add brand-new gem files
|
|
491
627
|
```
|
|
492
628
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
`assets:precompile` loads the Rails app in production mode and can be slow in Docker/Fly builds.
|
|
496
|
-
RubyCMS now skips non-asset runtime initializers during this phase (navigation registration,
|
|
497
|
-
dashboard registration, versioning hook, settings import, and permission seeding), which reduces
|
|
498
|
-
precompile overhead.
|
|
629
|
+
This is the reverse of `ruby_cms update`. By default sync only **updates files the gem already ships** — manifest globs like `helpers/**/*` also match app-specific files (a public-site helper, a marketing Stimulus controller) that the gem doesn't own, and absorbing those would pollute it. New matches are skipped and listed; pass `--include-new` to pull them in deliberately when you really are adding a file to the gem.
|
|
499
630
|
|
|
500
|
-
|
|
631
|
+
### Architecture (after install)
|
|
501
632
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
633
|
+
```
|
|
634
|
+
config/initializers/
|
|
635
|
+
admin.rb # RubyCms.configure + visual-editor preview
|
|
636
|
+
admin_nav.rb # Sidebar nav (generated from module fragments)
|
|
637
|
+
admin_dashboard.rb # Dashboard block registrations
|
|
638
|
+
ruby_cms_core.rb # Boot hooks (versionable, settings, permissions)
|
|
506
639
|
|
|
507
|
-
|
|
640
|
+
lib/ruby_cms.rb # Module API: nav_register, register_page, configure
|
|
641
|
+
lib/ruby_cms/
|
|
642
|
+
settings.rb # DB-backed settings
|
|
643
|
+
settings_registry.rb # Setting definitions
|
|
644
|
+
dashboard_blocks.rb # Dashboard registry
|
|
645
|
+
commands_registry.rb # Admin commands registry
|
|
646
|
+
icons.rb # Named Heroicon SVG registry
|
|
647
|
+
content_blocks_sync.rb # YAML ↔ DB import/export
|
|
648
|
+
content_blocks_grouping.rb # Multi-locale grouping
|
|
649
|
+
cli.rb # setup_admin interactive CLI
|
|
508
650
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
app/
|
|
517
|
-
|
|
518
|
-
app/views/ruby_cms/admin/ # Admin views
|
|
519
|
-
app/views/layouts/ruby_cms/ # Admin layout + sidebar
|
|
520
|
-
app/components/ # ViewComponents (AdminPage, etc.)
|
|
521
|
-
app/helpers/ # Content block, settings, dashboard helpers
|
|
651
|
+
app/controllers/admin/ # Dashboard, content blocks, analytics, etc.
|
|
652
|
+
app/views/admin/ # Admin ERB views
|
|
653
|
+
app/components/ruby_ui/admin_page/
|
|
654
|
+
admin_page.rb # Card wrapper (+ optional turbo_frame)
|
|
655
|
+
admin_page_header.rb # Breadcrumbs, title, actions
|
|
656
|
+
admin_table_content.rb # Turbo frame for tables
|
|
657
|
+
admin_resource_card.rb # Show-page layout constants
|
|
658
|
+
app/models/ # ContentBlock, Permission, Preference, etc.
|
|
659
|
+
lib/tasks/ruby_cms.rake # Seed, content blocks, setup_admin
|
|
522
660
|
```
|
|
523
661
|
|
|
524
|
-
### Key
|
|
662
|
+
### Key extension points
|
|
525
663
|
|
|
526
664
|
| What | How |
|
|
527
665
|
|------|-----|
|
|
528
|
-
| New admin page | `rails g ruby_cms:admin_page <name
|
|
529
|
-
| New nav item | `RubyCms.register_page(...)` or `RubyCms.nav_register(...)` |
|
|
530
|
-
| New permission | `RubyCms.register_permission_keys(:key)` |
|
|
531
|
-
| New dashboard block | `RubyCms.dashboard_register(...)` |
|
|
666
|
+
| New admin page | `rails g ruby_cms:admin_page <name> [field:type ...]` — registers itself in `config/initializers/admin_pages.rb` |
|
|
667
|
+
| New nav item | `RubyCms.register_page(...)` or `RubyCms.nav_register(...)` in `config/initializers/admin_pages.rb` (host-owned; `admin_nav.rb` is regenerated) |
|
|
668
|
+
| New app-specific permission | `RubyCms.register_permission_keys(:key)` in `config/initializers/admin_pages.rb` |
|
|
669
|
+
| New dashboard block | `RubyCms.dashboard_register(...)` in `config/initializers/admin_dashboard.rb` |
|
|
532
670
|
| New setting | `RubyCms::SettingsRegistry.register(...)` |
|
|
533
671
|
| New icon | Pass raw SVG string to `icon:` parameter |
|
|
672
|
+
| Add optional module | `ruby_cms install --add <module>` |
|
|
673
|
+
| Pull gem updates | `ruby_cms update` |
|
|
674
|
+
| Push changes to gem | `ruby_cms sync [--from ../app]` (gem repo) |
|
|
675
|
+
|
|
676
|
+
## Module reference
|
|
677
|
+
|
|
678
|
+
### Base modules (always installed)
|
|
679
|
+
|
|
680
|
+
`core`, `auth`, `permissions`, `users`, `content_blocks`, `visual_editor`
|
|
681
|
+
|
|
682
|
+
### Optional modules (`ruby_cms install` picker or `--add`)
|
|
683
|
+
|
|
684
|
+
`analytics`, `media`, `redirects`, `audit_log`, `trash`, `security`, `system_health`, `passkeys`, `commands`
|
|
685
|
+
|
|
686
|
+
App-specific features (contact forms, news, products, …) do **not** belong in the gem. Use **`rails g ruby_cms:admin_page`** to scaffold a CRUD admin page that plugs into nav, permissions, routes, and the shared table/UI stack — then add your model, mailers, and public controllers in the host app.
|
|
687
|
+
|
|
688
|
+
Permissions for each module are declared in the gem manifest (`lib/ruby_cms/manifest.rb` + `manifest_data.rb`) and seeded at install. You do not need to register them manually.
|
|
534
689
|
|
|
535
690
|
## License
|
|
536
691
|
|