/// <summary> /// Generates the Url slugs for itself, first pulling any Custom Url Slugs, then rendering all culture codes outlined in the settings /// </summary> public void BuildUrlSlugs() { string Pattern = DynamicRouteHelper.GetClass(ClassName).ClassURLPattern; // if no pattern, then default to node alias path, this way any child with a ParentUrl will still have a value. if (string.IsNullOrWhiteSpace(Pattern)) { Pattern = "{% NodeAliasPath %}"; } var SlugQuery = UrlSlugInfoProvider.GetUrlSlugs() .WhereEquals("UrlSlugNodeID", NodeID); // If not checking for updates (rebuild), then the only ones we want to keep are the Custom Url Slugs. if (!Settings.CheckingForUpdates) { SlugQuery.WhereEquals("IsCustom", true); } // Import the existing Slugs (Custom if not checking for imports, or all of them) foreach (UrlSlugInfo ExistingSlug in SlugQuery) { UrlSlugs.Add(new NodeUrlSlug() { IsCustom = ExistingSlug.UrlSlugIsCustom, IsDefault = ExistingSlug.UrlSlugCultureCode.Equals(Settings.DefaultCultureCode, StringComparison.InvariantCultureIgnoreCase), CultureCode = ExistingSlug.UrlSlugCultureCode, UrlSlug = ExistingSlug.UrlSlug, ExistingNodeSlugGuid = ExistingSlug.UrlSlugGuid }); } // Go through any cultures that do not have custom slugs already, these are the cultures that need to be rebuilt foreach (string CultureCode in Settings.CultureCodes.Where(culture => !UrlSlugs.Exists(slug => slug.IsCustom && slug.CultureCode.Equals(culture, StringComparison.InvariantCultureIgnoreCase)))) { var CultureResolver = Settings.BaseResolver.CreateChild(); CultureResolver.SetAnonymousSourceData(new object[] { DynamicRouteHelper.GetCulture(CultureCode) }); bool IsDefaultCulture = CultureCode.Equals(Settings.DefaultCultureCode, StringComparison.InvariantCultureIgnoreCase); // Get actual Document, if it's the default culture, it MUST return some document, no matter what. TreeNode Document = DocumentHelper.GetDocuments(ClassName) .WhereEquals("NodeID", NodeID) .Culture(CultureCode) .CombineWithDefaultCulture(IsDefaultCulture || Settings.GenerateIfCultureDoesntExist) .FirstOrDefault(); if (Document != null) { // Add Document values and ParentUrl var DocResolver = CultureResolver.CreateChild(); DocResolver.SetAnonymousSourceData(new object[] { Document }); if (Parent != null) { DocResolver.SetNamedSourceData("ParentUrl", Parent.GetUrlSlug(CultureCode)); } var NodeSlug = new NodeUrlSlug() { CultureCode = CultureCode, IsCustom = false, IsDefault = IsDefaultCulture, UrlSlug = DynamicRouteHelper.GetCleanUrl(DocResolver.ResolveMacros(Pattern), Settings.SiteName), }; // If checking for updates, need to flag that an update was found if (Settings.CheckingForUpdates) { var ExistingSlug = UrlSlugs.Where(x => x.CultureCode.Equals(CultureCode, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); if (ExistingSlug != null) { // Update the existing UrlSlug only if it is different and not custom if (!ExistingSlug.UrlSlug.Equals(NodeSlug.UrlSlug)) { ExistingSlug.IsNewOrUpdated = true; ExistingSlug.PreviousUrlSlug = ExistingSlug.UrlSlug; ExistingSlug.UrlSlug = NodeSlug.UrlSlug; } } else { // No Slug exists for this culture, add. NodeSlug.IsNewOrUpdated = true; UrlSlugs.Add(NodeSlug); } } else { // Not checking for updates to just adding node slug. NodeSlug.IsNewOrUpdated = true; UrlSlugs.Add(NodeSlug); } } } }
/// <summary> /// Generates the Url slugs for itself, first pulling any Custom Url Slugs, then rendering all culture codes outlined in the settings /// <paramref name="UseCurrentVersion">If true, then will look to the current version of the document, used only in Checking for conflicts to block publishing</paramref> /// </summary> public void BuildUrlSlugs(bool UseCurrentVersion = false) { // Temp replace Method version with Normal version string Pattern = Regex.Replace(DynamicRouteInternalHelper.GetClass(ClassName).ClassURLPattern, "ParentUrl\\(\\)", "ParentUrl", RegexOptions.IgnoreCase); // if no pattern, then default to node alias path, this way any child with a ParentUrl will still have a value. if (string.IsNullOrWhiteSpace(Pattern)) { Pattern = "{% NodeAliasPath %}"; } var SlugQuery = UrlSlugInfoProvider.GetUrlSlugs() .Source(x => x.Join(new QuerySourceTable("CMS_Tree", null, new string[] { }), new WhereCondition("NodeID = UrlSlugNodeID"), JoinTypeEnum.Inner)) .Columns(new string[] { "UrlSlugID", "UrlSlugGuid", "UrlSlugLastModified", "UrlSlug", "UrlSlugNodeID", "UrlSlugCultureCode", "UrlSlugIsCustom", "NodeSiteID" }) .WhereEquals("UrlSlugNodeID", NodeID); // If not checking for updates (rebuild), then the only ones we want to keep are the Custom Url Slugs. if (!Settings.CheckingForUpdates) { SlugQuery.WhereEquals("UrlSlugIsCustom", true); } // Import the existing Slugs (Custom if not checking for imports, or all of them) foreach (UrlSlugInfo ExistingSlug in SlugQuery) { UrlSlugs.Add(new NodeUrlSlug() { SiteID = ExistingSlug.GetIntegerValue("NodeSiteID", 1), IsCustom = ExistingSlug.UrlSlugIsCustom, IsDefault = ExistingSlug.UrlSlugCultureCode.Equals(Settings.DefaultCultureCode, StringComparison.InvariantCultureIgnoreCase), CultureCode = ExistingSlug.UrlSlugCultureCode, UrlSlug = ExistingSlug.UrlSlug, ExistingNodeSlugGuid = ExistingSlug.UrlSlugGuid }); } // Go through any cultures that do not have custom slugs already, these are the cultures that need to be rebuilt foreach (string CultureCode in Settings.CultureCodes.Where(culture => !UrlSlugs.Exists(slug => slug.IsCustom && slug.CultureCode.Equals(culture, StringComparison.InvariantCultureIgnoreCase)))) { var CultureResolver = Settings.BaseResolver.CreateChild(); CultureResolver.SetAnonymousSourceData(new object[] { DynamicRouteInternalHelper.GetCulture(CultureCode) }); bool IsDefaultCulture = CultureCode.Equals(Settings.DefaultCultureCode, StringComparison.InvariantCultureIgnoreCase); // Get actual Document, if it's the default culture, it MUST return some document, no matter what. var DocQuery = DocumentHelper.GetDocuments(ClassName) .WhereEquals("NodeID", NodeID) .Culture(CultureCode) .CombineWithDefaultCulture(IsDefaultCulture || Settings.GenerateIfCultureDoesntExist); if (UseCurrentVersion) { DocQuery.LatestVersion(true).Published(false); } else { DocQuery.PublishedVersion(true); } TreeNode Document = DocQuery.FirstOrDefault(); // If the Document is either Null because there is no Default Culture, then get any document // and set the culture code if the current Culture checking is either the default culture (required) // or is another culture but should be generated due to the GenerateIfCultureDoesntExist setting if (Document == null && (IsDefaultCulture || Settings.GenerateIfCultureDoesntExist)) { var AnyCultureDocQuery = DocumentHelper.GetDocuments(ClassName) .WhereEquals("NodeID", NodeID) .CombineWithAnyCulture(); if (UseCurrentVersion) { AnyCultureDocQuery.LatestVersion(true).Published(false); } else { AnyCultureDocQuery.PublishedVersion(true); } Document = AnyCultureDocQuery.FirstOrDefault(); Document.DocumentCulture = CultureCode; } if (Document != null) { // Add Document values and ParentUrl var DocResolver = CultureResolver.CreateChild(); DocResolver.SetAnonymousSourceData(new object[] { Document }); if (Parent == null) { // Look up parent Url Slug UrlSlugInfo ParentSlug = UrlSlugInfoProvider.GetUrlSlugs() .WhereEquals("UrlSlugNodeID", Document.NodeParentID) .OrderBy($"case when UrlSlugCultureCode = '{CultureCode}' then 0 else 1 end, case when UrlSlugCultureCode = '{Settings.DefaultCultureCode}' then 0 else 1 end, UrlSlugCultureCode") .FirstOrDefault(); if (ParentSlug != null) { DocResolver.SetNamedSourceData("ParentUrl", ParentSlug.UrlSlug); } else { DocResolver.SetNamedSourceData("ParentUrl", ""); } } else { DocResolver.SetNamedSourceData("ParentUrl", Parent.GetUrlSlug(CultureCode)); } var NodeSlug = new NodeUrlSlug() { SiteID = Document.NodeSiteID, CultureCode = CultureCode, IsCustom = false, IsDefault = IsDefaultCulture, UrlSlug = DynamicRouteInternalHelper.GetCleanUrl(DocResolver.ResolveMacros(Pattern), Settings.SiteName), }; // If checking for updates, need to flag that an update was found if (Settings.CheckingForUpdates) { var ExistingSlug = UrlSlugs.Where(x => x.CultureCode.Equals(CultureCode, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); if (ExistingSlug != null) { // Update the existing UrlSlug only if it is different and not custom if (!ExistingSlug.UrlSlug.Equals(NodeSlug.UrlSlug)) { ExistingSlug.IsNewOrUpdated = true; ExistingSlug.PreviousUrlSlug = ExistingSlug.UrlSlug; ExistingSlug.UrlSlug = NodeSlug.UrlSlug; } } else { // No Slug exists for this culture, add. NodeSlug.IsNewOrUpdated = true; UrlSlugs.Add(NodeSlug); } } else { // Not checking for updates to just adding node slug. NodeSlug.IsNewOrUpdated = true; UrlSlugs.Add(NodeSlug); } } else if (!Settings.GenerateIfCultureDoesntExist && !IsDefaultCulture) { // If document no longer exists but a Url slug exists, set this slug to be deleted. var SlugToDelete = UrlSlugs.Where(x => x.ExistingNodeSlugGuid != null && x.CultureCode.Equals(CultureCode, StringComparison.InvariantCultureIgnoreCase)).FirstOrDefault(); if (SlugToDelete != null) { SlugToDelete.Delete = true; } } } }