- Баллы
- 103
Представим ситуацию: сервер многоязычный и нужно локализовать плагин на несколько языков.
В bukkit такое в основном делается через костыли и боль.
Сегодня я покажу, как можно сделать несколько файлов локализации и использовать их.
Приступим.
Нам понадобится всего 2 класса. 1 - для загрузки и поиска в ResourceBundle, 2 - правильный Control для ResourceBundle, чтобы правильно загружать любые кодировки.
1. Загрузчик
Что здесь мы делаем? Мы объявляем функцию для поиска ResourceBundle.
Первый аргумент у getBundle отвечает за базовое имя переводов.
К примеру базовое имя locale, то тогда у нас будет несколько файлов:
locale.properties <-- базовый файл с переводами, тут используется Locale.DEFAULT(для sponge это en_US)
Для английского(США)
locale.properties
Для русского языка у нас будет так:
locale_ru_RU.properties
Как пользоваться?
Если, к примеру, нам надо будет отправить локализованное сообщение игроку о том, что ему нельзя совершить действие, то мы пишем это:
Мы получим объект Text, который содержит варианты переводов. Если перевода для какой-то локали не будет, то будет использована базовая локаль(en_US, locale.properties)
В locale.properties у нас будет такая строчка:
А в locale_ru_RU.properties будет такая запись:
Если locale_ru_RU будет отсутствовать или же в нем не будет строчки с переводом, то будет использоваться перевод по-умолчанию(locale.properties), если же такой строчки не будет в переводе по-умолчанию, то игроку выведется ключ перевода(player.nopermission)
Как отправить игроку? Как обычное сообщение, Sponge сам решит, в какой локали отправить игроку.
Так-же прилагаю исправленный Control для правильной загрузки текста в UTF-8:
В bukkit такое в основном делается через костыли и боль.
Сегодня я покажу, как можно сделать несколько файлов локализации и использовать их.
Приступим.
Нам понадобится всего 2 класса. 1 - для загрузки и поиска в ResourceBundle, 2 - правильный Control для ResourceBundle, чтобы правильно загружать любые кодировки.
1. Загрузчик
Java:
import org.spongepowered.api.text.Text;
import org.spongepowered.api.text.translation.ResourceBundleTranslation;
import javax.annotation.Nullable;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.function.Function;
public class TranslationHelper {
private static final Function<Locale, ResourceBundle> LOOKUP_FUNC = new Function<Locale, ResourceBundle>() {
@Nullable
@Override
public ResourceBundle apply(Locale input) {
return ResourceBundle.getBundle("locale", input, new UTF8Control());
}
};
private TranslationHelper() {}
public static Text getTranslation(String key, Object... args) {
return Text.of(new ResourceBundleTranslation(key, LOOKUP_FUNC));
}
}
Что здесь мы делаем? Мы объявляем функцию для поиска ResourceBundle.
Первый аргумент у getBundle отвечает за базовое имя переводов.
К примеру базовое имя locale, то тогда у нас будет несколько файлов:
locale.properties <-- базовый файл с переводами, тут используется Locale.DEFAULT(для sponge это en_US)
Для английского(США)
locale.properties
Для русского языка у нас будет так:
locale_ru_RU.properties
Как пользоваться?
Если, к примеру, нам надо будет отправить локализованное сообщение игроку о том, что ему нельзя совершить действие, то мы пишем это:
Java:
TranslationHelper.getTranslation("player.nopermission")
В locale.properties у нас будет такая строчка:
Код:
player.nopermission=You don't have permission
Код:
player.nopermission=У Вас нет доступа к этому действию
Если locale_ru_RU будет отсутствовать или же в нем не будет строчки с переводом, то будет использоваться перевод по-умолчанию(locale.properties), если же такой строчки не будет в переводе по-умолчанию, то игроку выведется ключ перевода(player.nopermission)
Как отправить игроку? Как обычное сообщение, Sponge сам решит, в какой локали отправить игроку.
Так-же прилагаю исправленный Control для правильной загрузки текста в UTF-8:
Java:
public class UTF8Control extends ResourceBundle.Control {
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload)
throws IllegalAccessException, InstantiationException, IOException {
// The below is a copy of the default implementation.
String bundleName = toBundleName(baseName, locale);
String resourceName = toResourceName(bundleName, "properties");
ResourceBundle bundle = null;
InputStream stream = null;
if (reload) {
URL url = loader.getResource(resourceName);
if (url != null) {
URLConnection connection = url.openConnection();
if (connection != null) {
connection.setUseCaches(false);
stream = connection.getInputStream();
}
}
} else {
stream = loader.getResourceAsStream(resourceName);
}
if (stream != null) {
try {
// Only this line is changed to make it to read properties files as UTF-8.
bundle = new PropertyResourceBundle(new InputStreamReader(stream, "UTF-8"));
} finally {
stream.close();
}
}
return bundle;
}
}
Последнее редактирование: