private void BuildPage( IFluentBuilder builder, EnvironmentRecord environment, PageVersionRecord pageVersion) { if (pageVersion.MasterPageId.HasValue) { long masterPageVersionId; if (!_pageVersions.TryGetValue(pageVersion.MasterPageId.Value, out masterPageVersionId)) { throw new Exception("Page with version ID " + pageVersion.RecordId + " has a master page ID of " + pageVersion.MasterPageId.Value + " but there is no version of that page configured for this version of the website"); } var masterPageRecord = GetPage(builder, environment, masterPageVersionId); if (string.IsNullOrEmpty(pageVersion.RequiredPermission)) { pageVersion.RequiredPermission = masterPageRecord.RequiredPermission; } if (string.IsNullOrEmpty(pageVersion.AssetPath)) { pageVersion.AssetPath = masterPageRecord.AssetPath; } if (string.IsNullOrEmpty(pageVersion.BodyStyle)) { pageVersion.BodyStyle = masterPageRecord.BodyStyle; } if (string.IsNullOrEmpty(pageVersion.ModuleName)) { pageVersion.ModuleName = masterPageRecord.ModuleName; } if (!pageVersion.LayoutId.HasValue && string.IsNullOrEmpty(pageVersion.LayoutName)) { pageVersion.LayoutId = masterPageRecord.LayoutId; pageVersion.LayoutName = masterPageRecord.LayoutName; } if (pageVersion.LayoutZones == null || pageVersion.LayoutZones.Length == 0) { pageVersion.LayoutZones = masterPageRecord.LayoutZones; } else if (masterPageRecord.LayoutZones != null && masterPageRecord.LayoutZones.Length > 0) { foreach (var layoutRegion in masterPageRecord.LayoutZones) { if (pageVersion.LayoutZones.FirstOrDefault( lr => string.Equals(layoutRegion.ZoneName, lr.ZoneName, StringComparison.OrdinalIgnoreCase)) == null) { pageVersion.LayoutZones = pageVersion.LayoutZones .Concat(Enumerable.Repeat(layoutRegion, 1)) .ToArray(); } } } if (pageVersion.Components == null || pageVersion.Components.Length == 0) { pageVersion.Components = masterPageRecord.Components; } else if (masterPageRecord.Components != null && masterPageRecord.Components.Length > 0) { foreach (var component in masterPageRecord.Components) { if (pageVersion.Components.FirstOrDefault( c => string.Equals(component.ComponentName, c.ComponentName, StringComparison.OrdinalIgnoreCase)) == null) { pageVersion.Components = pageVersion.Components .Concat(Enumerable.Repeat(component, 1)) .ToArray(); } } } } var pageUrl = pageVersion.CanonicalUrl; if (string.IsNullOrEmpty(pageUrl) && pageVersion.Routes != null && pageVersion.Routes.Length > 0) { pageUrl = pageVersion.Routes.OrderByDescending(r => r.Priority).First().Path; } string canonicalUrl = null; if (!string.IsNullOrEmpty(environment.BaseUrl) && !string.IsNullOrEmpty(pageUrl)) { canonicalUrl = environment.BaseUrl; if (canonicalUrl.EndsWith("/")) { if (pageUrl.StartsWith("/")) { canonicalUrl += pageUrl.Substring(1); } else { canonicalUrl += pageUrl; } } else { if (pageUrl.StartsWith("/")) { canonicalUrl += pageUrl; } else { canonicalUrl += "/" + pageUrl; } } } var pageDefinition = builder.BuildUpPage() .Name(pageVersion.VersionName) .AssetDeployment(pageVersion.AssetDeployment) .DeployIn(pageVersion.ModuleName) .Title(pageVersion.Title) .CanonicalUrl(canonicalUrl) .BodyStyle(pageVersion.BodyStyle) .RequiresPermission(pageVersion.RequiredPermission, pageVersion.AssetPath); if (pageVersion.LayoutId.HasValue) { pageDefinition.Layout(GetLayout(builder, pageVersion.LayoutId.Value)); } else { pageDefinition.Layout(pageVersion.LayoutName); } if (pageVersion.Routes != null) { foreach (var route in pageVersion.Routes) { pageDefinition.Route(route.Path, route.Priority); } } if (pageVersion.Components != null) { foreach (var component in pageVersion.Components) { pageDefinition.NeedsComponent(component.ComponentName); } } if (pageVersion.LayoutZones != null) { foreach (var layoutRegion in pageVersion.LayoutZones) { if (layoutRegion.RegionId.HasValue) { pageDefinition.ZoneRegion(layoutRegion.ZoneName, GetRegion(builder, layoutRegion.RegionId.Value)); } else if (layoutRegion.LayoutId.HasValue) { pageDefinition.ZoneLayout(layoutRegion.ZoneName, GetLayout(builder, layoutRegion.LayoutId.Value)); } else if (string.Equals(layoutRegion.ContentType, "region", StringComparison.OrdinalIgnoreCase)) { pageDefinition.ZoneRegion(layoutRegion.ZoneName, layoutRegion.ContentName); } else if (string.Equals(layoutRegion.ContentType, "html", StringComparison.OrdinalIgnoreCase)) { pageDefinition.ZoneHtml(layoutRegion.ZoneName, layoutRegion.ContentName, layoutRegion.ContentValue); } else if (string.Equals(layoutRegion.ContentType, "layout", StringComparison.OrdinalIgnoreCase)) { pageDefinition.ZoneLayout(layoutRegion.ZoneName, layoutRegion.ContentName); } else if (string.Equals(layoutRegion.ContentType, "template", StringComparison.OrdinalIgnoreCase)) { pageDefinition.ZoneTemplate(layoutRegion.ZoneName, layoutRegion.ContentName); } else if (string.Equals(layoutRegion.ContentType, "component", StringComparison.OrdinalIgnoreCase)) { pageDefinition.ZoneComponent(layoutRegion.ZoneName, layoutRegion.ContentName); } } } pageDefinition.Build(); }
IPackage IPackage.Build(IFluentBuilder fluentBuilder) { // All CMS manager assets will be contained in a single module var module = fluentBuilder.BuildUpModule() .Name("cms_manager") .AssetDeployment(AssetDeployment.PerModule) .Build(); // Build the API services fluentBuilder.BuildUpService(null, typeof(LiveUpdateService)) .Name("liveUpdate") .Route(_configuration.ServiceBasePath + "live-update/", new [] { Method.Get, Method.Post, Method.Delete }, 0) .RequiredPermission(Permissions.View, false) .CreateComponent("liveUpdateClient") .DeployIn(module) .Build(); fluentBuilder.BuildUpService(null, typeof(CrudService)) .Name("crud") .Route(_configuration.ServiceBasePath + "crud/", new [] { Method.Get, Method.Post, Method.Put, Method.Delete }, 0) .CreateComponent("crudClient") .DeployIn(module) .Build(); fluentBuilder.BuildUpService(null, typeof(ListService)) .Name("list") .Route(_configuration.ServiceBasePath + "list/", new [] { Method.Get, Method.Post }, 0) .CreateComponent("listClient") .DeployIn(module) .Build(); fluentBuilder.BuildUpService(null, typeof(VersionsService)) .Name("versions") .Route(_configuration.ServiceBasePath + "versions/", new [] { Method.Get, Method.Post, Method.Put, Method.Delete }, 0) .CreateComponent("versionsClient") .DeployIn(module) .Build(); fluentBuilder.BuildUpService(null, typeof(HistoryService)) .Name("history") .Route(_configuration.ServiceBasePath + "history/", new [] { Method.Get }, 0) .CreateComponent("historyClient") .DeployIn(module) .Build(); fluentBuilder.BuildUpService(null, typeof(SegmentTestingService)) .Name("segmentTesting") .Route(_configuration.ServiceBasePath + "segment-testing/", new [] { Method.Get, Method.Post, Method.Put, Method.Delete }, 0) .CreateComponent("segmentTestingClient") .DeployIn(module) .Build(); // Load templates and accumulate all of the CSS and JS assets var scriptModules = new List <string>(); LoadScriptModule("updateNotifierModule", scriptModules); LoadScriptModule("dataModule", scriptModules); LoadScriptModule("validationModule", scriptModules); LoadScriptModule("viewsModule", scriptModules); LoadScriptModule("filtersModule", scriptModules); LoadScriptModule("genericComponentsModule", scriptModules); LoadScriptModule("displayOnlyComponentsModule", scriptModules); LoadScriptModule("fieldEditorComponentsModule", scriptModules); LoadScriptModule("elementEditorComponentsModule", scriptModules); // Load templates that are directly loaded into regions var less = new StringBuilder(); var cmsManagerTemplatePath = AddTemplate("CmsManager", less, scriptModules); var debugToolsTemplatePath = AddTemplate("DebugTools", less, scriptModules); // Load Vue temlates that are dynamically constructed in JavaScript AddTemplate("EnvironmentSelector", less, scriptModules); AddTemplate("WebsiteVersionSelector", less, scriptModules); AddTemplate("UserSegmentSelector", less, scriptModules); AddTemplate("SegmentationScenarioSelector", less, scriptModules); AddTemplate("SegmentationTestSelector", less, scriptModules); AddTemplate("PageSelector", less, scriptModules); AddTemplate("LayoutSelector", less, scriptModules); AddTemplate("RegionSelector", less, scriptModules); AddTemplate("ComponentSelector", less, scriptModules); AddTemplate("UserSegmentDisplay", less, scriptModules); AddTemplate("ContextDisplay", less, scriptModules); AddTemplate("EnvironmentEditor", less, scriptModules); AddTemplate("WebsiteVersionEditor", less, scriptModules); AddTemplate("SegmentationScenarioEditor", less, scriptModules); AddTemplate("PageEditor", less, scriptModules); AddTemplate("LayoutEditor", less, scriptModules); AddTemplate("RegionEditor", less, scriptModules); AddTemplate("ComponentEditor", less, scriptModules); AddTemplate("UpdateNotifierLog", less, scriptModules); // Output JavaScript and CSS assets in a module var assetsComponentBuilder = fluentBuilder.BuildUpComponent(null) .Name("assets") .DeployIn(module) .RenderInitialization("cms-manager-init", "<script>ns." + NamespaceName + ".init();</script>") .DeployLess(less.ToString()); foreach (var scriptModule in scriptModules) { assetsComponentBuilder.DeployScript(scriptModule); } var assetsComponent = assetsComponentBuilder.Build(); // This region of the CMS manager is for editing pages of the website var editorRegion = Build(module, assetsComponent, fluentBuilder.BuildUpRegion() .Name("editor") .NeedsComponent("crudClient") .NeedsComponent("listClient") .NeedsComponent("versionsClient") .NeedsComponent("historyClient") .NeedsComponent("segmentTestingClient") .AddTemplate(cmsManagerTemplatePath)); // This region of the CMS manager is for debug tools var toolsRegion = Build(module, assetsComponent, fluentBuilder.BuildUpRegion() .Name("tools") .AddTemplate(debugToolsTemplatePath)); // To have the CMS manager fill the whole page make this the page layout var managerLayout = fluentBuilder.BuildUpLayout() .Name("manager") .ZoneNesting("editor,tools") .Region("editor", editorRegion) .Region("tools", toolsRegion) .Build(); // To have the CMS manager occupy a region of the page put this region // into a zone of the page layout var managerRegion = fluentBuilder.BuildUpRegion() .Name("manager") .Layout(managerLayout) .Build(); // If the ManagerPath is configured then add a page to the website that // contains the CMS manager if (!string.IsNullOrEmpty(_configuration.ManagerPath)) { fluentBuilder.BuildUpPage() .Name("cmsManager") .Route(_configuration.ManagerPath, 0, Method.Get) .Layout(managerLayout) .Build(); } return(this); }