Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ability to select Field groups to be saved in site template #931

Open
wants to merge 4 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/api/.manifest
Original file line number Diff line number Diff line change
Expand Up @@ -6258,6 +6258,7 @@
"PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.#ctor(Microsoft.SharePoint.Client.Web)": "PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.yml",
"PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.BaseTemplate": "PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.yml",
"PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.ContentTypeGroupsToInclude": "PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.yml",
"PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude": "PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.yml",
"PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.ExtensibilityHandlers": "PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.yml",
"PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.FileConnector": "PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.yml",
"PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.HandlersToProcess": "PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.yml",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ items:
- PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.#ctor(Microsoft.SharePoint.Client.Web)
- PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.BaseTemplate
- PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.ContentTypeGroupsToInclude
- PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude
- PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.ExtensibilityHandlers
- PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.FileConnector
- PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.HandlersToProcess
Expand Down Expand Up @@ -641,6 +642,43 @@ items:
- set
modifiers.vb:
- Public
- uid: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude
commentId: P:PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude
id: SiteFieldGroupsToInclude
parent: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation
langs:
- csharp
- vb
name: SiteFieldGroupsToInclude
nameWithType: ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude
fullName: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude
type: Property
source:
remote:
path: src/lib/PnP.Framework/Provisioning/ObjectHandlers/ProvisioningTemplateCreationInformation.cs
branch: dev
repo: https://github.com/wilecoyotegenius/pnpframework.git
id: SiteFieldGroupsToInclude
path: ../src/lib/PnP.Framework/Provisioning/ObjectHandlers/ProvisioningTemplateCreationInformation.cs
startLine: 218
assemblies:
- PnP.Framework
namespace: PnP.Framework.Provisioning.ObjectHandlers
summary: "\nList of content type groups\n"
example: []
syntax:
content: public List<string> SiteFieldGroupsToInclude { get; set; }
parameters: []
return:
type: System.Collections.Generic.List{System.String}
content.vb: Public Property SiteFieldGroupsToInclude As List(Of String)
overload: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude*
modifiers.csharp:
- public
- get
- set
modifiers.vb:
- Public
- uid: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.IncludeSiteGroups
commentId: P:PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.IncludeSiteGroups
id: IncludeSiteGroups
Expand Down Expand Up @@ -2198,6 +2236,11 @@ references:
name: ContentTypeGroupsToInclude
nameWithType: ProvisioningTemplateCreationInformation.ContentTypeGroupsToInclude
fullName: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.ContentTypeGroupsToInclude
- uid: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude*
commentId: Overload:PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude
name: SiteFieldGroupsToInclude
nameWithType: ProvisioningTemplateCreationInformation.SiteFieldGroupsToInclude
fullName: PnP.Framework.Provisioning.ObjectHandlers.ProvisioningTemplateCreationInformation.SiteFIeldGroupsToInclude
- uid: System.Collections.Generic.List{System.String}
commentId: T:System.Collections.Generic.List{System.String}
parent: System.Collections.Generic
Expand Down
62 changes: 62 additions & 0 deletions src/lib/PnP.Framework.Test/Extensions/WebExtensionsTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class WebExtensionsTests
const string APPNAME = "HelloWorldApp";
const string contentTypeName = "PnP Test Content Type";
const string contentTypeGroupName = "PnP Web Extensions Test";
const string siteFieldInternalName = "pnpTestSiteField";
const string siteFieldName = "PnP Test Site Field";
const string siteFieldGroupName = "PnP Web Extensions Test";
private ClientContext clientContext;

#region Test initialize and cleanup
Expand Down Expand Up @@ -50,9 +53,19 @@ public void Initialize()
};

provisionTemplate.ContentTypes.Add(contentType);

