I have seen this done in some applications, and it's not clear to me that this is ok or if it's a separation of powers violation.
Internationalisation and localisation (see definitions of the W3C) is not something monolithic. It encompasses a whole set of features some of them being relevant for the view, some for the controller, and some for the model.
Localization refers to the adaptation of a product, application or document content to meet the language, cultural and other requirements of a specific target market (a locale).
Typically, it's about formatting numbers, dates and time, and using the language of the user in the screen layout and the menus. All this is typically relevant for the view.
Interpreting keyboard shortcuts, function keys (e.g. the left and right arrow don't mean the same if you use a left-to-right language or a right-to-left one) or users commands is in principle a responsibility of the controller (disclaimer: I mean the controller in the sense of the original MVC pattern; some modern variants might defer this to the view as well).
From localisation to internationalization
Very soon however, the localisation may be about more touchy aspects. For example:
- Currency: if you have an USD value in your model, it will not be sufficient to display the label EUR, GBP or JPY of the local currency ! Currency values generally require a proper conversion. But using which rate: the historical rate at the time the amount was registered ? or the rate of the previous day ? or the intraday rate at the exact second of the display refresh ? In advanced accounting packages you may even work with several currencies in parallel: the currency of the group, the currency of the subsidiary for reporting to the local authorities, and the currency of the transaction (which might obey different conversion rules for the group's and the subsidiary's currencies). This is why currency is in principle in the model.
- Units of measures: measures can be expressed in metric (liters, meters, centimeters, ...) and the imperial system (gallons, yards, inches,...). Fortunately, it's simpler than the currency: there is no daily conversion rate. So you could very well assume one system in your model and convert on the flow into the other at the view level (but you can crash a satellite with the wrong assumptions). For some applications it's sufficient. But if you have business software that will add up many units of measures, the rounded converted sum might not correspond to the sum of the rounded converted items. To avoid such inconsistencies, you may need to address this in the model.
- Some systems are designed to be multilingual. For exampel a sales system may manage products with a description for each supported language, so that a German customer will see the German description on his invoice and the Japanese client will see the Japanese text. In this case, you need to add language to your model.
Internationalization is the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language.
According to this definition, you can design your application from the start for internationalisation. You then have the choice on where to put it:
- You can very well let in as implementation detail of the view and use configuration files (linux), embedded string resources (macOS), or additional DLL (windows).
- But you could chose to make it data/content like any other, with use cases for its management. A great part of the localization would then end-up in the model. It would not be my personal first spontaneous choice, because it could blur the strong lines between view and model and makes your software uterly complex to manage.
Despite my own preference, I won't be dogmatic: in the end it depends on the context, the costs and the expected benefits. If you're for example a major worldwide ERP vendor and you consider this as a critical market differentiation feature, you could very well consider it.
In a MVC application internationalization mostly belongs in the views. If a model or a service needs to translate some strings there is nothing wrong with using the internationalization components there as well.
The alternative is forcing the model to handle all strings. This would cause the model to have a lot of boilerplate code for no real benefit.
For elements that deal with presentation, like user interface components and error messages, the view seems the logical place for me.
But internationalization is more, like payment and tax rules may differ across countries. Or delivery options, return policy, privacy laws etc. Each should be taken into account and made part of the system.
Some of these topics, like the UI, belong in the view. Others like product descriptions in multiple languages seems better placed in the model.
And applying the appropriate rules to provide a service according to local laws looks like business rules.
Internationalisation, (I18n), is really an implementation detail but the "best" approach that I have seen to it is the use of tools such as gettext which allows the source code to contain any required strings in the developers preferred language but marked for run time substitution and for extraction and translation into language/locale specific external resources.
gettext your example might be:
printf(_("Hello")); // Greeting marked for I18n
gettext tools would extract this, with similarly marked text, into a
.pot file, this would be converted into a
.po file for french called
fr.po and the translations added and then compiled into a
.mo file. If this was shipped with your program and placed in the correct location the user would, if their language was set to French see Bonjour rather than Hello.
Where this is a big advantage is that:
- You don't need to build language specific versions of your software
- Your translators don't see your code
- You can add translations without re-building and even ship them seperately
- If a user is not happy with the language they can simply switch locale
- If an unsupported locale is selected the original messages are displayed.
- Your source code remains readable.
- Localisation is a separate concern handled by the
gettexttools & library.