Модули и многоязыковой сайт
Общее направление разработки программных модулей для системы должно соответствовать простому требованию: выносите из модуля наружу всё, что можно вынести. А именно:
- Не прописывайте в модулях стили.
- Используйте шаблоны
- Всё строки текста используемые в интерфейсе выносите в ресурсные файлы.
Ресурсные файлы сайта
Система asp.net имеет собственное мнение о том, где должны хранится файлы. Поскольку структура наших приложений несколько не вписывается в предлагаемый вариант, то пришлось разработать специальный класс для доступа к ресурсам.
Итак, ресурсы - это файлы с расширением .resx. Система ожидает их наличия в каталоге resources внутри каталога сайта. Таким образом, ресурсы всегда принадлежат только одному сайту. При попытке доступа к ресурсам из модуля в первую очередь они ищутся в файле с именем класса. То есть если ваш модуль называется impactmin.ascx, то файл ресурса должен называться impactmin_map.resx, если модуль находится внутри dll, то имя ресурса совпадает с именем класса.
Если невозможно найти ресурс в описанном выше файле, то производится попытка найти ресурс в файле common.resx. При желании все ресурсы можно прописать в этом файле, но лучше этот файл использовать для хранения часто повторяющихся строк.
Разделение ресурсов на языки производится на уровне имени файла ресурса. Язык указывается перед расширением, например для английского языка:
impactminmap_ascx.en.resx
common.en.resx
Где 'en' - двухбуквенный ISO-код языка.
Язык в названии можно не указывать. Такой ресурсный файл будет использоваться в случае, если для текущего языка не найден отдельный ресурсный файл.
В общем, почти всё то же самое, что и в стандартном функционале asp.net, за исключением места хранения файлов.
Структура ресурсного файла
Ресурсные файлы resx представляют собой xml-файлы. Как и в двоичных ресурсных файлах в них можно хранить всё что угодно, начиная от текста и картинок, заканчивая объектами clr. Редактирование ресурсного файла производится в стандарном редакторе VisualStudio.
Информация в файле содержится в виде набора ключей и связанных с ними ресурсами. Для каждого ресурса можно приводить комментарий, чтобы вконец не запутаться во всём этом.
Доступ к ресурсам из модуля
Для доступа к ресурсам сайта был разработан класс LanguageTextManager. Этот класс предоставляет доступ к строковым ресурсам посредством простого индексатора по ключам. Напрямую этим классом пользоваться не рекомендуется, поскольку это затруднит дальнейший рефакторинг системы.
Для удобства функциональность класса LanguageTextManager внесена в базовый класс WebModule (и WebModuleCustom) в виде свойства Lang. Таким образом доступ к строке в ресурсных файлах будет выглядеть примерно так:
public partial class Impactmin_map { public void Mode_Show() { Controls.AddLiteral("‹h1›", Lang["header1"], "‹/h1›"); } }
Предположим также, что существует файл Mapimpactmin.ascx следующего содержания:
‹%@ Control Language="C#" CodeFile="Mapimpactmin.ascx.cs" Inherits="Impactmin_map" %›
Предположим так же, что текущий язык русский.
В рассматриваемом примере мы можем видеть, что в режиме Show модуля на клиентскую сторону передается заголовок, содержание которого мы получаем из ресурсов сайта (Lang["header1"]). Поиск в ресурсах производится по ключевому слову 'header1'. Поиск регистронезависим и считается успешным, когда искомый файл ресурса существует и содержит ресурс с указанной меткой.
Путь поиска можно выразить так:
- Mapimpactmin_ascx.ru.resx
- Mapimpactmin_ascx.resx
- Comon.ru.resx
- Comon.resx
Аналогичная ситуация, если текущий язык английский:
- Mapimpactmin_ascx.en.resx
- Mapimpactmin_ascx.resx
- Comon.en.resx
- Comon.resx
Если ни в одном из указанных файлов ресурс не найден, то Lang["header1"] будет равен "[res:header1]". При виде такой надписи вы можете быть уверены, что в ресурсных файлах не хватает ресурса с меткой 'header1'.
Ресурсы по умолчанию
Стоит сразу предупредить: всегда создавайте файл для языка по умолчанию, поскольку может сложиться ситуация когда система не знает предпочтительный язык пользователя (до того момента пока он его не укажет). Для сайтов с одним языком предпочтительней использовать ресурсные файлы без указания языка.