var siteField = new PnP.Framework.Provisioning.Model.Field
{
SchemaXml = $@"<Field Type=""Text"" DisplayName=""{siteFieldName}"" StaticName=""{siteFieldInternalName}"" Name=""{siteFieldInternalName}"" ID=""{{d57adccd-45ab-4fd5-963b-63f39b7d78eb}}"" ShowInViewForms=""FALSE"" Required=""FALSE"" Hidden=""FALSE"" CanToggleHidden=""TRUE"" SourceID=""{{0c70531e-2bfd-4c54-849d-96e88c6b277a}}"" Group=""{siteFieldGroupName}"" />"
};

provisionTemplate.SiteFields.Add(siteField);

TokenParser parser = new TokenParser(clientContext.Web, provisionTemplate);
new ObjectContentType(FieldAndListProvisioningStepHelper.Step.ListAndStandardFields).ProvisionObjects(clientContext.Web, provisionTemplate, parser,
new ProvisioningTemplateApplyingInformation());
new ObjectField(FieldAndListProvisioningStepHelper.Step.ListAndStandardFields).ProvisionObjects(clientContext.Web, provisionTemplate, parser,
new ProvisioningTemplateApplyingInformation());
}

[TestCleanup()]
Expand Down Expand Up @@ -123,6 +136,13 @@ public void Cleanup()
clientContext.ExecuteQueryRetry();
}

var fld = clientContext.Web.GetFieldByInternalName(siteFieldInternalName);
if (fld != null)
{
fld.DeleteObject();
clientContext.ExecuteQueryRetry();
}

bool dirty = false;
clientContext.Load(clientContext.Web.Webs, wc => wc.Include(w => w.Title, w => w.ServerRelativeUrl));
clientContext.ExecuteQueryRetry();
Expand Down Expand Up @@ -475,6 +495,27 @@ public void GetProvisioningTemplateWithSelectedContentTypesTest()
}
}

[TestMethod]
public void GetProvisioningTemplateWithSelectedFieldsTest()
{
using (var clientContext = TestCommon.CreateClientContext())
{
var web = clientContext.Web;

// Arrange
var creationInfo = new ProvisioningTemplateCreationInformation(web);
creationInfo.FieldGroupsToInclude.Add(siteFieldGroupName);
creationInfo.HandlersToProcess = Handlers.Fields;

// Act
var template = web.GetProvisioningTemplate(creationInfo);

// Assert
Assert.AreEqual(1, template.SiteFields.Count);
StringAssert.Equals(siteFieldGroupName, template.SiteFields[0].SchemaXml.ElementAttributeValue("Group"));
}
}

[TestMethod]
public void GetProvisioningTemplateWithOutSelectedContentTypesTest()
{
Expand All @@ -495,6 +536,27 @@ public void GetProvisioningTemplateWithOutSelectedContentTypesTest()
Assert.IsTrue(template.ContentTypes.Count >= 1);
}
}

[TestMethod]
public void GetProvisioningTemplateWithOutSelectedSiteFieldsTest()
{
using (var clientContext = TestCommon.CreateClientContext())
{
var web = clientContext.Web;

// Arrange
var creationInfo = new ProvisioningTemplateCreationInformation(web)
{
HandlersToProcess = Handlers.Fields
};

// Act
var template = web.GetProvisioningTemplate(creationInfo);

// Assert
Assert.IsTrue(template.SiteFields.Count >= 1);
}
}
#endregion

#region NoScript tests
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ public partial class ExtractConfiguration
[JsonPropertyName("contentTypes")]
public ContentTypes.ExtractContentTypeConfiguration ContentTypes { get; set; } = new ContentTypes.ExtractContentTypeConfiguration();

[JsonPropertyName("siteFields")]
public Fields.ExtractFieldsConfiguration SiteFields { get; set; } = new Fields.ExtractFieldsConfiguration();

[JsonPropertyName("searchSettings")]
public SearchSettings.ExtractSearchConfiguration SearchSettings { get; set; } = new SearchSettings.ExtractSearchConfiguration();

