Подтвердить что ты не робот

Является ли добавление строк с заполнителями (`{0}`) в ресурсы хорошей идеей?

Я добавил строку в файл ресурсов. Мое приложение будет локализовано. Но, добавляет ли строки с заполнителями ({0}) в ресурсы хорошая идея?
Что делать, если какой-то нетехнический человек делает локализацию? Есть ли способ, чтобы он испортил это, неосознанно?

Если это не очень хорошая идея, что мне делать?

Вот простой пример. Я буду использовать ресурсные словари WPF.

Пример:

// Resource1.resx
//        Name               |            Value
//---------------------------------------------------------------
// RELATIONSHIP_STATUS_MSG   | {0} is in relationship with {1}. 
//


class Program
{
    static void Main(string[] args)
    {
        string msg = string.Format(Resource1.RELATIONSHIP_STATUS_MSG, 
                                   "Romeo", "Juliot");
        Console.WriteLine(msg);
    }
}
4b9b3361

Ответ 1

Хорошо, я считаю, что это хорошая идея, потому что это простой и быстрый способ рендеринга параметризованных и локализованных строк.

Кстати, как вы говорите в своем вопросе, нетехнические люди могут сломать ваши строки локализации, потому что они не понимают, что "{0}". У меня есть два подхода к решению этой проблемы.

  • Просто обратите внимание на техников, не поддерживающих локализованные строки, которые не должны заботиться о тексте в скобках.

  • Используйте именованные заполнители: "{some-identifier}" и просто используйте someTextResource.Replace("{some-identifier}", someTextVar).

О 2-м, вы можете реализовать некоторый метод, принимающий экземпляр IDictionary<TKey, TValue> отношений подстановки, где ключ - это заменяемый идентификатор и значение текста для замены идентификатора.

Ответ 2

Это зависит от.

Иногда у вас нет выбора, кроме как использовать заполнители, например, для динамических данных. В этом случае использование заполнителей, особенно пронумерованных ({0}, {1},...) является не только хорошей идеей, но и самой приемлемой идеей с точки зрения интернационализации. Это позволяет переупорядочить предложение во время перевода, что определенно то, что вы хотите поддержать.
Что касается нетехнических людей... Ну, если вы пользуетесь профессиональным поставщиком программного обеспечения, для них не будет никакой проблемы, они просто используются для перевода таких строк. Если вы хотите назначить услуги простого родового переводчика, это может создать проблему. Но в этом случае я должен предупредить вас, что технические переводы конкретные: переводчики должны по крайней мере подчиняться глоссарию общих терминов программного обеспечения.

ОК, теперь на , почему это зависит от. В принципе, форматирование строк с помощью string.Format() на самом деле является конкатенацией. Как я уже сказал, если у вас есть динамические данные, у вас нет выбора. Но если ваши данные являются статическими, и у вас всего несколько комбинаций, вы никогда не должны, при любых обстоятельствах, использовать заполнители (а также простые конкатенации строк с оператором конкатенации (+) и не сложнее с StringBuilder). Для статических данных вы должны просто создать столько строк, сколько необходимо.
Настоящей причиной этого является то, что многие языки нуждаются в разных формах перевода в зависимости от контекста. Например, на моем родном языке (польский) мы используем разные формы для женских и мужских существительных.
Это не просто теоретическая проблема: 4 года назад, когда я работал в Localization, нам пришлось локализовать новое основное антивирусное программное обеспечение. Проблема заключалась в том, что некоторые программисты оптимизировали ресурсы, так что у нас было одно сообщение, подобное этому:

The {0} is inactive. To activate {0} click...

Что было заменено на placeholder, было имя функции или программы. В польской функции женский, по программе мужской. Хуже того, наш лингвист хотел добавить слова "программа" и "funkcja", в зависимости от того, что на самом деле было неактивным.
Очевидно, что мы (разработчики программного обеспечения локализации) не смогли решить проблему, не касаясь кода (что нам не позволяли делать, но это совсем другая история...).

Подводя итог:
Используйте заполнители, если вам действительно нужно. Дисковое пространство дешево. Избегайте конкатенаций (так как это не позволит переупорядочить переведенное предложение).
Не беспокойтесь о переводчике, но не забудьте дать им контекст (возможно, также инструкции). Для них важно знать , где будет отображаться ваша строка, а что - возможные значения.

Ответ 3

Если вы сделаете это, убедитесь, что вы документируете поведение для нетехнических переводчиков. В противном случае вы должны быть в порядке.

Ответ 4

Несмотря на то, что вы предоставляете документ для нетехнических переводчиков, все еще есть некоторые шансы, что они могут использовать его (неосознанно), что было бы неразумно, если вы справитесь с таким случаем самостоятельно. Я предпочел бы конкатенацию строки.

Ответ 5

Это рекомендуемый подход, я думаю. Рекомендации для GNU GetText предлагают сделать это, например.

Как отмечает Эрно, убедитесь, что тот, кто выполняет перевод, знает, что означает {0}.

Преимущество этого подхода заключается в том, что вы можете контролировать, где вставлены значения и часть форматирования значений. То, что вы пропустите, - это плюрализация ценностей, но это еще одно обсуждение.

Ответ 6

Используйте автоматическое тестирование для проверки целостности файлов ресурсов, возвращаемых поставщиками переводов. В идеале предоставить поставщикам инструменты, которые делают это во время перевода, чтобы как можно раньше уловить дефекты.

Ответ 7

Я обычно придумываю схему именования для этих строк типа, чтобы они выделялись в коде.

Подобно Strings.RELATIONSHIP_STATUS_MSG_FORMAT

Ответ 8

Мне нравится Resharper naming conventtion: __0__is_in_relationship_with__1__

Указывает, какие аргументы ожидаются при использовании из кода:

string msg = string.Format(Properties.Resources.__0__is_in_relationship_with__1__,
                           "Romeo", 
                           "Juliet");