четверг, 26 июля 2012 г.

Обзор приемов работы с Site Pages

В одном из недавних постов я рассказал, почему я предпочитаю использовать Site Pages вместо Application Pages. Одна из важных мыслей в той статье касалась того, что для эффективного создания решений на основе Site Pages, нужно научиться по-другому думать и использовать совершенно другие блоки и инструменты.

Сегодня я хочу рассказать, какие существуют приемы разработки на основе Site Pages. Какие имеющиеся в SharePoint инструменты можно использовать, и как с их помощью можно очень быстро создавать гибкие и прекрасно кастомизируемые решения. Будет также реальный пример, как можно за 5 минут разбить поля на форме списка на вкладки.

А в свете выхода SharePoint 2013, ориентация на Site Pages особенно важна: ведь например возможности разрабатывать Application Pages в новых SharePoint Apps просто не существует…

Ну что ж, давайте начнем!

XSLT web parts

Конечно, прежде всего – о моем любимом XSLT :) Почти все представления списков в SharePoint отображаются с помощью XsltListViewWebPart. Уметь с ней работать – очень полезный скилл! :)

Помимо XsltListViewWebPart, есть еще очень замечательная DataFormWebPart. У DFWP есть несколько важных вариантов использования:

  1. Нужно отобразить кастомизированную форму списка (например, разбить поля на вкладки или категории)
  2. Нужно объединить данные из нескольких списков в одном представлении
  3. Нужно объединить данные из списков, из каких-то сторонних веб-сервисов, из XML-файлов.
  4. Нужно отобразить совершенно кастомные данные

Веб-часть DataFormWebPart, следует это признать, немного устарела. И все-таки это по-прежнему замечательный и гибкий инструмент, выбор №1 для отображения любых нестандартных комбинаций данных, а также неплохой вариант для использования в представлениях типа Master-Details (для отображения Details).

Например, совсем недавно, на основе DataFormWebPart мне удалось создать очень интересную Ajax-форму, которая в иерархическом виде отображает элементы списка и их вложения, и позволяет с ними осуществлять некие действия. В качестве источника данных я использовал собственную реализацию DataSourceControl.

image

Как XsltListViewWebPart, так и DataFormWebPart могут создаваться в SharePoint Designer буквально за считанные минуты, и потом сгенерированный XSLT код можно использовать в своих решениях. Это очень удобно и значительно ускоряет разработку. Вообще, по моему опыту, большинство конкретных задач, связанных с XSL-преобразованиями, решаются буквально парой строк XSLT. Всё остальное – это сгенерированный код.

Кроме XsltListViewWebPart и DataFormWebPart, есть еще очень полезные ContentByQueryWebPart и CoreResultsWebPart. Из-за особенностей текущей работы, я их использую очень мало и немногое о них знаю, но забывать об их наличии конечно же нельзя, т.к. это не менее мощные инструменты.

ParameterBindings

Все XSLT веб-части имеют свойство ParameterBindings. Благодаря этому свойству, можно передавать внутрь XSLT некоторые важные параметры. Например, можно передавать любые параметры командной строки, куки, значения свойств веб-части, значения публичных свойств контролов (которые лежат на той же странице, что и XSLT веб-часть), и многое другое. Очень хорошее описание ParameterBindings можно найти в блоге у Stefan Stanev.

WebPart connections

Выбираем элемент в одной веб-части – данные в других веб-частях меняются. Это очень мощный инструмент, значение которого многие недооценивают.

Дело в том, что почти все стандартные веб-части SharePoint уже имеют кучу преднастроенных вариантов соединений. Например, 2 минуты занимает сделать библиотеку Visio-файлов с предпросмотром: создаем библиотеку документов, загружаем в неё Visio-файлы, на страницу с представлением этой библиотеки кладем Visio Web Access WebPart, соединяем их – вуаля.

clip_image002

Более того, Web Access веб-части – не только Visio, но и Excel и другие, имеют и более сложные соединения. Например, путем соединения, можно подсвечивать или “центрировать” фигуры в Visio-диаграмме, и т.д. (подробнее можете прочитать на Office.microsoft.com).

Конечно, с помощью соединений можно фильтровать: в серверной версии для этого есть соответствующие готовые веб-части, а в Foundation можно такие веб-части создать самостоятельно (и я это делал – прекрасно работает). Фильтровать можно не только представления списков, но например и данные внутри некоего Excel файла…

А уж Master-Detail дашбоарды на основе связки XLV + DFWP – это вообще постоянно используемая классика…

В общем, даже самые простейшие OOTB веб-части – например, Image Viewer, могут использовать соединения. Если об этом помнить, и хорошо знать спектр предоставляемых SharePoint’ом веб-частей, то нередко сложные задачи оказываются вдруг очень простыми :)

