From f3442eb808a453b9f008778256ae8861f00bea92 Mon Sep 17 00:00:00 2001 From: navan Date: Tue, 12 Dec 2023 13:35:40 +1100 Subject: [PATCH] #155-Create-Sitemap: Sitemap-related files... --- Packages.props | 1 + src/Feature/Sitemap/Sitemap.module.json | 13 ++ .../Sitemap/items/templates/Sitemap.yml | 31 +++++ .../items/templates/Sitemap/_SitemapData.yml | 37 ++++++ .../Sitemap/_SitemapData/Sitemap Settings.yml | 31 +++++ .../Sitemap Settings/IncludeinSitemap.yml | 48 ++++++++ .../rendering/AppSettings/MvpSiteSettings.cs | 2 + .../GraphQL/GraphQLRequestBuilder.cs | 1 - .../MvpSite/items/content/MvpSite/Home.yml | 12 +- .../items/content/MvpSite/Home/About.yml | 9 +- .../content/MvpSite/Home/Application.yml | 12 +- .../MvpSite/Home/Application/Admin.yml | 12 +- .../Home/Application/Admin/Applications.yml | 12 +- .../content/MvpSite/Home/Become-an-mvp.yml | 9 +- .../items/content/MvpSite/Home/Benefits.yml | 9 +- .../items/content/MvpSite/Home/Contact.yml | 9 +- .../items/content/MvpSite/Home/Directory.yml | 9 +- .../content/MvpSite/Home/Mentor-Program.yml | 9 +- .../items/content/MvpSite/Home/Podcast.yml | 9 +- .../items/content/MvpSite/Home/Thank-you.yml | 12 +- .../items/templates/MvpSite/Homepage.yml | 7 +- .../MvpSite/items/templates/MvpSite/Page.yml | 7 +- src/Project/MvpSite/rendering/Constants.cs | 7 ++ .../Controllers/DefaultController.cs | 14 ++- .../CustomGraphQlLayoutServiceHandler.cs | 29 ++++- .../MvpSite/rendering/Models/SitemapModel.cs | 60 ++++++++++ .../Mvp.Project.MvpSite.Rendering.csproj | 1 + .../Sitemap/Providers/ISitemapUrlProvider.cs | 10 ++ .../Providers/MvpSitemapUrlProvider.cs | 112 ++++++++++++++++++ .../rendering/Sitemap/SitemapBuilder.cs | 33 ++++++ .../rendering/Sitemap/SitemapExtensions.cs | 13 ++ .../rendering/Sitemap/SitemapResponse.cs | 20 ++++ src/Project/MvpSite/rendering/Startup.cs | 11 +- .../rendering/appsettings.Development.json | 10 +- src/XmCloudIntroduction.sln | 50 ++++++++ 35 files changed, 618 insertions(+), 53 deletions(-) create mode 100644 src/Feature/Sitemap/Sitemap.module.json create mode 100644 src/Feature/Sitemap/items/templates/Sitemap.yml create mode 100644 src/Feature/Sitemap/items/templates/Sitemap/_SitemapData.yml create mode 100644 src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings.yml create mode 100644 src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings/IncludeinSitemap.yml create mode 100644 src/Project/MvpSite/rendering/Models/SitemapModel.cs create mode 100644 src/Project/MvpSite/rendering/Sitemap/Providers/ISitemapUrlProvider.cs create mode 100644 src/Project/MvpSite/rendering/Sitemap/Providers/MvpSitemapUrlProvider.cs create mode 100644 src/Project/MvpSite/rendering/Sitemap/SitemapBuilder.cs create mode 100644 src/Project/MvpSite/rendering/Sitemap/SitemapExtensions.cs create mode 100644 src/Project/MvpSite/rendering/Sitemap/SitemapResponse.cs diff --git a/Packages.props b/Packages.props index 2feb5e15..87b9185e 100644 --- a/Packages.props +++ b/Packages.props @@ -38,5 +38,6 @@ + diff --git a/src/Feature/Sitemap/Sitemap.module.json b/src/Feature/Sitemap/Sitemap.module.json new file mode 100644 index 00000000..0c776196 --- /dev/null +++ b/src/Feature/Sitemap/Sitemap.module.json @@ -0,0 +1,13 @@ +{ + "namespace": "Feature.Sitemap", + "items": { + "includes": [ + { + "name": "templates", + "path": "/sitecore/templates/Feature/Sitemap", + "allowedPushOperations": "createUpdateAndDelete", + "scope": "itemAndDescendants" + } + ] + } +} \ No newline at end of file diff --git a/src/Feature/Sitemap/items/templates/Sitemap.yml b/src/Feature/Sitemap/items/templates/Sitemap.yml new file mode 100644 index 00000000..b7f8e682 --- /dev/null +++ b/src/Feature/Sitemap/items/templates/Sitemap.yml @@ -0,0 +1,31 @@ +--- +ID: "51273b02-674d-4a04-947f-d249f2871bcd" +Parent: "8f343079-3cc5-4ef7-bc27-32addb46f45e" +Template: "0437fee2-44c9-46a6-abe9-28858d9fee8c" +Path: /sitecore/templates/Feature/Sitemap +Languages: +- Language: en + Versions: + - Version: 1 + Fields: + - ID: "25bed78c-4957-4165-998a-ca1b52f67497" + Hint: __Created + Value: 20231212T005121Z + - ID: "52807595-0f8f-4b20-8d2a-cb71d28c6103" + Hint: __Owner + Value: | + sitecore\qDWz4GMo2o + - ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f" + Hint: __Created by + Value: | + sitecore\qDWz4GMo2o + - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" + Hint: __Revision + Value: "61b184a4-32b9-46ae-a09a-b765d21b4b7a" + - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" + Hint: __Updated by + Value: | + sitecore\qDWz4GMo2o + - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" + Hint: __Updated + Value: 20231212T005449Z diff --git a/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData.yml b/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData.yml new file mode 100644 index 00000000..87d14d10 --- /dev/null +++ b/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData.yml @@ -0,0 +1,37 @@ +--- +ID: "00f7955a-eb3d-4659-94f9-9202865e39de" +Parent: "51273b02-674d-4a04-947f-d249f2871bcd" +Template: "ab86861a-6030-46c5-b394-e8f99e8b87db" +Path: /sitecore/templates/Feature/Sitemap/_SitemapData +SharedFields: +- ID: "12c33f3f-86c5-43a5-aeb4-5598cec45116" + Hint: __Base template + Value: | + {1930BBEB-7805-471A-A3BE-4858AC7CF696} + {4414A1F9-826A-4647-8DF4-ED6A95E64C43} +Languages: +- Language: en + Versions: + - Version: 1 + Fields: + - ID: "25bed78c-4957-4165-998a-ca1b52f67497" + Hint: __Created + Value: 20231212T000336Z + - ID: "52807595-0f8f-4b20-8d2a-cb71d28c6103" + Hint: __Owner + Value: | + sitecore\qDWz4GMo2o + - ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f" + Hint: __Created by + Value: | + sitecore\qDWz4GMo2o + - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" + Hint: __Revision + Value: "d85a32fd-cf94-4e5f-92f1-440bb8062c4b" + - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" + Hint: __Updated by + Value: | + sitecore\qDWz4GMo2o + - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" + Hint: __Updated + Value: 20231212T005128Z diff --git a/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings.yml b/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings.yml new file mode 100644 index 00000000..595722fb --- /dev/null +++ b/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings.yml @@ -0,0 +1,31 @@ +--- +ID: "f1cda39f-65de-4cde-a59b-bcd97968f090" +Parent: "00f7955a-eb3d-4659-94f9-9202865e39de" +Template: "e269fbb5-3750-427a-9149-7aa950b49301" +Path: /sitecore/templates/Feature/Sitemap/_SitemapData/Sitemap Settings +Languages: +- Language: en + Versions: + - Version: 1 + Fields: + - ID: "25bed78c-4957-4165-998a-ca1b52f67497" + Hint: __Created + Value: 20231212T000540Z + - ID: "52807595-0f8f-4b20-8d2a-cb71d28c6103" + Hint: __Owner + Value: | + sitecore\qDWz4GMo2o + - ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f" + Hint: __Created by + Value: | + sitecore\qDWz4GMo2o + - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" + Hint: __Revision + Value: "ae77877a-f036-42ac-ae2a-09cb0f49f373" + - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" + Hint: __Updated by + Value: | + sitecore\qDWz4GMo2o + - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" + Hint: __Updated + Value: 20231212T000718Z diff --git a/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings/IncludeinSitemap.yml b/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings/IncludeinSitemap.yml new file mode 100644 index 00000000..242bff92 --- /dev/null +++ b/src/Feature/Sitemap/items/templates/Sitemap/_SitemapData/Sitemap Settings/IncludeinSitemap.yml @@ -0,0 +1,48 @@ +--- +ID: "e319ae64-c32a-4e79-b102-256f8c869dae" +Parent: "f1cda39f-65de-4cde-a59b-bcd97968f090" +Template: "455a3e98-a627-4b40-8035-e683a0331ac7" +Path: /sitecore/templates/Feature/Sitemap/_SitemapData/Sitemap Settings/IncludeinSitemap +SharedFields: +- ID: "ab162cc0-dc80-4abf-8871-998ee5d7ba32" + Hint: Type + Value: Checkbox +- ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" + Hint: __Sortorder + Value: 100 +- ID: "be351a73-fcb0-4213-93fa-c302d8ab4f51" + Hint: Shared + Value: 1 +Languages: +- Language: en + Fields: + - ID: "19a69332-a23e-4e70-8d16-b2640cb24cc8" + Hint: Title + Value: Include in Sitemap + - ID: "b5e02ad9-d56f-4c41-a065-a133db87bdeb" + Hint: __Display name + Value: Include in Sitemap + Versions: + - Version: 1 + Fields: + - ID: "25bed78c-4957-4165-998a-ca1b52f67497" + Hint: __Created + Value: 20231212T000541Z + - ID: "52807595-0f8f-4b20-8d2a-cb71d28c6103" + Hint: __Owner + Value: | + sitecore\qDWz4GMo2o + - ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f" + Hint: __Created by + Value: | + sitecore\qDWz4GMo2o + - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" + Hint: __Revision + Value: "b83eade9-b538-40ac-943f-5e5bbdc0051a" + - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" + Hint: __Updated by + Value: | + sitecore\qDWz4GMo2o + - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" + Hint: __Updated + Value: 20231212T001324Z diff --git a/src/Foundation/Configuration/rendering/AppSettings/MvpSiteSettings.cs b/src/Foundation/Configuration/rendering/AppSettings/MvpSiteSettings.cs index 6913a395..d636ec41 100644 --- a/src/Foundation/Configuration/rendering/AppSettings/MvpSiteSettings.cs +++ b/src/Foundation/Configuration/rendering/AppSettings/MvpSiteSettings.cs @@ -12,6 +12,8 @@ public class MvpSiteSettings public string? NotFoundPage { get; set; } + public string? DefaultLanguageHeader { get; set; } + public Uri? RenderingHostUri { get; set; } public bool EnableExperienceEditor { get; set; } diff --git a/src/Foundation/DataFetching/rendering/GraphQL/GraphQLRequestBuilder.cs b/src/Foundation/DataFetching/rendering/GraphQL/GraphQLRequestBuilder.cs index ed6232ff..16dccee9 100644 --- a/src/Foundation/DataFetching/rendering/GraphQL/GraphQLRequestBuilder.cs +++ b/src/Foundation/DataFetching/rendering/GraphQL/GraphQLRequestBuilder.cs @@ -1,6 +1,5 @@ using Microsoft.Extensions.Configuration; using Mvp.Foundation.Configuration.Rendering.AppSettings; -using Mvp.Foundation.DataFetching.GraphQL; using System.Collections.Generic; namespace Mvp.Foundation.DataFetching.GraphQL diff --git a/src/Project/MvpSite/items/content/MvpSite/Home.yml b/src/Project/MvpSite/items/content/MvpSite/Home.yml index d19a285b..cfa31483 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home.yml @@ -7,6 +7,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 100 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -143,7 +146,7 @@ Languages: Value: MVP, Most Valuable Professional - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "198fd8d5-7f00-4749-9c29-b7e4bd29ff1f" + Value: "7bfb35cf-92df-47a0-b476-3021107d291e" - ID: "986ff3ab-18cd-47d7-b294-9a091f0e8cea" Hint: OgType Value: article @@ -160,13 +163,16 @@ Languages: - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\sebw@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221004T072522Z + Value: 20231212T000936Z - ID: "e08359cc-7bf5-4866-81a6-1e1d07226667" Hint: MetaDescription Value: MVP Home Description - ID: "eeb29922-a760-44a8-a5ab-f28efbdc641c" Hint: OgDescription Value: MVP Home Description + - ID: "efc0a3c7-6993-47d2-ba85-10b44961916e" + Hint: IncludeInMenu + Value: 1 diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/About.yml b/src/Project/MvpSite/items/content/MvpSite/Home/About.yml index 097db65e..d038cf42 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/About.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/About.yml @@ -7,6 +7,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 100 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -77,14 +80,14 @@ Languages: Value: 20200604T042230Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "94e9fd25-7606-41b5-9ea0-012b3f9065ba" + Value: "a2655e6a-c3ac-48d7-8446-4422faad31a0" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: About - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20220928T162952Z + Value: 20231212T000919Z diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Application.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Application.yml index 7803543f..05276979 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Application.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Application.yml @@ -8,6 +8,12 @@ SharedFields: - ID: "06d5295c-ed2f-4a54-9bf2-26228d113318" Hint: __Icon Value: office/32x32/desktop.png +- ID: "508c54c0-cd02-4266-8b68-d71f88de1aa9" + Hint: ChangeFrequency + Value: +- ID: "76fb6ffd-4487-4028-a1cf-705fbe360cba" + Hint: Priority + Value: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 200 @@ -58,20 +64,20 @@ Languages: sitecore\iva@sitecore.net - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "7bc00d1f-bc82-4fb1-8e39-4bf16d147865" + Value: "bc8bf505-aa89-4af2-bde3-12e5711e435f" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Application - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "c58ed264-1f55-4aa3-a30e-da12ce43cb38" Hint: RequiresAuthentication Value: 1 - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221006T145101Z + Value: 20231211T211623Z - ID: "efc0a3c7-6993-47d2-ba85-10b44961916e" Hint: IncludeInMenu Value: 1 diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin.yml index fbcbf03d..8877319b 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin.yml @@ -5,6 +5,12 @@ Template: "a054184c-3b20-4c2b-ab04-c8a03acd5522" Path: /sitecore/content/MvpSite/Home/Application/Admin BranchID: "ef8dd6f4-1bb8-4831-a1a6-defa3594051a" SharedFields: +- ID: "508c54c0-cd02-4266-8b68-d71f88de1aa9" + Hint: ChangeFrequency + Value: +- ID: "76fb6ffd-4487-4028-a1cf-705fbe360cba" + Hint: Priority + Value: - ID: "f6d8a61c-2f84-4401-bd24-52d2068172bc" Hint: __Originator Value: "{9AC6DDA3-8785-4C63-A2AB-457D8CC56D19}" @@ -26,20 +32,20 @@ Languages: sitecore\iva@sitecore.net - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "ad9443bb-2e94-471d-9a5a-bc36cd64c7e0" + Value: "eb4f172c-58e2-4014-b355-4003e0a5a97c" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Admin - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "c58ed264-1f55-4aa3-a30e-da12ce43cb38" Hint: RequiresAuthentication Value: 1 - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20220906T133451Z + Value: 20231211T211937Z - ID: "efc0a3c7-6993-47d2-ba85-10b44961916e" Hint: IncludeInMenu Value: diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin/Applications.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin/Applications.yml index 4efea86d..7978ecf0 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin/Applications.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Application/Admin/Applications.yml @@ -5,6 +5,12 @@ Template: "a054184c-3b20-4c2b-ab04-c8a03acd5522" Path: /sitecore/content/MvpSite/Home/Application/Admin/Applications BranchID: "ef8dd6f4-1bb8-4831-a1a6-defa3594051a" SharedFields: +- ID: "508c54c0-cd02-4266-8b68-d71f88de1aa9" + Hint: ChangeFrequency + Value: "{1C2878D9-80A6-4760-B7EB-DBADE16AE8C8}" +- ID: "76fb6ffd-4487-4028-a1cf-705fbe360cba" + Hint: Priority + Value: - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -51,20 +57,20 @@ Languages: sitecore\iva@sitecore.net - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "a3267a9e-4eac-4959-9816-20ba872215de" + Value: "9a98a22b-4d8b-4005-9623-33f3348ff476" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Applications - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "c58ed264-1f55-4aa3-a30e-da12ce43cb38" Hint: RequiresAuthentication Value: 1 - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20220912T154647Z + Value: 20231211T212020Z - ID: "efc0a3c7-6993-47d2-ba85-10b44961916e" Hint: IncludeInMenu Value: diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Become-an-mvp.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Become-an-mvp.yml index 520ff514..9378d2f0 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Become-an-mvp.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Become-an-mvp.yml @@ -7,6 +7,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 500 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -113,14 +116,14 @@ Languages: Value: 20200604T042242Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "2db96519-9c12-4758-a402-10371e24324d" + Value: "f8be1109-d04f-4936-931e-f46b2b997770" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Become an MVP - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20220928T162952Z + Value: 20231212T000926Z diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Benefits.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Benefits.yml index 9b82b6b3..c9cb28af 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Benefits.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Benefits.yml @@ -7,6 +7,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 600 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -82,14 +85,14 @@ Languages: Value: 20200604T042302Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "c29cebb8-f3a2-486f-af52-4d83e0dc91cb" + Value: "83632de6-ce07-49c1-8e92-474bf754de74" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Benefits - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20220928T162952Z + Value: 20231212T000931Z diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Contact.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Contact.yml index 1c72c644..5cc80d20 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Contact.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Contact.yml @@ -7,6 +7,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 700 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -76,17 +79,17 @@ Languages: Value: 20200604T042308Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "96d27636-5163-4256-b220-8acdc240f02a" + Value: "848ac1c8-8c08-4ddc-adf7-33e3992db2c7" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Contact - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20220928T162952Z + Value: 20231212T001400Z - ID: "efc0a3c7-6993-47d2-ba85-10b44961916e" Hint: IncludeInMenu Value: 1 diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Directory.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Directory.yml index e2e08735..16067e14 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Directory.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Directory.yml @@ -8,6 +8,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 800 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f6d8a61c-2f84-4401-bd24-52d2068172bc" Hint: __Originator Value: "{9AC6DDA3-8785-4C63-A2AB-457D8CC56D19}" @@ -35,14 +38,14 @@ Languages: Value: 20211103T205042Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "95324739-d670-4a3d-9774-323d8abc4831" + Value: "04115795-56de-45e2-a0ea-c7540f4f117e" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Directory - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221006T145101Z + Value: 20231212T001405Z diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Mentor-Program.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Mentor-Program.yml index af55d372..4be870ee 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Mentor-Program.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Mentor-Program.yml @@ -7,6 +7,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 900 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -62,14 +65,14 @@ Languages: Value: 20200604T042230Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "7b9b8644-e567-42b1-a4de-b54793bcef67" + Value: "348de4cd-84b0-4d8e-917b-ac63e405e577" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Mentor Program - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221006T145101Z + Value: 20231212T000942Z diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Podcast.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Podcast.yml index 54bb08d4..aa9a73b9 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Podcast.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Podcast.yml @@ -7,6 +7,9 @@ SharedFields: - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 1000 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 Languages: - Language: en Versions: @@ -46,14 +49,14 @@ Languages: Value: 20200728T080246Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "ce4324f9-1b80-41e8-bb66-6a95daa2c826" + Value: "52bb1a29-4676-40fc-bd13-932b5a1513f9" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Podcast - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221006T145101Z + Value: 20231212T001413Z diff --git a/src/Project/MvpSite/items/content/MvpSite/Home/Thank-you.yml b/src/Project/MvpSite/items/content/MvpSite/Home/Thank-you.yml index 94ef0530..3d1a24d0 100644 --- a/src/Project/MvpSite/items/content/MvpSite/Home/Thank-you.yml +++ b/src/Project/MvpSite/items/content/MvpSite/Home/Thank-you.yml @@ -4,9 +4,15 @@ Parent: "94de9ac3-a9f7-40ab-ae90-acda364b9c40" Template: "a054184c-3b20-4c2b-ab04-c8a03acd5522" Path: "/sitecore/content/MvpSite/Home/Thank-you" SharedFields: +- ID: "508c54c0-cd02-4266-8b68-d71f88de1aa9" + Hint: ChangeFrequency + Value: "{3F00CE6E-67BD-4C6C-897F-4C2F36CD2135}" - ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e" Hint: __Sortorder Value: 1100 +- ID: "e319ae64-c32a-4e79-b102-256f8c869dae" + Hint: IncludeinSitemap + Value: 1 - ID: "f1a1fe9e-a60c-4ddb-a3a0-bb5b29fe732e" Hint: __Renderings Value: | @@ -62,17 +68,17 @@ Languages: Value: 20200604T042308Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "dde6beb3-977f-4726-aed5-827014c26f69" + Value: "00625ebd-ebdf-4104-99cb-0592d908b26e" - ID: "b1ece12f-b2c9-44e6-92a3-c5dfd6514b59" Hint: MenuTitle Value: Thank You - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\iva@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221006T145101Z + Value: 20231212T001431Z - ID: "efc0a3c7-6993-47d2-ba85-10b44961916e" Hint: IncludeInMenu Value: diff --git a/src/Project/MvpSite/items/templates/MvpSite/Homepage.yml b/src/Project/MvpSite/items/templates/MvpSite/Homepage.yml index 8b3c0527..9115e2f5 100644 --- a/src/Project/MvpSite/items/templates/MvpSite/Homepage.yml +++ b/src/Project/MvpSite/items/templates/MvpSite/Homepage.yml @@ -15,6 +15,7 @@ SharedFields: {2FA21400-EB0C-4339-ADC0-71FB2D762256} {C8F3BF94-434C-4E7D-88A6-DF27EED63A94} {A991F79A-BB58-4BC3-AC44-21BFF5AEFD74} + {00F7955A-EB3D-4659-94F9-9202865E39DE} - ID: "f7d48a55-2158-4f02-9356-756654404f73" Hint: __Standard values Value: "{C51665EC-6662-4BEF-8A04-BE941861BEF7}" @@ -28,11 +29,11 @@ Languages: Value: 20200513T045547Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "fe584339-84de-41ac-bb4b-e610eef970f8" + Value: "d83a5a58-6210-471b-b803-07f887600d15" - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\sebw@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221004T072328Z + Value: 20231212T000836Z diff --git a/src/Project/MvpSite/items/templates/MvpSite/Page.yml b/src/Project/MvpSite/items/templates/MvpSite/Page.yml index df4b6779..72d1da5d 100644 --- a/src/Project/MvpSite/items/templates/MvpSite/Page.yml +++ b/src/Project/MvpSite/items/templates/MvpSite/Page.yml @@ -14,6 +14,7 @@ SharedFields: {2FA21400-EB0C-4339-ADC0-71FB2D762256} {C8F3BF94-434C-4E7D-88A6-DF27EED63A94} {A991F79A-BB58-4BC3-AC44-21BFF5AEFD74} + {00F7955A-EB3D-4659-94F9-9202865E39DE} - ID: "f7d48a55-2158-4f02-9356-756654404f73" Hint: __Standard values Value: "{9C05E623-3031-4A61-B75F-34E5EDB92DA0}" @@ -27,11 +28,11 @@ Languages: Value: 20200604T041523Z - ID: "8cdc337e-a112-42fb-bbb4-4143751e123f" Hint: __Revision - Value: "94ffc30f-00ad-4d1e-a42b-fd5e25b3e33c" + Value: "8b19c58e-ed78-4031-b31b-19c7ee99b72f" - ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a" Hint: __Updated by Value: | - sitecore\sebw@sitecore.net + sitecore\qDWz4GMo2o - ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522" Hint: __Updated - Value: 20221004T072359Z + Value: 20231212T000757Z diff --git a/src/Project/MvpSite/rendering/Constants.cs b/src/Project/MvpSite/rendering/Constants.cs index 4678f4b9..ad79a1a1 100644 --- a/src/Project/MvpSite/rendering/Constants.cs +++ b/src/Project/MvpSite/rendering/Constants.cs @@ -5,6 +5,13 @@ public class Constants public static class GraphQlQueries { public const string GetItem = "\r\n query LayoutQuery($path: String!, $language: String!, $site: String!) {\r\n layout(routePath: $path, language: $language, site: $site) {\r\n item {\r\n rendered\r\n }\r\n }\r\n }"; + + public const string GetSitemap = "\r\n query SitemapQuery(\r\n $rootItemId: String!\r\n $language: String!\r\n \r\n $site: String!\r\n $pageSize: Int = 10\r\n $hasLayout: String = \"true\"\r\n $after: String\r\n ) {\r\n search(\r\n where: {\r\n AND: [\r\n { name: \"_path\", value: $rootItemId, operator: CONTAINS }\r\n { name: \"_language\", value: $language }\r\n { name: \"site\", value: $site }\r\n { name: \"_hasLayout\", value: $hasLayout }\r\n { name: \"ExcludeSeoSitemaps\", value: \"0\" }\r\n ]\r\n }\r\n first: $pageSize\r\n after: $after\r\n ) {\r\n total\r\n pageInfo {\r\n endCursor\r\n hasNext\r\n }\r\n results {\r\n url {\r\n path\r\n }\r\n priority: field(name: \"Priority\") {\r\n ... on TextField {\r\n value\r\n }\r\n }\r\n }\r\n }\r\n }\r\n;"; + + public const string SitemapQuery = "query SitemapQuery(\r\n $rootItemId: String = \"{A43C6692-60F4-4743-A1BE-6424DE611DFA}\"\r\n $language: String = \"en\"\r\n $pageSize: Int = 100\r\n $hasLayout: String = \"true\"\r\n $after: String\r\n ) {\r\n search(\r\n where: {\r\n AND: [ \r\n { name: \"_path\", value: $rootItemId, operator: CONTAINS }\r\n { name: \"_language\", value: $language }\r\n { name: \"_hasLayout\", value: $hasLayout }\r\n { name: \"IncludeInMenu\", value: \"true\" }\r\n ]\r\n }\r\n first: $pageSize\r\n after: $after\r\n ) {\r\n total\r\n pageInfo {\r\n endCursor\r\n hasNext\r\n }\r\n results { \r\n \r\n url {\r\n path\r\n }\r\n }\r\n }\r\n }"; + + //the following query tested to return lookupfield displaynames + public const string GetSitemapQuery = "query SitemapQuery(\r\n $rootItemId: String = \"{A43C6692-60F4-4743-A1BE-6424DE611DFA}\"\r\n $language: String = \"en\"\r\n $pageSize: Int = 100\r\n $hasLayout: String = \"true\"\r\n $after: String\r\n) {\r\n search(\r\n where: {\r\n AND: [\r\n { name: \"_path\", value: $rootItemId, operator: CONTAINS }\r\n { name: \"_language\", value: $language }\r\n { name: \"_hasLayout\", value: $hasLayout }\r\n { name: \"IncludeinSitemap\", value: \"true\" }\r\n ]\r\n }\r\n first: $pageSize\r\n after: $after\r\n ) {\r\n total\r\n pageInfo {\r\n endCursor\r\n hasNext\r\n }\r\n results {\r\n updateddatetime: field(name: \"__updated\") {\r\n value\r\n }\r\n url {\r\n path\r\n }\r\n name\r\n ... on _Sitemap {\r\n priority {\r\n targetItem {\r\n displayName\r\n }\r\n }\r\n changeFrequency {\r\n targetItem {\r\n displayName\r\n }\r\n }\r\n }\r\n }\r\n }\r\n}\r\n"; } } } diff --git a/src/Project/MvpSite/rendering/Controllers/DefaultController.cs b/src/Project/MvpSite/rendering/Controllers/DefaultController.cs index 59cf430a..d14bd48c 100644 --- a/src/Project/MvpSite/rendering/Controllers/DefaultController.cs +++ b/src/Project/MvpSite/rendering/Controllers/DefaultController.cs @@ -4,22 +4,25 @@ using Sitecore.AspNet.RenderingEngine.Filters; using Sitecore.LayoutService.Client.Exceptions; using Sitecore.LayoutService.Client.Response.Model.Fields; -using System.Net; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Http.Extensions; using Okta.AspNetCore; using Mvp.Project.MvpSite.Middleware; +using Microsoft.AspNetCore.Http; +using Mvp.Project.MvpSite.Rendering; namespace Mvp.Project.MvpSite.Controllers { public class DefaultController : Controller { private readonly ILogger _logger; + private readonly SitemapBuilder _sitemap; - public DefaultController(ILogger logger) + public DefaultController(ILogger logger, SitemapBuilder sitemap) { _logger = logger; + _sitemap = sitemap; } // Inject Sitecore rendering middleware for this controller action @@ -78,5 +81,12 @@ public IActionResult Healthz() // TODO: Do we want to add logic here to confirm connectivity with SC etc? return Ok("Healthy"); } + + [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] + public IResult SiteMap() + { + var xml = _sitemap.GenerateAsync(); + return Results.Stream(xml.Result, "text/xml"); + } } } \ No newline at end of file diff --git a/src/Project/MvpSite/rendering/Middleware/CustomGraphQlLayoutServiceHandler.cs b/src/Project/MvpSite/rendering/Middleware/CustomGraphQlLayoutServiceHandler.cs index 86a8bfb2..1580c5d1 100644 --- a/src/Project/MvpSite/rendering/Middleware/CustomGraphQlLayoutServiceHandler.cs +++ b/src/Project/MvpSite/rendering/Middleware/CustomGraphQlLayoutServiceHandler.cs @@ -1,9 +1,11 @@ using Microsoft.Extensions.Configuration; using Mvp.Foundation.Configuration.Rendering.AppSettings; using Mvp.Foundation.DataFetching.GraphQL; +using Mvp.Project.MvpSite.Models; using Sitecore.LayoutService.Client.Request; using Sitecore.LayoutService.Client.RequestHandlers.GraphQL; using System; +using System.Collections.Generic; using System.Threading.Tasks; namespace Mvp.Project.MvpSite.Middleware @@ -38,7 +40,7 @@ public async Task CheckLayoutExists( var request = _graphQLRequestBuilder.BuildRequest(query, variables); var graphQlResponse = await client.SendQueryAsync(request); - string str = graphQlResponse?.Data?.Layout?.Item?.Rendered.ToString(); + string str = graphQlResponse.Data.Layout.Item.Rendered.ToString(); if (str == null) return false; } catch(Exception ex) @@ -49,6 +51,31 @@ public async Task CheckLayoutExists( return true; } + + public async Task> GetSitemap() + { + try + { + var client = _graphQLClientFactory.CreateGraphQlClient(); + var query = Constants.GraphQlQueries.GetSitemapQuery; + var variables = (object)new + { + rootItemId = "{94DE9AC3-A9F7-40AB-AE90-ACDA364B9C40}", + language = "en" + }; + + var request = _graphQLRequestBuilder.BuildRequest(query, variables); + var graphQlResponse = await client.SendQueryAsync(request); + + return graphQlResponse.Data.Search.Results; + } + catch (Exception ex) + { + _ = ex.Message;//log this? + return null; + } + + } } } diff --git a/src/Project/MvpSite/rendering/Models/SitemapModel.cs b/src/Project/MvpSite/rendering/Models/SitemapModel.cs new file mode 100644 index 00000000..d1594686 --- /dev/null +++ b/src/Project/MvpSite/rendering/Models/SitemapModel.cs @@ -0,0 +1,60 @@ +// Root myDeserializedClass = JsonConvert.DeserializeObject(myJsonResponse); +using System.Collections.Generic; + +public class ChangeFrequency +{ + public TargetItem TargetItem { get; set; } +} + +public class SitemapData +{ + public SearchData Search { get; set; } +} + +public class PageInfo +{ + public string endCursor { get; set; } + public bool hasNext { get; set; } +} + +public class Priority +{ + public TargetItem TargetItem { get; set; } +} + +public class Result +{ + public Updateddatetime UpdatedDatetime { get; set; } + public Url Url { get; set; } + public string Name { get; set; } + public Priority Priority { get; set; } + public ChangeFrequency ChangeFrequency { get; set; } +} + +public class Root +{ + public SitemapData Data { get; set; } +} + +public class SearchData +{ + public int total { get; set; } + public PageInfo pageInfo { get; set; } + public List Results { get; set; } +} + +public class TargetItem +{ + public string DisplayName { get; set; } +} + +public class Updateddatetime +{ + public string Value { get; set; } +} + +public class Url +{ + public string Path { get; set; } +} + diff --git a/src/Project/MvpSite/rendering/Mvp.Project.MvpSite.Rendering.csproj b/src/Project/MvpSite/rendering/Mvp.Project.MvpSite.Rendering.csproj index e1273cec..84b794c9 100644 --- a/src/Project/MvpSite/rendering/Mvp.Project.MvpSite.Rendering.csproj +++ b/src/Project/MvpSite/rendering/Mvp.Project.MvpSite.Rendering.csproj @@ -36,6 +36,7 @@ + diff --git a/src/Project/MvpSite/rendering/Sitemap/Providers/ISitemapUrlProvider.cs b/src/Project/MvpSite/rendering/Sitemap/Providers/ISitemapUrlProvider.cs new file mode 100644 index 00000000..689bf1f6 --- /dev/null +++ b/src/Project/MvpSite/rendering/Sitemap/Providers/ISitemapUrlProvider.cs @@ -0,0 +1,10 @@ +using DotnetSitemapGenerator; +using System.Collections.Generic; +using System.Threading.Tasks; + +namespace Mvp.Project.MvpSite.Rendering; + +public interface ISitemapUrlProvider +{ + Task> GetNodes(); +} \ No newline at end of file diff --git a/src/Project/MvpSite/rendering/Sitemap/Providers/MvpSitemapUrlProvider.cs b/src/Project/MvpSite/rendering/Sitemap/Providers/MvpSitemapUrlProvider.cs new file mode 100644 index 00000000..f023821e --- /dev/null +++ b/src/Project/MvpSite/rendering/Sitemap/Providers/MvpSitemapUrlProvider.cs @@ -0,0 +1,112 @@ +using DotnetSitemapGenerator; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Routing; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Mvp.Foundation.DataFetching.GraphQL; +using Mvp.Project.MvpSite.Middleware; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Threading.Tasks; + +namespace Mvp.Project.MvpSite.Rendering; + +public class Mvp +{ + public int Id { get; set; } + public string Name { get; set; } + public string Path { get; set; } +} + +public class MvpSitemapUrlProvider : ISitemapUrlProvider +{ + private readonly LinkGenerator _linkGenerator; + private readonly IHttpContextAccessor _httpContextAccessor; + private readonly ILogger _logger; + private readonly IGraphQLClientFactory _graphQLClientFactory; + private readonly IGraphQLRequestBuilder _graphQLRequestBuilder; + private readonly IConfiguration _configuration; + + public MvpSitemapUrlProvider( + LinkGenerator linkGenerator, + IHttpContextAccessor httpContextAccessor, + ILogger logger, + IGraphQLClientFactory graphQLClientFactory, + IGraphQLRequestBuilder graphQLRequestBuilder, + IConfiguration configuration) + { + _linkGenerator = linkGenerator; + _httpContextAccessor = httpContextAccessor; + _logger = logger; + _graphQLClientFactory = graphQLClientFactory; + _graphQLRequestBuilder = graphQLRequestBuilder; + _configuration = configuration; + } + + private static DotnetSitemapGenerator.ChangeFrequency GetChangeFrequency(string changefreq) + { + if (string.IsNullOrWhiteSpace(changefreq)) { return DotnetSitemapGenerator.ChangeFrequency.Never; } + + switch (changefreq.ToLowerInvariant()) + { + case "always": + return DotnetSitemapGenerator.ChangeFrequency.Always; + case "daily": + return DotnetSitemapGenerator.ChangeFrequency.Daily; + case "weekly": + return DotnetSitemapGenerator.ChangeFrequency.Weekly; + case "yearly": + return DotnetSitemapGenerator.ChangeFrequency.Yearly; + case "hourly": + return DotnetSitemapGenerator.ChangeFrequency.Hourly; + case "never": + return DotnetSitemapGenerator.ChangeFrequency.Never; + } + + return DotnetSitemapGenerator.ChangeFrequency.Never; + } + + public Task> GetNodes() + { + var nodes = new List(); + var results = GetSiteMap(); + + foreach (var result in results) + { + var url = _httpContextAccessor.HttpContext.Request.Scheme + "://" + _httpContextAccessor.HttpContext.Request.Host.Value + result.Url.Path; + + _logger.LogInformation("Adding product: {URL}", url); + + SitemapNode node = new(url) + { + LastModificationDate = DateTime.ParseExact(result.UpdatedDatetime.Value, + "yyyyMMdd'T'HHmmss'Z'", + CultureInfo.InvariantCulture), + Priority = Convert.ToDecimal(result.Priority.TargetItem.DisplayName), + ChangeFrequency = GetChangeFrequency(result.ChangeFrequency.TargetItem.DisplayName) + }; + nodes.Add(node); + } + + return Task.FromResult>(nodes); + } + + + private List GetMvpList() { + return ( + [ + new () { Id = 1, Name = "Home" }, + new () { Id = 2, Name = "About" }, + new() { Id = 3, Name = "Become an MVP" }, + new() { Id = 4, Name = "Contact" }, + new() { Id = 5, Name = "MVP List" } + ]); + } + + private List GetSiteMap() + { + CustomGraphQlLayoutServiceHandler customGraphQlLayoutServiceHandler = new(_configuration, _graphQLRequestBuilder, _graphQLClientFactory); + return customGraphQlLayoutServiceHandler.GetSitemap().Result; + } +} \ No newline at end of file diff --git a/src/Project/MvpSite/rendering/Sitemap/SitemapBuilder.cs b/src/Project/MvpSite/rendering/Sitemap/SitemapBuilder.cs new file mode 100644 index 00000000..61bdda09 --- /dev/null +++ b/src/Project/MvpSite/rendering/Sitemap/SitemapBuilder.cs @@ -0,0 +1,33 @@ +using DotnetSitemapGenerator; +using DotnetSitemapGenerator.Serialization; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; + +namespace Mvp.Project.MvpSite.Rendering; + +public class SitemapBuilder +{ + private readonly IEnumerable _providers; + + public SitemapBuilder(IEnumerable providers) + { + _providers = providers; + } + + public async Task GenerateAsync() + { + var nodes = new List(); + foreach (var provider in _providers) + { + nodes.AddRange(await provider.GetNodes()); + } + + IXmlSerializer sitemapProvider = new XmlSerializer(); + var memory = new MemoryStream(); + sitemapProvider.SerializeToStream(new SitemapModel(nodes), memory); + // reset the stream to the start + memory.Position = 0; + return memory; + } +} \ No newline at end of file diff --git a/src/Project/MvpSite/rendering/Sitemap/SitemapExtensions.cs b/src/Project/MvpSite/rendering/Sitemap/SitemapExtensions.cs new file mode 100644 index 00000000..5780e7bd --- /dev/null +++ b/src/Project/MvpSite/rendering/Sitemap/SitemapExtensions.cs @@ -0,0 +1,13 @@ +using Microsoft.Extensions.DependencyInjection; + +namespace Mvp.Project.MvpSite.Rendering; + +public static class SitemapExtensions +{ + public static void AddSitemap(this IServiceCollection services) + { + // add sitemap services + services.AddScoped(); + services.AddScoped(); + } +} \ No newline at end of file diff --git a/src/Project/MvpSite/rendering/Sitemap/SitemapResponse.cs b/src/Project/MvpSite/rendering/Sitemap/SitemapResponse.cs new file mode 100644 index 00000000..898cb7d4 --- /dev/null +++ b/src/Project/MvpSite/rendering/Sitemap/SitemapResponse.cs @@ -0,0 +1,20 @@ +using System.Text.Json; + +namespace Mvp.Project.MvpSite.Sitemap +{ + public class SitemapQueryResponse + { + // + // Summary: + // Gets or sets Layout Service GraphQL Response. + public SitemapModel SiteMap { get; set; } + } + + public class SitemapModel + { + // + // Summary: + // Gets or sets Layout Service GraphQL Response. + public JsonElement? Sitemap { get; set; } + } +} diff --git a/src/Project/MvpSite/rendering/Startup.cs b/src/Project/MvpSite/rendering/Startup.cs index 13a0c61f..5bcda33a 100644 --- a/src/Project/MvpSite/rendering/Startup.cs +++ b/src/Project/MvpSite/rendering/Startup.cs @@ -58,6 +58,8 @@ public void ConfigureServices(IServiceCollection services) .AddGraphQlHandler("default", Configuration.DefaultSiteName!, Configuration.ExperienceEdgeToken!, Configuration.LayoutServiceUri!) .AsDefaultHandler(); + services.AddHttpContextAccessor(); + services.AddSitemap(); services.AddFeatureUser(DotNetConfiguration); // Register the Sitecore Rendering Engine services. @@ -141,8 +143,7 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) // Enable Authentication & Authorization app.UseAuthentication(); - app.UseAuthorization(); - + app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( @@ -155,6 +156,12 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) "healthz", "healthz", new { controller = "Default", action = "Healthz" } + ); + + endpoints.MapControllerRoute( + "Sitemap", + "sitemap.xml", + new { controller = "Default", action = "SiteMap" } ); endpoints.MapOktaSigninRoute(); diff --git a/src/Project/MvpSite/rendering/appsettings.Development.json b/src/Project/MvpSite/rendering/appsettings.Development.json index 3dae2617..8f1c2d3c 100644 --- a/src/Project/MvpSite/rendering/appsettings.Development.json +++ b/src/Project/MvpSite/rendering/appsettings.Development.json @@ -16,11 +16,11 @@ } }, "AllowedHosts": "*", - "Okta" : { - "OktaDomain": "<>", - "ClientId": "<>", - "ClientSecret": "<>", - "AuthorizationServerId": "<>" + "Okta": { + "OktaDomain": "https:////dev-84331964.okta.com/", + "ClientId": "0oadc6ep0gRdeNCdT5d7", + "ClientSecret": "bKTgt2uVS6-xsiv6COly3jvFYXHDOaAHzUhfkwVGop2bmAbgaa9wpAB-LhnV5q2r", + "AuthorizationServerId": "default" }, "MvpSelectionsApiClient": { "BaseAddress": "<>" diff --git a/src/XmCloudIntroduction.sln b/src/XmCloudIntroduction.sln index fb578466..ebd2068a 100644 --- a/src/XmCloudIntroduction.sln +++ b/src/XmCloudIntroduction.sln @@ -100,57 +100,107 @@ EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU + Debug|x64 = Debug|x64 Release|Any CPU = Release|Any CPU + Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {816F099C-E14B-4468-9E34-87F993C6484D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {816F099C-E14B-4468-9E34-87F993C6484D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {816F099C-E14B-4468-9E34-87F993C6484D}.Debug|x64.ActiveCfg = Debug|Any CPU + {816F099C-E14B-4468-9E34-87F993C6484D}.Debug|x64.Build.0 = Debug|Any CPU {816F099C-E14B-4468-9E34-87F993C6484D}.Release|Any CPU.ActiveCfg = Release|Any CPU {816F099C-E14B-4468-9E34-87F993C6484D}.Release|Any CPU.Build.0 = Release|Any CPU + {816F099C-E14B-4468-9E34-87F993C6484D}.Release|x64.ActiveCfg = Release|Any CPU + {816F099C-E14B-4468-9E34-87F993C6484D}.Release|x64.Build.0 = Release|Any CPU {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Debug|x64.ActiveCfg = Debug|Any CPU + {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Debug|x64.Build.0 = Debug|Any CPU {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Release|Any CPU.ActiveCfg = Release|Any CPU {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Release|Any CPU.Build.0 = Release|Any CPU + {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Release|x64.ActiveCfg = Release|Any CPU + {2C5CF268-B0A9-4578-BB3C-1C93C53798E0}.Release|x64.Build.0 = Release|Any CPU {565AC1EA-01B0-4A93-8230-17081AE133A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {565AC1EA-01B0-4A93-8230-17081AE133A6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {565AC1EA-01B0-4A93-8230-17081AE133A6}.Debug|x64.ActiveCfg = Debug|Any CPU + {565AC1EA-01B0-4A93-8230-17081AE133A6}.Debug|x64.Build.0 = Debug|Any CPU {565AC1EA-01B0-4A93-8230-17081AE133A6}.Release|Any CPU.ActiveCfg = Release|Any CPU {565AC1EA-01B0-4A93-8230-17081AE133A6}.Release|Any CPU.Build.0 = Release|Any CPU + {565AC1EA-01B0-4A93-8230-17081AE133A6}.Release|x64.ActiveCfg = Release|Any CPU + {565AC1EA-01B0-4A93-8230-17081AE133A6}.Release|x64.Build.0 = Release|Any CPU {18086145-57F9-46EB-9213-6764DA298779}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {18086145-57F9-46EB-9213-6764DA298779}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18086145-57F9-46EB-9213-6764DA298779}.Debug|x64.ActiveCfg = Debug|Any CPU + {18086145-57F9-46EB-9213-6764DA298779}.Debug|x64.Build.0 = Debug|Any CPU {18086145-57F9-46EB-9213-6764DA298779}.Release|Any CPU.ActiveCfg = Release|Any CPU {18086145-57F9-46EB-9213-6764DA298779}.Release|Any CPU.Build.0 = Release|Any CPU + {18086145-57F9-46EB-9213-6764DA298779}.Release|x64.ActiveCfg = Release|Any CPU + {18086145-57F9-46EB-9213-6764DA298779}.Release|x64.Build.0 = Release|Any CPU {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Debug|Any CPU.Build.0 = Debug|Any CPU + {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Debug|x64.ActiveCfg = Debug|Any CPU + {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Debug|x64.Build.0 = Debug|Any CPU {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Release|Any CPU.ActiveCfg = Release|Any CPU {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Release|Any CPU.Build.0 = Release|Any CPU + {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Release|x64.ActiveCfg = Release|Any CPU + {79D774C4-1B40-48E3-8F84-880A02A63E7D}.Release|x64.Build.0 = Release|Any CPU {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Debug|x64.ActiveCfg = Debug|Any CPU + {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Debug|x64.Build.0 = Debug|Any CPU {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Release|Any CPU.ActiveCfg = Release|Any CPU {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Release|Any CPU.Build.0 = Release|Any CPU + {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Release|x64.ActiveCfg = Release|Any CPU + {5FF0FB81-8059-49E2-AF0A-C5CB8798067A}.Release|x64.Build.0 = Release|Any CPU {B9CDEDA7-3719-431E-8D57-72460403E934}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B9CDEDA7-3719-431E-8D57-72460403E934}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B9CDEDA7-3719-431E-8D57-72460403E934}.Debug|x64.ActiveCfg = Debug|Any CPU + {B9CDEDA7-3719-431E-8D57-72460403E934}.Debug|x64.Build.0 = Debug|Any CPU {B9CDEDA7-3719-431E-8D57-72460403E934}.Release|Any CPU.ActiveCfg = Release|Any CPU {B9CDEDA7-3719-431E-8D57-72460403E934}.Release|Any CPU.Build.0 = Release|Any CPU + {B9CDEDA7-3719-431E-8D57-72460403E934}.Release|x64.ActiveCfg = Release|Any CPU + {B9CDEDA7-3719-431E-8D57-72460403E934}.Release|x64.Build.0 = Release|Any CPU {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Debug|x64.ActiveCfg = Debug|Any CPU + {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Debug|x64.Build.0 = Debug|Any CPU {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Release|Any CPU.ActiveCfg = Release|Any CPU {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Release|Any CPU.Build.0 = Release|Any CPU + {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Release|x64.ActiveCfg = Release|Any CPU + {0BD6638A-3A5A-406A-8453-4DA6B35886FC}.Release|x64.Build.0 = Release|Any CPU {89A72153-4995-4607-98B1-B8C75679926E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89A72153-4995-4607-98B1-B8C75679926E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89A72153-4995-4607-98B1-B8C75679926E}.Debug|x64.ActiveCfg = Debug|Any CPU + {89A72153-4995-4607-98B1-B8C75679926E}.Debug|x64.Build.0 = Debug|Any CPU {89A72153-4995-4607-98B1-B8C75679926E}.Release|Any CPU.ActiveCfg = Release|Any CPU {89A72153-4995-4607-98B1-B8C75679926E}.Release|Any CPU.Build.0 = Release|Any CPU + {89A72153-4995-4607-98B1-B8C75679926E}.Release|x64.ActiveCfg = Release|Any CPU + {89A72153-4995-4607-98B1-B8C75679926E}.Release|x64.Build.0 = Release|Any CPU {44C9267F-344E-4AE3-BF21-90874835B7E2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {44C9267F-344E-4AE3-BF21-90874835B7E2}.Debug|Any CPU.Build.0 = Debug|Any CPU + {44C9267F-344E-4AE3-BF21-90874835B7E2}.Debug|x64.ActiveCfg = Debug|Any CPU + {44C9267F-344E-4AE3-BF21-90874835B7E2}.Debug|x64.Build.0 = Debug|Any CPU {44C9267F-344E-4AE3-BF21-90874835B7E2}.Release|Any CPU.ActiveCfg = Release|Any CPU {44C9267F-344E-4AE3-BF21-90874835B7E2}.Release|Any CPU.Build.0 = Release|Any CPU + {44C9267F-344E-4AE3-BF21-90874835B7E2}.Release|x64.ActiveCfg = Release|Any CPU + {44C9267F-344E-4AE3-BF21-90874835B7E2}.Release|x64.Build.0 = Release|Any CPU {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Debug|x64.ActiveCfg = Debug|Any CPU + {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Debug|x64.Build.0 = Debug|Any CPU {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Release|Any CPU.ActiveCfg = Release|Any CPU {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Release|Any CPU.Build.0 = Release|Any CPU + {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Release|x64.ActiveCfg = Release|Any CPU + {AA28B48F-C2A3-4F20-969B-4E6BAFE56F28}.Release|x64.Build.0 = Release|Any CPU {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Debug|x64.ActiveCfg = Debug|Any CPU + {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Debug|x64.Build.0 = Debug|Any CPU {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Release|Any CPU.ActiveCfg = Release|Any CPU {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Release|Any CPU.Build.0 = Release|Any CPU + {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Release|x64.ActiveCfg = Release|Any CPU + {B4EC41A8-ECA9-488C-88A0-2B6F91584B02}.Release|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE