четверг, 13 октября 2011 г.

SharePoint и XSLT: Hello world!

Продолжаю серию статей про XSLT в SharePoint.

В предыдущей статье я рассказывал, почему XSLT в SharePoint - это важно.

Сегодня - перейду по-тихоньку к практике, и вы узнаете: как написать простейшее XSL-преобразование, как подключить его к списку, как выбрать шаблон для изменения, где подсмотреть примеры XSLT-кода, как выглядит дерево шаблонов веб-части XsltListViewWebPart, и еще много разных нюансов :) Поехали?

XSL-преобразования

Каждый наверное представляет, хотя бы примерно, что такое XSLT. Если сказать кратко, XSLT - это шаблон преобразования одного XML в другой, и сам представляющий из себя тоже разновидность XML :) Чаще всего, некий входной XML с данными преобразовывается в HTML, который затем отображается в браузере. Также происходит и в SharePoint, когда дело доходит до отображения данных списков, результатов поиска и др.

XSLT - язык очень мощный и богатый. Что нам нужно знать сейчас, это то, что основу XSLT составляют т.н. "шаблоны" (templates, элемент xsl:template), каждый из которых позволяет преобразовывать в HTML конкретный кусок входного XML. Подобно функциям, шаблоны могут вызывать друг друга (в том числе рекурсивно), передавать параметры и т.д.

Вторая важная деталь касательно XSLT - это тот факт, что шаблоны можно переопределять (override), и можно подключать файлы с шаблонами друг в друга, подобно библиотекам. Таким образом, всегда можно использовать по большей части стандартное преобразование, а в собственном файле просто переопределить один-два шаблона, которые нас непосредственно интересуют. Таким образом объем финального кода чаще всего бывает небольшим.

Но давайте же посмотрим, как это всё выглядит...

Hello world в SharePoint XSLT

Итак, давайте создадим самое простое XSLT-преобразование. Это можно сделать без Visual Studio и даже без SharePoint Designer. Очень просто и быстро:
  1. Запускаем блокнот :)
  2. Открываем в браузере http://ваш портал/_layouts/xsl/main.xsl
  3. Копируем первый тэг (xsl:stylesheet) в блокнот. Там куча объявлений xmlns, которые впоследствии могут понадобиться, - и запоминать их нет никакой необходимости, т.к. всегда можно получить из стандартных файлов SharePoint.
  4. Создаем тэг корневого шаблона, <xsl:template match="/"> - этот шаблон будет всегда выполняться первым. В качестве содержимого шаблона записываем строку Hello world!
  5. Закрываем тэги, проверяем, должно получиться примерно следующее (я немного обрезал xsl:stylesheet, чтобы получше читалось):
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    
        <xsl:template match="/">
            Hello RUSUG!
        </xsl:template>
    
    </xsl:stylesheet>
  6. Загружаем файл в любую библиотеку документов.
  7. Открываем страницу с представлением списка, переходим в режим редактирования страницы, открываем настройки веб-части, и прописываем ссылку на наш xsl-файл.
  8. Вуаля :)
Таким образом, мы создали уникальнейшее преобразование, чего угодно - в надпись Hello world :)

Конечно, это не совсем то, что может пригодиться нам в реальной действительности. Вы наверняка заметили, что в шаблоне мы прописывали атрибут match="/" - это означает, что переопределяется корневой, самый первый шаблон. А шаблонов, которые можно переопределить, на самом деле, великое множество. Естественным образом, возникает следующий вопрос:

Какой шаблон переопределять?

Чтобы ответить на этот вопрос, лучше использовать более мощный инструмент, SharePoint Designer (далее - SPD).

Итак, запускаем SPD, переходим к любому имеющемуся списку, в котором есть хотя бы одна запись, открываем его представление по умолчанию (All items), и выделяем какую-нибудь ячейку списка. Например, так:


И уже здесь, сразу же, мы получаем очень интересную подсказку в строке состояния внизу:


Ого! XSLT-разметка!

Как можно догадаться, в строке состояния отображается полный "путь" к выделенному элементу в XSLT-разметке. Используя маленькую стрелочку слева, можно промотать этот путь до шаблонов верхнего уровня (если нужно). Код тэга любого шаблона можно посмотреть, выбрав в контекстном меню соответствующего элемента пункт "Edit Tag...":


Что интересно, "путь" к выделенному элементу генерируется индивидуально для каждого конкретного элемента (т.е. туда захардкожено название колонки). И он отображается в "Edit Tag...", т.е. мы можем сразу же получить код для шаблона, который нам нужен (этот шаблон будет вдобавок визуально подсвечен дизайнером):


Это означает, что если мы в своем собственном xslt-коде добавим представленный выше тэг xsl:template, и в качестве его содержимого пропишем, к примеру, строку Hello world, то вместо значений заголовочной ячейки мы получим нашу тестовую строку!

Звучит отлично, давайте попробуем.

Переключаемся в режим Code:


Находим наш XsltListViewWebPart:


Добавляем в разметку XsltListViewWebPart элемент Xsl:


