private SiteFooterLink ParseNodes(MenuNode node, ProvisioningTemplate template, string webServerRelativeUrl, bool persistLanguage, CultureInfo currentCulture, string parentKey, ProvisioningTemplateCreationInformation creationInfo) { var link = new SiteFooterLink(); if (persistLanguage) { if (UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{parentKey}_{node.Key}_Title", currentCulture.LCID, node.Title, creationInfo)) { link.DisplayName = $"{{res:FooterNavigationNode_{parentKey}_{node.Key}_Title}}"; } } else { link.DisplayName = node.Title; } link.Url = Tokenize(node.SimpleUrl, webServerRelativeUrl); if (node.Nodes.Count > 0) { link.FooterLinks = new SiteFooterLinkCollection(template); foreach (var childNode in node.Nodes) { link.FooterLinks.Add(ParseNodes(childNode, template, webServerRelativeUrl, persistLanguage, currentCulture, node.Key, creationInfo)); } } return(link); }
private void ParseNodesMUI(MenuNode node, string webServerRelativeUrl, CultureInfo currentCulture, string parentKey, ProvisioningTemplateCreationInformation creationInfo) { UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{parentKey}_{node.Key}_Title", currentCulture.LCID, node.Title, creationInfo); if (node.Nodes.Count > 0) { foreach (var childNode in node.Nodes) { ParseNodesMUI(childNode, webServerRelativeUrl, currentCulture, node.Key, creationInfo); } } }
private CustomAction CopyUserCustomAction(UserCustomAction userCustomAction, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template) { var customAction = new CustomAction(); customAction.Description = userCustomAction.Description; customAction.Enabled = true; customAction.Group = userCustomAction.Group; customAction.ImageUrl = userCustomAction.ImageUrl; customAction.Location = userCustomAction.Location; customAction.Name = userCustomAction.Name; customAction.Rights = userCustomAction.Rights; customAction.ScriptBlock = userCustomAction.ScriptBlock; customAction.ScriptSrc = userCustomAction.ScriptSrc; customAction.Sequence = userCustomAction.Sequence; customAction.Title = userCustomAction.Title; customAction.Url = userCustomAction.Url; customAction.RegistrationId = userCustomAction.RegistrationId; customAction.RegistrationType = userCustomAction.RegistrationType; #if !ONPREMISES customAction.ClientSideComponentId = userCustomAction.ClientSideComponentId; customAction.ClientSideComponentProperties = userCustomAction.ClientSideComponentProperties; #endif customAction.CommandUIExtension = !System.String.IsNullOrEmpty(userCustomAction.CommandUIExtension) ? XElement.Parse(userCustomAction.CommandUIExtension) : null; #if !ONPREMISES if (creationInfo.PersistMultiLanguageResources) { var resourceKey = userCustomAction.Name.Replace(" ", "_"); if (UserResourceExtensions.PersistResourceValue(userCustomAction.TitleResource, $"CustomAction_{resourceKey}_Title", template, creationInfo)) { var customActionTitle = $"{{res:CustomAction_{resourceKey}_Title}}"; customAction.Title = customActionTitle; } if (UserResourceExtensions.PersistResourceValue(userCustomAction.DescriptionResource, $"CustomAction_{resourceKey}_Description", template, creationInfo)) { var customActionDescription = $"{{res:CustomAction_{resourceKey}_Description}}"; customAction.Description = customActionDescription; } } #endif return(customAction); }
private static CustomAction CopyUserCustomAction(UserCustomAction userCustomAction, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template) { var customAction = new CustomAction { Description = userCustomAction.Description, Enabled = true, Group = userCustomAction.Group, ImageUrl = userCustomAction.ImageUrl, Location = userCustomAction.Location, Name = userCustomAction.Name, Rights = userCustomAction.Rights, ScriptBlock = userCustomAction.ScriptBlock, ScriptSrc = userCustomAction.ScriptSrc, Sequence = userCustomAction.Sequence, Title = userCustomAction.Title, Url = userCustomAction.Url, RegistrationId = userCustomAction.RegistrationId, RegistrationType = userCustomAction.RegistrationType, ClientSideComponentId = userCustomAction.ClientSideComponentId, ClientSideComponentProperties = userCustomAction.ClientSideComponentProperties, CommandUIExtension = !System.String.IsNullOrEmpty(userCustomAction.CommandUIExtension) ? XElement.Parse(userCustomAction.CommandUIExtension) : null }; if (creationInfo.PersistMultiLanguageResources) { var resourceKey = userCustomAction.Name.Replace(" ", "_"); if (UserResourceExtensions.PersistResourceValue(userCustomAction.TitleResource, $"CustomAction_{resourceKey}_Title", template, creationInfo)) { var customActionTitle = $"{{res:CustomAction_{resourceKey}_Title}}"; customAction.Title = customActionTitle; } if (!string.IsNullOrWhiteSpace(userCustomAction.Description) && UserResourceExtensions.PersistResourceValue(userCustomAction.DescriptionResource, $"CustomAction_{resourceKey}_Description", template, creationInfo)) { var customActionDescription = $"{{res:CustomAction_{resourceKey}_Description}}"; customAction.Description = customActionDescription; } } return(customAction); }
internal static Model.NavigationNode ToDomainModelNavigationNode(this Microsoft.SharePoint.Client.NavigationNode node, Web web, bool PersistLanguage, CultureInfo currentCulture, int ParentNodeId = 0) { string nodeTitle = node.Title; #if !SP2013 if (PersistLanguage && !string.IsNullOrWhiteSpace(nodeTitle)) { if (UserResourceExtensions.PersistResourceValue($"NavigationNode_{ParentNodeId}_{node.Id}_Title", currentCulture.LCID, nodeTitle)) { nodeTitle = $"{{res:NavigationNode_{ParentNodeId}_{node.Id}_Title}}"; } } #endif var result = new Model.NavigationNode { Title = nodeTitle, IsExternal = node.IsExternal, Url = web.ServerRelativeUrl != "/" ? node.Url.Replace(web.ServerRelativeUrl, "{site}") : $"{{site}}{node.Url}" }; node.Context.Load(node.Children); #if !SP2013 var acceptLanguage = node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"]; if (PersistLanguage) { node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = currentCulture.Name; } #endif node.Context.ExecuteQueryRetry(); result.NavigationNodes.AddRange(from n in node.Children.AsEnumerable() select n.ToDomainModelNavigationNode(web, PersistLanguage, currentCulture, node.Id)); #if !SP2013 if (PersistLanguage) { node.Context.PendingRequest.RequestExecutor.WebRequest.Headers["Accept-Language"] = acceptLanguage; } #endif return(result); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not creating field entities. if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns); return(template); } 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(web.Lists, ls => ls.Include(l => l.Id, l => l.Title)); web.Context.ExecuteQueryRetry(); var taxTextFieldsToMoveUp = new List <Guid>(); var calculatedFieldsToMoveDown = new List <Guid>(); var currentFieldIndex = 0; var fieldsToProcessCount = existingFields.Count; foreach (var field in existingFields) { currentFieldIndex++; WriteMessage($"Field|{field.InternalName}|{currentFieldIndex}|{fieldsToProcessCount}", ProvisioningMessageType.Progress); if (!BuiltInFieldId.Contains(field.Id)) { var fieldXml = field.SchemaXml; XElement element = XElement.Parse(fieldXml); // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths var listIdentifier = element.Attribute("List") != null?element.Attribute("List").Value : null; if (!string.IsNullOrEmpty(listIdentifier)) { //var listGuid = Guid.Empty; fieldXml = ParseFieldSchema(fieldXml, web.Lists); element = XElement.Parse(fieldXml); //if (Guid.TryParse(listIdentifier, out listGuid)) //{ // fieldXml = ParseListSchema(fieldXml, web.Lists); //if (newfieldXml == fieldXml) //{ // var list = web.Lists.GetById(listGuid); // web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl); // web.Context.ExecuteQueryRetry(); // var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/'); // element.Attribute("List").SetValue(listUrl); // fieldXml = element.ToString(); //} //} } // Check if the field is of type TaxonomyField if (field.TypeAsString.StartsWith("TaxonomyField")) { var taxField = (TaxonomyField)field; web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id); web.Context.ExecuteQueryRetry(); taxTextFieldsToMoveUp.Add(taxField.TextField); fieldXml = TokenizeTaxonomyField(web, element); } // Check if we have version attribute. Remove if exists if (element.Attribute("Version") != null) { element.Attributes("Version").Remove(); fieldXml = element.ToString(); } if (element.Attribute("Type").Value == "Calculated") { fieldXml = TokenizeFieldFormula(web.Fields, (FieldCalculated)field, fieldXml); calculatedFieldsToMoveDown.Add(field.Id); } if (creationInfo.PersistMultiLanguageResources) { #if !SP2013 // only persist language values for fields we actually will keep...no point in spending time on this is we clean the field afterwards bool persistLanguages = true; if (creationInfo.BaseTemplate != null) { int index = creationInfo.BaseTemplate.SiteFields.FindIndex(f => Guid.Parse(XElement.Parse(f.SchemaXml).Attribute("ID").Value).Equals(field.Id)); if (index > -1) { persistLanguages = false; } } if (persistLanguages) { var fieldElement = XElement.Parse(fieldXml); var escapedFieldTitle = field.Title.Replace(" ", "_"); if (UserResourceExtensions.PersistResourceValue(field.TitleResource, $"Field_{escapedFieldTitle}_DisplayName", template, creationInfo)) { var fieldTitle = $"{{res:Field_{escapedFieldTitle}_DisplayName}}"; fieldElement.SetAttributeValue("DisplayName", fieldTitle); } if (UserResourceExtensions.PersistResourceValue(field.DescriptionResource, $"Field_{escapedFieldTitle}_Description", template, creationInfo)) { var fieldDescription = $"{{res:Field_{escapedFieldTitle}_Description}}"; fieldElement.SetAttributeValue("Description", fieldDescription); } fieldXml = fieldElement.ToString(); } #endif } template.SiteFields.Add(new Field() { SchemaXml = fieldXml }); } } // move hidden taxonomy text fields to the top of the list foreach (var textFieldId in taxTextFieldsToMoveUp) { var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.Insert(0, field); } // move calculated fields to the bottom of the list // this will not be sufficient in the case of a calculated field is referencing another calculated field foreach (var calculatedFieldId in calculatedFieldsToMoveDown) { var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(calculatedFieldId)); template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(calculatedFieldId)); template.SiteFields.Add(field); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } WriteMessage($"Done processing fields", ProvisioningMessageType.Completed); return(template); }
private IEnumerable <ContentType> GetEntities(Web web, PnPMonitoredScope scope, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template) { var cts = web.ContentTypes; web.Context.Load(cts, ctCollection => ctCollection.IncludeWithDefaultProperties(ct => ct.FieldLinks)); web.Context.ExecuteQueryRetry(); if (cts.Count > 0 && web.IsSubSite()) { WriteMessage("We discovered content types in this subweb. While technically possible, we recommend moving these content types to the root site collection. Consider excluding them from this template.", ProvisioningMessageType.Warning); } List <ContentType> ctsToReturn = new List <ContentType>(); var currentCtIndex = 0; foreach (var ct in cts) { currentCtIndex++; WriteMessage($"Content Type|{ct.Name}|{currentCtIndex}|{cts.Count()}", ProvisioningMessageType.Progress); if (!BuiltInContentTypeId.Contains(ct.StringId) && (creationInfo.ContentTypeGroupsToInclude.Count == 0 || creationInfo.ContentTypeGroupsToInclude.Contains(ct.Group))) { string ctDocumentTemplate = null; if (!string.IsNullOrEmpty(ct.DocumentTemplate)) { if (!ct.DocumentTemplate.StartsWith("_cts/")) { ctDocumentTemplate = ct.DocumentTemplate; } } var newCT = new ContentType( ct.StringId, ct.Name, ct.Description, ct.Group, ct.Sealed, ct.Hidden, ct.ReadOnly, ctDocumentTemplate, false, (from fieldLink in ct.FieldLinks.AsEnumerable <FieldLink>() select new FieldRef(fieldLink.Name) { Id = fieldLink.Id, Hidden = fieldLink.Hidden, Required = fieldLink.Required, }) ) { DisplayFormUrl = ct.DisplayFormUrl, EditFormUrl = ct.EditFormUrl, NewFormUrl = ct.NewFormUrl, }; if (creationInfo.PersistMultiLanguageResources) { #if !SP2013 // only persist language values for content types we actually will keep...no point in spending time on this is we clean the field afterwards var persistLanguages = true; if (creationInfo.BaseTemplate != null) { int index = creationInfo.BaseTemplate.ContentTypes.FindIndex(c => c.Id.Equals(ct.StringId)); if (index > -1) { persistLanguages = false; } } if (persistLanguages) { var escapedCTName = ct.Name.Replace(" ", "_"); if (UserResourceExtensions.PersistResourceValue(ct.NameResource, $"ContentType_{escapedCTName}_Title", template, creationInfo)) { newCT.Name = $"{{res:ContentType_{escapedCTName}_Title}}"; } if (UserResourceExtensions.PersistResourceValue(ct.DescriptionResource, $"ContentType_{escapedCTName}_Description", template, creationInfo)) { newCT.Description = $"{{res:ContentType_{escapedCTName}_Description}}"; } } #endif } // If the Content Type is a DocumentSet if (Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.IsChildOfDocumentSetContentType(web.Context, ct).Value || ct.StringId.StartsWith(BuiltInContentTypeId.DocumentSet)) // TODO: This is kind of an hack... we should find a better solution ... { Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate = Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, ct); // Retrieve the Document Set web.Context.Load(documentSetTemplate, t => t.AllowedContentTypes, t => t.DefaultDocuments, t => t.SharedFields, t => t.WelcomePageFields); web.Context.ExecuteQueryRetry(); newCT.DocumentSetTemplate = new DocumentSetTemplate( null, // TODO: WelcomePage not yet supported (from allowedCT in documentSetTemplate.AllowedContentTypes.AsEnumerable() select allowedCT.StringValue).ToArray(), (from defaultDocument in documentSetTemplate.DefaultDocuments.AsEnumerable() select new DefaultDocument { ContentTypeId = defaultDocument.ContentTypeId.StringValue, Name = defaultDocument.Name, FileSourcePath = String.Empty, // TODO: How can we extract the proper file?! }).ToArray(), (from sharedField in documentSetTemplate.SharedFields.AsEnumerable() select sharedField.Id).ToArray(), (from welcomePageField in documentSetTemplate.WelcomePageFields.AsEnumerable() select welcomePageField.Id).ToArray() ); } ctsToReturn.Add(newCT); } } WriteMessage("Done processing Content Types", ProvisioningMessageType.Completed); return(ctsToReturn); }
private IEnumerable <ContentType> GetEntities(Web web, PnPMonitoredScope scope, ProvisioningTemplateCreationInformation creationInfo, ProvisioningTemplate template) { var cts = web.ContentTypes; web.Context.Load(cts, ctCollection => ctCollection.IncludeWithDefaultProperties(ct => ct.FieldLinks)); web.Context.ExecuteQueryRetry(); List <ContentType> ctsToReturn = new List <ContentType>(); foreach (var ct in cts) { if (!BuiltInContentTypeId.Contains(ct.StringId)) { ContentType newCT = new ContentType (ct.StringId, ct.Name, ct.Description, ct.Group, ct.Sealed, ct.Hidden, ct.ReadOnly, ct.DocumentTemplate, false, (from fieldLink in ct.FieldLinks.AsEnumerable <FieldLink>() select new FieldRef(fieldLink.Name) { Id = fieldLink.Id, Hidden = fieldLink.Hidden, Required = fieldLink.Required, }) ) { DisplayFormUrl = ct.DisplayFormUrl, EditFormUrl = ct.EditFormUrl, NewFormUrl = ct.NewFormUrl, }; if (creationInfo.PersistMultiLanguageResources) { #if !SP2013 if (UserResourceExtensions.PersistResourceValue(ct.NameResource, string.Format("ContentType_{0}_Title", ct.Name.Replace(" ", "_")), template, creationInfo)) { newCT.Name = string.Format("{{res:ContentType_{0}_Title}}", ct.Name.Replace(" ", "_")); } if (UserResourceExtensions.PersistResourceValue(ct.DescriptionResource, string.Format("ContentType_{0}_Description", ct.Name.Replace(" ", "_")), template, creationInfo)) { newCT.Description = string.Format("{{res:ContentType_{0}_Description}}", ct.Name.Replace(" ", "_")); } #endif } // If the Content Type is a DocumentSet if (Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.IsChildOfDocumentSetContentType(web.Context, ct).Value || ct.StringId.StartsWith(BuiltInContentTypeId.DocumentSet)) // TODO: This is kind of an hack... we should find a better solution ... { Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate documentSetTemplate = Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate.GetDocumentSetTemplate(web.Context, ct); // Retrieve the Document Set web.Context.Load(documentSetTemplate, t => t.AllowedContentTypes, t => t.DefaultDocuments, t => t.SharedFields, t => t.WelcomePageFields); web.Context.ExecuteQueryRetry(); newCT.DocumentSetTemplate = new DocumentSetTemplate( null, // TODO: WelcomePage not yet supported (from allowedCT in documentSetTemplate.AllowedContentTypes.AsEnumerable() select allowedCT.StringValue).ToArray(), (from defaultDocument in documentSetTemplate.DefaultDocuments.AsEnumerable() select new DefaultDocument { ContentTypeId = defaultDocument.ContentTypeId.StringValue, Name = defaultDocument.Name, FileSourcePath = String.Empty, // TODO: How can we extract the proper file?! }).ToArray(), (from sharedField in documentSetTemplate.SharedFields.AsEnumerable() select sharedField.Id).ToArray(), (from welcomePageField in documentSetTemplate.WelcomePageFields.AsEnumerable() select welcomePageField.Id).ToArray() ); } ctsToReturn.Add(newCT); } } return(ctsToReturn); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { web.EnsureProperties(w => w.FooterEnabled, w => w.ServerRelativeUrl, w => w.Url, w => w.Language); var defaultCulture = new CultureInfo((int)web.Language); var footer = new SiteFooter { Enabled = web.FooterEnabled }; var structureString = web.ExecuteGetAsync($"/_api/navigation/MenuState?menuNodeKey='{Constants.SITEFOOTER_NODEKEY}'", defaultCulture.Name).GetAwaiter().GetResult(); var menuState = JsonConvert.DeserializeObject <MenuState>(structureString); if (menuState.Nodes.Count > 0) { // Find the title node var titleNode = menuState.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_TITLENODEKEY); if (titleNode != null) { var titleNodeNodes = titleNode.Nodes; if (titleNodeNodes.Count > 0) { if (!string.IsNullOrEmpty(titleNodeNodes[0].SimpleUrl)) { footer.Logo = Tokenize(titleNodeNodes[0].SimpleUrl, web.ServerRelativeUrl); } if (!string.IsNullOrEmpty(titleNodeNodes[0].Title)) { if (creationInfo.PersistMultiLanguageResources) { if (UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title", defaultCulture.LCID, titleNodeNodes[0].Title, creationInfo)) { footer.Name = $"{{res:FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title}}"; } } else { footer.Name = titleNodeNodes[0].Title; } } } } // find the logo node if (string.IsNullOrEmpty(footer.Logo)) { var logoNode = menuState.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_LOGONODEKEY); if (logoNode != null) { footer.Logo = Tokenize(logoNode.SimpleUrl, web.ServerRelativeUrl); } } } // find the menu Nodes var menuNodesNode = menuState.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_MENUNODEKEY); if (menuNodesNode != null) { foreach (var innerMenuNode in menuNodesNode.Nodes) { footer.FooterLinks.Add(ParseNodes(innerMenuNode, template, web.ServerRelativeUrl, creationInfo.PersistMultiLanguageResources, defaultCulture, menuNodesNode.Key, creationInfo)); } } if (creationInfo.ExtractConfiguration != null && creationInfo.ExtractConfiguration.SiteFooter != null && creationInfo.ExtractConfiguration.SiteFooter.RemoveExistingNodes) { footer.RemoveExistingNodes = true; } if (creationInfo.PersistMultiLanguageResources) { //get Titles for the rest of the Languages foreach (var language in template.SupportedUILanguages.Where(c => c.LCID != defaultCulture.LCID)) { var currentCulture = new CultureInfo(language.LCID); var structureStringMUI = web.ExecuteGetAsync($"/_api/navigation/MenuState?menuNodeKey='{Constants.SITEFOOTER_NODEKEY}'", currentCulture.Name).GetAwaiter().GetResult(); var menuStateMUI = JsonConvert.DeserializeObject <MenuState>(structureStringMUI); if (menuStateMUI.Nodes.Count > 0) { var titleNode = menuStateMUI.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_TITLENODEKEY); if (titleNode != null) { var titleNodeNodes = titleNode.Nodes; if (titleNodeNodes.Count > 0) { if (!string.IsNullOrEmpty(titleNodeNodes[0].Title)) { if (UserResourceExtensions.PersistResourceValue($"FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title", currentCulture.LCID, titleNodeNodes[0].Title, creationInfo)) { footer.Name = $"{{res:FooterNavigationNode_{titleNode.Key}_{titleNodeNodes[0].Key}_Title}}"; } } } } } // find the menu Nodes var menuNodesNodeMUI = menuStateMUI.Nodes.FirstOrDefault(n => n.Title == Constants.SITEFOOTER_MENUNODEKEY); if (menuNodesNodeMUI != null) { foreach (var innerMenuNode in menuNodesNodeMUI.Nodes) { ParseNodesMUI(innerMenuNode, web.ServerRelativeUrl, currentCulture, menuNodesNode.Key, creationInfo); } } } } template.Footer = footer; if (creationInfo.PersistBrandingFiles) { // Extract site logo if property has been set and it's not dynamic image from _api URL if (!string.IsNullOrEmpty(template.Footer.Logo) && (!template.Footer.Logo.ToLowerInvariant().Contains("_api/"))) { // Convert to server relative URL if needed (can be set to FQDN URL of a file hosted in the site (e.g. for communication sites)) Uri webUri = new Uri(web.Url); string webUrl = $"{webUri.Scheme}://{webUri.DnsSafeHost}"; string footerLogoServerRelativeUrl = template.Footer.Logo.Replace(webUrl, ""); if (PersistFile(web, creationInfo, scope, footerLogoServerRelativeUrl)) { template.Files.Add(GetTemplateFile(web, footerLogoServerRelativeUrl)); } } template.Footer.Logo = Tokenize(template.Footer.Logo, web.Url, web); var files = template.Files.Distinct().ToList(); template.Files.Clear(); template.Files.AddRange(files); } } return(template); }
public override ProvisioningTemplate ExtractObjects(Web web, ProvisioningTemplate template, ProvisioningTemplateCreationInformation creationInfo) { using (var scope = new PnPMonitoredScope(this.Name)) { // if this is a sub site then we're not creating field entities. if (web.IsSubSite()) { scope.LogDebug(CoreResources.Provisioning_ObjectHandlers_Fields_Context_web_is_subweb__skipping_site_columns); return(template); } 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(web.Lists, ls => ls.Include(l => l.Id, l => l.Title)); web.Context.ExecuteQueryRetry(); var taxTextFieldsToMoveUp = new List <Guid>(); foreach (var field in existingFields) { if (!BuiltInFieldId.Contains(field.Id)) { var fieldXml = field.SchemaXml; XElement element = XElement.Parse(fieldXml); // Check if the field contains a reference to a list. If by Guid, rewrite the value of the attribute to use web relative paths var listIdentifier = element.Attribute("List") != null?element.Attribute("List").Value : null; if (!string.IsNullOrEmpty(listIdentifier)) { var listGuid = Guid.Empty; fieldXml = ParseFieldSchema(fieldXml, web.Lists); element = XElement.Parse(fieldXml); //if (Guid.TryParse(listIdentifier, out listGuid)) //{ // fieldXml = ParseListSchema(fieldXml, web.Lists); //if (newfieldXml == fieldXml) //{ // var list = web.Lists.GetById(listGuid); // web.Context.Load(list, l => l.RootFolder.ServerRelativeUrl); // web.Context.ExecuteQueryRetry(); // var listUrl = list.RootFolder.ServerRelativeUrl.Substring(web.ServerRelativeUrl.Length).TrimStart('/'); // element.Attribute("List").SetValue(listUrl); // fieldXml = element.ToString(); //} //} } // Check if the field is of type TaxonomyField if (field.TypeAsString.StartsWith("TaxonomyField")) { var taxField = (TaxonomyField)field; web.Context.Load(taxField, tf => tf.TextField, tf => tf.Id); web.Context.ExecuteQueryRetry(); taxTextFieldsToMoveUp.Add(taxField.TextField); fieldXml = TokenizeTaxonomyField(web, element); } // Check if we have version attribute. Remove if exists if (element.Attribute("Version") != null) { element.Attributes("Version").Remove(); fieldXml = element.ToString(); } if (element.Attribute("Type").Value == "Calculated") { fieldXml = TokenizeFieldFormula(fieldXml); } if (creationInfo.PersistMultiLanguageResources) { #if !SP2013 var fieldElement = XElement.Parse(fieldXml); if (UserResourceExtensions.PersistResourceValue(field.TitleResource, string.Format("Field_{0}_DisplayName", field.Title.Replace(" ", "_")), template, creationInfo)) { var fieldTitle = string.Format("{{res:Field_{0}_DisplayName}}", field.Title.Replace(" ", "_")); fieldElement.SetAttributeValue("DisplayName", fieldTitle); } if (UserResourceExtensions.PersistResourceValue(field.DescriptionResource, string.Format("Field_{0}_Description", field.Title.Replace(" ", "_")), template, creationInfo)) { var fieldDescription = string.Format("{{res:Field_{0}_Description}}", field.Title.Replace(" ", "_")); fieldElement.SetAttributeValue("Description", fieldDescription); } fieldXml = fieldElement.ToString(); #endif } template.SiteFields.Add(new Field() { SchemaXml = fieldXml }); } } // move hidden taxonomy text fields to the top of the list foreach (var textFieldId in taxTextFieldsToMoveUp) { var field = template.SiteFields.First(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.RemoveAll(f => Guid.Parse(f.SchemaXml.ElementAttributeValue("ID")).Equals(textFieldId)); template.SiteFields.Insert(0, field); } // If a base template is specified then use that one to "cleanup" the generated template model if (creationInfo.BaseTemplate != null) { template = CleanupEntities(template, creationInfo.BaseTemplate); } } return(template); }