Comments 14
Много вариантов локализаций видел.
Часто не удобно работать не со строками в коде, а package[150] или Resource.Id.
Обычно пишешь со строками на одном языке, запускаешь, а потом нужны еще. И начинаешь лопатить код. А писать сразу через ресурсы, неудобно.
Как-то писал проект (но как обычно забросил).
Он ildasm переводил IL код, парсил его. Там операция инициализации строки простая.
Собирал БД адресов строк и строки.
Потом для каждой строки делал перевод.
Правил IL код. Собирал ilasm в сборку на нужном языке.
Часто не удобно работать не со строками в коде, а package[150] или Resource.Id.
Обычно пишешь со строками на одном языке, запускаешь, а потом нужны еще. И начинаешь лопатить код. А писать сразу через ресурсы, неудобно.
Как-то писал проект (но как обычно забросил).
Он ildasm переводил IL код, парсил его. Там операция инициализации строки простая.
Собирал БД адресов строк и строки.
Потом для каждой строки делал перевод.
Правил IL код. Собирал ilasm в сборку на нужном языке.
0
В DEBUG-версии библиотеки при попытке получения строки с несуществующим идентификатором, будет возвращено пустое значение, но сама строка при этом будет создана и при завершении работы программы эти изменения можно будет сохранить.
Но лично я вижу более удобное решение, которое уже реализовано в другом проекте, где используется эта библиотека, а именно: коды строк, их значения и краткие описания (для переводчиков) хранятся в Excel-файле, а специальная программа по требованию парсит его и генерирует для каждого листа класс-набор констант, примерно так:
Заодно пополняет словарь локализации, в программе остается вызывать только package[STR_COMMON.Welcome] и строка получена.
Для потенциального переводчика надо будет только перевести тексты сообщений в Excel-файле для получения локализации на другом языке.
Но лично я вижу более удобное решение, которое уже реализовано в другом проекте, где используется эта библиотека, а именно: коды строк, их значения и краткие описания (для переводчиков) хранятся в Excel-файле, а специальная программа по требованию парсит его и генерирует для каждого листа класс-набор констант, примерно так:
public static class STR_COMMON
{
public const int Welcome = 0x00000001;
public const int ServerUnavailable = 0x00000002;
public const int ConnectionRefused = 0x00000003;
// и т.д.
}
Заодно пополняет словарь локализации, в программе остается вызывать только package[STR_COMMON.Welcome] и строка получена.
Для потенциального переводчика надо будет только перевести тексты сообщений в Excel-файле для получения локализации на другом языке.
0
Вариант с вызовом функции наподобие
У нас в приложении тоже используется локализация — и да, проблема с корректной формой числительных актуальна как никогда. Правда, мы решили вопрос по-другому: у нас есть строки типа «plural form» в формате «user|users» или «пользователь|пользователя|пользователей», и есть одна специальная строка с кодом функции, выбирающей номер такой формы в зависимости от числа. В таком формате сложнее ошибиться.
Plural(%0, "str1", "str2")
имеет одну фатальную опасность, если у вас много переводчиков и они работают удаленно: переводчик может вдруг решить перевести название функции и программа будет не просто выдавать некорректную строку, а падать с необработанным исключением, и проверить это крайне сложно.У нас в приложении тоже используется локализация — и да, проблема с корректной формой числительных актуальна как никогда. Правда, мы решили вопрос по-другому: у нас есть строки типа «plural form» в формате «user|users» или «пользователь|пользователя|пользователей», и есть одна специальная строка с кодом функции, выбирающей номер такой формы в зависимости от числа. В таком формате сложнее ошибиться.
0
Зачем переводчику заменять названия функций? Это нелогично, т.к. функции оформлены спец-символами, а именно
Но если это все же произошло (например, написали
Плюс, при желании, можно добавить свои функции или переопределить уже существующие, например так:
И в дальнейшем использовать наиболее удобный псевдоним.
Хотя, надо признать, сейчас не реализована полная проверка синтаксиса строк, и если допустить ошибку (забыть знак %), то в некоторых случаях программа упадет.
%Plural(%0, "str1", "str2", "str3")%
Но если это все же произошло (например, написали
%Множественный(%0, "str1", "str2", "str3")%
), интерпретатор выдаст исключение о том, что функция «Множественный» не найдена.Плюс, при желании, можно добавить свои функции или переопределить уже существующие, например так:
[Function("P", "Множественный", "ЧислФорма")]
protected override object Plural(int count, params object[] forms)
{
int m10 = count % 10;
int m100 = count % 100;
if (m10 == 1 && m100 != 11)
{
return forms[0];
}
else if (m10 >= 2 && m10 <= 4 && (m100 < 10 || m100 >= 20))
{
return forms[1];
}
else
{
return forms[2];
}
}
И в дальнейшем использовать наиболее удобный псевдоним.
Хотя, надо признать, сейчас не реализована полная проверка синтаксиса строк, и если допустить ошибку (забыть знак %), то в некоторых случаях программа упадет.
0
Согласен, что с точки зрения программиста это абсолютно нелогично, но такие случаи у нас были. Главная проблема заключалась в том, что строка компилировалась только во время запуска программы с конкретной локалью. Если в вашей системе строки компилируются предварительно (например, при подготовке релиза) и это можно отследить заблаговременно — то хорошо :)
0
Зачем переводчику заменять названия функций?
Халтура, когда весь или часть материала переводчик фигачит в гугл транслейт.
0
Я с .Net конечно не очень знаком, но разве есть какие-то препоны перед использованием gettext? Судя по тому, что Вы говорите о «многих летах» я не могу поверить, что Вы о нём не знаете.
0
Да, читал о нем, но его функционал не подходит для моего проекта. Там есть только поддержка множественного числа и ничего более.
А для меня важно было иметь возможность расширения функционала пакетов своими функциями, возможность подгрузки и смены пакетов «на лету», возможность, в конце концов, использовать числа в качестве идентификаторов. Последнее имеет принципиальное значение при передаче сообщений между клиентом и сервером — не будете же вы передавать по сети длинную строку идентификатора вместо компактного числа.
А для меня важно было иметь возможность расширения функционала пакетов своими функциями, возможность подгрузки и смены пакетов «на лету», возможность, в конце концов, использовать числа в качестве идентификаторов. Последнее имеет принципиальное значение при передаче сообщений между клиентом и сервером — не будете же вы передавать по сети длинную строку идентификатора вместо компактного числа.
0
вот очень удобная тулза
www.multi-language-software.de/tiki/tiki-index.php
а уж про то как удобно отдавать в перевод excel файл и его же принимать обратно вообще молчу :)
www.multi-language-software.de/tiki/tiki-index.php
а уж про то как удобно отдавать в перевод excel файл и его же принимать обратно вообще молчу :)
0
UpperF — Capitalize
0
Чтобы не изобретать свой синтаксис для ресурсных строк у нас в проекте использовался Razor (ну и работало все через RazorEngine). Туда можно было засунуть любые пользовательские функции, иногда даже какую-то простую логику без необходимости корячить функцию.
Сами ресурсные строки хранились в xml, который элементарно преобразовывался в формат excel, для передачи переводчикам.
Сами ресурсные строки хранились в xml, который элементарно преобразовывался в формат excel, для передачи переводчикам.
0
Возможно, я неформал, но очень не люблю таскать чужие библиотеки в своих проектах. Уж извините, такая у меня слабость.
Но вы подкинули хорошую идею. Добавлю в библиотеку возможность подстановки полей классов, если соответствующий аргумент является классом. В моем синтаксисе это будет выглядеть примерно так:
Но вы подкинули хорошую идею. Добавлю в библиотеку возможность подстановки полей классов, если соответствующий аргумент является классом. В моем синтаксисе это будет выглядеть примерно так:
%0.Name%
0
Что насчёт NuGet пакета и как с этим работать, например в Asp.Net MVC?
0
Sign up to leave a comment.
Локализация проектов на .NET с интерпретатором функций