super 0.0.4 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +13 -0
  3. data/CONTRIBUTING.md +56 -0
  4. data/README.md +60 -85
  5. data/STABILITY.md +50 -0
  6. data/app/assets/javascripts/super/application.js +1169 -359
  7. data/app/assets/stylesheets/super/application.css +86648 -30707
  8. data/app/controllers/super/application_controller.rb +44 -71
  9. data/app/views/layouts/super/application.html.erb +26 -6
  10. data/app/views/super/application/{_resources_header.html.erb → _collection_header.html.erb} +5 -6
  11. data/app/views/super/application/_display_rich_text.html.erb +1 -0
  12. data/app/views/super/application/_filter.html.erb +14 -0
  13. data/app/views/super/application/_filter_type_select.html.erb +31 -0
  14. data/app/views/super/application/_filter_type_text.html.erb +22 -0
  15. data/app/views/super/application/_filter_type_timestamp.html.erb +35 -0
  16. data/app/views/super/application/_flash.html.erb +13 -13
  17. data/app/views/super/application/_form_field__destroy.html.erb +6 -2
  18. data/app/views/super/application/_form_field_checkbox.html.erb +15 -0
  19. data/app/views/super/application/_form_field_generic.html.erb +19 -0
  20. data/app/views/super/application/_form_field_rich_text_area.html.erb +13 -0
  21. data/app/views/super/application/_form_field_select.html.erb +11 -5
  22. data/app/views/super/application/_form_field_text.html.erb +13 -5
  23. data/app/views/super/application/_form_has_many.html.erb +3 -3
  24. data/app/views/super/application/_form_inline_errors.html.erb +1 -1
  25. data/app/views/super/application/{_resource_header.html.erb → _member_header.html.erb} +6 -6
  26. data/app/views/super/application/_super_layout.html.erb +12 -17
  27. data/app/views/super/application/_super_pagination.html.erb +16 -0
  28. data/app/views/super/application/_super_panel.html.erb +3 -7
  29. data/app/views/super/application/_super_schema_display_actions.html.erb +5 -0
  30. data/app/views/super/application/_super_schema_display_index.html.erb +24 -0
  31. data/app/views/super/application/_super_schema_display_show.html.erb +8 -0
  32. data/app/views/super/application/{_form.html.erb → _super_schema_form.html.erb} +2 -4
  33. data/app/views/super/application/edit.html.erb +1 -1
  34. data/app/views/super/application/index.html.erb +1 -1
  35. data/app/views/super/application/new.html.erb +1 -1
  36. data/app/views/super/application/show.html.erb +1 -1
  37. data/app/views/super/feather/{_chevron_down.svg → _chevron_down.html} +0 -0
  38. data/config/locales/en.yml +5 -0
  39. data/docs/README.md +8 -0
  40. data/docs/action_text.md +48 -0
  41. data/docs/cheat.md +41 -0
  42. data/docs/faq.md +44 -0
  43. data/docs/installation.md +21 -0
  44. data/docs/quick_start.md +30 -0
  45. data/docs/webpacker.md +25 -0
  46. data/docs/yard_customizations.rb +41 -0
  47. data/frontend/super-frontend/build.js +1 -1
  48. data/frontend/super-frontend/dist/application.css +86648 -30707
  49. data/frontend/super-frontend/dist/application.js +1169 -359
  50. data/frontend/super-frontend/package.json +2 -3
  51. data/frontend/super-frontend/src/javascripts/super/{application.ts → application.js} +5 -8
  52. data/frontend/super-frontend/src/javascripts/super/apply_template_controller.js +17 -0
  53. data/frontend/super-frontend/src/javascripts/super/{toggle_pending_destruction_controller.ts → toggle_pending_destruction_controller.js} +2 -2
  54. data/frontend/super-frontend/tailwind.config.js +7 -1
  55. data/frontend/super-frontend/yarn.lock +1368 -1391
  56. data/lib/generators/super/action_text/USAGE +23 -0
  57. data/lib/generators/super/action_text/action_text_generator.rb +30 -0
  58. data/lib/generators/super/action_text/templates/pack_super_action_text.css +23 -0
  59. data/lib/generators/super/action_text/templates/pack_super_action_text.js +4 -0
  60. data/lib/generators/super/install/install_generator.rb +16 -0
  61. data/lib/generators/super/resource/templates/resources_controller.rb.tt +1 -31
  62. data/lib/generators/super/webpacker/USAGE +5 -4
  63. data/lib/generators/super/webpacker/webpacker_generator.rb +10 -1
  64. data/lib/super.rb +22 -5
  65. data/lib/super/action_inquirer.rb +2 -2
  66. data/lib/super/assets.rb +112 -38
  67. data/lib/super/client_error.rb +43 -0
  68. data/lib/super/compatibility.rb +25 -0
  69. data/lib/super/configuration.rb +21 -69
  70. data/lib/super/controls.rb +9 -257
  71. data/lib/super/controls/optional.rb +79 -0
  72. data/lib/super/controls/required.rb +13 -0
  73. data/lib/super/controls/steps.rb +114 -0
  74. data/lib/super/display.rb +66 -3
  75. data/lib/super/display/guesser.rb +34 -0
  76. data/lib/super/display/schema_types.rb +61 -25
  77. data/lib/super/engine.rb +7 -1
  78. data/lib/super/error.rb +8 -9
  79. data/lib/super/filter.rb +12 -0
  80. data/lib/super/filter/form_object.rb +97 -0
  81. data/lib/super/filter/guesser.rb +30 -0
  82. data/lib/super/filter/operator.rb +103 -0
  83. data/lib/super/filter/plugin.rb +47 -0
  84. data/lib/super/filter/schema_types.rb +112 -0
  85. data/lib/super/form.rb +35 -0
  86. data/lib/super/form/builder.rb +48 -0
  87. data/lib/super/form/guesser.rb +27 -0
  88. data/lib/super/form/schema_types.rb +29 -22
  89. data/lib/super/form/strong_params.rb +29 -0
  90. data/lib/super/layout.rb +28 -0
  91. data/lib/super/link.rb +55 -32
  92. data/lib/super/pagination.rb +55 -0
  93. data/lib/super/panel.rb +13 -0
  94. data/lib/super/partial.rb +12 -0
  95. data/lib/super/partial/resolving.rb +24 -0
  96. data/lib/super/plugin.rb +34 -63
  97. data/lib/super/schema.rb +12 -22
  98. data/lib/super/schema/common.rb +25 -0
  99. data/lib/super/schema/guesser.rb +77 -0
  100. data/lib/super/version.rb +1 -1
  101. data/lib/super/view_helper.rb +43 -0
  102. metadata +138 -41
  103. data/app/helpers/super/application_helper.rb +0 -32
  104. data/app/views/super/application/_index.html.erb +0 -45
  105. data/app/views/super/application/_show.html.erb +0 -10
  106. data/frontend/super-frontend/src/javascripts/super/apply_template_controller.ts +0 -21
  107. data/frontend/super-frontend/src/javascripts/super/rails__ujs.d.ts +0 -1
  108. data/frontend/super-frontend/tsconfig.json +0 -13
  109. data/lib/super/action.rb +0 -22
  110. data/lib/super/action/step.rb +0 -36
  111. data/lib/super/test_support/copy_app_templates/controllers/favorite_things_controller.rb +0 -50
  112. data/lib/super/test_support/copy_app_templates/controllers/members_controller.rb +0 -74
  113. data/lib/super/test_support/copy_app_templates/controllers/ships_controller.rb +0 -47
  114. data/lib/super/test_support/copy_app_templates/migrations/20190216224956_create_members.rb +0 -11
  115. data/lib/super/test_support/copy_app_templates/migrations/20190803143320_create_ships.rb +0 -11
  116. data/lib/super/test_support/copy_app_templates/migrations/20190806014121_add_ship_to_members.rb +0 -5
  117. data/lib/super/test_support/copy_app_templates/migrations/20191126050453_create_favorite_things.rb +0 -10
  118. data/lib/super/test_support/copy_app_templates/models/favorite_thing.rb +0 -7
  119. data/lib/super/test_support/copy_app_templates/models/member.rb +0 -23
  120. data/lib/super/test_support/copy_app_templates/models/ship.rb +0 -3
  121. data/lib/super/test_support/copy_app_templates/routes.rb +0 -11
  122. data/lib/super/test_support/copy_app_templates/seeds.rb +0 -2
  123. data/lib/super/test_support/copy_app_templates/views/members/_favorite_things.html.erb +0 -11
  124. data/lib/super/test_support/fixtures/favorite_things.yml +0 -9
  125. data/lib/super/test_support/fixtures/members.yml +0 -336
  126. data/lib/super/test_support/fixtures/ships.yml +0 -10
  127. data/lib/super/test_support/generate_copy_app.rb +0 -42
  128. data/lib/super/test_support/generate_dummy.rb +0 -93
  129. data/lib/super/test_support/starfleet_seeder.rb +0 -50
  130. data/lib/tasks/super_tasks.rake +0 -4
