Делаем сайт на SharePoint 2010. Брендинг
Сайт на SharePoint 2010. Брендинг
Сайт на SharePoint 2010. Оптимизация
Сайт на SharePoint 2010. Брендинг Wiki-страниц
Сайт на SharePoint 2010. Построение иерархии страниц
Этим постом я начну рассказывать о создании интернет сайта на основе MS SharePoint 2010. Первые посты будут посвящены использованию для этого бесплатной версии MS SharePoint Foundation 2010. В последних постах я опишу дополнительные возможности, получаемые при покупке платных версий SharePoint 2010 (Standart и Enterprise).
Начнем с минимальных исходных данных. Сайт будет под управлением MS SharePoint Foundation, а базы данных будут располагаться на MS SQL Server 2008 Express Edition. Оба этих продукта совершенно бесплатны, что не может не радовать.
SharePoint 2010 или другие CMS
Использование SharePoint 2010 для построения сайта имеет ряд неоспоримых преимуществ:
- Интерфейсы, предназначенные для управления содержимым соответствуют тем, которыми пользователи пользуются ежедневно при работе с корпоративным порталом. Т.е. обучение пользователей не требуется;
- Возможность использования бесплатного "толстого" Windows-клиента MS SharePoint Designer для управления сайтом;
- Управление контентом в оффлайн режиме. Например, создали новость/статью/что_угодно, сидя в самолете, добрались до ближайшего Wi-Fi и опубликовали на сайте;
- Возможность работать с содержимым сайта через MS Outlook;
- Работа с библиотеками на портале как с обычными сетевыми дисками;
- Возможность публикации информации на сайте с корпоративного портала SharePoint;
Я перечислил только то, что является козырями в руках SharePoint. А теперь подробнее о брендинге SharePoint.
Анонимный доступ
Это первое, что надо задействовать на сайте под управлением MS SharePoint 2010. Перед началом разработки, т.к. есть здесь подводные камни. Например Linq-To-SharePoint не работает в режиме анонимного доступа. Для обхода этого придется писать "обертку". Описание самого процесса включения анонимного доступа есть на MSDN.
От портала к интернет-сайту
При брендинге SharePoint есть одна проблема - интерфейс SharePoint не создавался для использование его в качестве public-face. Поэтому надо адаптировать интерфейс SharePoint. Нам не понадобятся ни Ribbon, ни SiteActions. Например, ribbon абсолютно бесполезен для пользователя, имеющего права только на чтение (именно такими правами будут обладать анонимные пользователи): можно только отправить ссылку на текущую библиотеку/список по почте и подписаться на уведомления. И то и другое можно реализовать и без ribbbon'а. Также добавлю, что для подписки, пользователю придется делать "лишний" клик по закладке, а это очень плохо.
Ничего из этого нам не надо. Способов "отфильтровать" элементы управления несколько.
Security Trimmed Controls
Контрол SharePoint для отображения или сокрытия элементов, исходя из прав пользователей. На ASP.NET странице он выглядит вот так:
<Sharepoint:SPSecurityTrimmedControl runat="server" Permissions="ManageLists">
Контент, видимый пользователям, имеющим права, указанные в атрибуте Permissions
</SharePoint:SPSecurityTrimmedControl>
Можно обернуть все, что надо спрятать от посетителей в такие контролы. Этот способ мне не нравится, т.к. поддерживать решения, в которых используется такой подход дорого. Есть и ещё несколько минусов, но о них ниже.
Назад к SharePoint 2007
Можно понизить версию интерфейса с 4 на 3. После этого наш будущий сайт становится очень похож на SharePoint 2007: все элементы управления, мирно уживающиеся в одном месте (на рибоне), теперь "разлетелись" по всей странице. Впрочем, и большинство из них нам не понадобятся.
Я ни в коем случае не против нового интерфейса SharePoint 2010, а именно идеи собрать все элементы управления в одном месте. Данный подход (понижение версии интерфейса) ни в коем случае не ограничивает функционал SharePoint, т.к. версия интерфейса задается на уровне узла. Таким образом для удобства редакторов контента вполне возможно создать отдельный узел, где будут собраны все списки/библиотеки и ribbon будет функционировать. Помимо этого есть еще и возможность публиковать содержимое с внутреннего корпоративного портала. Тем не менее, неудобства обеспечена.
Здесь я прерву описание этого метода, т.к. далее всё сводится к одному: проблема и как её решать. Взять, например WYSIWYG-редактор: он будет работать только в Internet Explorer или придется встраивать сторонний редактор.
Динамическое представление сайта
Третий, мой любимый способ заключается в использовании двух представлений: исключительно контент (для посетителей сайта) и полнофункциональный SharePoint для модераторов. Этот способ мне кажется самым верным, поэтому его я опишу более подробно.
Сначала сделаем два проекта:
проект-брендинг, который будет содержать две master-страницы (как минимум, если требования в сайту "хитрые", то можно и больше), стили и изображения нам необходимые:
проект-сайт, содержащий SiteDefinition:
Master-страницу для бэкофиса (v4.moderator.master) я взял стандартную без каких-либо изменений, дабы сохранить стандартный интерфейс и его функциональность для редакторов содержимого.
С другой стороны, master-страницу для посетителей сайта я упростил максимально, удалив из неё всё, кроме PlaceHolderMain и прочей мелочи. Убрал даже FormDigest. Насколько это оправдано я напишу в следующих постах. Получилось совсем немного (без директив):
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html lang="<%$Resources:wss,language_value%>" dir="<%$Resources:wss,multipages_direction_dir_value%>" runat="server" xmlns:o="urn:schemas-microsoft-com:office:office">
<head runat="server">
<meta http-equiv="X-UA-Compatible" content="IE=8"/>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<meta http-equiv="Expires" content="0"/>
<title id="onetidTitle">
<asp:ContentPlaceHolder id="PlaceHolderPageTitle" runat="server"/>
</title>
<SharePoint:CssLink runat="server" Version="4"/>
<script type="text/javascript">
var _fV4UI = true;
</script>
<link rel="shortcut icon" href="/_layouts/images/favicon.ico"
type="image/vnd.microsoft.icon" />
</head>
<body onload="if (typeof(_spBodyOnLoadWrapper) != 'undefined') _spBodyOnLoadWrapper();" class="v4master">
<form runat="server"
onsubmit="if (typeof(_spFormOnSubmitWrapper) != 'undefined') {
return _spFormOnSubmitWrapper();} else {return true;}">
<WebPartPages:SPWebPartManager id="m" runat="Server" />
<a id="HiddenAnchor" href="javascript:;" style="display:none;"></a>
<div id="MSO_ContentDiv" runat="server">
<a name="mainContent"></a>
<asp:ContentPlaceHolder id="PlaceHolderMain" runat="server">
</asp:ContentPlaceHolder>
</div>
<input type="text" name="__spText1" title="text" style="display:none;" />
<input type="text" name="__spText2" title="text" style="display:none;" />
</form>
</body>
</html>
Что касается страницы default.aspx в SiteDefinition, то она также проста. Здесь только несколько зон для веб-партов:
<asp:Content ContentPlaceHolderId="PlaceHolderPageTitle" runat="server">
<SharePoint:ProjectProperty Property="Title" runat="server"/>
</asp:Content>
<asp:Content ContentPlaceHolderID="PlaceHolderMain" runat="server">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td valign="top" width="100%" colspan="2">
<WebPartPages:WebPartZone runat="server"
AllowPersonalization="false" Title="TopZone" ID="TopZone" Orientation="Vertical"
QuickAdd-GroupNames="Top" QuickAdd-ShowListsAndLibraries="false"/>
</td>
</tr>
<tr>
<td valign="top">
<WebPartPages:WebPartZone runat="server"
AllowPersonalization="false" Title="LeftZone" ID="LeftZone" Orientation="Vertical"
QuickAdd-GroupNames="Left" QuickAdd-ShowListsAndLibraries="false"/>
</td>
<td valign="top">
<WebPartPages:WebPartZone runat="server"
AllowPersonalization="false" Title="RightZone" ID="RightZone" Orientation="Vertical"
QuickAdd-GroupNames="Right" QuickAdd-ShowListsAndLibraries="false"/>
</td>
</tr>
<tr>
<td colspan="2">
<WebPartPages:WebPartZone runat="server"
AllowPersonalization="false" Title="BottomZone" ID="BottomZone" Orientation="Vertical"
QuickAdd-GroupNames="Bottom" QuickAdd-ShowListsAndLibraries="false"/>
</td>
</tr>
</table>
</asp:Content>
Для обеспечения динамического переключения master-страниц, надо изменить директиву Page страницы, указав в качестве наследуемого наш новый класс FluentWebPartPage
:
public class FluentWebPartPage : WebPartPage
{
protected override void OnPreInit(EventArgs e)
{
base.OnPreInit(e);
if (IsAnonymous)
SetAnonymousView();
else
SetModeratorView();
}
/// <summary>
/// Изменение master-page
/// </summary>
/// <param name="url"></param>
private void SetMasterPages(string url)
{
MasterPageFile = url;
}
private void SetAnonymousView()
{
SetMasterPages("/_catalogs/masterpage/v4.guest.master");
}
private void SetModeratorView()
{
SetMasterPages("/_catalogs/masterpage/v4.moderator.master");
}
/// <summary>
/// Является ли пользователь анонимным
/// </summary>
private static bool IsAnonymous
{
get
{
if (SPContext.Current == null) return true;
return SPContext.Current.Web.CurrentUser == null;
}
}
}
Сам класс унаследован от Microsoft.SharePoint.WebPartPages.WebPartPage. На событии OnPreInit мы проверяем, является ли пользователь анонимным и в зависимости от этого подставляем соответствующую master-страницу. Поведение этого класса может быть различно: можно проверять какие-нибудь права у пользователя, можно по умолчанию брать страницу из параметров данного сайта (MasterUrl
или CustomMasterUrl
) и т.д.
Результат
В результате мы оставляем функционал и интерфейс нетронутым для редакторов контента и полную свободу действий для создания интернет-сайта на базе SharePoint.
В следующем посте я расскажу про дальнейшую оптимизацию с целью уменьшить размер страниц, т.е. ускорение загрузки.