fnando / i18n-js

It's a small library to provide the I18n translations on the Javascript. It comes with Rails support.
MIT License
3.77k stars 520 forks source link

Feature Request: Mechanism to specify explicit order of plugins #692

Open oleksii-leonov opened 1 year ago

oleksii-leonov commented 1 year ago

Description

Now there is no built-in mechanism to specify an order of plugins. Sometimes, you need to run plugins in a specific order.

For example, I have made a custom rake task to register plugins in a specific order:

namespace :"i18n-js" do
  desc "Export i18n localization to JSON files"
  task export: :environment do
    require "i18n-js"

    # NOTE: Custom plugins.
    require_relative "../i18n_js/filter_procs_plugin"
    require_relative "../i18n_js/sort_keys_plugin"

    # NOTE: Register plugins in a specific order:
    # 1. Filter; 2. Fallbacks; 3. Sort.
    I18nJS.register_plugin(I18nJS::FilterProcsPlugin)
    I18nJS.load_plugins!
    I18nJS.register_plugin(I18nJS::SortKeysPlugin)

    # Export i18n localization to JSON files.
    I18nJS.call(config_file: "config/i18n.yml")
  end
end

# bundle exec rake i18n-js:export

Describe the solution

It would be nice to be able to specify run_before and run_after in the configuration file. For example:

# config/i18n.yml

translations:
- file: "app/packs/locales/generated/:locale.json"
  patterns:
    - '*'

filter_procs:
  enabled: true

embed_fallback_translations:
  enabled: true
  run_after: filter_procs

sort_keys:
  enabled: true
  run_after: embed_fallback_translations

Alternatives you considered

Custom script or rake task to register plugins in a specific order.

oleksii-leonov commented 1 year ago

Even better would be to keep the order specified in the configuration file.

For example, the next configuration should run plugins in the specified order (filter_procs, embed_fallback_translations, sort_keys):

# config/i18n.yml

translations:
- file: "app/packs/locales/generated/:locale.json"
  patterns:
    - '*'

filter_procs:
  enabled: true

embed_fallback_translations:
  enabled: true

sort_keys:
  enabled: true
fnando commented 1 year ago

# NOTE: Register plugins in a specific order: # 1. Filter; 2. Fallbacks; 3. Sort.

I think you're onto something. Maybe we should categorize plugins, based on 4 behaviours:

  1. Filter
  2. Fallback
  3. Sort
  4. Output

I think the implicit aspect of trusting the config order is too brittle.

So, maybe the plugin method names should match something like that, because then it wouldn't be an issue.

class I18nJS::Plugin
  def validate_schema; end
  def setup; end

  def filter(translations:); end
  def fallbacks(translations:); end
  def sort(translations:); end
  def output(files:); end
end

If not that, then I think the configuration should have something like plugin_order: [], which by default is set as the stack of plugins as they're registered.