@@ -1,5 +1,13 @@
1
- <div class="super-field-group">
2
- <%= form.label(column, class: "block") %>
3
- <%= form.text_field(column, class: "super-input w-full mt-1") %>
4
- <%= render "form_inline_errors", form: form, column: column %>
5
- </div>
1
+ <% if !local_assigns[:ungrouped] %>
2
+ <div class="super-field-group">
3
+ <% end %>
4
+ <% if !local_assigns[:hide_label] %>
5
+ <%= form.label(column, class: "block") %>
6
+ <% end %>
7
+ <div class="<%= Super::ViewHelper.classes(["mt-1", !local_assigns[:hide_label]]) %>">
8
+ <%= form.text_field(column, class: "super-input w-full") %>
9
+ <%= render "form_inline_errors", form: form, column: column %>
10
+ </div>
11
+ <% if !local_assigns[:ungrouped] %>
12
+ </div>
13
+ <% end %>
@@ -10,12 +10,12 @@
10
10
  child_index: "TEMPLATEINDEX"
11
11
  ) do |ff|
12
12
  %>
13
- <template data-target="apply-template.template">
13
+ <template data-apply-template-target="template">
14
14
  <%= render "form_fieldset", form_fieldset: form_has_many, form: ff %>
15
15
  </template>
