public static string GetWebPartPageTemplateContent(WebPartPageDefinition webPartPageModel)
        {
            // gosh! would u like to offer a better way?
            switch (webPartPageModel.PageLayoutTemplate)
            {
                case 1:
                    return WebPartPageTemplates.spstd1;
                case 2:
                    return WebPartPageTemplates.spstd2;
                case 3:
                    return WebPartPageTemplates.spstd3;
                case 4:
                    return WebPartPageTemplates.spstd4;
                case 5:
                    return WebPartPageTemplates.spstd5;
                case 6:
                    return WebPartPageTemplates.spstd6;
                case 7:
                    return WebPartPageTemplates.spstd7;
                case 8:
                    return WebPartPageTemplates.spstd8;
            }

            throw new Exception(string.Format("PageLayoutTemplate: [{0}] is not supported.", webPartPageModel.PageLayoutTemplate));
        }
        protected SPListItem FindWebPartPage(SPFolder folder, WebPartPageDefinition webpartPageModel)
        {
            var webPartPageName = GetSafeWebPartPageFileName(webpartPageModel);

            if (!webPartPageName.EndsWith(".aspx"))
                webPartPageName += ".aspx";

            foreach (SPFile file in folder.Files)
                if (file.Name.ToUpper() == webPartPageName.ToUpper())
                    return file.Item;

            return null;
        }
        public virtual string GetWebPartPageTemplateContent(WebPartPageDefinition webPartPageModel)
        {
            // TODO, add support for SP2016
            // Built-in web part page templates should be correctly resolved for SP2010/2013 #683

            var spRuntimeVersion = typeof(SPField).Assembly.GetName().Version;

            if (spRuntimeVersion.Major == 14)
            {
                return GetSP2010WebPartPageTemplateContent(webPartPageModel);
            }

            if (spRuntimeVersion.Major == 15)
            {
                return GetSP2013WebPartPageTemplateContent(webPartPageModel);
            }

            throw new Exception(string.Format("PageLayoutTemplate: [{0}] is not supported.", webPartPageModel.PageLayoutTemplate));
        }
        public override ModelNode ReverseSingleHost(object reverseHost, ReverseOptions options)
        {
            var item = (reverseHost as WebPartPageReverseHost).HostWebPartPageFile;
            var context = (reverseHost as WebPartPageReverseHost).HostClientContext;

            var def = new WebPartPageDefinition();

            def.FileName = item.Name;
            def.Title = item.Title;

            // always reverse to CustomPageLayout
            // we don't know what is the content of the web part page
            using (var stream = File.OpenBinaryDirect(
                context,
                item.ServerRelativeUrl).Stream)
            {
                def.CustomPageLayout = Encoding.UTF8.GetString(ModuleFileUtils.ReadFully(stream));
            }

            def.NeedOverride = true;

            return new WebPartPageModelNode
            {
                Options = { RequireSelfProcessing = true },
                Value = def
            };
        }
        protected string GetSafeWebPartPageFileName(WebPartPageDefinition webpartPageModel)
        {
            var webPartPageName = webpartPageModel.FileName;

            if (!webPartPageName.EndsWith(".aspx"))
                webPartPageName += ".aspx";

            return webPartPageName;
        }
 protected virtual string GetWebPartTemplateContent(WebPartPageDefinition webPartPageModel)
 {
     return GetWebPartPageTemplateContent(webPartPageModel);
 }
        private SPListItem GetOrCreateNewWebPartPage(object modelHost, SPFolder folder,
            WebPartPageDefinition webpartPageModel)
        {
            var targetPage = FindWebPartPage(folder, webpartPageModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = targetPage == null ? null : targetPage.File,
                ObjectType = typeof(SPFile),
                ObjectDefinition = webpartPageModel,
                ModelHost = modelHost
            });

            if (targetPage == null || webpartPageModel.NeedOverride)
            {
                if (webpartPageModel.NeedOverride)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing web part page");
                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "NeedOverride = true. Replacing web part page.");
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new web part page");
                }

                var webPartPageName = GetSafeWebPartPageFileName(webpartPageModel);

                byte[] fileContent = null;

                if (!string.IsNullOrEmpty(webpartPageModel.CustomPageLayout))
                {
                    fileContent = Encoding.UTF8.GetBytes(webpartPageModel.CustomPageLayout);
                }
                else
                {
                    fileContent = Encoding.UTF8.GetBytes(GetWebPartTemplateContent(webpartPageModel));
                }

                ModuleFileModelHandler.DeployModuleFile(folder,
                  SPUrlUtility.CombineUrl(folder.ServerRelativeUrl, webPartPageName),
                  webPartPageName,
                  fileContent,
                  true,
                    file =>
                    {
                        InvokeOnModelEvent(this, new ModelEventArgs
                        {
                            CurrentModelNode = null,
                            Model = null,
                            EventType = ModelEventType.OnProvisioned,
                            Object = file,
                            ObjectType = typeof(SPFile),
                            ObjectDefinition = webpartPageModel,
                            ModelHost = modelHost
                        });
                    },
                  null);

                targetPage = FindWebPartPage(folder, webpartPageModel);
            }
            else
            {
                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing web part page");
                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "NeedOverride = false. Skipping replacing web part page.");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = targetPage == null ? null : targetPage.File,
                    ObjectType = typeof(SPFile),
                    ObjectDefinition = webpartPageModel,
                    ModelHost = modelHost
                });

                targetPage.Update();
            }

            return targetPage;
        }
        public void Deploy_WebParts()
        {
            // Step 1, define security groups
            var gettingStarted = new SPMeta2.Definitions.WebPartDefinition
            {
                Title = "Getting started with site",
                Id = "spmGettingStarted",
                ZoneId = "Main",
                ZoneIndex = 100,
                WebpartXmlTemplate = ResourceReader.ReadFromResourceName("Templates.Webparts.Get started with your site.webpart")
            };

            var contentEditor = new SPMeta2.Definitions.WebPartDefinition
            {
                Title = "SPMeta2 Content Editor Webpart",
                Id = "spmContentEditorWebpart",
                ZoneId = "Main",
                ZoneIndex = 200,
                WebpartXmlTemplate = ResourceReader.ReadFromResourceName("Templates.Webparts.Content Editor.dwp")
            };

            var webpartPage = new WebPartPageDefinition
            {
                Title = "Getting started",
                FileName = "Getting-Started.aspx",
                PageLayoutTemplate = BuiltInWebPartPageTemplates.spstd1
            };

            // Step 2, define web model and artifact relationships - add security groups t the web 
            var model = SPMeta2Model
                             .NewWebModel(web =>
                             {
                                 web
                                   .AddList(BuiltInListDefinitions.SitePages, list =>
                                   {
                                       list
                                           .AddWebPartPage(webpartPage, page =>
                                           {
                                               page
                                                   .AddWebPart(gettingStarted)
                                                   .AddWebPart(contentEditor);
                                           });
                                   });
                             });

            // Step 3, deploy model
            DeployWebModel(model);
        }
        public void Deploy_WebPartPages()
        {
            // Step 1, define security groups
            var sales = new WebPartPageDefinition
            {
                Title = "Sales Dashboard",
                FileName = "Sales-Dashboard.aspx",
                PageLayoutTemplate = BuiltInWebPartPageTemplates.spstd1
            };

            var ratings = new WebPartPageDefinition
            {
                Title = "Ratings Dashboard",
                FileName = "Ratings-Dashboard.aspx",
                PageLayoutTemplate = BuiltInWebPartPageTemplates.spstd2
            };

            var performance = new WebPartPageDefinition
            {
                Title = "Performance Dashboard",
                FileName = "Performance-Dashboard.aspx",
                PageLayoutTemplate = BuiltInWebPartPageTemplates.spstd3
            };

            // Step 2, define web model and artifact relationships - add security groups t the web 
            var model = SPMeta2Model
                             .NewWebModel(web =>
                             {
                                 web
                                   .AddList(BuiltInListDefinitions.SitePages, list =>
                                   {
                                       list
                                           .AddWebPartPage(sales)
                                           .AddWebPartPage(ratings)
                                           .AddWebPartPage(performance);
                                   });
                             });

            // Step 3, deploy model
            DeployWebModel(model);
        }
        protected virtual string GetSP2013WebPartPageTemplateContent(WebPartPageDefinition webPartPageModel)
        {
            switch (webPartPageModel.PageLayoutTemplate)
            {
                case 1:
                    return SP2013WebPartPageTemplates.spstd1;
                case 2:
                    return SP2013WebPartPageTemplates.spstd2;
                case 3:
                    return SP2013WebPartPageTemplates.spstd3;
                case 4:
                    return SP2013WebPartPageTemplates.spstd4;
                case 5:
                    return SP2013WebPartPageTemplates.spstd5;
                case 6:
                    return SP2013WebPartPageTemplates.spstd6;
                case 7:
                    return SP2013WebPartPageTemplates.spstd7;
                case 8:
                    return SP2013WebPartPageTemplates.spstd8;
            }

            throw new Exception(string.Format("PageLayoutTemplate: [{0}] is not supported.", webPartPageModel.PageLayoutTemplate));
        }
        protected SPListItem FindWebPartPage(SPList list, WebPartPageDefinition webpartPageModel)
        {
            var webPartPageName = GetSafeWebPartPageFileName(webpartPageModel);

            if (!webPartPageName.EndsWith(".aspx"))
                webPartPageName += ".aspx";

            return list.Items.OfType<SPListItem>().FirstOrDefault(i => string.Compare(i.Name, webPartPageName, true) == 0);
        }
        private SPListItem GetOrCreateNewWebPartPage(SPList list, 
            WebPartPageDefinition webpartPageModel)
        {
            var targetPage = FindWebPartPage(list, webpartPageModel);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = targetPage == null ? null : targetPage.File,
                ObjectType = typeof(SPFile),
                ObjectDefinition = webpartPageModel,
                ModelHost = list
            });

            if (targetPage == null || webpartPageModel.NeedOverride)
            {
                var webPartPageName = GetSafeWebPartPageFileName(webpartPageModel);

                // web part page name has to be without .aspx extensions in xmlCmd for ProcessBatchData method!
                var xmlCmd = string.Format(WebPartPageCmdTemplate,
                                   new object[]{
                                            list.ID.ToString(),
                                            Path.GetFileNameWithoutExtension(webPartPageName),
                                            (int)webpartPageModel.PageLayoutTemplate,
                                            webpartPageModel.NeedOverride.ToString().ToLower()});

                var result = list.ParentWeb.ProcessBatchData(xmlCmd);

                // TODO. analyse the result
                // <Result ID="0, NewWebPage" Code="0"></Result>

                targetPage = FindWebPartPage(list, webpartPageModel);
            }

            return targetPage;
        }
        private SPFile GetOrCreateNewWebPartFile(object modelHost, SPFolder folder,
            WebPartPageDefinition definition)
        {
            var list = folder.DocumentLibrary;
            var targetFile = FindWebPartPage(folder, definition);

            InvokeOnModelEvent(this, new ModelEventArgs
            {
                CurrentModelNode = null,
                Model = null,
                EventType = ModelEventType.OnProvisioning,
                Object = targetFile,
                ObjectType = typeof(SPFile),
                ObjectDefinition = definition,
                ModelHost = modelHost
            });

            if (targetFile == null || definition.NeedOverride)
            {
                if (definition.NeedOverride)
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing web part page");
                    TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "NeedOverride = true. Replacing web part page.");
                }
                else
                {
                    TraceService.Information((int)LogEventId.ModelProvisionProcessingNewObject, "Processing new web part page");
                }

                var webPartPageName = GetSafeWebPartPageFileName(definition);

                byte[] fileContent = null;

                if (!string.IsNullOrEmpty(definition.CustomPageLayout))
                {
                    fileContent = Encoding.UTF8.GetBytes(definition.CustomPageLayout);
                }
                else
                {
                    fileContent = Encoding.UTF8.GetBytes(GetWebPartPageTemplateContent(definition));
                }

                ModuleFileModelHandler.DeployModuleFile(folder,
                  SPUrlUtility.CombineUrl(folder.ServerRelativeUrl, webPartPageName),
                  webPartPageName,
                  fileContent,
                  true,
                    file =>
                    {

                    },
                    after =>
                    {
                        FieldLookupService.EnsureDefaultValues(after.ListItemAllFields, definition.DefaultValues);

                        if (!string.IsNullOrEmpty(definition.ContentTypeId) ||
                           !string.IsNullOrEmpty(definition.ContentTypeName))
                        {
                            if (!string.IsNullOrEmpty(definition.ContentTypeId))
                                after.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupListContentTypeById(list, definition.ContentTypeId);

                            if (!string.IsNullOrEmpty(definition.ContentTypeName))
                                after.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupContentTypeByName(list, definition.ContentTypeName);
                        }

                        FieldLookupService.EnsureValues(after.ListItemAllFields, definition.Values, true);

                        if (definition.DefaultValues.Any()
                            || definition.Values.Any()
                            || !string.IsNullOrEmpty(definition.ContentTypeId)
                            || !string.IsNullOrEmpty(definition.ContentTypeName))
                        {
                            after.ListItemAllFields.Update();
                        }

                        InvokeOnModelEvent(this, new ModelEventArgs
                        {
                            CurrentModelNode = null,
                            Model = null,
                            EventType = ModelEventType.OnProvisioned,
                            Object = after,
                            ObjectType = typeof(SPFile),
                            ObjectDefinition = definition,
                            ModelHost = modelHost
                        });
                    });

                targetFile = FindWebPartPage(folder, definition);
            }
            else
            {
                FieldLookupService.EnsureDefaultValues(targetFile.ListItemAllFields, definition.DefaultValues);

                if (!string.IsNullOrEmpty(definition.ContentTypeId) ||
                !string.IsNullOrEmpty(definition.ContentTypeName))
                {
                    if (!string.IsNullOrEmpty(definition.ContentTypeId))
                        targetFile.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupListContentTypeById(list, definition.ContentTypeId);

                    if (!string.IsNullOrEmpty(definition.ContentTypeName))
                        targetFile.ListItemAllFields["ContentTypeId"] = ContentTypeLookupService.LookupContentTypeByName(list, definition.ContentTypeName);
                }

                TraceService.Information((int)LogEventId.ModelProvisionProcessingExistingObject, "Processing existing web part page");
                TraceService.Verbose((int)LogEventId.ModelProvisionCoreCall, "NeedOverride = false. Skipping replacing web part page.");

                InvokeOnModelEvent(this, new ModelEventArgs
                {
                    CurrentModelNode = null,
                    Model = null,
                    EventType = ModelEventType.OnProvisioned,
                    Object = targetFile,
                    ObjectType = typeof(SPFile),
                    ObjectDefinition = definition,
                    ModelHost = modelHost
                });

                targetFile.Update();
            }

            return targetFile;
        }
 public static ModelNode AddWebPartPage(this ModelNode model, WebPartPageDefinition definition, Action<ModelNode> action)
 {
     return model.AddDefinitionNode(definition, action);
 }
 public static ModelNode AddWebPartPage(this ModelNode model, WebPartPageDefinition definition)
 {
     return AddWebPartPage(model, definition, null);
 }
        public virtual string GetWebPartTemplateContent(WebPartPageDefinition webPartPageModel)
        {
            // gosh! would u like to offer a better way?
            // always SP2013 for CSOM yet
            // Built-in web part page templates should be correctly resolved for SP2010/2013 #683

            // TODO, sp2016 support, if any
            switch (webPartPageModel.PageLayoutTemplate)
            {
                case 1:
                    return SP2013WebPartPageTemplates.spstd1;
                case 2:
                    return SP2013WebPartPageTemplates.spstd2;
                case 3:
                    return SP2013WebPartPageTemplates.spstd3;
                case 4:
                    return SP2013WebPartPageTemplates.spstd4;
                case 5:
                    return SP2013WebPartPageTemplates.spstd5;
                case 6:
                    return SP2013WebPartPageTemplates.spstd6;
                case 7:
                    return SP2013WebPartPageTemplates.spstd7;
                case 8:
                    return SP2013WebPartPageTemplates.spstd8;
            }

            throw new Exception(string.Format("PageLayoutTemplate: [{0}] is not supported.", webPartPageModel.PageLayoutTemplate));
        }