Class: RubyCms::Generators::InstallGenerator
- Inherits:
-
Rails::Generators::Base
- Object
- Rails::Generators::Base
- RubyCms::Generators::InstallGenerator
- Defined in:
- lib/generators/ruby_cms/install_generator.rb
Constant Summary collapse
- NEXT_STEPS_MESSAGE =
"\n\u2713 RubyCMS install complete.\n\nNext steps (if not already done):\n- rails db:migrate\n- rails ruby_cms:seed_permissions (includes manage_visitor_errors and manage_analytics)\n- rails ruby_cms:setup_admin (or: rails ruby_cms:grant_manage_admin [email protected])\n- To seed content blocks from YAML: add content under content_blocks in config/locales/<locale>.yml, then run rails ruby_cms:content_blocks:seed (or call it from db/seeds.rb).\n\nNotes:\n- If the host uses /admin already, remove or change those routes.\n- Avoid root to: redirect(\"/admin\") \u2014 use a real root or ruby_cms.unauthorized_redirect_path.\n- Review config/initializers/ruby_cms.rb (session, CSP).\n- Add 'css: bin/rails tailwindcss:watch' to Procfile.dev for Tailwind in development.\n- Visit /admin (sign in as the admin you configured).\n\nTracking:\n- Visitor errors: Automatically captured via ApplicationController (see /admin/visitor_errors)\n- Page views (Ahoy): Include RubyCms::PageTracking in your public controllers to track page views\n Example: class PagesController < ApplicationController; include RubyCms::PageTracking; end\n- Analytics: View visit/event data in Ahoy tables (ahoy_visits, ahoy_events)\n"- SKIP_VIEW_DIRS =
Directories to skip when scanning for page templates
%w[layouts shared mailers components admin].freeze
Instance Method Summary collapse
- #add_catch_all_route ⇒ Object
- #add_current_user_to_authentication ⇒ Object
- #add_page_tracking_to_home_controller ⇒ Object
- #add_permittable_to_user ⇒ Object
- #add_visitor_error_capture ⇒ Object
- #copy_fallback_css ⇒ Object
- #create_admin_layout ⇒ Object
- #create_initializer ⇒ Object
- #install_action_text ⇒ Object
- #install_ahoy ⇒ Object
- #install_ruby_ui ⇒ Object
- #install_tailwind ⇒ Object
- #mount_engine ⇒ Object
- #run_authentication ⇒ Object
- #run_migrate ⇒ Object
- #run_ruby_ui_install ⇒ Object
- #run_seed_permissions ⇒ Object
- #run_setup_admin ⇒ Object
- #show_next_steps ⇒ Object
- #verify_application_controller ⇒ Object
- #verify_auth ⇒ Object
- #verify_session_model ⇒ Object
- #verify_user_model ⇒ Object
Instance Method Details
#add_catch_all_route ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 96 def add_catch_all_route routes_path = Rails.root.join("config/routes.rb") return unless routes_path.exist? content = File.read(routes_path) return if content.include?("ruby_cms/errors#not_found") # Add catch-all route at the end of the routes block (before final 'end') catch_all = "\n # RubyCMS: Catch-all route for 404 error tracking (must be LAST)\n match \"*path\", to: \"ruby_cms/errors#not_found\", via: :all,\n constraints: ->(req) { !req.path.start_with?(\"/rails/\", \"/assets/\") }\n ROUTE\n\n # Insert before the last 'end' in the file\n gsub_file routes_path, /(\\nend)\\s*\\z/ do\n \"\#{catch_all}end\\n\"\n end\n say \"\u2713 Catch-all route: Added for 404 error tracking\", :green\nrescue StandardError => e\n say \"\u26A0 Catch-all route: Could not add automatically: \#{e.message}. \" \\\n \"Add manually at the END of routes.rb:\\n \" \\\n 'match \"*path\", to: \"ruby_cms/errors#not_found\", via: :all, ' \\\n 'constraints: ->(req) { !req.path.start_with?(\"/rails/\", \"/assets/\") }',\n :yellow\nend\n" |
#add_current_user_to_authentication ⇒ Object
138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 138 def add_current_user_to_authentication auth_path = Rails.root.join("app/controllers/concerns/authentication.rb") return unless auth_path.exist? return if File.read(auth_path).include?("def current_user") gsub_file auth_path, " helper_method :authenticated?\n", " helper_method :authenticated?, :current_user\n" inject_into_file auth_path, after: " private\n" do " def current_user\n Current.user\n end\n\n" end end |
#add_page_tracking_to_home_controller ⇒ Object
171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 171 def add_page_tracking_to_home_controller home_path = Rails.root.join("app/controllers/home_controller.rb") return unless home_path.exist? content = File.read(home_path) return if content.include?("RubyCms::PageTracking") inject_into_file home_path, after: /class HomeController.*\n/ do " include RubyCms::PageTracking\n" end say "✓ Page tracking: Added RubyCms::PageTracking to HomeController", :green rescue StandardError => e say "⚠ Page tracking: Could not add to HomeController: #{e.message}. " \ "Add manually: include RubyCms::PageTracking", :yellow end |
#add_permittable_to_user ⇒ Object
124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 124 def add_permittable_to_user user_path = Rails.root.join("app/models/user.rb") unless File.exist?(user_path) say "Skipping User: app/models/user.rb not found.", :yellow return end return if File.read(user_path).include?("RubyCms::Permittable") inject_into_file user_path, after: /class User .*\n/ do " include RubyCms::Permittable\n" end end |
#add_visitor_error_capture ⇒ Object
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 150 def add_visitor_error_capture ac_path = Rails.root.join("app/controllers/application_controller.rb") return unless ac_path.exist? content = File.read(ac_path) return if content.include?("RubyCms::VisitorErrorCapture") to_inject = " include RubyCms::VisitorErrorCapture\n" to_inject += " rescue_from StandardError, with: :handle_visitor_error\n" \ unless content.include?("rescue_from StandardError") inject_into_file ac_path, after: /class ApplicationController.*\n/ do to_inject end say "✓ Visitor error capture: Added to ApplicationController", :green rescue StandardError => e say "⚠ Visitor error capture: Could not add to ApplicationController: #{e.message}. " \ "Add manually: include RubyCms::VisitorErrorCapture and rescue_from StandardError, with: :handle_visitor_error", :yellow end |
#copy_fallback_css ⇒ Object
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 189 def copy_fallback_css src_dir = RubyCms::Engine.root.join("app/assets/stylesheets/ruby_cms") dest_dir = Rails.root.join("app/assets/stylesheets/ruby_cms") return unless src_dir.exist? FileUtils.mkdir_p(dest_dir) copy_admin_css(dest_dir) # Don't copy component files - only the compiled admin.css is needed # copy_components_css(src_dir, dest_dir) say "✓ Task css/copy: Combined component CSS into " \ "app/assets/stylesheets/ruby_cms/admin.css", :green rescue StandardError => e say "⚠ Task css/copy: Could not copy CSS files: #{e.message}.", :yellow end |
#create_admin_layout ⇒ Object
205 206 207 208 209 210 211 212 213 214 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 205 def create_admin_layout layout_path = Rails.root.join("app/views/layouts/admin.html.erb") return if File.exist?(layout_path) template "admin.html.erb", layout_path.to_s say "✓ Layout admin: Created app/views/layouts/admin.html.erb", :green rescue StandardError => e say "⚠ Layout admin: Could not create admin.html.erb: #{e.message}. " \ "Create it manually using the RubyCMS template.", :yellow end |
#create_initializer ⇒ Object
87 88 89 90 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 87 def create_initializer @detected_pages = detect_page_templates template "ruby_cms.rb", "config/initializers/ruby_cms.rb" end |
#install_action_text ⇒ Object
260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 260 def install_action_text migrate_dir = Rails.root.join("db/migrate") return unless migrate_dir.directory? if action_text_already_installed?(migrate_dir) say "ℹ Task action_text: Existing Action Text setup detected. Skipping action_text:install.", :cyan else say "ℹ Task action_text: Installing Action Text for rich text/image content blocks.", :cyan run "bin/rails action_text:install" say "✓ Task action_text: Installed Action Text", :green end configure_action_text_assets rescue StandardError => e say "⚠ Task action_text: Could not install: #{e.message}. Rich text will be disabled.", :yellow end |
#install_ahoy ⇒ Object
241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 241 def install_ahoy if ahoy_already_installed? say "ℹ Task ahoy: Existing Ahoy setup detected (tables or migrations). Skipping ahoy:install.", :cyan configure_ahoy_server_side_only return end say "ℹ Task ahoy: Installing Ahoy for visit/event tracking.", :cyan run "bin/rails generate ahoy:install" add_ahoy_security_fields_migration configure_ahoy_server_side_only say "✓ Task ahoy: Installed Ahoy (visits, events, tracking)", :green rescue StandardError => e say "⚠ Task ahoy: Could not install: #{e.message}. " \ "Run 'rails g ahoy:install' manually.", :yellow end |
#install_ruby_ui ⇒ Object
490 491 492 493 494 495 496 497 498 499 500 501 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 490 def install_ruby_ui gemfile = Rails.root.join("Gemfile") gemfile_content = File.read(gemfile) return if ruby_ui_in_gemfile?(gemfile_content) add_ruby_ui_gem rescue StandardError => e say "⚠ Task ruby_ui: Could not add: #{e.message}. " \ "Run 'bundle add ruby_ui --group development --require false' manually.", :yellow nil end |
#install_tailwind ⇒ Object
446 447 448 449 450 451 452 453 454 455 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 446 def install_tailwind gemfile = Rails.root.join("Gemfile") tailwind_css = detect_tailwind_entry_css_path install_tailwind_if_needed(gemfile, tailwind_css) configure_tailwind(tailwind_css) rescue StandardError => e say "⚠ Task tailwind: Could not install: #{e.message}. Add tailwindcss-rails manually.", :yellow end |
#mount_engine ⇒ Object
92 93 94 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 92 def mount_engine route 'mount RubyCms::Engine => "/"' end |
#run_authentication ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 34 def run_authentication user_path = Rails.root.join("app/models/user.rb") return if File.exist?(user_path) say "ℹ Task authentication: User model not found. " \ "Running 'rails g authentication' (Rails 8+).", :cyan @authentication_attempted = true run "bin/rails generate authentication" run "bundle install" rescue StandardError => e say "⚠ Could not run 'rails g authentication': #{e.message}.", :yellow say " On Rails 8+, run 'rails g authentication' and 'bundle install' manually.", :yellow end |
#run_migrate ⇒ Object
969 970 971 972 973 974 975 976 977 978 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 969 def run_migrate say "ℹ Task db:migrate: Running db:migrate.", :cyan success = run("bin/rails db:migrate") raise "db:migrate failed" unless success say "✓ Task db:migrate: Completed", :green rescue StandardError => e say "⚠ Task db:migrate: Failed: #{e.message}. Run rails db:create db:migrate if needed.", :yellow end |
#run_ruby_ui_install ⇒ Object
503 504 505 506 507 508 509 510 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 503 def run_ruby_ui_install gemfile = Rails.root.join("Gemfile") gemfile_content = File.read(gemfile) return unless ruby_ui_in_gemfile?(gemfile_content) return if ruby_ui_already_installed? install_ruby_ui_generator end |
#run_seed_permissions ⇒ Object
980 981 982 983 984 985 986 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 980 def say "ℹ Task permissions: Seeding RubyCMS permissions.", :cyan success = (success) rescue StandardError => e (e) end |
#run_setup_admin ⇒ Object
988 989 990 991 992 993 994 995 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 988 def run_setup_admin return if skip_setup_admin_due_to_existing_admin? return unless setup_admin_tty? run_setup_admin_task rescue StandardError => e say_setup_admin_error(e) end |
#show_next_steps ⇒ Object
1119 1120 1121 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 1119 def show_next_steps say NEXT_STEPS_MESSAGE, :green end |
#verify_application_controller ⇒ Object
73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 73 def verify_application_controller ac_path = Rails.root.join("app/controllers/application_controller.rb") return unless ac_path.exist? content = File.read(ac_path) return if content.include?("include Authentication") return if @authentication_warning_shown say "ℹ Task authentication: ApplicationController does not include " \ "Authentication. Ensure /admin is protected.", :yellow @authentication_warning_shown = true end |
#verify_auth ⇒ Object
48 49 50 51 52 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 48 def verify_auth verify_user_model verify_session_model verify_application_controller end |
#verify_session_model ⇒ Object
65 66 67 68 69 70 71 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 65 def verify_session_model return if defined?(::Session) say "ℹ Task authentication: Session model not found. " \ "The host app should provide authentication.", :yellow end |
#verify_user_model ⇒ Object
54 55 56 57 58 59 60 61 62 63 |
# File 'lib/generators/ruby_cms/install_generator.rb', line 54 def verify_user_model return if defined?(::User) = if @authentication_attempted "Run 'rails db:migrate' if the authentication generator succeeded." else "User model not found. Run 'rails g authentication' before using /admin." end say "ℹ Task authentication: #{message}", :yellow end |