WebPartZone

Зоны веб-частей не так просты, как кажутся. Во-первых, для каждой зоны веб-частей можно задать очень важные атрибуты: AllowCustomization, AllowPersonalization и AllowLayoutChange. Из названия понятно, за что эти свойства отвечают. Суммарно это означает, что некоторые зоны веб-частей мы можем зафиксировать, а некоторые – давать изменять.

Плюс, у веб-частей есть куча свойств, начинающихся с Allow – особенно пригождаются свойства AllowDelete, AllowClose, AllowHide, AllowMinimize и AllowZoneChange.

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

Или же можно даже давать двигать нашу обязательную веб-часть в пределах центральной зоны веб-частей, но запрещать её удалять или перемещать в другую зону. На любой вкус…

Также, хочется отметить, что зоны веб-частей могут не только определять положение на странице для веб-частей, которые мы в них поместим. Они также могут являться более динамическими контейнерами.

Например, мы можем настроить нашу страницу так, чтобы некая зона веб-частей неторопливо выезжала из-за края экрана, если пользователь туда навел мышку… Или же, мы можем объединять веб-части некой зоны веб-частей во вкладки – как раз реализация варианта со вкладками рассмотрена ниже.

EasyTabs

EasyTabs – это очень простенькое OpenSource решение от Christophe Humbert. Простое, но чрезвычайно ценное своей идеей! А идея такова: берем все веб-части в текущей зоне веб-частей, заголовок веб-части становится заголовком вкладки, а тело веб-части становится содержимым этой вкладки.

Ну вроде, блин, банальность, что это нам даёт-то?

EasyTabs я использую еще со времен MOSS 2007. На реальных проектах. И пользователи весьма довольны.

Простой пример: как разбить поля на форме списка на вкладки.

Открываем SharePoint Designer, создаем кастомизированную форму списка, переходим на неё.

Копи-пастим исходный DFWP, и удаляем прямо в визуальном редакторе строки которые нам не нужны в каждой из получившихся веб-частей. Обратите внимание, тулбары удалять нельзя, иначе риббон потом работать не будет.

Должно получиться как-то так:

image

Следующим шагом нужно положить снизу от двух наших DFWP веб-часть Content Editor WebPart, сделать его hidden, и настроить ему ссылку на скрипт EasyTabs. Это подробно описано на странице EasyTabs Builder’a.

Дальше, небольшая хитрость: EasyTabs работают, только если у веб-частей есть хром. А на формах списков, по умолчанию, хром запрещен в настройках зоны. Придется открыть файл в расширенном режиме (Edit in Advanced Mode), и удалить свойство FrameType у зоны веб-частей:

image

Также, нужно изменить у обеих веб-частей свойство ChromeType на Default, и также задать им нормальные заголовки (Title):

image

Еще раз сохраняем, смотрим результат:

image

Всё, никакого кода, ничего… Пять минут всех дел. Вкладки можно другим цветом сделать, не проблема, у Кристофа можно выбрать цвета на странице загрузки.

И в любой момент клиент может перетасовать поля на вкладках, переименовать вкладки и т.д. Хотя и не супер дружественный интерфейс, но и несложно. Вот так-вот, а народ целую историю из этого делает. Разбить поля на вкладки… Ого!! Две недели трудозатрат. Дааа :)

Возвращаясь к EasyTab, хочется напомнить, что проект OpenSource. Это просто скрипт. Его можно подправить как вам нужно. Например, можно добавить несколько веб-частей EasyTabs на страницу – т.о. получив несколько панелей с вкладками. Кроме того, можно изменить логику так, чтобы например объединялись не веб-части, и зоны веб-частей (т.е. одна зона веб-частей = 1 вкладка). И так далее…

Контролы SharePoint

В SharePoint довольно много стандартных контролов. Например, очень часто пригождается SPSecurityTrimmedControl, с его помощью можно показать какие-нибудь дополнительные кнопки для админов. Другие контролы работают с данными – напомню, такие контролы часто можно линковать с XSLT-веб частями с помощью ParameterBindings.

Также не забывайте и про ASP:Net контролы, самые простые и стандартные, типа DropDownList. Никто не запрещает вам их использовать, иногда они могут быть весьма полезны даже без Code Behind.

JavaScript

Конечно, очень многое можно сделать на JavaScript, и об этом нельзя забывать. OOTB есть ASP.Net Ajax и JavaScript Client Object Model, и еще много разных полезных функций из файлов init.js и core.js. В интернете – множество, глаза разбегаются, разных javascript-библиотек и jQuery-плагинов, на любой вкус. На codeplex’e – масса javascript и jQuery решений, сделанных специально для SharePoint…