Создаем внутри Xsl-тэга элемент xsl:stylesheet, и в нем прописываем ссылку на стандартный файл main.xsl:


Код для xsl:stylesheet (все эти xmlns), как я уже упоминал выше, можно легко подсмотреть в файле main.xsl, или любом другом файле вот этого очень полезного каталога:
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\XSL\ 
Именно в этом каталоге располагаются файлы, на которые я впоследствии буду часто ссылаться: main.xsl, vwstyles.xsl, fldtypes.xsl и др.

Последним шагом, добавляем шаблон xsl:template - просто копируем его из Quick Tag Editor, а в качестве содержимого шаблона используем строку Hello world. У меня в конечном итоге получился следующий код:

<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">

    <xsl:include href="/_layouts/xsl/main.xsl" />

    <xsl:template match="FieldRef[@Name='LinkTitle']" name="LinkTitleNoMenu.LinkTitle" mode="Computed_LinkTitle_body" ddwrt:tag="a" ddwrt:dvt_mode="body" ddwrt:ghost="">
        Hello world!
    </xsl:template>

</xsl:stylesheet>

Переключаемся обратно в дизайнер, смотрим:



Ага, уже интересно! Но что, если я хочу не подменить, а добавить какой-нибудь элемент оформления, или немного исправить существующий? Откуда взять исходный код шаблона, чтобы не писать его с нуля, а только слегка подправить?

Где взять стандартный XSLT-код?

Это можно сделать опять же с помощью SharePoint Designer, и снова через вполне интуитивный визуальный интерфейс.

Трюк здесь в следующем: в SPD есть очень интересная возможность, которая называется Conditional Formatting. С помощью этого механизма можно подсветить или как-то выделить нужную ячейку (столбец) или целую строку в зависимости от некоторых условий.

И если копнуть чуть глубже, оказывается, что работает этот механизм как раз на основе XSLT. То есть мы получаем визуальный интерфейс для генерации XSL-преобразования, с возможностью последующего подсматривания сгенерированного кода на вкладке Code.

По-моему, это прекрасная возможность изучить, пусть и частично, SharePoint'овские XSLT-шаблоны и способы их изменения.

Давайте попробуем!

Xsl-тэг, использовавшийся в предыдущем абзаце, я удалил, и переключился на вкладку дизайнера. Поехали!

Щелкаем по нашей ячейке, на риббоне отыскиваем Conditional formatting, выбираем Format Column, - появляется диалоговое окно условий.

Условия эти нужны, чтобы применять форматирование не ко всем строкам, а только к подходящим под заданные условия. В принципе логично :) Но в данном случае, нам это неинтересно, поэтому мы можем задать совершенно любое условие, в том числе невыполнимое, например, "ID < 0":


Жмем Set Style,  появляется еще одно диалоговое окно, в котором можно выбрать уже конкретный стиль форматирования. Например, изменить цвет фона (background-color), или размер шрифта (font-size)... Как не трудно догадаться, эти настройки в итоге мапятся в соответствующие css-атрибуты. Впрочем, это нам тоже не интересно, можно выбрать первый попавшийся стиль.

В общем, в конце концов нажимаем ОК, стили применяются, если условие у нас было невыполнимым - внешний вид списка никак не изменится, но зато, если перейти на вкладку Code, мы увидим, что у нашей XsltListViewWebPart появился сгенерированный тэг Xsl, с кучей кода.

Этот код будет включать нужный шаблон, плюс наше невыполнимое условие и применение стиля. Этот кусок кода, кстати сказать, можно найти и безболезненно удалить. Он выглядит примерно так:

<xsl:attribute name="style">
    <xsl:if test="$thisNode/@ID &lt; '0'" ddwrt:cf_explicit="1">background-color: #FFEAAD;</xsl:if>
</xsl:attribute>

После удаления этого куска, перед нами - девственно чистый исходный шаблон, который вы можете изменять, как вам вздумается. Рекомендую поизучать и поизменять этот шаблон в SharePoint Designer, на тестовом списке, и может быть, сразу попробовать реализовать пару каких-нибудь своих идей...

Но с помощью Conditional Formatting, можно вытащить только пару шаблонов. Вдоволь с ними наигравшись и поняв их возможности, у вас неизбежно возникнет очередной вопрос:

Где взять полное дерево шаблонов?

Дерево шаблонов веб-части XsltListViewWebPart довольно сложное, и полное его описание - отдельная задача. Но базовые сведения о структуре шаблонов для отображения представления списка вполне можно получить из вот этой статьи на MSDN: Overview of XSLT List View Rendering System.

В виде упрощенной схемы эту структуру (она на самом деле очень неполная) можно представить следующим образом:



