-
-
Notifications
You must be signed in to change notification settings - Fork 147
Locales
I18N is the concept of making your app translatable. In ACF, we automatically load English language tables (and potentially more), and provide the tools to let you change the messaging.
This method should work as long as you do not need to let your end-users adjust the messaging (if you do, see below for File System based)
For Bukkit, Bungee and Sponge, if you create a file named acf-YourPlugin_<language>.properties
in your resources folder, ACF will automatically load this file.
for language, use en
for english, or any of the other Locale based codes (de, fr, es, etc)
You may override any predefined key and or load new languages this way.
However, in order to add a new language, you must first, before ever calling manager.getLocales()
, call manager.addSupportedLanguage(Locale.XXXX)
.
You must do this before accessing .getLocales(), as getLocales will load the bundle.
If you need to manually load a bundle that is not a "Supported Language", or just want to use alternate file names, you may call:
// To load for all supported language locales
manager.getLocales().addMessageBundle("bundleName");
// to load for an explicit locale (may or may not be supported)
manager.getLocales().addMessageBundle("bundleName", locale);
CommandManager.getLocales
provides an API to load messages into the language table.
For the Bukkit platform, YAML based API (and an API for anything that supports the FileConfiguration API) has been provided.
If you create a YAML file such as lang_en.yaml
, in the following format:
acf-minecraft:
multiple_players_match: "<language here">
# ... more
acf-core:
permission_denied: "Perm denied message here"
# ... more
Then you may load it with
manager.getLocales().loadYamlLanguageFile("lang_en.yml", Locale.ENGLISH);
Repeat this for other languages.
While not directly part of the Locales API, it strongly relates. Messages in ACF route through a platform agnostic Message Format system.
ACF is designed to support multiple colors, but not (currently) other formatting options.
Everything is color 1 by default, unless overridden with <c#>TEXT</c#>
tags, for example:
Error: Multiple players matched <c2>{search}</c2> <c3>({all})</c3>, please be more specific.
This will use color 2 for {Search}, color 3 for the list of all valid options, and color 1 for everything else.
Colors are registered on a per message type basis, so you may change them like so:
// Sets 1,2,3 (and more, as many colors you provide)
manager.setFormat(MessageType.ERROR, ChatColor.ORANGE, ChatColor.RED, ChatColor.YELLOW);
// Change only a specific color
manager.setFormat(MessageType.ERROR, 3, ChatColor.ORANGE);
If you wish to use other formatting options (such as italic/bold for Minecraft), you may use those characters in your language files, as long as you are not sharing those language files between another platform (such as Sponge) which might not understand it.
But as Minecraft stands, I believe all 3 platforms support the section symbol codes.
ACF defaults to English as the default Locale as that is what we provide language files for. Currently, only the default locale is used to look up messages, as we have not completed the work yet to do per-player contextual Locales.
So if you need to use non English language for ACF, then simply ensure you load messages completely for your language, and then call:
manager.getLocales().setDefaultLocale(locale);
Java provides a few constants in the Locale class. ACF has taken that concept and built an even larger constant pool for more languages in Locales
So if you need a reference to a Locale, you may use Locales.SPANISH
for example. This should behave the same as doing new Locale("es")
.
Simply PR new files to the languages
folder following same pattern as the others. Then in CommandManager.java
add the language to the supportedLanguages
Set at the top.
Please use a reference to the Locales class, adding a Locale if the locale is missing.
I am wanting to keep it to just root languages for now, and not country-specific dialects.
You can load country specific versions using the API. We do not need it in core.
Per Issuer Locales is a system for determining what is the preferred language. This will vary depending on Implementation This is currently only supported on the Bukkit/Paper platforms. PR's welcome to add support to other platforms.
Call manager.usePerIssuerLocale(true);
to enable.
Minecraft does not send the Locale data as part of the join process, so this means PlayerJoinEvent, the place commonly used to send on join messages, can not be used if your trying to use ACF's Locale API yourself to send translated messages.
You may use the onLocaleChange
API to help know when it's ready.
manager.onLocaleChange((issuer, oldLocale, newLocale) -> {
if (oldLocale == null) {
// joined
}
});
But note that this solution isn't perfect and may have issues.
Give your players the ability to set their desired language, and in PlayerJoinEvent before you send any messages,
Then call manager.setPlayerLocale(player, preferredLocale)
, and that language will be used for I18N.
If the value passed to one of your annotations needs to also be translated, you may use the following syntax:
@Description("{@@my-plugin.cmd-help.mycommand}")
The {@@<key>}
portion will be replaced with whatever is in your Locales language tables.
Using for @Description
is a great example on how you could translate your help documentation, and then using
above mentioned Per Issuer Locales
, your players will receive the help descriptions in their own language.