SharePoint 2010: секрeт XSL Link

Разработчику SharePoint 2010 приходится сталкиваться с подобной задачей постоянно... Есть список, данные которого необходимо вывести на странице портала в определённом виде. Вроде бы ничего сложного - мы имеем стандартные возможности настройки представления списка: сортировка фильтрация, выбор полей для показа и т.п.

Однако не всё так просто. Вскоре мы выясняем, что никак не получаeтся убрать заголовок таблицы, убрать табличную верстку и заменить ее на блочную, провести вычисления со значениями полей и т.д.

Для решения этой проблемы раньше я использовал два пути:

  1. Первый и, как казалось, наиболее простой - написать свою вею-часть для показа списка. Основной недостаток этого решения в том, что со временем у нас появляется несметное количество веб-частей, но несмотря на это нам приходится писать всё новые и новые.
  2. Второй подход - открыть страницу в SharePoint Designer и изменить XSLT код вебчасти показа списка. Однако не каждая страница откроется в SPD - если мы имеем дело со страницей публикации и веб-часть внедрена в WiKi текст, то нас ждёт разочарование. Кроме того, стандартный XSLT код для представления списка расчитан на все случаи жизни и, соответственно, чрезвычайно сложен. Любая ваша ошибка при изменении этого кода, приведёт к тому, что вместо вашего кода будет молча выполняться встроенный. 

Однако есть и третий путь, по простоте реализации даже превосходящий первый!

В разделе "Разное"  (Miscellaneous) настроек веб-части списка вы найдёте поле "Ссылка на XSL" (XSL link), Это есть ни что иное, как поле для ссылки на альтернативный сточник XSL для веб-части. Ссылаться можно на любые каталоги сайта, как физические, так и виртуальные включая библиотеки сайта и коллекции сайтов.

На рисунке слева, я сослался на XSLT шаблон в папке portal в библиотеке "Материалы сайта" (Site Assets). Эта библиотека удобна тем, что все пользователи по умолчанию имеют к ней доступ (хотя-бы на чтение).

Задача этого шаблона: получить на входе данные, которые получает обычная веб-часть просмотра списка, но отформатировать их так как мне надо.

Но какие это данные? Какой формат у входящего XML документа и как называются поля?

Узнать это очень просто в процессе создания шаблона XSL. Достаточно лишь в теле первого же шаблона, который обрабатывает корень входящего документа написать: <xsl:copy-of select="." />, Что означает "вывести текущий элемент со всеми подчинёнными".

Короче, весь шаблон вывода исходных данных выглядит так:

<xsl:stylesheet xmlns:x="http: //www.w3.org/2001/XMLSchema" xmlns:d="http: //schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-prefixes="xsl msxsl ddwrt" xmlns:ddwrt="http: //schemas.microsoft.com/WebParts/v2/DataView/runtime" xmlns:asp="http: //schemas.microsoft.com/ASPNET/20" xmlns:__designer="http: //schemas.microsoft.com/WebParts/v2/DataView/designer" xmlns:xsl="http: //www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal" xmlns:o="urn:schemas-microsoft-com:office:office" ddwrt:ghost="show_all">

<xsl:template match="/" >
<xsl:copy-of select="." />
</xsl:template>


 </xsl:stylesheet>
Код который возвращает этот шаблон можно найти просмотрев HTML код результирующей страницы в браузере..

Узнав как выглядит исходный XML вы можете заменить код шаблона, который копирует исходник на необходимый вам код.

Например для списка сообщений (Announce):

     <xsl:template match="/" > 
        <xsl:for-each select=".//Row">
           <xsl:call-template name="NewsBody"></xsl:call-template>
        </xsl:for-each>
     </xsl:template>
     <xsl:template name="NewsBody">
       <div class="NewsItemBody">
        <div class="InnerNews">
           <h1><xsl:value-of select="@Title"></xsl:value-of></h1>
           <i><xsl:value-of select="ddwrt:FormatDateTime(substring-after(@Created_x0020_Date,'#'), 1049,'dd MMM yyyy')"></xsl:value-of></i><br/>
           <div class="NewsBody"><xsl:value-of select="@Body" disable-output-escaping="yes"></xsl:value-of>
           <div class="clear"></div>
           </div>
         </div>
       </div>
     </xsl:template>
Далее мы настраиваем стили выводимых нами классов и получаем вполне симпатичную ленту новостей: