ruby_cms 0.2.1.1 → 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 -75
- data/README.md +293 -158
- 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 +13 -13
- 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/{app/views/layouts/ruby_cms → lib/generators/ruby_cms/templates/views/layouts/admin}/_admin_sidebar.html.erb +47 -48
- 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 -328
- metadata +606 -170
- 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 -49
- 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.html.erb +0 -77
- data/app/views/layouts/ruby_cms/minimal.html.erb +0 -181
- data/app/views/ruby_cms/_tailwind_safelist.html.erb +0 -2
- 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 -1159
- 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 -90
- 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)
|
|
@@ -231,8 +331,6 @@ RubyCms.nav_register(
|
|
|
231
331
|
|
|
232
332
|
### nav_group (accordion)
|
|
233
333
|
|
|
234
|
-
Define a sidebar accordion group in the same config file as your pages:
|
|
235
|
-
|
|
236
334
|
```ruby
|
|
237
335
|
RubyCms.nav_group(
|
|
238
336
|
key: :operations,
|
|
@@ -240,9 +338,7 @@ RubyCms.nav_group(
|
|
|
240
338
|
icon: :folder,
|
|
241
339
|
section: "main",
|
|
242
340
|
order: 20,
|
|
243
|
-
|
|
244
|
-
path: ->(view) { view.main_app.admin_operations_path },
|
|
245
|
-
# Child pages are referenced by the keys you used in register_page/nav_register
|
|
341
|
+
path: ->(view) { view.admin_operations_path },
|
|
246
342
|
children: %i[backups reports]
|
|
247
343
|
)
|
|
248
344
|
```
|
|
@@ -254,7 +350,7 @@ Groups are hidden automatically when they have no visible children and no `path`
|
|
|
254
350
|
| Format | Example | Behavior |
|
|
255
351
|
|--------|---------|----------|
|
|
256
352
|
| Symbol | `:admin_backups_path` | Auto-wrapped: `view.main_app.send(:admin_backups_path)` |
|
|
257
|
-
| Lambda | `->
|
|
353
|
+
| Lambda | `->(view) { view.admin_backups_path }` | Called with view context |
|
|
258
354
|
| String | `"/admin/backups"` | Used as-is |
|
|
259
355
|
|
|
260
356
|
### Named Icons
|
|
@@ -263,19 +359,16 @@ Use symbol keys from `RubyCms::Icons`:
|
|
|
263
359
|
|
|
264
360
|
```ruby
|
|
265
361
|
RubyCms::Icons.available
|
|
266
|
-
# => [:home, :pencil_square, :document_duplicate, :chart_bar, :shield_check,
|
|
267
|
-
# :exclamation_triangle, :user_group, :cog_6_tooth, :archive_box, :folder,
|
|
268
|
-
# :bell, :clock, :tag, :cube, :envelope, :wrench, :globe, :photograph,
|
|
269
|
-
# :list_bullet, :plus_circle, :trash, :eye, :lock_closed, :currency_dollar]
|
|
362
|
+
# => [:home, :pencil_square, :document_duplicate, :chart_bar, :shield_check, ...]
|
|
270
363
|
```
|
|
271
364
|
|
|
272
365
|
Raw SVG strings are also accepted for custom icons.
|
|
273
366
|
|
|
274
367
|
### Permission Keys
|
|
275
368
|
|
|
276
|
-
|
|
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.
|
|
277
370
|
|
|
278
|
-
Register additional keys:
|
|
371
|
+
Register additional app-specific keys in any initializer (e.g. `config/initializers/admin_nav.rb`):
|
|
279
372
|
|
|
280
373
|
```ruby
|
|
281
374
|
RubyCms.register_permission_keys(:manage_orders, :manage_reports)
|
|
@@ -283,8 +376,6 @@ RubyCms.register_permission_keys(:manage_orders, :manage_reports)
|
|
|
283
376
|
|
|
284
377
|
### Permission Templates
|
|
285
378
|
|
|
286
|
-
Group permission keys into reusable templates:
|
|
287
|
-
|
|
288
379
|
```ruby
|
|
289
380
|
RubyCms.register_permission_template(:editor,
|
|
290
381
|
label: "Editor",
|
|
@@ -292,17 +383,16 @@ RubyCms.register_permission_template(:editor,
|
|
|
292
383
|
description: "Can manage content but not users"
|
|
293
384
|
)
|
|
294
385
|
|
|
295
|
-
# Apply to a user:
|
|
296
386
|
RubyCms::Permission.apply_template!(user, :editor)
|
|
297
387
|
```
|
|
298
388
|
|
|
299
389
|
### cms_page Macro
|
|
300
390
|
|
|
301
|
-
In controllers
|
|
391
|
+
In controllers under `Admin::ApplicationController`, use `cms_page` to enforce the permission from `register_page`:
|
|
302
392
|
|
|
303
393
|
```ruby
|
|
304
|
-
class Admin::BackupsController <
|
|
305
|
-
cms_page :backups
|
|
394
|
+
class Admin::BackupsController < Admin::ApplicationController
|
|
395
|
+
cms_page :backups
|
|
306
396
|
|
|
307
397
|
def index
|
|
308
398
|
@backups = Backup.recent
|
|
@@ -312,49 +402,50 @@ end
|
|
|
312
402
|
|
|
313
403
|
## Admin Page Generator
|
|
314
404
|
|
|
315
|
-
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:
|
|
316
408
|
|
|
317
409
|
```bash
|
|
318
|
-
rails g ruby_cms:admin_page
|
|
410
|
+
rails g ruby_cms:admin_page product name:string price:decimal published:boolean
|
|
319
411
|
```
|
|
320
412
|
|
|
321
413
|
This generates:
|
|
322
414
|
|
|
323
415
|
| File | Description |
|
|
324
416
|
|------|-------------|
|
|
325
|
-
| `app/controllers/admin/
|
|
326
|
-
| `app/views/admin/
|
|
327
|
-
| `
|
|
328
|
-
| `
|
|
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`) |
|
|
329
424
|
|
|
330
425
|
### Options
|
|
331
426
|
|
|
332
427
|
```bash
|
|
333
|
-
rails g ruby_cms:admin_page
|
|
334
|
-
--permission=manage_backups \
|
|
335
|
-
--icon=archive_box \
|
|
336
|
-
--section=settings \
|
|
337
|
-
--order=15
|
|
428
|
+
rails g ruby_cms:admin_page report --read-only --section=settings --icon=chart_bar --order=15
|
|
338
429
|
```
|
|
339
430
|
|
|
340
431
|
| Option | Default | Description |
|
|
341
432
|
|--------|---------|-------------|
|
|
342
|
-
| `--permission` | `manage_<
|
|
343
|
-
| `--icon` | `folder` | Icon from `RubyCms::Icons` |
|
|
433
|
+
| `--permission` | `manage_<plural>` | Permission key |
|
|
434
|
+
| `--icon` | `folder` | Icon from `RubyCms::Icons` (`RubyCms::Icons.available`) |
|
|
344
435
|
| `--section` | `main` | `main` or `settings` |
|
|
345
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 |
|
|
346
440
|
|
|
347
441
|
After generating, run `rails ruby_cms:seed_permissions` to create the permission row in the database.
|
|
348
442
|
|
|
349
443
|
## Settings
|
|
350
444
|
|
|
351
|
-
|
|
445
|
+
DB-backed settings with a registry for defaults and types:
|
|
352
446
|
|
|
353
447
|
```ruby
|
|
354
|
-
# Read
|
|
355
448
|
RubyCms::Settings.get(:analytics_default_period, default: "week")
|
|
356
|
-
|
|
357
|
-
# Write (admin UI or programmatic)
|
|
358
449
|
RubyCms::Settings.set(:analytics_default_period, "month")
|
|
359
450
|
```
|
|
360
451
|
|
|
@@ -374,7 +465,7 @@ Settings are managed in **Admin > Settings** with tabs per category.
|
|
|
374
465
|
|
|
375
466
|
## Visitor Error Tracking
|
|
376
467
|
|
|
377
|
-
Public exceptions are
|
|
468
|
+
Public exceptions are captured when `VisitorErrorCapture` is included in your `ApplicationController` (added by the install generator).
|
|
378
469
|
|
|
379
470
|
View captured errors in **Admin > Visitor errors** with status codes, paths, timestamps, and resolution tracking.
|
|
380
471
|
|
|
@@ -382,22 +473,20 @@ View captured errors in **Admin > Visitor errors** with status codes, paths, tim
|
|
|
382
473
|
|
|
383
474
|
RubyCMS integrates with Ahoy for server-side page view and event tracking.
|
|
384
475
|
|
|
385
|
-
Include `
|
|
476
|
+
Include `PageTracking` in public controllers:
|
|
386
477
|
|
|
387
478
|
```ruby
|
|
388
479
|
class PagesController < ApplicationController
|
|
389
|
-
include
|
|
480
|
+
include PageTracking
|
|
390
481
|
end
|
|
391
482
|
```
|
|
392
483
|
|
|
393
|
-
View analytics in **Admin > Analytics** with
|
|
394
|
-
- Visit and event counts
|
|
395
|
-
- Popular pages
|
|
396
|
-
- Top visitors
|
|
397
|
-
- Configurable date ranges and periods
|
|
484
|
+
View analytics in **Admin > Analytics** with visit/event counts, popular pages, top visitors, and configurable date ranges.
|
|
398
485
|
|
|
399
486
|
### Customization Hooks
|
|
400
487
|
|
|
488
|
+
Place these in `config/initializers/admin.rb` inside the `RubyCms.configure` block:
|
|
489
|
+
|
|
401
490
|
```ruby
|
|
402
491
|
RubyCms.configure do |c|
|
|
403
492
|
c.analytics_visit_scope = ->(scope) { scope.where.not(ip: ["127.0.0.1"]) }
|
|
@@ -410,147 +499,193 @@ end
|
|
|
410
499
|
|
|
411
500
|
## Seeding Content Blocks from YAML
|
|
412
501
|
|
|
413
|
-
Set the translation namespace:
|
|
414
|
-
|
|
415
502
|
```ruby
|
|
503
|
+
# config/initializers/admin.rb
|
|
416
504
|
RubyCms.configure do |c|
|
|
417
505
|
c.content_blocks_translation_namespace = "content_blocks"
|
|
418
506
|
end
|
|
419
507
|
```
|
|
420
508
|
|
|
421
|
-
Create locale files:
|
|
422
|
-
|
|
423
509
|
```yaml
|
|
424
510
|
# config/locales/en.yml
|
|
425
511
|
en:
|
|
426
512
|
content_blocks:
|
|
427
513
|
hero_title: "Welcome to my site"
|
|
428
|
-
footer_text: "Copyright 2026"
|
|
429
514
|
```
|
|
430
515
|
|
|
431
|
-
Import:
|
|
432
|
-
|
|
433
516
|
```bash
|
|
434
517
|
rails ruby_cms:content_blocks:import
|
|
435
|
-
```
|
|
436
|
-
|
|
437
|
-
Export DB content blocks back to YAML:
|
|
438
|
-
|
|
439
|
-
```bash
|
|
440
518
|
rails ruby_cms:content_blocks:export
|
|
441
519
|
```
|
|
442
520
|
|
|
443
521
|
## Configuration
|
|
444
522
|
|
|
445
|
-
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:
|
|
446
528
|
|
|
447
529
|
```ruby
|
|
530
|
+
# config/initializers/admin.rb
|
|
531
|
+
|
|
448
532
|
RubyCms.configure do |c|
|
|
449
|
-
# Base controller (must provide current_user + authentication)
|
|
450
533
|
c.admin_base_controller = "ApplicationController"
|
|
451
|
-
|
|
452
|
-
# Admin layout
|
|
453
534
|
c.admin_layout = "admin/admin"
|
|
454
|
-
|
|
455
|
-
# User model class name
|
|
456
535
|
c.user_class_name = "User"
|
|
457
|
-
|
|
458
|
-
# Allow user.admin? bypass when no Permission records exist
|
|
459
536
|
c.bootstrap_admin_with_role = true
|
|
460
|
-
|
|
461
|
-
# Redirect path for unauthenticated/unauthorized users
|
|
462
537
|
c.unauthorized_redirect_path = "/"
|
|
463
|
-
|
|
464
|
-
# Visual editor
|
|
465
538
|
c.preview_templates = { "home" => "pages/home" }
|
|
466
|
-
c.preview_data = ->(page_key,
|
|
467
|
-
|
|
468
|
-
# Content blocks
|
|
539
|
+
c.preview_data = ->(page_key, _view, _variant = nil) { {} }
|
|
469
540
|
c.content_blocks_translation_namespace = "content_blocks"
|
|
470
541
|
c.image_content_types = %w[image/png image/jpeg image/gif image/webp]
|
|
471
542
|
c.image_max_size = 5 * 1024 * 1024
|
|
472
543
|
end
|
|
473
544
|
```
|
|
474
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
|
+
|
|
475
591
|
## Rake Tasks
|
|
476
592
|
|
|
593
|
+
Copied to `lib/tasks/ruby_cms.rake` in the host app:
|
|
594
|
+
|
|
477
595
|
| Task | Description |
|
|
478
596
|
|------|-------------|
|
|
479
597
|
| `ruby_cms:seed_permissions` | Create default permission rows + settings |
|
|
480
598
|
| `ruby_cms:setup_admin` | Interactive first admin user setup |
|
|
481
|
-
| `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 |
|
|
482
600
|
| `ruby_cms:content_blocks:export` | Export DB content blocks to YAML |
|
|
483
601
|
| `ruby_cms:content_blocks:import` | Import content blocks from YAML |
|
|
484
602
|
| `ruby_cms:content_blocks:sync` | Export + optional import |
|
|
485
603
|
| `ruby_cms:import_initializer_settings` | Import initializer values into DB settings |
|
|
486
|
-
| `ruby_cms:css:compile` | Compile admin CSS to host app |
|
|
487
|
-
| `ruby_cms:css:compile_gem` | Compile admin CSS within the gem |
|
|
488
604
|
|
|
489
605
|
## Development
|
|
490
606
|
|
|
491
|
-
###
|
|
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.
|
|
492
610
|
|
|
493
611
|
```bash
|
|
494
612
|
git clone https://github.com/jobhammer00/ruby_cms.git
|
|
495
613
|
cd ruby_cms
|
|
496
614
|
bundle install
|
|
497
|
-
```
|
|
498
|
-
|
|
499
|
-
### Running Tests
|
|
500
|
-
|
|
501
|
-
```bash
|
|
502
615
|
bundle exec rspec
|
|
503
616
|
```
|
|
504
617
|
|
|
505
|
-
|
|
618
|
+
### Syncing changes from a host app
|
|
506
619
|
|
|
507
|
-
|
|
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):
|
|
508
621
|
|
|
509
622
|
```bash
|
|
510
|
-
|
|
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
|
|
511
627
|
```
|
|
512
628
|
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
`assets:precompile` loads the Rails app in production mode and can be slow in Docker/Fly builds.
|
|
516
|
-
RubyCMS now skips non-asset runtime initializers during this phase (navigation registration,
|
|
517
|
-
dashboard registration, versioning hook, settings import, and permission seeding), which reduces
|
|
518
|
-
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.
|
|
519
630
|
|
|
520
|
-
|
|
631
|
+
### Architecture (after install)
|
|
521
632
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
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)
|
|
526
639
|
|
|
527
|
-
|
|
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
|
|
528
650
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
app/
|
|
537
|
-
|
|
538
|
-
app/views/ruby_cms/admin/ # Admin views
|
|
539
|
-
app/views/layouts/ruby_cms/ # Admin layout + sidebar
|
|
540
|
-
app/components/ # ViewComponents (AdminPage, etc.)
|
|
541
|
-
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
|
|
542
660
|
```
|
|
543
661
|
|
|
544
|
-
### Key
|
|
662
|
+
### Key extension points
|
|
545
663
|
|
|
546
664
|
| What | How |
|
|
547
665
|
|------|-----|
|
|
548
|
-
| New admin page | `rails g ruby_cms:admin_page <name
|
|
549
|
-
| New nav item | `RubyCms.register_page(...)` or `RubyCms.nav_register(...)` |
|
|
550
|
-
| New permission | `RubyCms.register_permission_keys(:key)` |
|
|
551
|
-
| 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` |
|
|
552
670
|
| New setting | `RubyCms::SettingsRegistry.register(...)` |
|
|
553
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.
|
|
554
689
|
|
|
555
690
|
## License
|
|
556
691
|
|