Skip to content

Commit

Permalink
Add a locale switcher (#620)
Browse files Browse the repository at this point in the history
* application_controller.rb: Adjust set_locale logic

Adds a :locale parameter (which should come from the URL, e.g.:
`refugerestrooms.org/?locale=en` or something like that.)

* application_controller.rb: set up default_url_options

Allows URLs auto-generated by Rails to automatically be expanded
to include "?locale=xyz" or "&locale=xyz"

See: https://guides.rubyonrails.org/v5.2.4/i18n.html#setting-the-locale-from-url-params

For example, this affects URLs made with ActionView URL helpers
('button_to', 'link_to', etc.)

See: https://api.rubyonrails.org/v5.2.4/classes/ActionView/Helpers/UrlHelper.html

(Hard-coded URLS will generally not get the parameter added.)

* header: Use link_to helper for homepage link

Use a link_to helper to dynamically create the homepage link,
because URL helpers now automatically include the 'locale=' parameter.

* header: Un-hard-code the api docs path

Use the 'api_docs_path' helper, rather than hard-coding '/api/docs'.

(This is for the navigation header, under the "Resources" drop-down.)

* config/routes.rb: Add (optional) locale scope to all pages

Adds an optional locale prefix for almost every page in the app.

See: https://guides.rubyonrails.org/v5.2.4/i18n.html#setting-the-locale-from-url-params

You can now visit e.g. '/es/restrooms/new' and you will see the
"Submit a New Restroom" page in Spanish.

All links in the app auto-generate this locale prefix,
so users can specify a locale via visiting a specific locale prefix,
and the links in the app will not misdirect them into another locale.

(You can still visit URLs without a locale prefix,
like '/restrooms/new', and the app will simply auto-detect the locale
based on the preferred languages in your browser settings.)

This preserves the existing URLs in working order,
and any links out there on the web, or in people's bookmarks,
will still work.)

The home page does not always get the prefix:
- The home page link in nav is just '/?locale=[I18n.locale]'
  - You can visit '/?locale=es' to see the homepage in Spanish.
  - The homepage link in the nav are auto-generated
    as '/?locale=[I18n.locale]'; This is equivalent in functionality
    to the locale prefixes (e.g. '/es/').
  - The homepage links in the footer are auto-generated as
    '/[I18n.locale]/'.
  - You can visit '/es/' to see the homepage in Spanish.

* _footer.html.haml: Add locale switcher links

Adds locale switcher links in the footer,
which displays at the bottom of every page.

These links dynamically link to the current page the user is viewing,
but with the current locale overridden with a specific, new locale.

Uses the Rails API's "ActionDispatch::Request" feature
to get a string containing the last requested page,
(i.e. the page the user is currently viewing).
This includes query parameters, such as "?lat=[num]&long=[num]"

See: https://api.rubyonrails.org/v5.2.4/classes/ActionDispatch/Request.html#method-i-GET

(Parameters can also be derived from the URL,
such as the "es/" in "/es/restrooms/new", if routed properly.)

See: https://guides.rubyonrails.org/routing.html

See these StackOverflow answers/this Wikipedia article for details:
- https://stackoverflow.com/questions/3762430/rails-preserving-get-query-string-parameters-in-link-to
- https://stackoverflow.com/questions/6885990/rails-params-explained
- https://en.wikipedia.org/wiki/Query_string

* CSS: Better styling of the locale-switcher links

Spaced out the links a bit, and added bullet-point separators.

* spec: Fix a path construction, test passes now

Passing the whole array of restroom data was causing the whole
array to be erroneously interpreted as if it was the :locale
prefix in the path.

Explicitly pass :id, and only :id,
to the `restroom_path` route helper for this test.

(We only need the :id from the newly-constructed test restroom
in order to visit the correct path. Other restroom data isn't
needed here anyhow.)
  • Loading branch information
DeeDeeG authored Apr 16, 2020
1 parent 93d5733 commit aed3e1e
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 12 deletions.
4 changes: 4 additions & 0 deletions app/assets/stylesheets/components/common.scss
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,7 @@ footer {
color: #BE1E2D;
}
}