16
16
  <% end %>
17
17
 
18
- <button data-action="apply-template#call" class="super-button super-button--fill-blue mt-2">
18
+ <a href="#" data-action="apply-template#call" class="super-button super-button--fill-blue mt-2 inline-block">
19
19
  Add <%= form_has_many.label %>
20
- </button>
20
+ </a>
21
21
  </div>
@@ -1,5 +1,5 @@
1
1
  <% if form.object %>
2
- <% form.object.errors.full_messages_for(column).each do |error_message| %>
2
+ <% Super::ViewHelper.errors_accounting_for_reflections(form.object, column).each do |error_message| %>
3
3
  <p class="text-red-400 text-xs italic pt-1"><%= error_message %></p>
4
4
  <% end %>
5
5
  <% else %>
@@ -3,13 +3,13 @@
3
3
  <%= controls.title %>
4
4
  </h1>
5
5
  <div>
6
- <% controls.resource_actions(@resource, params: params, action: action_inquirer).each do |link| %>
7
- <%= link_to(
8
- link.text,
9
- link.href,
10
- link.options.reverse_merge(
6
+ <% controls.member_actions(action: action_inquirer).each do |link| %>
7
+ <%= link.to_s(
8
+ default_options: {
11
9
  class: "super-button super-button--border-blue super-button-sm inline-block ml-2"
12
- )
10
+ },
11
+ record: @record,
12
+ params: params
13
13
  ) %>
14
14
  <% end %>
15
15
  </div>
@@ -1,34 +1,29 @@
1
- <%
2
- super_layout_headers = super_resolve_list_for_rendering(super_layout.headers)
3
- super_layout_asides = super_resolve_list_for_rendering(super_layout.asides)
4
- super_layout_mains = super_resolve_list_for_rendering(super_layout.mains)
5
- super_layout_footers = super_resolve_list_for_rendering(super_layout.footers)
6
- %>
1
+ <% super_layout.resolve(self) %>
7
2
 
8
- <% super_layout_headers.each do |partial| %>
9
- <%= super_render_partialish(partial) %>
3
+ <% super_layout.resolved_headers.each do |partial| %>
4
+ <%= Super::Partial.render(partial, template: self) %>
10
5
  <% end %>
11
6
 
12
- <% if super_layout_asides.empty? %>
13
- <% super_layout_mains.each do |partial| %>
14
- <%= super_render_partialish(partial) %>
7
+ <% if super_layout.resolved_asides.empty? %>
8
+ <% super_layout.resolved_mains.each do |partial| %>
9
+ <%= Super::Partial.render(partial, template: self) %>
15
10
  <% end %>
16
11
  <% else %>
17
12
  <div class="clearfix -mx-2">
18
13
  <div class="md:float-left md:w-9/12 px-2">
19
- <% super_layout_mains.each do |partial| %>
20
- <%= super_render_partialish(partial) %>
14
+ <% super_layout.resolved_mains.each do |partial| %>
15
+ <%= Super::Partial.render(partial, template: self) %>
21
16
  <% end %>
22
17
  </div>
23
18
 
24
19
  <div class="md:float-right md:w-3/12 px-2">
25
- <% super_layout_asides.each do |partial| %>
26
- <%= super_render_partialish(partial) %>
20
+ <% super_layout.resolved_asides.each do |partial| %>
21
+ <%= Super::Partial.render(partial, template: self) %>
27
22
  <% end %>
28
23
  </div>
29
24
  </div>
30
25
  <% end %>
31
26
 
32
- <% super_layout_footers.each do |partial| %>
33
- <%= super_render_partialish(partial) %>
27
+ <% super_layout.resolved_footers.each do |partial| %>
28
+ <%= Super::Partial.render(partial, template: self) %>
34
29
  <% end %>
@@ -0,0 +1,16 @@
1
+ <% if @pagination.necessary? %>
2
+ <div class="flex justify-end mr-2">
3
+ <div class="mt-4">
4
+ <% @pagination.each do |page_query_params, is_current_page, display| %>
5
+ <%= link_to(
6
+ display,
7
+ polymorphic_path(
8
+ Super.configuration.path_parts(controls.model),
9
+ page_query_params
10
+ ),
11
+ class: "inline-block ml-2 text-lg #{is_current_page ? " text-gray-900" : ""}"
12
+ ) %>
13
+ <% end %>
14
+ </div>
15
+ </div>
16
+ <% end %>
@@ -1,11 +1,7 @@
1
- <%
2
- super_panel_parts = super_resolve_list_for_rendering(super_panel.parts, Proc.new)
3
- %>
4
-
5
- <% if super_panel_parts.any? %>
1
+ <% if super_panel.resolve(self, block_given? ? Proc.new { yield } : nil).resolved_parts.any? %>
6
2
  <div class="border rounded shadow border-gray-400 bg-white px-5 pt-4 pb-8 mt-6">
7
- <% super_panel_parts.each do |partial| %>
8
- <%= super_render_partialish(partial) %>
3
+ <% super_panel.resolved_parts.each do |partial| %>
4
+ <%= Super::Partial.render(partial, template: self) %>
9
5
  <% end %>
10
6
  </div>
11
7
  <% end %>
@@ -0,0 +1,5 @@
1
+ <div>
2
+ <% controls.member_actions(action: action_inquirer).each do |link| %>
3
+ <span class="pr-2 last:pr-0"><%= link.to_s(record: record, params: params) %></span>
4
+ <% end %>
5
+ </div>
@@ -0,0 +1,24 @@
1
+ <div class="mt-4 overflow-x-auto lg:overflow-x-visible">
2
+ <table class="w-full border-separate relative" cellspacing="0" cellpadding="0">
3
+ <thead class="">
4
+ <tr class="">
5
+ <% super_schema_display_index.each_attribute_name do |attribute_name| %>
6
+ <th class="p-2 first:pl-6 border-b border-b-2 border-gray-400 text-gray-600 text-left text-sm font-normal bg-white sticky top-0 z-10">
7
+ <%= controls.model.human_attribute_name(attribute_name) %>
8
+ </th>
9
+ <% end %>
10
+ </tr>
11
+ </thead>
12
+ <tbody class="">
13
+ <% @records.each.with_index do |record, row_index| %>
14
+ <tr id="record-pk-<%= record.id %>" class="group">
15
+ <% super_schema_display_index.each_attribute_name do |attribute_name| %>
16
+ <td class="py-1 px-2 first:pl-5 border-transparent border-t border-b group-hover:bg-blue-200 first:border-l first:rounded-l-lg last:border-r last:rounded-r-lg bg-white <%= Super::ViewHelper.classes(["bg-gray-100", row_index.odd?]) %>">
17
+ <%= super_schema_display_index.render_field(template: self, record: record, column: attribute_name) %>
18
+ </td>
19
+ <% end %>
20
+ </tr>
21
+ <% end %>
22
+ </tbody>
23
+ </table>
24
+ </div>
@@ -0,0 +1,8 @@
1
+ <table class="max-w-full mt-4">
2
+ <% super_schema_display_show.each_attribute_name do |attribute_name| %>
3
+ <tr>
4
+ <th class="py-1 align-baseline text-right px-4"><%= controls.model.human_attribute_name(attribute_name) %></th>
5
+ <td class="py-1 align-baseline"><%= super_schema_display_show.render_field(template: self, record: @record, column: attribute_name) %></td>
6
+ </tr>
7
+ <% end %>
8
+ </table>
@@ -1,8 +1,6 @@
1
- <% schema = controls.form_schema(action: action_inquirer) %>
2
-
3
- <%= form_for(Super.configuration.path_parts(@resource)) do |f| %>
1
+ <%= form_for(Super.configuration.path_parts(@record), builder: Super::Form::Builder) do |f| %>
4
2
  <div class="max-w-3xl">
5
- <% schema.fields.each do |field, type| %>
3
+ <% super_schema_form.each_attribute do |field, type| %>
6
4
  <%= render(
7
5
  type,
8
6
  form: f,
@@ -1 +1 @@
1
- <%= render(@super_action.page) %>
1
+ <%= render(@view) %>
@@ -1 +1 @@
1
- <%= render(@super_action.page) %>
1
+ <%= render(@view) %>
@@ -1 +1 @@
1
- <%= render(@super_action.page) %>
1
+ <%= render(@view) %>
@@ -1 +1 @@
1
- <%= render(@super_action.page) %>
1
+ <%= render(@view) %>
@@ -0,0 +1,5 @@
1
+ ---
2
+ en:
3
+ super:
4
+ layout:
5
+ powered_by: "%{env} environment. Powered by Super %{version}."
@@ -0,0 +1,8 @@
1
+ # Docs
2
+
3
+ * [Quick Start](./quick_start.md)
4
+ * [Installation](./installation.md)
5
+ * [Webpacker](./webpacker.md)
6
+ * [ActionText](./action_text.md)
7
+ * [Cheat sheet](./cheat.md)
8
+ * [FAQ](./faq.md)
@@ -0,0 +1,48 @@
1
+ <!--
2
+ # @title ActionText
3
+ -->
4
+
5
+ # Using ActionText with Super
6
+
7
+ Super has some basic support for editing and viewing ActionText. Since
8
+ ActionText only works with Webpacker, you'll have to set up Webpacker for your
9
+ application. You can optionally set up [Super to use Webpacker](./webpacker.md).
10
+
11
+ Once you've set that up, ActionText should be relatively simple. The following
12
+ command will copy over the necessary JS and CSS into your application:
13
+
14
+ ```bash
15
+ bundle exec rails generate super:action_text
16
+ ```
17
+
18
+ As an example, let's say we're making admin pages for a blog. We'll keep this
19
+ example simple and work with a `Post` model with just a `#title` column and
20
+ a rich text `#content` field.
21
+
22
+ ```ruby
23
+ class Post < ApplicationRecord
24
+ has_rich_text :content
25
+ end
26
+ ```
27
+
28
+ We'll need to configure the `#form_schema` and `#display_schema` methods.
29
+
30
+ ```ruby
31
+ class Controls < Super::Controls
32
+ # ...
33
+
34
+ def form_schema(action:)
35
+ Super::Form.new do |fields, type|
36
+ fields[:title] = type.text
37
+ fields[:content] = type.rich_text_area
38
+ end
39
+ end
40
+
41
+ def display_schema(action:)
42
+ Super::Display.new(action: action) do |fields, type|
43
+ fields[:title] = type.text
44
+ fields[:content] = type.rich_text
45
+ end
46
+ end
47
+ end
48
+ ```
@@ -0,0 +1,41 @@
1
+ <!--
2
+ # @title Cheat sheet
3
+ -->
4
+
5
+ # Cheat sheet
6
+
7
+ ## Controls
8
+
9
+ You can configure most of your admin page's behavior by editing Controls.
10
+ They only work with ActiveRecord models
11
+
12
+ Controls have several required and optional methods. Note that all arguments
13
+ must be defined, even if they are ignored.
14
+
15
+
16
+ ### Required methods
17
+
18
+ The following are the methods that must be defined in the `Controls` class.
19
+
20
+ * **`#model()`**
21
+ The model that your controller is working with
22
+
23
+
24
+ ### Optional methods
25
+
26
+ The following are the methods that can be defined in the `Controls` class.
27
+
28
+ * **`#title()`**
29
+ The title to show on the main panel
30
+ * **`#collection_actions(action:)`**
31
+ The list of collection-level links
32
+ * **`#member_actions(action:)`**
33
+ The list of member-level links and `#show` pages
34
+ * **`#scope(action:)`**
35
+ The starting point of the query/relation. Defaults to `#all`
36
+ * **`#display_schema(action:)`**
37
+ The display schema definition for the `#index` and `#show` pages
38
+ * **`#form_schema(action:)`**
39
+ The form schema definition for the `#new` and `#edit` pages
40
+ * **`#permitted_params(params, action:)`**
41
+ The strong parameters definition
@@ -0,0 +1,44 @@
1
+ <!--
2
+ # @title FAQ
3
+ -->
4
+
5
+ # FAQ
6
+
7
+ ## How do I handle authorization?
8
+
9
+ Assuming you already have authentication set up, it should only require defining
10
+ a `Controls#initialize` that accepts an authenticated user. From there, you can
11
+ customize `Controls#scope` to have the required behavior.
12
+
13
+ ```ruby
14
+ class PostsController < AdminController
15
+ def new_controls
16
+ Controls.new(current_user)
17
+ end
18
+
19
+ class Controls < Super::Controls
20
+ def initialize(current_user)
21
+ @current_user = current_user
22
+ end
23
+
24
+ def model
25
+ Post
26
+ end
27
+
28
+ def scope(action:)
29
+ # Example: admins can read and write; others can only read
30
+ if @current_user.admin?
31
+ return model.all
32
+ end
33
+
34
+ if action.read?
35
+ return model.all
36
+ end
37
+
38
+ raise Super::ClientError::Forbidden
39
+ end
40
+
41
+ # ...
42
+ end
43
+ end
44
+ ```
@@ -0,0 +1,21 @@
1
+ <!--
2
+ # @title Installation
3
+ -->
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem "super"
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ ```bash
16
+ bundle install
17
+ bundle exec rails generate super:install # check out the `--help` option!
18
+ ```
19
+
20
+ If you prefer, you can configure Super to use Webpacker instead of Sprockets.
21
+ Check out the [Webpacker guide](./webpacker.md).
@@ -0,0 +1,30 @@
1
+ <!--
2
+ # @title Quick start
3
+ -->
4
+
5
+ # Quick start
6
+
7
+ See [Installation](./installation.md) for the installation guide.
8
+
9
+
10
+ ## Usage
11
+
12
+ ### Creating new admin pages
13
+
14
+ ```bash
15
+ bundle exec rails generate super:resource Thing # check out the `--help` option!
16
+ ```
17
+
18
+ The example above will create a controller called `Admin::ThingsController`. It
19
+ generates a `Controls` class inside the controller as well; it's where most
20
+ configuration lives. See the documentation on [Controls](./controls.md) for more
21
+ info.
22
+
23
+ You'll have to manually update your routes file. It'll probably look something
24
+ like the following:
25
+
26
+ ```ruby
27
+ namespace :admin do
28
+ resources :things
29
+ end
30
+ ```
@@ -0,0 +1,25 @@
1
+ <!--
2
+ # @title Webpacker
3
+ -->
4
+
5
+ # Installation with Webpacker
6
+
7
+ Super supports using Webpacker instead of Sprockets. You'll first need to set up
8
+ Webpacker to handle ERB templates.
9
+
10
+ After installing Super (see the [Installation guide](./installation.md)), run
11
+ one the following:
12
+
13
+ ## Webpacker 4 and 5
14
+
15
+ ```bash
16
+ bundle exec rails webpacker:install:erb # if you haven't already
17
+ bundle exec rails generate super:webpacker
18
+ ```
19
+
20
+ ## Webpacker 6
21
+
22
+ ```bash
23
+ yarn add rails-erb-loader # if you haven't already
24
+ bundle exec rails generate super:webpacker
25
+ ```