Как стать автором
Обновить
0

Локализация ASP.NET MVC приложений

Время на прочтение 5 мин
Количество просмотров 23K
На тему локализации уже было несколько статей на Хабре, например Локализация ASP.NET MVC приложения с помощью БД или MVC 2: Полное руководство по локализации, но все-таки проблема до сих пор актуальна.

Совсем недавно у нас возникла задача локализации (перевода) интерфейса сайта на другой язык. Наш проект разрабатывается на ASP.NET MVC и в проекте достаточно много клиентского кода на JavaScript и шаблонах jQuery. Еще одним важным моментом для нас является возможность интерактивной работы переводчиков, фактически перевода сайта на лету.

В основном все статьи, касающиеся этой темы, предписывают использовать файлы ресурсов, при этом решение получается не гибким, громоздким, и к тому же, никак не учитывается проблема перевода скриптов и шаблонов, которые в любом современном веб-проекте составляют значительную часть. В конечном итоге мы решили написать свою библиотеку Knoema.Localization, которую недавно выложили в открытый доступ. Наш код базируется на замечательной разработке Griffin, но был существенно усовершенствован, включает интерактивный инструмент для перевода, а также средства естественной локализации JS кода и шаблонов.

Возможности

Библиотека позволяет локализовать:
  • Представления (views)
  • Строковые константы в коде
  • Модели и текст в атрибутах валидации данных
  • Текст в коде на JavaScript
  • Шаблоны jQuery

Основная идея заключается в том, что все локализуемые строки определяются именем файла или классом, а затем представляются в таком виде, в котором они находятся в проекте.


Подключение и конфигурация

Для подключения библиотеки к проекту достаточно установить Nuget пакет Knoema.Localization.Mvc. Для хранения локализованных данных вам также потребуется реализация репозитория. В простейшем случае достаточно подключить готовую реализацию для EF установив пакет Knoema.Localization.EFProvider. Альтернативным вариантом является разработка своего провайдера путем реализации достаточно простого интерфейса ILocalizationRepository.

В Global.asax в Application_Start() инициализировать созданный репозиторий:
Knoema.Localization.LocalizationManager.Repository = new Knoema.Localization.EFProvider.LocalizationRepository();

и в методе RegisterRoutes прописать:
routes.IgnoreRoute("_localization/{*route}");

Если вы используете Nuget, то при добавлении сборок в web.config автоматически добавятся следующие значения:
 <system.webServer>  
		<modules>
			<add name="Knoema.Localization" type="Knoema.Localization.Web.LocalizationModule"/>
		</modules>
		<handlers>
			<add name="Knoema.Localization" verb="*" path="_localization/*" type="Knoema.Localization.Web.LocalizationHandler" allowPathInfo="true" resourceType="Unspecified" />
		</handlers>
	</system.webServer>

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

Локализация представлений

Для локализации представлений в web.config нужно указать, что в качестве базового класса для страниц будет использоваться LocalizedWebViewPage:
 <system.web.webPages.razor>
    ...
    <pages pageBaseType="Knoema.Localization.Mvc.LocalizedWebViewPage">
      <namespaces>
        <add namespace="System.Web.Mvc" />
      ...
      </namespaces>
    </pages>
  </system.web.webPages.razor>

После этого, в коде представления станет доступен Html helper:
public string R(string text, params object[] formatterArguments);

Пример

<p>@R("Hello world!")</p>

Текст можно параметризовать:
<p>@R("Hello {0}!", username)</p>

Локализация строковых констант в коде

Строки в коде локализуются с помощью расширения:
public static string Resource(this string value, object obj)

или, если метод статический, где нет объекта this, можно использовать:
public static string Resource(this string value, Type type)

Пример

"The given input does not refer to a valid Search.".Resource(this)

Локализация модели

Для локализации моделей необходимо переопределить стандартный провайдер валидации и провайдер метаданных. Для этого в Application_Start() в Global.asax добавить:
ModelValidatorProviders.Providers.Clear();
ModelValidatorProviders.Providers.Add(new ValidationLocalizer());
ModelMetadataProviders.Current = new MetadataLocalizer();

Все модели, которые могут быть локализованы, должны быть помечены атрибутом Localized.

Пример

[Localized]
public class SignInViewModel
{
	[Required(ErrorMessage = "Please provide your e-mail")]
	[Display(Name = "E-mail")]
	public string EMail { get; set; }

	[Required(ErrorMessage = "Please type your password")]
	public string Password { get; set; }
}

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

Локазиция javascript и html шаблонов

Строковые константы в javascript коде локализуются с помощью расширения JQuery:
$.localize(text, scriptSource);

Расширение можно подключить в любом месте сраницы с помощью хелпера, лучше для всего приложения сразу:
@RenderLocalizationIncludes(User.IsInRole("Admin"))	 

Кроме того, RenderLocalizationIncludes встроит на сайт виджет (при условии, что вы администратор), где вы сможете перевести все, что локализовали.

Пример

$.localize("Layout options", "~/js/shared/site.js");

Примечание

Нам показалось неудобным, что каждый раз необходимо указывать имя файла. В нашем проекте мы используем минификатор ресурсов Cassette, где есть возможность добавить обработчик ресурсов, перед тем как они скомпилируются. Простой пример конфигурации:
public class CassetteConfiguration : ICassetteConfiguration
{
	private void CustomizeScript(ScriptBundle bundle)
	{
		bundle.Processor = new ScriptPipeline().Prepend(new LocalizationResourceProcessor());
	}

	public void Configure(BundleCollection bundles, CassetteSettings settings)
	{
		bundles.AddPerIndividualFile<ScriptBundle>("js/shared/site.js", customizeBundle: CustomizeScript);
	}
}

Теперь длинный вызов $.localize(«Layout options», "~/js/shared/site.js") можно заменить на:
__R("Layout options");

LocalizationResourceProcessor заменит __R на $.localize и добавит вторым параметром имя файла.

Добавление перевода

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

Серым цветом выделены те представления или модели, которые полностью переведены.

Редактирование:


Можно добавлять новый язык, экспортировать / импортировать уже существующий.


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

Ссылки:
Исходный код на GitHub
Knoema.Localization.Core
Knoema.Localization.MVC
Knoema.Localization.Cassette
Теги:
Хабы:
+14
Комментарии 75
Комментарии Комментарии 75

Публикации

Информация

Сайт
knoema.com
Дата регистрации
Дата основания
Численность
11–30 человек
Местоположение
США

Истории