.locale_link {
margin: 0px 5px;
}
6 changes: 5 additions & 1 deletion app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ def mobile_filter_header
end

def set_locale
I18n.locale = http_accept_language.language_region_compatible_from(I18n.available_locales)
I18n.locale = params[:locale] || http_accept_language.language_region_compatible_from(I18n.available_locales)
end

def default_url_options
{ locale: I18n.locale }
end

end
18 changes: 17 additions & 1 deletion app/views/layouts/_footer.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,20 @@
%a{:href => "https://patreon.com/refugerestrooms"} #{t('.on-patreon')}
%br/
= "\© #{t('.copyleft')} #{Date.today.year} #{t('.refuge-restrooms')}".html_safe

%br/
%br/
= link_to 'English', request.query_parameters.merge({:locale => 'en'}), class: "locale_link"
•
= link_to 'Español', request.query_parameters.merge({:locale => 'es'}), class: "locale_link"
•
= link_to 'Filipino/Tagalog', request.query_parameters.merge({:locale => 'fil'}), class: "locale_link"
•
= link_to 'Français', request.query_parameters.merge({:locale => 'fr'}), class: "locale_link"
•
= link_to 'हिन्दी', request.query_parameters.merge({:locale => 'hi'}), class: "locale_link"
•
= link_to 'Italiano', request.query_parameters.merge({:locale => 'it'}), class: "locale_link"
•
= link_to 'polski', request.query_parameters.merge({:locale => 'pl'}), class: "locale_link"
•
= link_to 'Português do Brasil', request.query_parameters.merge({:locale => 'pt-BR'}), class: "locale_link"
4 changes: 2 additions & 2 deletions app/views/layouts/_navigation.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
%nav.nav.navbar-default{:role => "navigation"}
/ Brand and toggle get grouped for better mobile display
.navbar-header
%a#logo.toiletLogo{:href => "/"}
= link_to root_path, id: "logo", class: "toiletLogo" do
.navbar-brand Refuge Restrooms
%button.navbar-toggle{"data-target" => "#bs-example-navbar-collapse-1", "data-toggle" => "collapse", :type => "button"}
%span.sr-only= t('.toggle-navigation-button-label')
Expand All @@ -21,5 +21,5 @@
%b.caret
%ul.dropdown-menu
%li= link_to t('.download-unisex-restroom-signs-hyperlink-label'), page_path('signs')
%li= link_to t('.public-api-hyperlink-label'), '/api/docs/'
%li= link_to t('.public-api-hyperlink-label'), api_docs_path
/ /.navbar-collapse
23 changes: 16 additions & 7 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,27 @@
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html

devise_for :admin_users, ActiveAdmin::Devise.config
get '/:locale' => 'pages#index'
root 'pages#index'

ActiveAdmin.routes(self)
resources :restrooms, except: [:edit, :destroy]
scope "(:locale)" do
resources :restrooms, except: [:edit, :destroy]
end

namespace :api do
resources :docs, only: [:index]
scope "(:locale)" do
resources :docs, only: [:index]
end
end

mount API::Base => '/api'
scope "(:locale)" do
get '/contact', to: 'contacts#new'
get "/*id" => 'pages#show', as: :page, format: false
end

get '/contact', to: 'contacts#new'
get "/*id" => 'pages#show', as: :page, format: false
root 'pages#index'

resources "contacts", only: [:new, :create]
scope "(:locale)" do
resources "contacts", only: [:new, :create]
end
end
2 changes: 1 addition & 1 deletion spec/features/contacts_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
it 'should show a generic contact when contact is not from restroom form' do
restroom = create(:restroom, name: "Mission Creek Cafe")

visit restroom_path restroom
visit restroom_path(:id => restroom.id)
click_link 'Contact'

expect(page).to_not have_content('Mission Creek Cafe')
Expand Down

0 comments on commit aed3e1e

Please sign in to comment.