Last active
October 22, 2025 19:49
-
-
Save lucasgeron/304c62c2330b332f377ef05799625e0f to your computer and use it in GitHub Desktop.
Rails Starter Pack
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # place this code in ~/.railsrc | |
| --css=tailwind | |
| --template=~/.rails/template.rb |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| This gist is a Rails Started Pack, developed to speed up the setup of a new rails project. | |
| Feel free to customize and use as needed. Developed by [lucasgeron](https://lucasgeron.github.io/) | |
| When configured, a custom template dialog will be ivoked after run a `rails new` command. | |
| NOTE: If you're using postgres with docker, consider to review `template_helper.rb` line: 300. | |
| The default environment variables is set to: | |
| username: postgres | |
| password: password | |
| Update your postgres container, or the variables to work as expected. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # place this code in ~/.rails/template.rb | |
| require_relative 'template_helper' | |
| def show_template_dialog | |
| validate_args | |
| if ask("Do you want to use template?", %i[blue bold], default: 'y', limited_to: %w[y n]) == 'y' | |
| say('The default template includes:') | |
| TemplateHelper::RESOURCES.each do |key, attr| | |
| say("• #{key}", (attr[:required] ? :green : :red)) | |
| end | |
| unless ask('Use default template?', %i[blue], default: 'y', limited_to: %w[y n]) == 'y' | |
| TemplateHelper::RESOURCES.each do |key, attr| | |
| if ask("• #{key.to_s.ljust(25)} #{attr[:info]}", %i[white], default: 'y', limited_to: %w[y n]) == 'y' | |
| TemplateHelper::RESOURCES[key][:required] = true | |
| else | |
| TemplateHelper::RESOURCES[key][:required] = false | |
| end | |
| end | |
| say('Your custom template includes:', %i[blue]) | |
| TemplateHelper::RESOURCES.each do |key, attr| | |
| say("• #{key}", (attr[:required] ? :green : :red)) | |
| end | |
| ask('Press any key to continue, or CTRL + C to cancel...', %i[blue bold]) | |
| end | |
| TemplateHelper::RESOURCES.sort_by{|key, attr| [attr[:order] || Float::INFINITY, key]}.each do |key, attr| | |
| if attr[:required] | |
| say("\nSetting up #{key}...", :green) | |
| send(key) | |
| say("#{key} has been set up!\n", :green) | |
| end | |
| end | |
| say('Template has been applied!', %i[green bold]) | |
| end | |
| after_bundle do | |
| git_init | |
| generate_sample_page | |
| start_server | |
| end | |
| end | |
| # RESOURCES METHODS - - - - - - - - - - - - - - - - - - | |
| def devise | |
| insert_into_file 'Gemfile', TemplateHelper::DEVISE, before: "group :development, :test do\n" | |
| generate 'devise:install' | |
| after_bundle do | |
| insert_into_file 'app/views/layouts/application.html.erb', TemplateHelper::DEVISE_NOTIFICATIONS, after: "<body>\n" | |
| end | |
| generate 'devise:views' | |
| if ask("Do you want to create a deviser User model?", :blue, default: 'y', limited_to: %w[y n]) == 'y' | |
| generate 'devise User' | |
| rails_command 'db:migrate' | |
| end | |
| if TemplateHelper::RESOURCES[:rspec][:required] | |
| insert_into_file 'spec/rails_helper.rb', TemplateHelper::DEVISE_RSPEC_HELPERS, after: "RSpec.configure do |config|\n" | |
| end | |
| # If you want to use Devise without Rspec, consider to read the [documentation](https://github.com/heartcombo/devise?tab=readme-ov-file#controller-tests) | |
| end | |
| def factory_bot | |
| insert_into_file 'Gemfile', TemplateHelper::FACTORY_BOT, after: "group :development, :test do\n" | |
| insert_into_file 'spec/rails_helper.rb', TemplateHelper::FACTORY_BOT_HELPER, after: "RSpec.configure do |config|\n" if(TemplateHelper::RESOURCES[:rspec][:required]) | |
| end | |
| def faker | |
| insert_into_file 'Gemfile', TemplateHelper::FAKER, after: "group :development, :test do\n" | |
| end | |
| def ffaker | |
| insert_into_file 'Gemfile', TemplateHelper::FFAKER, after: "group :development, :test do\n" | |
| end | |
| def flowbite | |
| run 'npm install flowbite' | |
| insert_into_file '.gitignore', TemplateHelper::FLOWBITE_NODE_MODULES_GITIGNORE, after: "/config/master.key\n" | |
| after_bundle do | |
| insert_into_file 'config/tailwind.config.js', TemplateHelper::FLOWBITE_CONFIG_PLUGIN, after: "plugins: [\n" | |
| insert_into_file 'config/tailwind.config.js', TemplateHelper::FLOWBITE_CONFIG_CONTENT, after: "'./app/javascript/**/*.js',\n" | |
| insert_into_file 'config/tailwind.config.js', TemplateHelper::FLOWBITE_CONFIG_DARKMODE, after: "module.exports = {\n" | |
| append_to_file 'app/javascript/controllers/application.js', TemplateHelper::FLOWBITE_TAILWIND_DARKMODE | |
| append_to_file 'config/importmap.rb', TemplateHelper::FLOWBITE_CONFIG_IMPORTMAP | |
| append_to_file 'app/javascript/application.js', TemplateHelper::FLOWBITE_CONFIG_JS | |
| insert_into_file 'app/views/layouts/application.html.erb', " class='dark:bg-gray-900 dark:text-slate-200'", after: "<body" | |
| end | |
| end | |
| def font_awesome | |
| insert_into_file 'Gemfile', TemplateHelper::FONT_AWESOME, before: "group :development, :test do\n" | |
| File.rename('app/assets/stylesheets/application.css', 'app/assets/stylesheets/application.css.scss') | |
| insert_into_file 'app/assets/stylesheets/application.css.scss', TemplateHelper::FONT_AWESOME_CONFIG, after: "*/\n" | |
| end | |
| def htmlbeautifier | |
| insert_into_file 'Gemfile', TemplateHelper::HTMLBEAUTIFIER, after: "group :development do\n" | |
| end | |
| def postgres_with_docker | |
| insert_into_file 'config/database.yml', TemplateHelper::POSTGRES_WITH_DOCKER, after: "default: &default\n" | |
| db_prepare | |
| end | |
| def pry_rails | |
| insert_into_file 'Gemfile', TemplateHelper::PRY_RAILS, after: "group :development do\n" | |
| end | |
| def pundit | |
| run 'bundle add pundit' | |
| generate 'pundit:install' | |
| insert_into_file 'app/controllers/application_controller.rb', TemplateHelper::PUNDIT_INCLUDE, after: "class ApplicationController < ActionController::Base\n" | |
| if TemplateHelper::RESOURCES[:rspec][:required] | |
| insert_into_file 'spec/rails_helper.rb', TemplateHelper::PUNDIT_REQUIRE, before: "# This file is copied to spec/ when you run 'rails generate rspec:install'\n" | |
| else | |
| insert_into_file 'test/test_helper.rb', TemplateHelper::PUNDIT_REQUIRE, before: "module ActiveSupport" | |
| end | |
| end | |
| def rspec | |
| insert_into_file 'Gemfile', TemplateHelper::RSPEC, after: "group :development, :test do\n" | |
| generate 'rspec:install' | |
| insert_into_file 'spec/rails_helper.rb', TemplateHelper::RSPEC_URL_HELPERS, after: "RSpec.configure do |config|\n" | |
| remove_dir 'test' | |
| end | |
| def rswag | |
| insert_into_file 'Gemfile', TemplateHelper::RSWAG, before: "group :development, :test do\n" | |
| insert_into_file 'Gemfile', TemplateHelper::RSWAG_SPEC, after: "group :development, :test do\n" | |
| unless TemplateHelper::RESOURCES[:rspec][:required] | |
| say('Rswag requires RSpec to be installed. Installing RSpec...', :yellow) | |
| rspec | |
| end | |
| generate 'rswag:install' | |
| gsub_file('config/initializers/rswag_ui.rb', 'swagger_endpoint', 'openapi_endpoint') | |
| rails_command ' rswag:specs:swaggerize' | |
| end | |
| def ruby_lsp | |
| inject_into_file 'Gemfile', TemplateHelper::RUBY_LSP, after: "group :development do\n" | |
| end | |
| def rubocop | |
| insert_into_file 'Gemfile', TemplateHelper::RUBOCOP, after: "group :development do\n" | |
| create_file '.rubocop.yml', TemplateHelper::RUBOCOP_DEFAULT_CONFIG.call | |
| end | |
| def shoulda_matchers | |
| insert_into_file 'Gemfile', TemplateHelper::SHOULDA_MATCHERS, after: "group :test do\n" | |
| if TemplateHelper::RESOURCES[:rspec][:required] | |
| append_to_file 'spec/rails_helper.rb', TemplateHelper::SHOULDA_MATCHERS_CONFIG | |
| else | |
| append_to_file 'test/test_helper.rb', TemplateHelper::SHOULDA_MATCHERS_CONFIG | |
| end | |
| end | |
| def simplecov | |
| insert_into_file 'Gemfile', TemplateHelper::SIMPLECOV, after: "group :test do\n" | |
| if TemplateHelper::RESOURCES[:rspec][:required] | |
| insert_into_file 'spec/rails_helper.rb', TemplateHelper::SIMPLECOV_CONFIG, before: "# This file is copied to spec/ when you run 'rails generate rspec:install'\n" | |
| else | |
| insert_into_file 'test/test_helper.rb', TemplateHelper::SIMPLECOV_CONFIG, before: "module ActiveSupport" | |
| end | |
| insert_into_file '.gitignore', TemplateHelper::SIMPLECOV_GITIGNORE, after: "/config/master.key\n" | |
| end | |
| # CUSTOM METHODS - - - - - - - - - - - - - - - - - - - | |
| def db_prepare | |
| say('Setting up database...', :green) | |
| rails_command 'db:drop db:create' | |
| rails_command 'db:migrate' | |
| say('Database has been set up!', :green) | |
| end | |
| def git_init | |
| say('Intializing git...', :green) | |
| git :init | |
| git add: "." | |
| git commit: %Q{ -m 'Initial commit' } | |
| say('Git has been initialized!', :green) | |
| end | |
| def generate_sample_page | |
| if ask("Do you wish to generate a sample page?", :blue, default: 'y', limited_to: %w[y n]) == 'y' | |
| say('Generating sample page...', :green) | |
| if TemplateHelper::RESOURCES[:rspec][:required] | |
| generate :controller, 'pages', '--no-helper --no-request-specs --no-controller-specs --no-view-specs --no-helper-specs', 'home' | |
| else | |
| generate :controller, 'pages', '--no-helper', 'home' | |
| remove_file 'test/controllers/pages_controller_test.rb' | |
| end | |
| route "root to: 'pages#home'" | |
| file 'app/views/pages/home.html.erb', TemplateHelper.generate_report, force: true | |
| say('Sample page has been generated!', :green) | |
| end | |
| end | |
| def start_server | |
| after_bundle do | |
| if ask("Do you wish to start the application server?", :blue, default: 'y', limited_to: %w[y n]) == 'y' | |
| run './bin/dev' | |
| end | |
| end | |
| end | |
| def validate_args | |
| # CHECK IF DATABASE IS POSTGRESQL | |
| database_arg = ARGV.find { |arg| arg =~ /^--database=/ } | |
| database_name = database_arg ? database_arg.split('=')[1] : 'sqlite3' | |
| TemplateHelper::RESOURCES.delete(:postgres_with_docker) unless database_name == 'postgresql' | |
| end | |
| # - - - - - - - - - - - - - - - - - - - | |
| show_template_dialog |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # place this code in ~/.rails/template_helper.rb | |
| module TemplateHelper | |
| RESOURCES = { | |
| :devise => { | |
| required: true, | |
| info: 'https://github.com/heartcombo/devise', | |
| }, | |
| :factory_bot => { | |
| required: true, | |
| info: 'https://github.com/thoughtbot/factory_bot_rails', | |
| }, | |
| :faker => { | |
| required: true, | |
| info: 'https://github.com/faker-ruby/faker', | |
| }, | |
| :ffaker => { | |
| required: true, | |
| info: 'https://github.com/ffaker/ffaker', | |
| }, | |
| :flowbite => { | |
| required: true, | |
| info: 'https://github.com/themesberg/flowbite', | |
| }, | |
| :font_awesome => { | |
| required: true, | |
| info: 'https://github.com/FortAwesome/font-awesome-sass', | |
| }, | |
| :htmlbeautifier => { | |
| required: true, | |
| info: 'https://github.com/threedaymonk/htmlbeautifier', | |
| }, | |
| :postgres_with_docker => { | |
| required: true, | |
| info: 'Setup database.yml for PostgreSQL with Docker', | |
| order: 1, | |
| }, | |
| :pry_rails => { | |
| required: true, | |
| info: 'https://github.com/pry/pry', | |
| }, | |
| :pundit => { | |
| required: true, | |
| info: 'https://github.com/varvet/pundit' | |
| }, | |
| :rspec => { | |
| required: true, | |
| info: 'https://github.com/rspec/rspec-rails', | |
| order: 2 | |
| }, | |
| :rswag => { | |
| required: true, | |
| info: 'https://github.com/rswag/rswag', | |
| }, | |
| :ruby_lsp => { | |
| required: true, | |
| info: 'https://github.com/Shopify/ruby-lsp', | |
| }, | |
| :rubocop => { | |
| required: true, | |
| info: 'https://github.com/rubocop/rubocop', | |
| }, | |
| :shoulda_matchers => { | |
| required: true, | |
| info: 'https://github.com/thoughtbot/shoulda-matchers', | |
| }, | |
| :simplecov => { | |
| required: true, | |
| info: 'https://github.com/simplecov-ruby/simplecov', | |
| }, | |
| # TODO | |
| # :active_storage => {}, | |
| # :action_text => {}, | |
| # :sidekiq => {}, | |
| # :i18n => {}, # remember devise i18n | |
| } | |
| # PROCS - - - - - - - - - - - - - - - - - - | |
| DEVISE = Proc.new { | |
| <<-RUBY.indent(0) | |
| # Use devise for authentication [https://github.com/heartcombo/devise] | |
| gem 'devise' | |
| RUBY | |
| } | |
| DEVISE_NOTIFICATIONS = Proc.new { | |
| <<-HTML.indent(0) | |
| <p class="notice"><%= notice %></p> | |
| <p class="alert"><%= alert %></p> | |
| HTML | |
| } | |
| DEVISE_RSPEC_HELPERS = Proc.new { | |
| <<-RUBY.indent(2) | |
| # include Devise helpers to use in specs | |
| config.include Devise::Test::ControllerHelpers, type: :controller | |
| config.include Devise::Test::ControllerHelpers, type: :view | |
| config.include Devise::Test::IntegrationHelpers, type: :feature | |
| config.include Devise::Test::IntegrationHelpers, type: :request | |
| RUBY | |
| } | |
| FACTORY_BOT = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'factory_bot_rails' | |
| RUBY | |
| } | |
| FACTORY_BOT_HELPER = Proc.new { | |
| <<-RUBY.indent(2) | |
| # include FactoryBot methods to use in specs | |
| config.include FactoryBot::Syntax::Methods | |
| RUBY | |
| } | |
| FAKER = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'faker' | |
| RUBY | |
| } | |
| FFAKER = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'ffaker' | |
| RUBY | |
| } | |
| FLOWBITE_CONFIG_PLUGIN = Proc.new { | |
| <<-JS.indent(4) | |
| require('flowbite/plugin'), | |
| JS | |
| } | |
| FLOWBITE_CONFIG_CONTENT = Proc.new { | |
| <<-JS.indent(4) | |
| './node_modules/flowbite/**/*.js', | |
| JS | |
| } | |
| FLOWBITE_CONFIG_DARKMODE = Proc.new { | |
| <<-JS.indent(2) | |
| darkMode: 'selector', | |
| JS | |
| } | |
| FLOWBITE_CONFIG_JS = Proc.new { | |
| <<-JS.indent(0) | |
| import 'flowbite'; | |
| import 'flowbite-datepicker'; | |
| JS | |
| } | |
| FLOWBITE_CONFIG_IMPORTMAP = Proc.new { | |
| <<-RUBY.indent(0) | |
| pin "flowbite", to: "https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.3.0/flowbite.turbo.min.js" | |
| pin "flowbite-datepicker", to: "https://cdnjs.cloudflare.com/ajax/libs/flowbite/2.3.0/datepicker.turbo.min.js" | |
| RUBY | |
| } | |
| FLOWBITE_NODE_MODULES_GITIGNORE = Proc.new { | |
| <<-TXT.indent(0) | |
| # Ignore node_modules | |
| /node_modules | |
| TXT | |
| } | |
| FLOWBITE_TAILWIND_DARKMODE = Proc.new { | |
| <<-JS.indent(0) | |
| // On page load or when changing themes, best to add inline in `head` to avoid FOUC | |
| if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { | |
| document.documentElement.classList.add('dark'); | |
| } else { | |
| document.documentElement.classList.remove('dark') | |
| } | |
| // - - - - - - - | |
| var themeToggleDarkIcon = document.getElementById('theme-toggle-dark-icon'); | |
| var themeToggleLightIcon = document.getElementById('theme-toggle-light-icon'); | |
| // Change the icons inside the button based on previous settings | |
| if (localStorage.getItem('color-theme') === 'dark' || (!('color-theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) { | |
| themeToggleLightIcon.classList.remove('hidden'); | |
| } else { | |
| themeToggleDarkIcon.classList.remove('hidden'); | |
| } | |
| var themeToggleBtn = document.getElementById('theme-toggle'); | |
| themeToggleBtn.addEventListener('click', function() { | |
| // toggle icons inside button | |
| themeToggleDarkIcon.classList.toggle('hidden'); | |
| themeToggleLightIcon.classList.toggle('hidden'); | |
| // if set via local storage previously | |
| if (localStorage.getItem('color-theme')) { | |
| if (localStorage.getItem('color-theme') === 'light') { | |
| document.documentElement.classList.add('dark'); | |
| localStorage.setItem('color-theme', 'dark'); | |
| } else { | |
| document.documentElement.classList.remove('dark'); | |
| localStorage.setItem('color-theme', 'light'); | |
| } | |
| // if NOT set via local storage previously | |
| } else { | |
| if (document.documentElement.classList.contains('dark')) { | |
| document.documentElement.classList.remove('dark'); | |
| localStorage.setItem('color-theme', 'light'); | |
| } else { | |
| document.documentElement.classList.add('dark'); | |
| localStorage.setItem('color-theme', 'dark'); | |
| } | |
| } | |
| }); | |
| JS | |
| } | |
| FONT_AWESOME = Proc.new { | |
| <<-RUBY.indent(0) | |
| # User Font-Awesome [https://github.com/FortAwesome/font-awesome-sass] | |
| gem 'font-awesome-sass' | |
| RUBY | |
| } | |
| FONT_AWESOME_CONFIG = Proc.new { | |
| <<-SCSS.indent(0) | |
| @import "font-awesome"; | |
| SCSS | |
| } | |
| HTMLBEAUTIFIER = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'htmlbeautifier' | |
| RUBY | |
| } | |
| POSTGRES_WITH_DOCKER = Proc.new { | |
| <<-YML.indent(2) | |
| username: postgres | |
| password: password | |
| host: localhost | |
| port: 5432 | |
| YML | |
| } | |
| PRY_RAILS = Proc.new { | |
| <<-RUBY.indent(2) | |
| # Use pry for debugging [https://github.com/pry/pry-rails] | |
| gem 'pry-rails' | |
| RUBY | |
| } | |
| PUNDIT_INCLUDE = Proc.new { | |
| <<-RUBY.indent(2) | |
| include Pundit::Authorization | |
| rescue_from Pundit::NotAuthorizedError, with: :not_authorized | |
| private | |
| def not_authorized | |
| flash[:alert] = 'You are not authorized to perform this action.' | |
| redirect_back(fallback_location: root_path) | |
| end | |
| RUBY | |
| } | |
| PUNDIT_REQUIRE = Proc.new { | |
| <<-RUBY.indent(0) | |
| require 'pundit/rspec' | |
| RUBY | |
| } | |
| RSPEC = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'rspec-rails' | |
| RUBY | |
| } | |
| RSPEC_URL_HELPERS = Proc.new { | |
| <<-RUBY.indent(2) | |
| # include url_helpers to use routes in specs | |
| config.include Rails.application.routes.url_helpers, type: :request | |
| RUBY | |
| } | |
| RSWAG = Proc.new { | |
| <<-RUBY.indent(0) | |
| # Use rswag for API documentation [https://github.com/rswag/rswag] | |
| gem 'rswag' | |
| RUBY | |
| } | |
| RSWAG_SPEC = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'rswag-specs' | |
| RUBY | |
| } | |
| RUBY_LSP = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem "ruby-lsp", require: false | |
| gem 'ruby-lsp-rails' | |
| # gem 'ruby-lsp-rspec', require: false | |
| RUBY | |
| } | |
| RUBOCOP = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'rubocop', require: false | |
| RUBY | |
| } | |
| RUBOCOP_DEFAULT_CONFIG = Proc.new { | |
| <<-YML.indent(0) | |
| AllCops: | |
| NewCops: enable | |
| YML | |
| } | |
| SHOULDA_MATCHERS = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'shoulda-matchers', '~> 6.0' | |
| RUBY | |
| } | |
| SHOULDA_MATCHERS_CONFIG = Proc.new { | |
| <<-RUBY.indent(2) | |
| # include ShouldaMatchers methods to use in specs | |
| Shoulda::Matchers.configure do |config| | |
| config.integrate do |with| | |
| with.test_framework :rspec | |
| with.library :rails | |
| end | |
| end | |
| RUBY | |
| } | |
| SIMPLECOV = Proc.new { | |
| <<-RUBY.indent(2) | |
| gem 'simplecov', require: false | |
| RUBY | |
| } | |
| SIMPLECOV_CONFIG = Proc.new { | |
| <<-RUBY.indent(0) | |
| require 'simplecov' | |
| SimpleCov.start do | |
| # add_filter 'spec' # removes spec folder from coverage | |
| add_filter 'spec/rails_helper.rb' # removes rails_helper.rb from coverage | |
| add_filter 'spec/swagger_helper.rb' # removes swagger_helper.rb from coverage | |
| add_group 'Models', 'app/models' | |
| add_group 'Controllers', 'app/controllers' | |
| add_group 'Policies', 'app/policies' | |
| add_group 'Specs/Requests', ['spec/requests', 'spec/controllers'] | |
| add_group 'Specs/Models', 'spec/models' | |
| add_group 'Specs/Policies', 'spec/policies' | |
| add_group 'Configs', 'config' | |
| add_group 'Helpers', 'app/helpers' | |
| add_group 'Factories', 'spec/factories' | |
| end | |
| RUBY | |
| } | |
| SIMPLECOV_GITIGNORE = Proc.new { | |
| <<-TXT.indent(0) | |
| # Ignore simplecov reports. | |
| /coverage | |
| TXT | |
| } | |
| # CUSTOM METHODS - - - - - - - - - - - - - - - - - - - | |
| def self.generate_report | |
| template_report = <<-HTML | |
| <div class=" w-full text-center grid grid-cols-1 gap-2 justify-items-center place-items-center mb-28"> | |
| <button id="theme-toggle" type="button" class="text-gray-500 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5"> | |
| <svg id="theme-toggle-dark-icon" class="hidden w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"></path></svg> | |
| <svg id="theme-toggle-light-icon" class="hidden w-5 h-5" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" fill-rule="evenodd" clip-rule="evenodd"></path></svg> | |
| </button> | |
| <div> | |
| <h1 class="font-bold text-4xl">Pages#home</h1> | |
| <p>Find me in app/views/pages/home.html.erb</p> | |
| <p class='text-gray-500'>This page was generated by template.</p> | |
| </div> | |
| <div class="relative w-1/2 overflow-x-auto sm:rounded-lg"> | |
| <table class="w-full mx-auto text-sm text-center rtl:text-right text-gray-500 dark:text-gray-400"> | |
| <thead class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"> | |
| <tr> | |
| <th scope="col" class="px-6 py-3"> | |
| Resource | |
| </th> | |
| <th scope="col" class="px-6 py-3"> | |
| Enabled? | |
| </th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| HTML | |
| RESOURCES.except(:postgres_with_docker).each do |key, attr| | |
| template_report += <<-HTML | |
| <tr class="bg-white border-b hover:bg-gray-50 dark:hover:bg-gray-600 dark:bg-gray-800 dark:border-gray-700"> | |
| <td scope="row" class="px-6 py-2 font-medium text-gray-900 whitespace-nowrap dark:text-white"> | |
| <%= link_to '#{key.to_s.humanize}', '#{attr[:info]}', class: 'hover:text-blue-600 dark:hover:text-blue-400' %> | |
| </td> | |
| <td class="px-6 py-2"> | |
| <% if #{attr[:required]} %> | |
| <p class="text-green-600 dark:text-green-400">Enabled</p> | |
| <% else %> | |
| <p class="text-red-600">Disabled</p> | |
| <% end %> | |
| </td> | |
| </tr> | |
| HTML | |
| end | |
| template_report += <<-HTML | |
| </tbody> | |
| </table> | |
| </div> | |
| <div class='text-sm'> | |
| <p><b>Ruby version:</b> <%= RUBY_VERSION %></p> | |
| <p><b>Rails version:</b> <%= Rails::VERSION::STRING %></p> | |
| <p><b>Database:</b> <%= ActiveRecord::Base.connection_db_config.configuration_hash[:adapter] %> (<%= ActiveRecord::Base.connection_db_config.configuration_hash[:database] %>)</p> | |
| <p class='text-xs text-gray-500'>To remove this page run <code class="text-red-500 font-bold">rails d controller Pages</code> on rails console, and review <code class="font-bold text-blue-500">routes.rb</code></p> | |
| </div> | |
| <div> | |
| <p class="text-gray-500 inline-flex place-items-center gap-1 text-sm">Developed by | |
| <%= link_to 'http://lucasgeron.github.io', class:'hover:text-blue-600 inline-flex place-items-center gap-2', target:'_blank' do %> | |
| <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" class="dark:hidden"> | |
| <title>github</title> | |
| <rect width="24" height="24" fill="none"/> | |
| <path d="M12,2A10,10,0,0,0,8.84,21.5c.5.08.66-.23.66-.5V19.31C6.73,19.91,6.14,18,6.14,18A2.69,2.69,0,0,0,5,16.5c-.91-.62.07-.6.07-.6a2.1,2.1,0,0,1,1.53,1,2.15,2.15,0,0,0,2.91.83,2.16,2.16,0,0,1,.63-1.34C8,16.17,5.62,15.31,5.62,11.5a3.87,3.87,0,0,1,1-2.71,3.58,3.58,0,0,1,.1-2.64s.84-.27,2.75,1a9.63,9.63,0,0,1,5,0c1.91-1.29,2.75-1,2.75-1a3.58,3.58,0,0,1,.1,2.64,3.87,3.87,0,0,1,1,2.71c0,3.82-2.34,4.66-4.57,4.91a2.39,2.39,0,0,1,.69,1.85V21c0,.27.16.59.67.5A10,10,0,0,0,12,2Z"/> | |
| </svg> | |
| <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#fff" class="hidden dark:inline"> | |
| <title>github</title> | |
| <rect width="24" height="24" fill="none"/> | |
| <path d="M12,2A10,10,0,0,0,8.84,21.5c.5.08.66-.23.66-.5V19.31C6.73,19.91,6.14,18,6.14,18A2.69,2.69,0,0,0,5,16.5c-.91-.62.07-.6.07-.6a2.1,2.1,0,0,1,1.53,1,2.15,2.15,0,0,0,2.91.83,2.16,2.16,0,0,1,.63-1.34C8,16.17,5.62,15.31,5.62,11.5a3.87,3.87,0,0,1,1-2.71,3.58,3.58,0,0,1,.1-2.64s.84-.27,2.75,1a9.63,9.63,0,0,1,5,0c1.91-1.29,2.75-1,2.75-1a3.58,3.58,0,0,1,.1,2.64,3.87,3.87,0,0,1,1,2.71c0,3.82-2.34,4.66-4.57,4.91a2.39,2.39,0,0,1,.69,1.85V21c0,.27.16.59.67.5A10,10,0,0,0,12,2Z"/> | |
| </svg> | |
| lucasgeron | |
| <% end %> | |
| </p> | |
| </div> | |
| </div> | |
| HTML | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment