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