Expand Down Expand Up @@ -83,6 +86,7 @@ public static ExtractConfiguration FromCreationInformation(ProvisioningTemplateC
BaseTemplate = information.BaseTemplate
};
config.ContentTypes.Groups = information.ContentTypeGroupsToInclude;
config.SiteFields.Groups = information.FieldGroupsToInclude;
config.Extensibility.Handlers = information.ExtensibilityHandlers;
config.FileConnector = information.FileConnector;
if (information.HandlersToProcess == Model.Handlers.All)
Expand Down Expand Up @@ -162,6 +166,7 @@ public ProvisioningTemplateCreationInformation ToCreationInformation(Web web)
IncludeHiddenLists = this.Lists.IncludeHiddenLists,
IncludeSiteGroups = this.SiteSecurity.IncludeSiteGroups,
ContentTypeGroupsToInclude = this.ContentTypes.Groups,
FieldGroupsToInclude = this.SiteFields.Groups,
IncludeContentTypesFromSyndication = !this.ContentTypes.ExcludeFromSyndication,
IncludeTermGroupsSecurity = this.Taxonomy.IncludeSecurity,
IncludeSiteCollectionTermGroup = this.Taxonomy.IncludeSiteCollectionTermGroup,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace PnP.Framework.Provisioning.Model.Configuration.Fields
{
public class ExtractFieldsConfiguration
{
[JsonPropertyName("groups")]
public List<string> Groups { get; set; } = new List<string>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ private static void CreateField(Web web, XElement templateFieldElement, PnPMonit
// Add newly created field to token set, this allows to create a field + use it in a formula in the same provisioning template
parser.AddToken(new FieldTitleToken(web, field.InternalName, field.Title));
parser.AddToken(new FieldIdToken(web, field.InternalName, field.Id));

bool isDirty = false;

if (originalFieldXml.ContainsResourceToken())
Expand Down Expand Up @@ -526,7 +526,7 @@ public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplat

var existingFields = web.Fields;
web.Context.Load(web, w => w.ServerRelativeUrl);
web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title));
web.Context.Load(existingFields, fs => fs.Include(f => f.Id, f => f.SchemaXml, f => f.TypeAsString, f => f.InternalName, f => f.Title, f => f.Group));
web.Context.Load(web.Lists, ls => ls.Include(l => l.Id, l => l.Title));
web.Context.ExecuteQueryRetry();

Expand All @@ -539,7 +539,8 @@ public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplat
{
currentFieldIndex++;
WriteSubProgress("Field", field.InternalName, currentFieldIndex, fieldsToProcessCount);
if (!BuiltInFieldId.Contains(field.Id))
if (!BuiltInFieldId.Contains(field.Id) &&
(creationInfo.FieldGroupsToInclude.Count == 0 || creationInfo.FieldGroupsToInclude.Contains(field.Group)))
{
var fieldXml = field.SchemaXml;
XElement element = XElement.Parse(fieldXml);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class ProvisioningTemplateCreationInformation
private bool includeSearchConfiguration = false;
private List<String> propertyBagPropertiesToPreserve;
private List<String> contentTypeGroupsToInclude;
private List<string> fieldGroupsToInclude;
private bool persistPublishingFiles = false;
private bool includeNativePublishingFiles = false;
private bool skipVersionCheck = false;
Expand Down Expand Up @@ -53,6 +54,7 @@ public ProvisioningTemplateCreationInformation(Web web)
this.baseTemplate = web.GetBaseTemplate();
this.propertyBagPropertiesToPreserve = new List<String>();
this.contentTypeGroupsToInclude = new List<String>();
this.fieldGroupsToInclude = new List<String>();
}

/// <summary>
Expand Down Expand Up @@ -222,6 +224,15 @@ public List<String> ContentTypeGroupsToInclude
set { this.contentTypeGroupsToInclude = value; }
}

/// <summary>
/// List of site field groups
/// </summary>
public List<string> FieldGroupsToInclude
{
get { return this.fieldGroupsToInclude; }
set { this.fieldGroupsToInclude = value; }
}

/// <summary>
/// if true, includes site groups in the template
/// </summary>
Expand Down