Skip to content

Commit

Permalink
Introduce suspenders:views generator (#1154)
Browse files Browse the repository at this point in the history
Configures flash messages, page titles via the [title][] gem, and sets
the document [lang][].

[title]: https://github.com/calebhearth/title
[lang]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang

It should be noted that running `rails gscaffold` generates [views][]
that contain the flash. Although we could have [overridden][] this
generator, that would risk drift between our overridden generator and
the one in Rails core.

Additionally, we decided to remove the `FlashesHelper` introduced in
[6c562b9][] since that is not a pattern
we currently use.

[views]: https://github.com/rails/rails/blob/main/railties/lib/rails/generators/erb/scaffold/templates/index.html.erb.tt
[overridden]: https://guides.rubyonrails.org/generators.html#overriding-rails-generator-templates
[6c562b9]: 6c562b9
  • Loading branch information
stevepolitodesign authored Jan 10, 2024
1 parent 8628dcb commit 51dcd4b
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 0 deletions.
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Unreleased
* Introduce `suspenders:jobs` generator
* Introduce `suspenders:lint` generator
* Introduce `suspenders:rake` generator
* Introduce `suspenders:views` generator

20230113.0 (January, 13, 2023)

Expand Down
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,14 @@ Configures the default Rake task to audit and lint the codebase with
[bundler-audit]: https://github.com/rubysec/bundler-audit
[standard]: https://github.com/standardrb/standard

### Views

Configures flash messages, page titles via the [title][] gem, and sets the
document [lang][].

[title]: https://github.com/calebhearth/title
[lang]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang

## Contributing

See the [CONTRIBUTING] document.
Expand Down
26 changes: 26 additions & 0 deletions lib/generators/suspenders/views_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
module Suspenders
module Generators
class ViewsGenerator < Rails::Generators::Base
include Suspenders::Generators::APIAppUnsupported

desc "Configures flash messages, page titles and the document lang."
source_root File.expand_path("../../templates/views", __FILE__)

def install_gems
gem "title"

Bundler.with_unbundled_env { run "bundle install" }
end

def create_views
copy_file "flashes.html.erb", "app/views/application/_flashes.html.erb"
end

def update_application_layout
insert_into_file "app/views/layouts/application.html.erb", " <%= render \"flashes\" -%>\n", after: "<body>\n"
gsub_file "app/views/layouts/application.html.erb", /<html>/, "<html lang=\"<%= I18n.locale %>\">"
gsub_file "app/views/layouts/application.html.erb", /<title>.*<\/title>/, "<title><%= title %></title>"
end
end
end
end
7 changes: 7 additions & 0 deletions lib/generators/templates/views/flashes.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<% if flash.any? %>
<div class="flashes">
<% flash.each do |type, message| -%>
<div class="flash-<%= type %>"><%= message %></div>
<% end -%>
</div>
<% end %>
104 changes: 104 additions & 0 deletions test/generators/suspenders/views_generator_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
require "test_helper"
require "generators/suspenders/views_generator"

module Suspenders
module Generators
class ViewsGeneratorTest < Rails::Generators::TestCase
include Suspenders::TestHelpers

tests Suspenders::Generators::ViewsGenerator
destination Rails.root
setup :prepare_destination
teardown :restore_destination

test "raises if API only application" do
within_api_only_app do
assert_raises Suspenders::Generators::APIAppUnsupported::Error do
run_generator
end

assert_file app_root("Gemfile") do |file|
assert_no_match "title", file
end
end
end

test "creates flash partial" do
expected = <<~ERB
<% if flash.any? %>
<div class="flashes">
<% flash.each do |type, message| -%>
<div class="flash-<%= type %>"><%= message %></div>
<% end -%>
</div>
<% end %>
ERB

run_generator

assert_file app_root("app/views/application/_flashes.html.erb") do |file|
assert_equal expected, file
end
end

test "includes flash partial in layout" do
run_generator

assert_file app_root("app/views/layouts/application.html.erb") do |file|
assert_match(/<body>\s{5}<%= render "flashes" -%>$/, file)
end
end

test "sets the language" do
run_generator

assert_file app_root("app/views/layouts/application.html.erb") do |file|
assert_match(/<html lang="<%= I18n.locale %>">/, file)
end
end

test "adds gems to Gemfile" do
expected_output = <<~RUBY
gem "title"
RUBY

run_generator

assert_file app_root("Gemfile") do |file|
assert_match(expected_output, file)
end
end

test "installs gems with Bundler" do
output = run_generator

assert_match(/bundle install/, output)
end

test "sets title" do
run_generator

assert_file app_root("app/views/layouts/application.html.erb") do |file|
assert_match(/<title><%= title %><\/title>/, file)
end
end

test "has a custom description" do
assert_no_match(/Description:\n/, generator_class.desc)
end

private

def prepare_destination
touch "Gemfile"
backup_file "app/views/layouts/application.html.erb"
end

def restore_destination
remove_file_if_exists "Gemfile"
remove_file_if_exists "app/views/application/_flashes.html.erb"
restore_file "app/views/layouts/application.html.erb"
end
end
end
end

0 comments on commit 51dcd4b

Please sign in to comment.