Skip to content

Commit 9233e36

Browse files
Introduce suspenders:views generator (#1154)
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
1 parent 8fb94d2 commit 9233e36

File tree

5 files changed

+146
-0
lines changed

5 files changed

+146
-0
lines changed

NEWS.md

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Unreleased
99
* Introduce `suspenders:jobs` generator
1010
* Introduce `suspenders:lint` generator
1111
* Introduce `suspenders:rake` generator
12+
* Introduce `suspenders:views` generator
1213

1314
20230113.0 (January, 13, 2023)
1415

README.md

+8
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,14 @@ Configures the default Rake task to audit and lint the codebase with
126126
[bundler-audit]: https://github.com/rubysec/bundler-audit
127127
[standard]: https://github.com/standardrb/standard
128128

129+
### Views
130+
131+
Configures flash messages, page titles via the [title][] gem, and sets the
132+
document [lang][].
133+
134+
[title]: https://github.com/calebhearth/title
135+
[lang]: https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang
136+
129137
## Contributing
130138

131139
See the [CONTRIBUTING] document.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
module Suspenders
2+
module Generators
3+
class ViewsGenerator < Rails::Generators::Base
4+
include Suspenders::Generators::APIAppUnsupported
5+
6+
desc "Configures flash messages, page titles and the document lang."
7+
source_root File.expand_path("../../templates/views", __FILE__)
8+
9+
def install_gems
10+
gem "title"
11+
12+
Bundler.with_unbundled_env { run "bundle install" }
13+
end
14+
15+
def create_views
16+
copy_file "flashes.html.erb", "app/views/application/_flashes.html.erb"
17+
end
18+
19+
def update_application_layout
20+
insert_into_file "app/views/layouts/application.html.erb", " <%= render \"flashes\" -%>\n", after: "<body>\n"
21+
gsub_file "app/views/layouts/application.html.erb", /<html>/, "<html lang=\"<%= I18n.locale %>\">"
22+
gsub_file "app/views/layouts/application.html.erb", /<title>.*<\/title>/, "<title><%= title %></title>"
23+
end
24+
end
25+
end
26+
end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<% if flash.any? %>
2+
<div class="flashes">
3+
<% flash.each do |type, message| -%>
4+
<div class="flash-<%= type %>"><%= message %></div>
5+
<% end -%>
6+
</div>
7+
<% end %>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
require "test_helper"
2+
require "generators/suspenders/views_generator"
3+
4+
module Suspenders
5+
module Generators
6+
class ViewsGeneratorTest < Rails::Generators::TestCase
7+
include Suspenders::TestHelpers
8+
9+
tests Suspenders::Generators::ViewsGenerator
10+
destination Rails.root
11+
setup :prepare_destination
12+
teardown :restore_destination
13+
14+
test "raises if API only application" do
15+
within_api_only_app do
16+
assert_raises Suspenders::Generators::APIAppUnsupported::Error do
17+
run_generator
18+
end
19+
20+
assert_file app_root("Gemfile") do |file|
21+
assert_no_match "title", file
22+
end
23+
end
24+
end
25+
26+
test "creates flash partial" do
27+
expected = <<~ERB
28+
<% if flash.any? %>
29+
<div class="flashes">
30+
<% flash.each do |type, message| -%>
31+
<div class="flash-<%= type %>"><%= message %></div>
32+
<% end -%>
33+
</div>
34+
<% end %>
35+
ERB
36+
37+
run_generator
38+
39+
assert_file app_root("app/views/application/_flashes.html.erb") do |file|
40+
assert_equal expected, file
41+
end
42+
end
43+
44+
test "includes flash partial in layout" do
45+
run_generator
46+
47+
assert_file app_root("app/views/layouts/application.html.erb") do |file|
48+
assert_match(/<body>\s{5}<%= render "flashes" -%>$/, file)
49+
end
50+
end
51+
52+
test "sets the language" do
53+
run_generator
54+
55+
assert_file app_root("app/views/layouts/application.html.erb") do |file|
56+
assert_match(/<html lang="<%= I18n.locale %>">/, file)
57+
end
58+
end
59+
60+
test "adds gems to Gemfile" do
61+
expected_output = <<~RUBY
62+
gem "title"
63+
RUBY
64+
65+
run_generator
66+
67+
assert_file app_root("Gemfile") do |file|
68+
assert_match(expected_output, file)
69+
end
70+
end
71+
72+
test "installs gems with Bundler" do
73+
output = run_generator
74+
75+
assert_match(/bundle install/, output)
76+
end
77+
78+
test "sets title" do
79+
run_generator
80+
81+
assert_file app_root("app/views/layouts/application.html.erb") do |file|
82+
assert_match(/<title><%= title %><\/title>/, file)
83+
end
84+
end
85+
86+
test "has a custom description" do
87+
assert_no_match(/Description:\n/, generator_class.desc)
88+
end
89+
90+
private
91+
92+
def prepare_destination
93+
touch "Gemfile"
94+
backup_file "app/views/layouts/application.html.erb"
95+
end
96+
97+
def restore_destination
98+
remove_file_if_exists "Gemfile"
99+
remove_file_if_exists "app/views/application/_flashes.html.erb"
100+
restore_file "app/views/layouts/application.html.erb"
101+
end
102+
end
103+
end
104+
end

0 commit comments

Comments
 (0)