В предыдущей статье я рассказывал, почему 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. Очень просто и быстро:
- Запускаем блокнот :)
- Открываем в браузере http://ваш портал/_layouts/xsl/main.xsl
- Копируем первый тэг (xsl:stylesheet) в блокнот. Там куча объявлений xmlns, которые впоследствии могут понадобиться, - и запоминать их нет никакой необходимости, т.к. всегда можно получить из стандартных файлов SharePoint.
- Создаем тэг корневого шаблона, <xsl:template match="/"> - этот шаблон будет всегда выполняться первым. В качестве содержимого шаблона записываем строку Hello world!
- Закрываем тэги, проверяем, должно получиться примерно следующее (я немного обрезал 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>
- Загружаем файл в любую библиотеку документов.
- Открываем страницу с представлением списка, переходим в режим редактирования страницы, открываем настройки веб-части, и прописываем ссылку на наш xsl-файл.
- Вуаля :)
Конечно, это не совсем то, что может пригодиться нам в реальной действительности. Вы наверняка заметили, что в шаблоне мы прописывали атрибут 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 < '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.
В виде упрощенной схемы эту структуру (она на самом деле очень неполная) можно представить следующим образом:
Чаще всего требуются:
- Корневой шаблон (/) - для добавления ссылок на скрипты и css-файлы (использовать нужно аккуратно, проверяя, не был ли уже этот же файл подключен ранее).
- Шаблон RenderView - здесь выводится тэг <table> (т.е. здесь к нему можно добавлять стили) и производится перечисление отображаемых на текущей странице элементов списка. Также, отсюда вызываются шаблоны группировки и отображения промежуточных итогов. Этот шаблон - хорошая точка для старта самостоятельных исследований.
- Шаблон Item - вывод <tr>, перечисление всех полей.
- Шаблон PrintTableCellEcbAllowed - вывод <td>.
- Подробно про переопределение отображения содержимого полей с помощью шаблонов типа 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-веб частей.
До новых встреч! :)
Шикарная статья Андрюх, спасибо за введение. Многим будет полезной
ОтветитьУдалитьЭто еще только начало! С боевыми примерами будет намного интереснее, я надеюсь :)
ОтветитьУдалитьНа мой взгляд для Hello world, очень тяжеловато.
ОтветитьУдалитьА фраза "Открываем блокнот" совсем не серьезно...
Роман, под Hello World имелось в виду, что будут рассмотрены базовые моменты.
ОтветитьУдалитьОк, можешь открыть Visual Studio и создать XSLT-файл с её помощью. Никто ж не запрещает? :) Получишь все преимущества intellisense при создании файла из пяти строк :)))
На самом деле, дело немножко в другом. Студия ведь обычно есть только на девелоперских компьютерах, но не на тестовых, и не на компьютерах клиентов (актуально для тех, кто работает onsite). Соответственно, мне хотелось подчеркнуть, что XSLT-шаблоны можно создавать где угодно, но что еще важнее, это может делать кто угодно - и ITPro, и администратор, и дизайнер.
Спасибо, XSLT это не просто и интересно. Жду продолжения!
ОтветитьУдалитьPavel, спасибо за отзыв! Продолжение обязательно будет, скорее всего в понедельник - рассмотрим уже конкретную боевую задачу-пример. Надеюсь, хорошие примеры помогут понять XSLT в SharePoint лучше и начать самостоятельно использовать XSL-преобразования.
ОтветитьУдалитьПри сохранении изменений в файле представления "пропадает" кусок с template. С чем может быть связано? (2ой пример)
ОтветитьУдалитьElenXYZ, ddwrt:ghost="hide" поменяйте на ddwrt:ghost="", или вообще удалите этот атрибут.
ОтветитьУдалитьСпасибо, Андрей, за ваше творчество! Я вставляю в представление тег посредством включения сокращенной панели инструментов, редактирую эту саму панель, результат получается нужный, потом сохраняю, закрываю дизайнер, потом снова открываю представление, а там как будто я ничего не менял. В чем может быть проблема?
ОтветитьУдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьЗдравствуйте! я столкнулась с такой проблемой. Мне нужно менять цвет строки в зависимости от её статуса (Выполнено, Отклонено и Закрыто), использовать 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
но у меня не вышло не работает
как это можно реализовать?
с условиями не получается сделать стандартно, т.к. тут еще условия задаются с временем (часами)
ОтветитьУдалить7.Открываем страницу с представлением списка, переходим в режим редактирования страницы, открываем настройки веб-части, и прописываем ссылку на наш xsl-файл.
ОтветитьУдалитьМожно подробнее: где именно прописываем ссылку?
И какой тип веб-части?