Последняя и самая сложная тема, которую мы рассмотрим применительно к Решениям, это локализация.
Начнем с того, что рассмотрим какие типы ресурсов встречаются в WSS 3.0. Условно все ресурсы можно разбить на два типа:
1). ресурсы, которые используются в сборках Вашего Шаблона, сборках веб-частей и т. д. В этом случае файлы с ресурсами должны быть откомпилированы и встроены в вашу сборку, если это ресурсы по умолчанию, либо разместиться в GAC в виде отдельной сборки с характерной культурой.
При создании этого типа ресурсов механизм очень прост. Воспользуйтесь Visual Studio и добавьте файл ресурсов в проект, например NMUPortal.resx. Visual Studio автоматически создаст прокси-класс, который упростит доступ к ресурсам и позволит получать доступ к записям, используя соответствующие имена переменных. Например, если создать запись с именем Portal_Title, то доступ к этой записи из кода можно будет получить следующим образом:
NMUPortal.Resources.NMUPortal.Portal_Title
Если Вы хотите добавить ресурсы для конкретной культуры, используйте в имени файла идентификатор культуры. Например для русского языка файл ресурсов будет иметь имя NMUPortal.ru-RU.resx.
Visual Studio ресурсы по умолчанию встраивает в сборку, а ресурсы, соответствующие культурам, компилирует в отдельные сборки и разбрасывает их по соответствующим папкам. Таким образом, Вы развертываете на сервере ни одну сборку с кодом, но и сборки с ресурсами. В зависимости от установленной культуры пользователя, данные будут выбираться из соответствующей сборки.
Если ресурсы используются внутри сборки, то их развертывание в GAC осуществляется с помощью уже знакомого элемента Assembly в manifest.xml.
2). ресурсы, которые используются во время обработки CAML-файлов (onet.xml, feature.xml и т. д.) и при компиляции страниц приложения и элементов управления. В этом случае ресурсы не компилируются, а поставляются в исходном виде (XML).
Тут все намного сложнее, так как нет единого места для таких ресурсов.
а). Если Вы используете ресурсы в страницах приложений или элементах управления, то все они должны располагаться в папке App_GlobalResources веб-приложения. Как ни странно, но если приложение уже создано, то после развертывания шаблона их нужно скопировать в App_GlobalResources самостоятельно. В теории это должен был бы делать элемент ApplicationResource в манифесте, но он создает папку resources и копирует все туда. Поэтому использование последнего для меня до сих пор большая загадка. В общем же случае, чтобы ресурсы попали в папку вновь созданного веб-приложения, их нужно разместить в C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\CONFIG\Resources. Это можно сделать с помощью элемента RootFile в манифесте.
<RootFiles> <RootFile Location="Config\Resources\NMUPortal.resx"/></RootFiles>
Использовать ресурсы довольно просто. Например:
<asp:Label runat=server text="<%$Resources:NMUPortal,Portal_Title %>"></asp:Label>
б). Если Вы хотите использовать ресурсы в onet.xml или features.xml, то их нужно скопировать в другие папки. Глобальной папкой является C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\Resources. Если ресурсы находятся тут, то они доступны и в onet.xml и в других CAML файлах.
Пример использования:
<NavBars> <NavBar Body="$Resources:NMUPortal,Portal_Title" ID="1212" Name="$Resources:NMUPortal,Portal_Title" Url="http://www.microsoft.com"></NavBar></NavBars>
Развернуть сюда ресурсы можно с помощью того же элемента RootFile
<RootFiles> <RootFile Location="Resources\NMUPortal.resx"/></RootFiles>
c). Если Вы планируете использовать ресурсы только с конкретной Feature, то было бы логично развернуть их в директории Feature. Это можно сделать с помощью элемента Resources в манифесте:
<Resources> <Resource Location="AddNewsSiteAction\Resources\NMUPortal.resx"/></Resources>
В теории их можно развернуть в любую директорию внутри директории соответствующей Feature.
<?xml version="1.0" encoding="utf-8" ?><Feature DefaultResourceFile="_res" xmlns="http://schemas.microsoft.com/sharepoint/" Id="91E266BE-CAFB-4197-B920-31E6627C2056" Title="Add News" Description="Add news to the main page" Scope="Site" Hidden="FALSE" ImageUrl="menuprofile.gif" > <ElementManifests> <ElementManifest Location="elements.xml"/> </ElementManifests></Feature>
DefaultResourceFile как раз и позволяет установить директорию. Если этот атрибут не установлен или _res, то используется директория Resources внутри внутри директории Feature. А вот пример использования:
<?xml version="1.0" encoding="utf-8" ?><Elements xmlns="http://schemas.microsoft.com/sharepoint/"> <CustomAction Id="AddNewsAction" GroupId="SiteActions" Location="Microsoft.SharePoint.StandardMenu" Sequence="100" Title="$Resources:Portal_Title;" Description="Manage news" ImageUrl="_layouts/images/menuprofile.gif"> <UrlAction Url="_layouts/NMUPortal/MyApplicationPage.aspx" /> </CustomAction></Elements>
Вот и все, что касается ресурсов.
Последний компонент, который требуется локализовать, это webtemp*.xml. Он не может использовать ресурсы. Поэтому для его локализации требуется создавать несколько webTemp*.xml - для каждой культуры. При этом их нужно разворачивать в директорию с иденетификатором соответствующей культуры (вместо 1033 номер вашей культуры).
И теперь о главном - как все это развернуть. Механизм тут следующий:
Шаг 1. Разверните базовый шаблон, не включая ресурсы, соответствующие конкретной культуре.
Шаг 2. Для каждого типа культуры создайте отдельный пакет (его принято называть Language Pack). В manifest.xml этого пакета включите все ресурсы и webtemp*.xml.
Шаг 3. Разверните Language Pack с использованием stsadm:
%stsadm% -o addsolution -filename %WSPackage% -lcid 1049%stsadm% -o execadmsvcjobs%stsadm% -o deploysolution -name NMUPortal.wsp -immediate -allowGacDeployment -force -lcid 1049%stsadm% -o execadmsvcjobs
Тут мы добавили lcid для спецификации культуры.
Удаление решения происходит в обратном порядке (сначало удаляем все Language Packs, а затем основное решение)