Søren Mastrup
06/25/2024, 7:44 AMFrontpage
├── About us
├── Random Page
├── Products
│ ├── Category #1 (Virtual)
│ │ ├── Product #1.1 (Virtual)
│ │ ├── Product #1.2 (Virtual)
│ ├── Category #2 (Virtual)
│ │ ├── Product #2.1 (Virtual)
│ │ ├── Product #2.2 (Virtual)
│ │ ├── Product #2.3 (Virtual)
After reading various posts in the forum, it seems that it can be done with either a Custom routes within the Umbraco pipeline (https://docs.umbraco.com/umbraco-cms/v/13.latest-lts/reference/routing/custom-routes#custom-routes-within-the-umbraco-pipeline) or a Content Finder (https://docs.umbraco.com/umbraco-cms/v/13.latest-lts/reference/routing/request-pipeline/icontentfinder).
I currently have it working with a custom controller that implements the IVirtualPageController
interface so I am able to request:
/en-us/products/category-1-virtual
/en-us/products/category-1-virtual/product-1-1
Since my site uses language variants, I need the routes to be dynamic so I can generate the routes for each language, so I have like:
/en-us/products/category-1-virtual
/en-us/products/category-1-virtual/product-1-1
/da-dk/produkter/category-1-virtual
/da-dk/produkter/category-1-virtual/product-1-1
Also, the routes must only live beneath existing nodes in Umbraco that is of the type productsOverview
.
In the example above, it would be the Products node
Any suggestions as to how this might be achieved would be most welcome.Kaspar Boel Kjeldsen
06/27/2024, 12:45 PMcsharp
public void Compose(IUmbracoBuilder builder)
{
builder.Services.Configure<UmbracoPipelineOptions>(options =>
{
options.AddFilter(new UmbracoPipelineFilter(nameof(EventPageController))
{
Endpoints = app => app.UseEndpoints(e =>
{
// danish
e.MapControllerRoute("EventPageController", "/dk/arrangementer/{eventName}/{id}", new { Controller = "EventPage", Action = "Index" });
e.MapControllerRoute("EventPageController", "/dk/arrangementer/{eventName}/{id}/tilmeld", new { Controller = "EventRegistrationPage", Action = "Index" });
e.MapControllerRoute("EventPageController", "/dk/arrangementer/{eventName}/{id}/tak", new { Controller = "EventConfirmationPage", Action = "Index" });
e.MapControllerRoute("EventPageController", "/dk/arrangementer/{eventName}/{id}/rediger", new { Controller = "EventUpdatePage", Action = "Index" });
// english
e.MapControllerRoute("EventPageController", "/en/events/{eventName}/{id}", new { Controller = "EventPage", Action = "Index" });
e.MapControllerRoute("EventPageController", "/en/evens/{eventName}/{id}/signup", new { Controller = "EventRegistrationPage", Action = "Index" });
e.MapControllerRoute("EventPageController", "/en/events/{eventName}/{id}/thanks", new { Controller = "EventConfirmationPage", Action = "Index" });
e.MapControllerRoute("EventPageController", "/dk/events/{eventName}/{id}/edit", new { Controller = "EventUpdatePage", Action = "Index" });
})
});
});
}
}
Kaspar Boel Kjeldsen
06/27/2024, 12:45 PMcsharp
public IPublishedContent? FindContent(ActionExecutingContext actionExecutingContext)
{
_umbracoContextAccessor.TryGetUmbracoContext(out var umbracoContext);
// danish or english ?
var culture = actionExecutingContext.HttpContext.Request.RawUrl().Contains("arrangementer") ? "dk" : "en";
var eventContainer = umbracoContext.Content.GetByContentType(EventContainer.GetModelContentType(_publishedSnapshotAccessor))
.FirstOrDefault(x => (culture == "en" && x.Name == "Events") || (culture == "dk" && x.Name != "Events"));;
var eventPage = eventContainer.Descendant<Finansforbundet.Code.Models.EventPage>();
return eventPage;
}
Note that this doesn't work proper from 13.3.1 through 13.3.2 but was fixed in 13.4Sebastiaan
06/27/2024, 1:50 PMSebastiaan
06/27/2024, 1:50 PMKaspar Boel Kjeldsen
07/01/2024, 7:06 AMSøren Mastrup
07/02/2024, 6:23 AM