Skip to content
Janko Marohnić edited this page Sep 27, 2022 · 2 revisions

Let's assume we want to localize our app for French and Spanish, with English remaining as the default locale. Requests prefixed with /fr/* or /es/* would make requests to French or Spanish pages respectively, while requests without a locale prefix would retrieve English pages. Also, route paths would be automatically generated for the current locale, so that we don't need to remember to pass it.

We might set this up in Rails as follows:

# config/application.rb
module MyApp
  class Application < Rails::Application
    # ...
    config.i18n.available_locales = [:en, :fr, :es]
  end
end
# config/routes.rb
Rails.application.routes.draw do
  path_locales = I18n.available_locales.map(&:to_s) - [I18n.default_locale.to_s]

  scope "(:locale)", locale: Regexp.union(path_locales) do
    # app routes
  end
end
# app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  around_action :switch_locale

  private

  def switch_locale(&action)
    I18n.with_locale(params[:locale], &action)
  end


  def default_url_options
    { locale: params[:locale] }
  end
end

By default, this won't have any effect on Rodauth routes, since those are routed independently from the Rails router. In order to localize Rodauth routes, we'll need to route locale prefixes in Roda, and make the path prefix localized, so that localized route paths are generated automatically:

# app/misc/rodauth_app.rb
class RodauthApp < Rodauth::Rails::App
  configure RodauthMain

  route do |r|
    path_locales = I18n.available_locales.map(&:to_s) - [I18n.default_locale.to_s]

    # route an optional locale prefix, together with a static "/auth" prefix
    r.on [*path_locales, true], "auth" do |locale|
      rails_request.params[:locale] = locale # for controller callback
      r.rodauth # route rodauth requests
      break # let other /{locale}/auth/* requests through
    end
  end
end
# app/misc/rodauth_main.rb
class RodauthMain < Rodauth::Rails::Auth
  configure do
    # ...
    # automatically localize generated route paths
    prefix do
      if I18n.locale == I18n.default_locale
        "/auth"
      else
        "/#{I18n.locale}/auth"
      end
    end
    # ...
  end
end

The added static /auth prefix is not required, it was just included in the example to show how it would be incorporated. You'll probably want to pair this with the rodauth-i18n gem:

$ bundle add rodauth-i18n
# app/misc/rodauth_main.rb
class RodauthMain < Rodauth::Rails::Auth
  configure do
    enable ..., :i18n
  end
end
Clone this wiki locally