Skip to content

Instantly share code, notes, and snippets.

@lucasgeron
Last active October 22, 2025 19:49
Show Gist options
  • Save lucasgeron/304c62c2330b332f377ef05799625e0f to your computer and use it in GitHub Desktop.
Save lucasgeron/304c62c2330b332f377ef05799625e0f to your computer and use it in GitHub Desktop.
Rails Starter Pack
# place this code in ~/.railsrc
--css=tailwind
--template=~/.rails/template.rb
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.
# 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
# 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