Общие сведения о модели преобразования страниц и ее настройке
Сердцем решения преобразования страницы является модель, которая передает преобразование: модель сообщает подсистеме, какие свойства веб-части важны, позволяет управлять этими свойствами и динамически выбирать сопоставление для веб-части. Модель преобразования страницы выражается в ФОРМАТЕ XML и поставляется со схемой, которая используется для проверки правильности модели.
Важно!
Модернизация SharePoint PnP является частью платформы PnP и постоянно развивается. См. заметки о выпуске, чтобы быть в курсе последних изменений. Если у вас возникнут проблемы, внесите данные о них в список проблем в GitHub на платформе PnP.
Высокоуровневая архитектура преобразования страницы
На приведенном ниже рисунке показаны 4 этапа преобразования страницы.
- Для начала необходимо сообщить подсистеме преобразования, как вы хотите преобразовать страницы. Для этого указывается модель преобразования страниц. Эта модель представляет собой XML-файл, в котором описывается, как требуется сопоставить каждую из классических веб-частей с современным эквивалентом. Модель содержит список применимых свойств и данные о сопоставлении для каждой классической веб-части. Дополнительные сведения см. в статье Общие сведения о модели преобразования страниц и ее настройке. Если вы хотите разобраться, как классические веб-части сравниваются с современными веб-частями, рекомендуем ознакомиться со статьей Возможности классических и современных веб-частей.
- Теперь следует проанализировать преобразуемую страницу. Подсистема преобразования разделит страницу на коллекцию веб-частей (текст вики-страниц преобразуется в одну или несколько веб-частей вики-текста) и попробует определить используемый макет.
- Сведений, полученных в ходе анализа на этапе 2, часто не хватает для сопоставления веб-части с современным эквивалентом, поэтому на этапе 3 мы дополним эти сведения, вызвав функции, которые принимают свойства, полученные на этапе 2, и создают новые свойства на основе свойств, введенных на этапе 2. После шага 3 у нас есть все необходимые сведения для сопоставления веб-части... Кроме того, при необходимости необходимо вызвать определенный селектор, чтобы понять, какое сопоставление нам потребуется, если одна классическая веб-часть может быть сопоставлена с несколькими современными конфигурациями.
- Последний шаг — создание и настройка современной страницы, после чего к ней добавляются сопоставленные современные веб-части.
Структура модели преобразования страниц
При открытии модели преобразования страниц отображаются следующие элементы верхнего уровня:
BaseWebPart. Этот элемент содержит конфигурацию, которая применяется ко всем веб-частям. Например, он указывает, что свойство Title будет получено для всех веб-частей. Это также место, которое определяет сопоставление веб-частей по умолчанию: если веб-часть не имеет определенного сопоставления, подсистема вернется к этому сопоставлению, чтобы представить веб-часть на целевой странице.
AddOns: пользователю преобразования страницы может потребоваться применить пользовательскую логику для реализации своих потребностей, например преобразовать заданное свойство таким образом, чтобы оно могло работать с пользовательской веб-частью SPFX. Для этого платформа позволяет вам добавить сборки с функциями и селекторами. Для этого она просто определяет их в разделе AddOn, а затем ссылается на настраиваемые функции и селекторы, добавляя перед ними заданное имя, что позволяет использовать настраиваемый код при преобразовании страниц.
WebParts. Этот элемент содержит сведения для каждой веб-части, которую вы хотите преобразовать. Для каждой веб-части отображаются определения используемых свойств, выполняемые с ними функции, возможные сопоставления, которые определяют целевой объект преобразования, а также селектор, с помощью которого вы можете динамически выбрать необходимое сопоставление.
Дополнительные сведения смотрите в главах, которые вскоре появятся.
Определение элемента WebPart в модели преобразования страниц
Давайте проанализируем, как настраивается веб-часть в модели преобразования страниц, что лучше всего сделать на основе упрощенного примера определения XsltListViewWebPart.
<!-- XsltListView web part -->
<WebPart Type="Microsoft.SharePoint.WebPartPages.XsltListViewWebPart, Microsoft.SharePoint, Version=16.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c">
<Properties>
<Property Name="XmlDefinitionLink" Type="string" />
<Property Name="ListUrl" Type="string" />
<Property Name="ListId" Type="guid" Functions="{ListWebRelativeUrl} = ListAddWebRelativeUrl({ListId}); {ListServerRelativeUrl} = ListAddServerRelativeUrl({ListId})"/>
<Property Name="Direction" Type="string"/>
<Property Name="GhostedXslLink" Type="string" />
<Property Name="DisableViewSelectorMenu" Type="bool"/>
<Property Name="XmlDefinition" Type="string" Functions="{ListViewId} = ListDetectUsedView({ListId},{XmlDefinition})"/>
<Property Name="SelectParameters" Type="string"/>
</Properties>
<!-- This selector outputs: Library, List -->
<Mappings Selector="ListSelectorListLibrary({ListId})">
<Mapping Name="List" Default="true">
<ClientSideText Text="You can map a source web part ({Title}) to a combination of modern web parts :-)" Order="10" />
<ClientSideWebPart Type="List" Order="20" JsonControlData="{"serverProcessedContent":{"htmlStrings":{},"searchablePlainTexts":{},"imageSources":{},"links":{}},"dataVersion":"1.0","properties":{"isDocumentLibrary":false,"selectedListId":"{ListId}","listTitle":"{Title}","selectedListUrl":"{ListServerRelativeUrl}","webRelativeListUrl":"{ListWebRelativeUrl}","webpartHeightKey":4,"selectedViewId":"{ListViewId}"}}" />
</Mapping>
<Mapping Name="Library" Default="false">
<ClientSideWebPart Type="List" Order="10" JsonControlData="{"serverProcessedContent":{"htmlStrings":{},"searchablePlainTexts":{},"imageSources":{},"links":{}},"dataVersion":"1.0","properties":{"isDocumentLibrary":true,"selectedListId":"{ListId}","listTitle":"{Title}","selectedListUrl":"{ListServerRelativeUrl}","webRelativeListUrl":"{ListWebRelativeUrl}","webpartHeightKey":4,"selectedViewId":"{ListViewId}"}}" />
</Mapping>
</Mappings>
</WebPart>
Элемент Properties
Для каждой веб-части модель определяет свойства, которые могут быть полезны для настройки целевых современных веб-частей. Если вы пропустили определенные свойства, их можно просто вставить в модель. В некоторых свойствах вы увидите атрибут Functions: этот атрибут содержит одну или несколько функций (отдельные функции через ;) которые выполняются при сопоставлении исходной веб-части с целевой современной веб-частью. Вот как выглядит структура функции:
{Output} = FunctionName({Input1}, {Input2})
Функция может включать одно или несколько входных значений, представляющих собой:
- свойства, определенные в этой веб-части (например, {ListId});
- свойства, определенные в базовой веб-части (например, {Title});
- свойства, выведенные после выполнения предыдущей функции (например, {ListWebRelativeUrl});
- стандартные свойства уровня сайта: {Host}, {Web}, {Site}, {WebId}, {SiteId}.
При выполнении функции ее выходные данные будут иметь следующие значения:
- Одному строковому значению ({Output} в представленной модели). Оно будет добавлено в список свойств веб-частей с именем Output и значением, возвращенным после выполнения свойства
FunctionName
. - Список пар "ключ-значение" (строка словаря,строка<>): в этом случае каждая возвращаемая пара "ключ-значение" добавляется в список свойств веб-части.
Если функция не определяет выходной параметр, значение свойства веб-части, определяющего функцию, будет перезаписано с указанием результата функции.
Вот пример:
<Property Name="ListId" Type="guid" Functions="FormatGuid({ListId})"/>
Предположим, что свойство веб-части изначально содержит GUID в формате {AAFAD7D0-D57A-4BB1-8706-969A608C686B}. После выполнения свойства FormatGuid
для значения будет задан результат FormatGuid
(например, GUID без скобок AAFAD7D0-D57A-4BB1-8706-969A608C686B).
Если функция возвращает несколько значений, каждая возвращенная пара "ключ-значение", уже настроенная в качестве свойства веб-части, перезаписывает это значение свойства.
Примечание.
Все стандартные функции описаны в статье Функции и селекторы преобразования страниц
Элемент Mappings
Этот элемент определяет одну или несколько возможных целевых конфигураций для заданной исходной веб-части. Так как можно определить несколько целевых конфигураций, нужен механизм для определения используемого сопоставления:
- Если элемент сопоставления содержит заполненный атрибут Selector, результат выполнения выбора селектора используется для поиска нужного сопоставления по имени (например, функция селектора
ListSelectorListLibrary
возвращает строку Library, в результате чего используется сопоставление с именем Library). Селекторы идентичны функциям, которые возвращают одно значение, поэтому вы можете ввести в функцию селектора любой атрибут веб-части. - Если имеется только одно сопоставление, оно используется при отсутствии результата селектора.
- Если отсутствует результат селектора и при этом определено несколько сопоставлений, используется сопоставление с меткой Default.
Примечание.
Все стандартные селекторы описаны в статье Функции и селекторы преобразования страниц
Далее описан сам элемент Mapping.
Элемент Mapping
Внутри элемента Mapping можно иметь один или несколько элементов ClientSideText или ClientSideWebPart, как показано в приведенном ниже фрагменте кода. Обратите внимание, что функции можно запускать в сопоставлении, что удобно, если вы хотите выполнять обработку только в том случае, если выбрано определенное сопоставление.
<Mapping Name="List" Default="true" Functions="{SampleVariable} = SampleFunction({ListId})>
<ClientSideText Text="You can map a source web part ({Title}) to a combination of modern web parts :-)" Order="10" />
<ClientSideWebPart Type="List" Order="20" JsonControlData="{"serverProcessedContent":{"htmlStrings":{},"searchablePlainTexts":{},"imageSources":{},"links":{}},"dataVersion":"1.0","properties":{"isDocumentLibrary":false,"selectedListId":"{ListId}","listTitle":"{Title}","selectedListUrl":"{ListServerRelativeUrl}","webRelativeListUrl":"{ListWebRelativeUrl}","webpartHeightKey":4,"selectedViewId":"{ListViewId}"}}" />
</Mapping>
В приведенном выше примере исходная веб-часть XSLTListView сопоставлена с современной текстовой частью (ClientSideText
) и современной веб-частью (ClientSideWebPart
):
- Атрибут
Order
позволяет определить, какая из них идет на первом месте. - Для веб-части
ClientSideWebPart
нужно указатьType
. Если выбран типCustom
, также понадобится указать свойствоControlId
для определения необходимой настраиваемой веб-части. - Свойства
Text
,JsonControlData
иControlId
могут содержать токены в формате {Token}, которые заменяются фактическими значениями в среде выполнения. Каждый определенный токен должен поддерживать использование в качестве свойства или функции веб-части, как объяснялось раннее.
Определение элементов AddOns в модели преобразования страниц
С помощью надстроек вы можете вставить настраиваемую логику в модель сопоставления, выполнив следующие 2 действия:
- создав настраиваемую сборку, в которой размещены настраиваемые функции и селекторы;
- объявив эту настраиваемую сборку в элементах AddOns.
Создание настраиваемой сборки с функциями и селекторами
Чтобы создать собственные функции, вам потребуется вставить ссылку на сборку SharePoint.Modernization.Framework в проект, а затем создать класс, наследующий класс SharePointPnP.Modernization.Framework.Functions.FunctionsBase
:
using Microsoft.SharePoint.Client;
using SharePointPnP.Modernization.Framework.Functions;
using System;
namespace Contoso.Modernization
{
public class MyCustomFunctions: FunctionsBase
{
public MyCustomFunctions(ClientContext clientContext) : base(clientContext)
{
}
public string MyListAddServerRelativeUrl(Guid listId)
{
if (listId == Guid.Empty)
{
return "";
}
else
{
var list = this.clientContext.Web.GetListById(listId);
list.EnsureProperties(p => p.RootFolder.ServerRelativeUrl);
return list.RootFolder.ServerRelativeUrl;
}
}
}
}
Объявление настраиваемой сборки
Прежде чем использовать настраиваемые функции, их необходимо объявить в модели, добавив одну ссылку на библиотеку или класс в элемент AddOns:
<AddOn Name="Custom" Type="Contoso.Modernization.MyCustomFunctions" Assembly="Contoso.Modernization.dll" />
Можно также добавить такой код (обратите внимание на полный путь):
<AddOn Name="Custom" Type="Contoso.Modernization.MyCustomFunctions" Assembly="c:\transform\Contoso.Modernization.dll" />
Обратите внимание, что в приведенном выше примере каждое объявление имеет имя Custom.
Использование настраиваемых функций или селекторов
После определения сборки вы можете использовать функции и селекторы, ссылаясь на них с помощью имени, похожего на префикс Custom в этом примере:
<Property Name="ListId" Type="guid" Functions="{ListServerRelativeUrl} = Custom.MyListAddServerRelativeUrl({ListId})"/>