Кстати, в последних проектах часто использую KnockoutJs. И он показал себя очень хорошо, нужно признать, и особенно при создании Ajax-форм на основе Site pages. На какой-нибудь ближайшей конференции я вам обязательно расскажу об этом в подробностях, обещаю! :)

Ну и конечно, не забывайте про модальные диалоги и всплывающие подсказки :)

Заключение

Когда вы работаете с Site Pages, нужно использовать имеющиеся в SharePoint инструменты, и стараться поменьше писать кастомных контролов или веб-частей. Это позволит быстро создавать гибкие, кастомизируемые и хорошо масштабируемые решения, которые имеют очень хорошие шансы заработать в новых SharePoint 2013 Apps без каких-либо изменений и без необходимости внешнего хостинга.

22 комментария:

  1. По мотивам EasyTab, и других таб-решений у них есть недостатки.
    В силу чего мы разработали свой SP.ITabs, с описанием (и недостатками других) можно ознакомится по https://docs.google.com/file/d/0BzXAvUmzZfbha3VRNm1UdW9VeTg/edit.
    Решение SP.ITabs входит в состав нашего sharepoint component framework, который пока для личного пользования, но планируется выложить preview в скором времени.

    ОтветитьУдалить
    Ответы
    1. Александр, согласен, EasyTabs - далек от идеала. Когда я его использовал в реальных решениях, всегда приходилось дописывать и частично переписывать скрипт. Даже сам код написан довольно убого и неоптимально. Но это в общем-то неважно.

      Потому что, как я уже отметил выше: самое ценное в этом решении - это его идея.

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

      А вот сама идея того, что кинул веб-часть в зону веб-частей, бац, зона веб-частей превратилась во вкладки... И заголовки вкладок автоматически берутся из заголовков веб-частей. Вот это здорово! И тот факт, что пользователи могут докидывать свои веб-части туда, тем самым добавляя вкладки, это тоже очень важно. Это прекрасный пример использования встроенных в SharePoint средств в собственных целях.

      Что касается вашего документа: документ очень классный, спасибо что поделились. Половину из приведенных решений не видел. Недостатки выделены четко, всё логично и понятно.

      С другой стороны, я всё-таки не стал бы изобретать целую веб-часть с кучей настроек, и которую ради EditorPart приходится деплоить в GAC. Очень большое преимущество EasyTabs состоит в том, что она максимально легковесна, и как следствие работает везде - в том числе будет работать в новых SharePoint Apps.

      Если нужны серьезные возможности, я бы поступил следующим образом: распарзил бы веб-части, запихнул бы их в div'ы так, как мне нравится, создал бы список заголовков вкладок (ul), и применил бы к этому всему jQuery tabs. Всё, уж jQuery tabs отдокументированы дальше некуда, и возможностей у них сколько угодно.

      А насчет того, что нужен удобный UI для пользователей для настройки вкладок - это очень спорно. Если делать мало настроек, получится не гибко. Если делать много настроек, получится гибко но сложно в настройке. И чаще всего разбивать контент на вкладки всё равно будут поручать админам, а уж у администраторов порталов всегда есть базовые знания по css и javascript.

      Поэтому, мне кажется, потуги с созданием хорошего интерфейса, именно для вкладок, излишни. Много трудозатрат, мало профита.

      Удалить
    2. Андрей спасибо за отзыв!!!

      1) С apps - да засада выйдет. придется переписывать функ. настройки на jscript.
      2) UI настройки - да получился дорогой.
      2.1) но если на настройку Easy Tab уходило 20-40 минут времени, то на настройку SP.ITabs - 10-20 минут.
      2.2)и самое главное почему Easy Tab нас не устроил, то что на одной закладке хотелось видеть две веб-части сразу.
      2.3)а наша идея была как раз в том, что бы в коде не ковырять особо, а мышкой наклацать расположение так как надо.
      2.4) + у нас клиенты сами с усами и сами много что в шарике умеют настраивать, но вот такие танцы как настройка Easy Tab для них пока дремучий лес, ибо привыкли МОПить (мышко-ориентированное программирование)

      Удалить
    3. Я когда-то давно переделывал, чтобы EasyTabs зоны веб-частей заменял на табы (1 зона = 1 вкладка), причем не все, а только у которых FrameType!=None или по какому-то другому свойству, уже не помню (чтобы можно было добавлять контент вне вкладок).

      В этом случае получается гибко, и можно добавлять сколько угодно веб-частей в каждую из вкладок.

      Работало нормально, хотя управление вкладками в этом случае можно было только из SPD осуществлять.

      Другой вариант сделать больше одной вкладки - это анализировать заголовки, и веб-части с одинаковыми заголовками объединять в одну вкладку. Это еще проще делается.

      Насчет мышко-ориентированного программирования, ну а что, в примере выше, помимо удаления атрибута FrameType="None" (который удаляется всего один раз), там вроде все остальное мышкой как раз, в SPD или в браузере.

      Удалить
    4. Андрей, добрый день.
      Можете ли Вы дать несколько консультаций (подсказок в каком направлении двигаться) по SP (Foundation 2010)?
      Я руководитель небольшой фирмы. Пытаюсь сам внедрить SP. Пока на платную версию и на разработку / внедрение финансов нет. Программировать не умею, теги и т.д. не читаю. Собираю через SPD 2010.
      Но SP очень нужен!

      Вопрос 1: создал главный сайт и несколько сайтов дочерних (отделы компании) на одном семействе. На дочернем сайте в списке мне необходимо чтобы данные в столбце подстановки брались из списка, расположенного на главном сайте. В меню выбора столбцов SP разрешает выбрать только данные только из списков и библиотек текущего сайта. Можно ли сделать это без программирования?
      Вопрос 2: знающие программисты пугают: если в списке больше 100 столбцов и будет больше 5000 строк (5000 строк у меня наберётся за 0,8 года по одному списку) то SP откажется работать. Как обойти проблему? Папки не вариант. Имеется ли встроенная функция архивирования (перенос строк из одного списка в другой)?
      Спасибо.
      Дмитрий Александрович. conexru@gmail.com

      Удалить
    5. 1. Сохраните поле подстановки на главном сайте (Lookup, страница - /_layouts/mngfield.aspx) - и сможете его использовать на подсайтах (Cross Site Lookup)
      2. Встроенную архивацию есть только в сервере (retention policies). Вы же можете использовать View (Представления) для отображения актуальных элементов, а не всех сразу.

      Удалить
    6. 1. Сохраните поле подстановки на главном сайте (Lookup, страница - /_layouts/mngfield.aspx)

      Как это можно сделать? Создаю поле подстановки на дочернем сайте и поле сохраняется(Lookup, страница - /posayt4/_layouts/mngfield.aspx)на дочернем сайте. Как его перенести на головной сайт?

      Спасибо.
      Дмитрий Александрович.

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

      Удалить
    8. Например тут описан весь процесс (http://bramnuyts.be/2011/04/11/creating-a-cross-site-lookup-field-without-code/).

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

    ОтветитьУдалить
    Ответы
    1. Кстати, а программисты SP могут на подряде выполнять небольшие участки работы, например, "Хочу посчитать сумму в столбце списка по фильтру"? Или такие мелкие не интересны? Оплатить работу по целому проекту нет фин. возможностей.

      Спасибо.

      Удалить
  3. А как убрать веб-чать редактор контента? Выставил hidden = "true", но все равно отображается во вкладках.

    ОтветитьУдалить
  4. Спасибо за статью! Если есть время пожалуйста подскажите как вставить это меню в нужную часть страницы - оно по умолчанию возникает вверху страницы.
    Структура страницы такая:
    - (тут возникает EasyTabs)
    - веб часть контента
    - (а тут она должна бы возникать)
    - веб-часть списка 1 используемая в EasyTabs
    - веб часть списка 2 используемая в EasyTabs
    - веб часть представление библиотеки документов
    - веб часть контента с кодом EasyTabs

    ОтветитьУдалить
    Ответы
    1. Привет Дмитрий,
      Используй разные зоны веб-частей, или второй вариант - можно просто у контент едитора по идее убрать хром.

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

      Удалить
    3. Дмитрий ознакомьтесь с https://docs.google.com/file/d/0BzXAvUmzZfbha3VRNm1UdW9VeTg/edit - данное решение входит в состав нашего SharePoint Componet Framework https://docs.google.com/file/d/0BzXAvUmzZfbhQllZSm91WEhEbDg/edit, превью версию которого я выложил https://docs.google.com/file/d/0BzXAvUmzZfbhOXM0SXZNdUdSOVk/edit

      Удалить
  5. подскажите пожалуйста, мне необходимо программно(с помощью c#) открыть файл, находящийся в библиотеке SharePoint и построчно считать из него данные, как это сделать?

    ОтветитьУдалить
  6. Подскажите, пожалуйста, как разбить поля на вкладки в спсике sharepoint 2013?

    ОтветитьУдалить
    Ответы
    1. Ксения, в SP2013 правильный способ это сделать - это использовать Client Side Rendering.
      Однако, задача все же нетривиальная.
      Готовое решение есть в проекте-примере для SPTypeScript, можете посмотреть (SPTypeScript -> Sample_CSRTabs).

      Удалить
  7. Андрей, спасибо за информацию, подскажите, пжл, есть ли пошаговая инструкция или руководство по использованию данного примера?

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

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