Class: TurboOverlay::Generators::InstallGenerator

Inherits:
Rails::Generators::Base
  • Object
show all
Defined in:
lib/generators/turbo_overlay/install_generator.rb

Overview

Wires the host app to use turbo_overlay. Detects the host’s JS and CSS toolchain, then either injects the required one-liners or prints the snippets the user needs to paste. Also copies the chosen chrome partials into ‘app/views/turbo_overlay/` so the app owns its modal/drawer appearance from day one (and so Tailwind / similar scanners can see the markup).

bin/rails g turbo_overlay:install
bin/rails g turbo_overlay:install --theme tailwind

Re-running is idempotent: existing files and already-injected wiring are detected and skipped. Pass ‘–force` to overwrite files when upgrading.

Constant Summary collapse

GEM_ROOT =
File.expand_path("../../..", __dir__)
THEMES =
%w[plain tailwind bootstrap5 bootstrap3].freeze
FALLBACK_PARTIALS =

Chrome + loading partials the gem ships fallbacks for under ‘app/views/turbo_overlay/`. For the `plain` theme the install generator copies those fallbacks directly so we don’t have two canonical copies of the same markup. Themed (‘tailwind`, `bootstrap5`, `bootstrap3`) installs source from the per-theme template directory.

‘_loading.html.erb` is a single shared partial — the same body renders inside modal, drawer, popover, and hint chromes, with chrome-context CSS handling the size differences. Apps that want chrome-specific loading markup can add `_loading.html+<variant>.erb` and the existing lookup will prefer it over the shared file.

%w[
  _modal.html.erb
  _drawer.html.erb
  _popover.html.erb
  _hint.html.erb
  _loading.html.erb
].freeze
THEME_ONLY_PARTIALS =

Confirm partials have no gem-side fallback — they’re optional (only used when ‘register(application, confirm: true)`) and require per-theme markup. Always source from the theme directory. A single `_confirm.html.erb` serves both modal- and popover-style confirms; add `_confirm.html+<variant>.erb` for chrome-specific tuning.

%w[
  _confirm.html.erb
].freeze

Instance Method Summary collapse

Instance Method Details

#copy_chrome_partialsObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/generators/turbo_overlay/install_generator.rb', line 92

def copy_chrome_partials
  return if options[:skip_chrome]

  FALLBACK_PARTIALS.each do |filename|
    dest = "app/views/turbo_overlay/#{filename}"
    if @theme == "plain"
      copy_gem_fallback_partial(filename, dest)
    else
      copy_file chrome_source_path(filename), dest
    end
  end

  THEME_ONLY_PARTIALS.each do |filename|
    copy_file chrome_source_path(filename),
      "app/views/turbo_overlay/#{filename}"
  end
end

#copy_initializerObject



88
89
90
# File 'lib/generators/turbo_overlay/install_generator.rb', line 88

def copy_initializer
  template "initializer.rb.tt", "config/initializers/turbo_overlay.rb"
end

#inject_stack_tagObject



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/generators/turbo_overlay/install_generator.rb', line 110

def inject_stack_tag
  if options[:skip_layout_inject]
    @layout_instructions_only = true
    return
  end

  layout_path = locate_application_layout
  unless layout_path
    @layout_instructions_only = true
    say_status :skip, "no application.html.erb found; see post-install instructions for `overlay_stack_tag`", :yellow
    return
  end

  contents = File.read(File.join(destination_root, layout_path))
  if contents.include?("overlay_stack_tag") || contents.include?("overlay_frame_tags")
    say_status :identical, layout_path, :blue
    return
  end

  inject_into_file layout_path, before: %r{</body>} do
    "    <%= overlay_stack_tag %>\n  "
  end
end

#show_post_install_messageObject



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/generators/turbo_overlay/install_generator.rb', line 170

def show_post_install_message
  say "\nTurbo Overlay installed with the #{@theme} theme.\n"
  say "\nSetup checklist:\n"

  print_controller_step
  print_layout_step
  print_js_step
  print_css_step

  say "\nUsage:\n"
  say <<~MSG
      Open views as overlays:

        <%= modal_link_to   "New",     new_thing_path %>
        <%= drawer_link_to  "Filters", filters_path %>
        <%= popover_link_to "Edit",    edit_thing_path(@thing) %>

      Add hover-hint previews with `hint: true` (and `hint_url:` for
      content from a separate URL):

        <%= hint_link_to "User",       user_path(@user) %>
        <%= modal_link_to "Edit", path, hint: true, hint_url: hint_path %>
  MSG
end

#validate_themeObject



80
81
82
83
84
85
86
# File 'lib/generators/turbo_overlay/install_generator.rb', line 80

def validate_theme
  @theme = options[:theme].to_s
  unless THEMES.include?(@theme)
    raise Thor::Error,
      "Theme '#{@theme}' not recognized. Choose from: #{THEMES.join(", ")}."
  end
end

#wire_javascriptObject



134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/generators/turbo_overlay/install_generator.rb', line 134

def wire_javascript
  if options[:skip_javascript]
    @js_instructions_only = true
    return
  end

  @js_setup = detect_js_setup
  case @js_setup
  when :importmap
    wire_importmap_stimulus_entry
  when :jsbundling
    @js_instructions_only = true
  else
    @js_instructions_only = true
  end
end

#wire_stylesheetObject



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'lib/generators/turbo_overlay/install_generator.rb', line 151

def wire_stylesheet
  if options[:skip_stylesheet]
    @css_instructions_only = true
    return
  end

  @css_setup = detect_css_setup
  case @css_setup
  when :sprockets
    wire_sprockets_stylesheet
  when :propshaft
    wire_propshaft_stylesheet
  when :cssbundling
    @css_instructions_only = true
  else
    @css_instructions_only = true
  end
end