Чаще всего требуются:
  1. Корневой шаблон (/) - для добавления ссылок на скрипты и css-файлы (использовать нужно аккуратно, проверяя, не был ли уже этот же файл подключен ранее).
  2. Шаблон RenderView - здесь выводится тэг <table> (т.е. здесь к нему можно добавлять стили) и производится перечисление отображаемых на текущей странице элементов списка. Также, отсюда вызываются шаблоны группировки и отображения промежуточных итогов. Этот шаблон - хорошая точка для старта самостоятельных исследований.
  3. Шаблон Item - вывод <tr>,  перечисление всех полей.
  4. Шаблон PrintTableCellEcbAllowed - вывод <td>.
  5. Подробно про переопределение отображения содержимого полей с помощью шаблонов типа Text_body можно почитать на MSDN: How to: Customize the Rendering of a Field on a List View.
Перечислены, повторюсь, не все шаблоны. Более подробно вы можете исследовать сами. Исходный код всех этих шаблонов можно обнаружить в каталоге
C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\XSL\  
, в файлах vwstyles.xsl и fldtypes.xsl.

Подводя итог

Итак, сегодня я показал, как можно начать работать с XSLT в SharePoint, как сделать первые шаги, что читать дальше, и где можно раскопать еще больше сведений.

В следующих нескольких статьях серии будем рассматривать конкретные, наглядные примеры решения реальных задач с помощью XSL-преобразований, и попутно изучать расширения SharePoint, которые предусмотрены для XSLT-веб частей.

До новых встреч! :)

13 комментариев:

  1. Шикарная статья Андрюх, спасибо за введение. Многим будет полезной

    ОтветитьУдалить
  2. Это еще только начало! С боевыми примерами будет намного интереснее, я надеюсь :)

    ОтветитьУдалить
  3. На мой взгляд для Hello world, очень тяжеловато.
    А фраза "Открываем блокнот" совсем не серьезно...

    ОтветитьУдалить
  4. Роман, под Hello World имелось в виду, что будут рассмотрены базовые моменты.

    Ок, можешь открыть Visual Studio и создать XSLT-файл с её помощью. Никто ж не запрещает? :) Получишь все преимущества intellisense при создании файла из пяти строк :)))

    На самом деле, дело немножко в другом. Студия ведь обычно есть только на девелоперских компьютерах, но не на тестовых, и не на компьютерах клиентов (актуально для тех, кто работает onsite). Соответственно, мне хотелось подчеркнуть, что XSLT-шаблоны можно создавать где угодно, но что еще важнее, это может делать кто угодно - и ITPro, и администратор, и дизайнер.

    ОтветитьУдалить
  5. Спасибо, XSLT это не просто и интересно. Жду продолжения!

    ОтветитьУдалить
  6. Pavel, спасибо за отзыв! Продолжение обязательно будет, скорее всего в понедельник - рассмотрим уже конкретную боевую задачу-пример. Надеюсь, хорошие примеры помогут понять XSLT в SharePoint лучше и начать самостоятельно использовать XSL-преобразования.

    ОтветитьУдалить
  7. При сохранении изменений в файле представления "пропадает" кусок с template. С чем может быть связано? (2ой пример)

    ОтветитьУдалить
  8. ElenXYZ, ddwrt:ghost="hide" поменяйте на ddwrt:ghost="", или вообще удалите этот атрибут.

    ОтветитьУдалить
  9. Спасибо, Андрей, за ваше творчество! Я вставляю в представление тег посредством включения сокращенной панели инструментов, редактирую эту саму панель, результат получается нужный, потом сохраняю, закрываю дизайнер, потом снова открываю представление, а там как будто я ничего не менял. В чем может быть проблема?

    ОтветитьУдалить
  10. Этот комментарий был удален автором.

    ОтветитьУдалить
  11. Здравствуйте! я столкнулась с такой проблемой. Мне нужно менять цвет строки в зависимости от её статуса (Выполнено, Отклонено и Закрыто), использовать 3 любых цвета, я пыталась сделать в xsl
    xsl:variable name="bgColor"
    xsl:value-of select='normalize-space(./@USColor)'/

    <xsl:if test="$bgColor !='.'"
    xsl:attribute name="style"
    xsl:value-of select="normalize-space(concat('background-color: ',$bgColor, ';'))"/
    /xsl:attribute
    /xsl:if
    <xsl:if test="$bgColor = ''"
    /xsl:if
    xsl:template name="FieldRef_headerUSColor" ddwrt:dvt_mode="header" match="FieldRef[@Name='USColor']" mode="header"
    /xsl:template
    xsl:template name="FieldRef_USColor" ddwrt:dvt_mode="body" match="FieldRef[@Name='USColor']" mode="Text_body"
    /xsl:template
    но у меня не вышло не работает
    как это можно реализовать?

    ОтветитьУдалить
  12. с условиями не получается сделать стандартно, т.к. тут еще условия задаются с временем (часами)

    ОтветитьУдалить
  13. 7.Открываем страницу с представлением списка, переходим в режим редактирования страницы, открываем настройки веб-части, и прописываем ссылку на наш xsl-файл.

    Можно подробнее: где именно прописываем ссылку?
    И какой тип веб-части?

    ОтветитьУдалить

Внимание! Реклама и прочий спам будут беспощадно удаляться.