Files
nairobi/app/components/shared/globalize_locales_component.rb
Javi Martín 647121d13e Allow different locales per tenant
Note that, currently, we take these settings from the database but we
don't provide a way to edit them through the admin interface, so the
locales must be manually introduced through a Rails console.

While we did consider using a comma-separated list, we're using spaces
in order to be consistent with the way we store the allowed content
types settings.

The `enabled_locales` nomenclature, which contrasts with
`available_locales`, is probably subconsciously based on similar
patterns like the one Nginx uses to enable sites.

Note that we aren't using `Setting.enabled_locales` in the globalize
initializer when setting the fallbacks. This means the following test
(which we could add to the shared globalizable examples) would fail:

```
it "Falls back to an enabled locale if the fallback is not enabled" do
  Setting["locales.default"] = "en"
  Setting["locales.enabled"] = "fr en"
  allow(I18n.fallbacks).to receive(:[]).and_return([:fr, :es])
  Globalize.set_fallbacks_to_all_available_locales

  I18n.with_locale(:fr) do
    expect(record.send(attribute)).to eq "In English"
  end
end
```

The reason is that the code making this test pass could be:

```
def Globalize.set_fallbacks_to_all_available_locales
  Globalize.fallbacks = I18n.available_locales.index_with do |locale|
    ((I18n.fallbacks[locale] & Setting.enabled_locales) + Setting.enabled_locales).uniq
  end
end
```

However, this would make it impossible to run `rake db:migrate` on new
applications because the initializer would try to load the `Setting`
model but the `settings` table wouldn't exist at that point.

Besides, this is a really rare case that IMHO we don't need to support.
For this scenario, an installation would have to enable a locale, create
records with contents in that locale, then disable that locale and have
that locale as a fallback for a language where content for that record
wasn't created. If that happened, it would be solved by creating content
for that record in every enabled language.
2024-06-05 16:10:56 +02:00

96 lines
2.5 KiB
Ruby

class Shared::GlobalizeLocalesComponent < ApplicationComponent
attr_reader :resource, :manage_languages
use_helpers :first_translation, :first_marked_for_destruction_translation,
:enabled_locale?, :name_for_locale, :highlight_translation_html_class
def initialize(resource = nil, manage_languages: true)
@resource = resource
@manage_languages = manage_languages
end
private
def options_for_select_language
options_for_select(available_locales, selected_locale)
end
def available_locales
Setting.enabled_locales.select { |locale| enabled_locale?(resource, locale) }.map do |locale|
[name_for_locale(locale), locale, { data: { locale: locale }}]
end
end
def selected_locale
return first_i18n_content_locale if resource.blank?
if resource.locales_not_marked_for_destruction.any?
first_translation(resource)
elsif resource.locales_persisted_and_marked_for_destruction.any?
first_marked_for_destruction_translation(resource)
else
I18n.locale
end
end
def first_i18n_content_locale
if i18n_content_locales.empty? || i18n_content_locales.include?(I18n.locale)
I18n.locale
else
i18n_content_locales.first
end
end
def selected_languages_description
sanitize(t("shared.translations.languages_in_use", count: active_locales_count))
end
def select_language_error
return if resource.blank?
current_translation = resource.translation_for(selected_locale)
if current_translation.errors.added? :base, :translations_too_short
tag.div class: "small error" do
current_translation.errors[:base].join(", ")
end
end
end
def active_locales_count
if active_locales.size > 0
active_locales.size
else
1
end
end
def active_locales
if resource.present?
resource.locales_not_marked_for_destruction
else
i18n_content_locales
end
end
def display_destroy_locale_style(locale)
"display: none;" unless display_destroy_locale_link?(locale)
end
def display_destroy_locale_link?(locale)
selected_locale == locale
end
def options_for_add_language
options_for_select(all_language_options, nil)
end
def all_language_options
Setting.enabled_locales.map do |locale|
[name_for_locale(locale), locale]
end
end
def i18n_content_locales
I18nContentTranslation.existing_locales
end
end