Доброго времени суток, уважаемые пользователи Хабрахабра. Я хочу поделиться с вами опытом создания корпоративного сайта на платформе Microsoft SharePoint Foundation 2010 (далее – SPF). Недавно состоялся релиз новой версии платформы — SharePoint 2013, — но я думаю, что эта статья будет во многом актуальна и для нее. Я не буду описывать здесь достоинства и недостатки SharePoint как системы управления контентом сайта. Цель данной статьи – показать, как сравнительно быстро и недорого по трудозатратам можно разработать сайт организации на этой бесплатной платформе. Надеюсь, для кого-то из вас этот опыт окажется полезным.
Итак, приступим. Прежде всего, почему в качестве платформы для сайта была выбрана SPF, а не SharePoint Server (далее – SPS)? В соответствии с лицензионной политикой корпорации Microsoft для сценариев работы через Интернет, когда доступ к корпоративным ресурсам через SPS получает неограниченное количество анонимных пользователей, необходимо приобретать лицензию SharePoint Server for Internet Sites. SPF бесплатна и это основной аргумент.
Но, выбирая SPF, мы лишаемся части функционала системы управления контентом сайта, которая доступна в SPS в полном объеме. Главным образом, это дополнительные шаблоны корпоративных сайтов и возможность публикации контента. Шаблоны корпоративных сайтов говорят сами за себя и позволяют создать сайт на основе стандартного шаблона. Возможность (feature) публикации позволяет использовать специальные типы контента публикации, списки и библиотеки документов, веб-части, мастер-страницы (master pages) и макеты страниц (page layouts). Вкупе с функционалом централизованного управления мастер-страницами и наследования их дочерними сайтами, управления навигацией сайта и функцией блокировки определенных страниц сайта для анонимных пользователей возможность публикации обеспечивает инфраструктуру системы управления контентом сайта. В SPF нам придется обходиться другими средствами.
Существует популярное мнение, что хороший корпоративный сайт на SharePoint – это сайт, который не выглядит как сайт на SharePoint. Для того чтобы добиться такого эффекта лучше отказаться от использования стандартных шаблонов мастер-страниц и макетов страниц SharePoint и заменить их своими. Первым делом нужно создать мастер-страницу сайта с брэндингом в корпоративном стиле. Проще всего начать с шаблона мастер-страницы с минимумом элементов управления ASP.NET/SharePoint и верстки, например, таким как starter.master. Многие для этих целей также используют этот гайд для создания мастер-страницы minimal.master. Для брэндинга сайта потребуется переопределить стандартные CSS-стили, определенные в файлах corev4.css, forms.css и т.д. Новые файлы стилей можно разместить в хайве SharePoint или специально созданной папке в иерархии сайта. Также брэндинг можно сделать с помощью функционала тем SharePoint, создав тему в Microsoft Office Power Point или Microsoft Theme Builder и добавив ее в коллекцию тем сайта. В зависимости от дизайна, часто для главной страницы сайта есть смысл создать отдельную мастер-страницу без панели навигации быстрого запуска или верхней панели ссылок.
Если структура корпоративного сайта такова, что сайт верхнего уровня имеет много дочерних сайтов, то следует правильно подходить к решению вопроса распространения обновлений основной мастер-страницы на дочерние сайты. Как отмечалось ранее, в SPF нет функционала централизованного управления мастер-страницами дочерних сайтов. Конечно, можно делать это вручную, копированием файла обновленной мастер-страницы в коллекцию мастер-страниц каждого из сайтов, но это, мягко говоря, неудобно. Логичнее завернуть основную мастер-страницу в возможность и устанавливать ее с помощью решения (solution). Вот пример конфигурационных файлов такой возможности:
<Feature Id="23E27B3A-120C-3259-02DA-103CC45179BB" Title="Site Master Page" Scope="Site" Version="1.0.0.0" Hidden="FALSE" DefaultResourceFile="core" xmlns="http://schemas.microsoft.com/sharepoint/" Description="This feature deploys the site master page">
<ElementManifests>
<ElementManifest Location="elements.xml" />
<ElementFile Location="MasterPagessitemasterpage.master" />
</ElementManifests>
</Feature>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="SiteMasterPage" Url="_catalogs/masterpage" Path="MasterPages" RootWebOnly="FALSE"> <File Url="sitemasterpage.master" Type="GhostableInLibrary" />
</Module>
</Elements>
Атрибут RootWebOnly=«FALSE» говорит о том, что мастер-страница будет установлена в коллекции мастер-страниц всех сайтов семейства, а атрибут Type=«GhostableInLibrary» означает, что все установленные таким образом мастер-страницы будут ссылаться на один файл мастер-страницы, расположенный в папке возможности в хайве, поэтому любые изменения в этом файле будут отражаться на всех сайтах.
Поговорим о навигации сайта. В отличие от SPS, в SPF нет возможности создавать иерархическое многоуровневое меню в верхней панели ссылок навигации сайта через стандартную страницу администрирования сайта. Но это можно сделать программно, например, с помощью нехитрого скрипта PowerShell:
[System.Reflection.Assembly]::Load("Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c");
$url = "http://site"
$site = new-object Microsoft.SharePoint.SPSite $url;
$web = $site.OpenWeb()
$topnav = $web.Navigation.TopNavigationBar
while ($topnav.Count -gt 0) { $topnav.Delete($topnav[0])}
$node1 = new-object Microsoft.SharePoint.Navigation.SPNavigationNode -argumentlist @("О компании", "/company", $False)
$node1 = $topnav.AddAsLast($node1)
$node2 = new-object Microsoft.SharePoint.Navigation.SPNavigationNode -argumentlist @("История", "/company/pages/history.aspx", $True)
$node2 = $node1.Children.AddAsLast($node2)
$node3 = new-object Microsoft.SharePoint.Navigation.SPNavigationNode -argumentlist @("События", "/company/events", $False)
$node3 = $node1.Children.AddAsLast($node3)
$node4 = new-object Microsoft.SharePoint.Navigation.SPNavigationNode -argumentlist @("Новости", "/company/events/Lists/news", $False)
$node4 = $node3.Children.AddAsLast($node4)
Для меню быстрого запуска можно создать два уровня иерархии с помощью страницы администрирования сайта. Если этого недостаточно, можно аналогично создать структуру навигации скриптом.
Как было отмечено ранее, в SPS возможность публикации создает инфраструктуру для управления контентом сайта. Помимо прочего она позволяет хранить контент в специальных библиотеках документов «Страницы» (Pages), для которых включены опции утверждения и хранения определенного числа основных и промежуточных версий контента. В SPF мы можем воспроизвести этот функционал, создав библиотеки документов «Страницы» вручную и в свойствах настроив для них утверждение и версионность контента. Если для хранения контента на сайте используются другие списки и библиотеки документов — их можно настроить аналогично.
Возможность публикации в SPS несет в себе и специальные типы контента, например, «Страница статьи». С их помощью в библиотеках документов «Страницы» SPS можно относительно просто создавать новый контент сайта, контент размещается на странице в специальных элементах управления публикации. В SPF для этих целей можно использовать страницу веб-частей, добавлять на нее веб-часть «Редактор контента», размещать контент в этой веб-части, а страницу размещать в предварительно созданной библиотеке документов «Страницы». Если необходимо хранить HTML-контент в элементах списка, то для этого неплохо подходит поле типа «Многострочный текст» с опцией «Расширенный форматированный текст».
При создании сайта на SharePoint сложно обойтись без кастомизации стандартных веб-частей представлений списков типа XsltListViewWebPart. Их архитектура довольно своеобразна, и если требуется серьезная кастомизация большого количества таких веб-частей, например, с изменением XSLT-шаблонов рендеринга, можно съесть на этом немало стекла. Столкнувшись с такой задачей, для себя я сделал выбор в пользу написания своей универсальной (для моих целей) веб-части, которая по заданной в XML VIEW-схеме запроса получает данные из указанного списка/библиотеки документов и накладывает на них простой шаблон XSLT, который, как правило, пишется за 5 минут. Как говорится, почувствуйте разницу:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ext="webparts.xsltlistviewwebpart">
<xsl:param name="ListUrl"/>
<xsl:output method="html"/>
<xsl:template match="rows">
<div id="news">
<div class="page_title" style="margin-top:7px !important; margin-bottom: 10px;">
<span>Архив новостей</span>
</div>
<table width="100%" border="0" cellspacing="0" cellpadding="3" class="ms-listviewtable">
<tbody>
<xsl:for-each select="row">
<tr>
<td style="vertical-align:top;">
<span class="date_text" style="display:inline-block;">
<xsl:value-of select="ext:Frmt_Date_Time(PublishDate, 'dd MMMM yyyy')"/>
</span>
</td>
<td style="vertical-align:top;">
<a class="title_item" style="font-size: 10pt;">
<xsl:attribute name="href">javascript:</xsl:attribute>
<xsl:attribute name="onclick">javascript: window.location.href='<xsl:value-of select="concat($ListUrl,concat('/DispForm.aspx?ID=',ID))" disable-output-escaping="yes"/>&Source=' + escape(window.location.href);</xsl:attribute>
<xsl:value-of select="Title" disable-output-escaping="yes"/>
</a>
</td>
</tr>
</xsl:for-each>
</tbody>
</table>
</div>
</xsl:template>
</xsl:stylesheet>
Еще один важный вопрос, с которым сталкивается разработчик сайта на SPF – нужно каким-то образом запретить доступ к определенным страницам сайта для анонимных пользователей, например, к системным страницам (application pages), доступным через /_layouts/, или служебным представлениям списков и библиотек документов. В SPS, на сайтах, созданных из шаблона «Портал публикации» (publishing portal), используется возможность «Режим блокировки для семейства сайтов» (ViewFormPagesLockDown), которая задействует функцию блокировки системных страниц сайта для анонимных пользователей. В SPF такая возможность отсутствует, и наиболее логичным решением, на мой взгляд, является создание своего http-модуля, для анализа и блокировки http-запросов к определенным страницам с последующим редиректом на страницу с информацией о запрете доступа. URL запрещенных страниц удобно задавать в конфиге веб-приложения сайта, например, в таком виде:
<SecuritySettings>
<Extensions>
<res ext=".aspx" />
<res ext=".html" />
<res ext=".htm" />
</Extensions>
<Allowed>
<res url="*/_layouts/searchresults.aspx*" />
</Allowed>
<Denied>
<res url="*/_forms/*" />
<res url="*/_layouts/*" />
<res url="*/_catalogs/*" />
<res url="*/_controltemplates/*" />
<res url="*/_cts/*" />
<res url="*/_private/*" />
<res url="*/_login/default.aspx*" />
<res url="*/m/default.aspx*" />
<res url="*/approval.aspx*" />
<res url="*/latestreports.aspx*" />
<res url="*/personalviews.aspx*" />
<res url="*/last2weeks.aspx*" />
<res url="*/allitems.aspx*" />
</Denied>
</SecuritySettings>
Адепты поисковой оптимизации контента сайта для поисковых систем с помощью meta-тегов, вероятно, будут озадачены способом, которым можно создавать такие теги для динамических страниц сайта, таких как формы просмотра элементов списков и библиотек документов (DispForm.aspx). В моем случае я решил этот вопрос следующим образом:
- на сайте был создан список ключевых слов с полем «Ключевое слово» (keyword),
- в списках и библиотеках документов, для которых в формах просмотра элементов требуются meta-теги, было добавлено поле подстановки по полю «Ключевое слово» из списка ключевых слов, а также поле «Описание» (description) для поискового описания контента, определяемого ключевым словом,
- был разработан элемент управления (web control), который в процессе рендеринга определял и при наличии записывал значение поля подстановки в meta-тег «keywords», а значение поля «Описание» в meta-тег «description»,
- этот элемент управления регистрировался на мастер-странице сайта в качестве DelegateControl AdditionalPageHead с помощью возможности:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Control Id="AdditionalPageHead" Sequence="50"
ControlClass="MetaTagGenerator"
ControlAssembly="MetaTagGenerator, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=18bdc3dfdc022d0b" />
</Elements>
В итоге, в процессе рендеринга страницы формы просмотра элемента списка или библиотеки документов, для которого заполнено поле подстановки ключевых слов, на странице размещаются соответствующие meta-теги.
И напоследок несколько слов о функционале поиска по сайту в SPF. Стандартный поиск предлагает выбрать области поиска. На корпоративном сайте, нам мой взгляд, такие настройки только мешают пользователю, так как обычно требуется поиск по всему контенту. Поэтому я рекомендую избавить пользователя от этого выбора путем небольшой кастомизации. Для этого нужно сделать следующее:
- создать свой элемент управления поиска, полностью аналогичный стандартному Microsoft.SharePoint.WebControls.SearchArea, но не создавать в его разметке список областей поиска SearchScope,
- с помощью возможности зарегистрировать созданный элемент управления на мастер-странице в качестве DelegateControl SmallSearchInputBox,
- в разметке стандартной страницы результатов поиска /_layouts/searchresulsts.aspx закомментировать элемент управления списка областей поиска SearchScope.
В этом случае, при отправке запроса на поиск системный скрипт СORE.js в функции_SubmitSearchRedirect, не обнаружив в разметке список областей поиска SearchScope, не установит параметр области поиска, что будет воспринято службой поиска как поиск по всем сайтам семейства сайтов.
Автор: amiqrious