diff --git a/src/UmbracoUrlHandling/App_Data/Models/all.dll.path b/src/UmbracoUrlHandling/App_Data/Models/all.dll.path index 68bc0fd..8ced112 100644 --- a/src/UmbracoUrlHandling/App_Data/Models/all.dll.path +++ b/src/UmbracoUrlHandling/App_Data/Models/all.dll.path @@ -1 +1 @@ -C:\Users\mantu\AppData\Local\Temp\Temporary ASP.NET Files\vs\027ab051\822a0174\App_Web_all.generated.cs.8f9494c4.oibqrept.dll \ No newline at end of file +C:\Users\brendeld\AppData\Local\Temp\Temporary ASP.NET Files\vs\db0e3ea5\41b4334d\App_Web_all.generated.cs.8f9494c4.feq1txiv.dll \ No newline at end of file diff --git a/src/UmbracoUrlHandling/App_Data/Models/all.generated.cs b/src/UmbracoUrlHandling/App_Data/Models/all.generated.cs index 115b903..460dc58 100644 --- a/src/UmbracoUrlHandling/App_Data/Models/all.generated.cs +++ b/src/UmbracoUrlHandling/App_Data/Models/all.generated.cs @@ -8,7 +8,7 @@ using Umbraco.ModelsBuilder; using Umbraco.ModelsBuilder.Umbraco; [assembly: PureLiveAssembly] -[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "e4d2aa0bdb7a3315")] +[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "4ad86b1aa0722510")] [assembly:System.Reflection.AssemblyVersion("0.0.0.1")] @@ -83,6 +83,15 @@ public string Introduction get { return this.GetPropertyValue("introduction"); } } + /// + /// Tags: Tags related to this blog post + /// + [ImplementPropertyType("tags")] + public IEnumerable Tags + { + get { return this.GetPropertyValue>("tags"); } + } + /// /// Url Name: The url name which should be used /// diff --git a/src/UmbracoUrlHandling/App_Data/Models/models.generated.cs b/src/UmbracoUrlHandling/App_Data/Models/models.generated.cs index 29a3196..1bb92fb 100644 --- a/src/UmbracoUrlHandling/App_Data/Models/models.generated.cs +++ b/src/UmbracoUrlHandling/App_Data/Models/models.generated.cs @@ -19,7 +19,7 @@ using Umbraco.ModelsBuilder.Umbraco; [assembly: PureLiveAssembly] -[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "e4d2aa0bdb7a3315")] +[assembly:ModelsBuilderAssembly(PureLive = true, SourceHash = "4ad86b1aa0722510")] [assembly:System.Reflection.AssemblyVersion("0.0.0.2")] namespace Umbraco.Web.PublishedContentModels @@ -67,6 +67,15 @@ public string Introduction get { return this.GetPropertyValue("introduction"); } } + /// + /// Tags: Tags related to this blog post + /// + [ImplementPropertyType("tags")] + public IEnumerable Tags + { + get { return this.GetPropertyValue>("tags"); } + } + /// /// Url Name: The url name which should be used /// diff --git a/src/UmbracoUrlHandling/App_Data/Models/models.hash b/src/UmbracoUrlHandling/App_Data/Models/models.hash index 4061f08..c9c743b 100644 --- a/src/UmbracoUrlHandling/App_Data/Models/models.hash +++ b/src/UmbracoUrlHandling/App_Data/Models/models.hash @@ -1 +1 @@ -e4d2aa0bdb7a3315 \ No newline at end of file +4ad86b1aa0722510 \ No newline at end of file diff --git a/src/UmbracoUrlHandling/App_Data/Umbraco.sdf b/src/UmbracoUrlHandling/App_Data/Umbraco.sdf index 01d94a4..91bec56 100644 Binary files a/src/UmbracoUrlHandling/App_Data/Umbraco.sdf and b/src/UmbracoUrlHandling/App_Data/Umbraco.sdf differ diff --git a/src/UmbracoUrlHandling/Controller/BlogPostRepositoryController.cs b/src/UmbracoUrlHandling/Controller/BlogPostRepositoryController.cs new file mode 100644 index 0000000..1db8624 --- /dev/null +++ b/src/UmbracoUrlHandling/Controller/BlogPostRepositoryController.cs @@ -0,0 +1,42 @@ +using System.Linq; +using System.Web.Mvc; +using Umbraco.Web.Models; +using Umbraco.Web.Mvc; +using UmbracoUrlHandling.Models; + +namespace UmbracoUrlHandling.Controller +{ + /// + /// Route hijacking using controller to handle custom model building for templates + /// + /// + public class BlogPostRepositoryController : RenderMvcController + { + /// + /// Method to show tags overview template. + /// + /// The model. + /// + public ActionResult Categories(RenderModel model) + { + var tags = Services.TagService.GetAllContentTags().ToList(); + var viewModel = new TagsOverviewViewModel(model.Content) {Tags = tags}; + return View("TagsOverview", viewModel); + } + + /// + /// Shows all content that was tagged with a specific category. + /// + /// The model. + /// The category. + /// + public ActionResult Category(RenderModel model, string category) + { + var tagsService = Services.TagService; + var relatedContentTaggedEntities = tagsService.GetTaggedContentByTag(category); + var relatedContent = Umbraco.TypedContent(relatedContentTaggedEntities.Select(x => x.EntityId)); + var viewModel = new CategoryContentViewModel(model.Content) { Category = category, RelatedContentForCategory = relatedContent}; + return View("RelatedContentForCategory", viewModel); + } + } +} \ No newline at end of file diff --git a/src/UmbracoUrlHandling/Models/CategoryContentViewModel.cs b/src/UmbracoUrlHandling/Models/CategoryContentViewModel.cs new file mode 100644 index 0000000..ae1d02a --- /dev/null +++ b/src/UmbracoUrlHandling/Models/CategoryContentViewModel.cs @@ -0,0 +1,37 @@ +using System.Collections.Generic; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; + +namespace UmbracoUrlHandling.Models +{ + /// + /// ViewModel to render all content for aspecific category + /// + /// + public class CategoryContentViewModel : PublishedContentWrapped + { + /// + /// Initializes a new instance of the class. + /// + /// The content to wrap and extend. + public CategoryContentViewModel(IPublishedContent content) : base(content) + { + } + + /// + /// Gets or sets the category. + /// + /// + /// The category. + /// + public string Category { get; set; } + + /// + /// Gets or sets the related content for category. + /// + /// + /// The related content for category. + /// + public IEnumerable RelatedContentForCategory { get; set; } + } +} \ No newline at end of file diff --git a/src/UmbracoUrlHandling/Models/TagsOverviewViewModel.cs b/src/UmbracoUrlHandling/Models/TagsOverviewViewModel.cs new file mode 100644 index 0000000..05ebf0b --- /dev/null +++ b/src/UmbracoUrlHandling/Models/TagsOverviewViewModel.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using Umbraco.Core.Models; +using Umbraco.Core.Models.PublishedContent; + +namespace UmbracoUrlHandling.Models +{ + /// + /// View model for tags overview of blog posts + /// + /// + public class TagsOverviewViewModel : PublishedContentWrapped + { + /// + /// Initializes a new instance of the class. + /// + /// The content to wrap and extend. + public TagsOverviewViewModel(IPublishedContent content) : base(content) + { + } + + /// + /// Gets or sets the tags. + /// + /// + /// The tags. + /// + public IEnumerable Tags { get; set; } + } +} \ No newline at end of file diff --git a/src/UmbracoUrlHandling/RouteHandler/BlogRepositoryRouteHandler.cs b/src/UmbracoUrlHandling/RouteHandler/BlogRepositoryRouteHandler.cs new file mode 100644 index 0000000..49d95db --- /dev/null +++ b/src/UmbracoUrlHandling/RouteHandler/BlogRepositoryRouteHandler.cs @@ -0,0 +1,19 @@ +using Umbraco.Web.Mvc; + +namespace UmbracoUrlHandling.RouteHandler +{ + /// + /// BlogPostRepositoryrouteHandler to handle routes to BlogPostRepository + /// + /// + public class BlogRepositoryRouteHandler : UmbracoVirtualNodeByIdRouteHandler + { + /// + /// Initializes a new instance of the class. + /// + /// The real node identifier. + public BlogRepositoryRouteHandler(int realNodeId) : base(realNodeId) + { + } + } +} \ No newline at end of file diff --git a/src/UmbracoUrlHandling/Startup.cs b/src/UmbracoUrlHandling/Startup.cs index 5eb6997..2a552ec 100644 --- a/src/UmbracoUrlHandling/Startup.cs +++ b/src/UmbracoUrlHandling/Startup.cs @@ -1,4 +1,5 @@ -using System.Web; +using System.Linq; +using System.Web; using System.Web.Mvc; using System.Web.Routing; using Umbraco.Core; @@ -27,6 +28,7 @@ public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, App ContentFinderResolver.Current.InsertTypeBefore(); + //Make a route based on a node Id RouteTable.Routes.MapUmbracoRoute( "ProductRoute", "Products/{sku}", @@ -43,6 +45,36 @@ public void OnApplicationStarting(UmbracoApplicationBase umbracoApplication, App public void OnApplicationStarted(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) { ContentService.Published += (sender, args) => HttpContext.Current.Cache.Remove("CachedBlogPostNodes"); + + //Dynamic routes based on node type and node urls + var blogRepositoryNodes = UmbracoContext.Current.ContentCache.GetByXPath("//BlogPostRepository").ToArray(); + + foreach (var repository in blogRepositoryNodes) + { + var uri = repository.Url().TrimStart("/"); + var hash = uri.GetHashCode(); + + RouteTable.Routes.MapUmbracoRoute( + $"blog_repository_categories_{hash}", + $"{uri.EnsureEndsWith('/')}categories/", + new + { + controller = "BlogPostRepository", + action = "Categories" + }, + new BlogRepositoryRouteHandler(repository.Id)); + + RouteTable.Routes.MapUmbracoRoute( + $"blog_repository_category_{hash}", + $"{uri.EnsureEndsWith('/')}category/{{category}}", + new + { + controller = "BlogPostRepository", + action = "Category", + category = UrlParameter.Optional + }, + new BlogRepositoryRouteHandler(repository.Id)); + } } } } \ No newline at end of file diff --git a/src/UmbracoUrlHandling/UmbracoUrlHandling.csproj b/src/UmbracoUrlHandling/UmbracoUrlHandling.csproj index 811722a..ce23b8a 100644 --- a/src/UmbracoUrlHandling/UmbracoUrlHandling.csproj +++ b/src/UmbracoUrlHandling/UmbracoUrlHandling.csproj @@ -294,6 +294,8 @@ + + Web.config @@ -331,7 +333,11 @@ + + + + diff --git a/src/UmbracoUrlHandling/Views/RelatedContentForCategory.cshtml b/src/UmbracoUrlHandling/Views/RelatedContentForCategory.cshtml new file mode 100644 index 0000000..4f77a71 --- /dev/null +++ b/src/UmbracoUrlHandling/Views/RelatedContentForCategory.cshtml @@ -0,0 +1,14 @@ +@inherits UmbracoViewPage +@{ + Layout = "Master.cshtml"; +} + +

Pages related to category "@Model.Category":

+
    + @foreach (var content in Model.RelatedContentForCategory) + { +
  • + @content.Name +
  • + } +
\ No newline at end of file diff --git a/src/UmbracoUrlHandling/Views/TagsOverview.cshtml b/src/UmbracoUrlHandling/Views/TagsOverview.cshtml new file mode 100644 index 0000000..e81645d --- /dev/null +++ b/src/UmbracoUrlHandling/Views/TagsOverview.cshtml @@ -0,0 +1,13 @@ +@inherits UmbracoViewPage +@{ + Layout = "Master.cshtml"; +} + +

All tags

+ +
    + @foreach (var tag in Model.Tags) + { +
  • @tag.Text
  • + } +
\ No newline at end of file