Same controller different views?

Is there a way to use the same page field template (and controller) for different websites but have separate views for each website? Like in previous versions where you could use the same pagetype but could use a different pagetemplate for each website.

Litium version: 7

Often when you return a view you are using something like this

        public ActionResult Index(CategoryModel currentCategoryModel)
        {
            var model = ...;
            return View(model);
        }

and if you instead is doing the following you are using the my_special_view instead of the default for this controller.

        public ActionResult Index(CategoryModel currentCategoryModel)
        {
            var model = ...;
            return View("my_special_view", model);
        }

To be able to have multiple different controller/views exists only as an inbuilt function for product display templates, not for pages.

In previous to the Litium 7 we have the Litium.Foundation.Modules.CMS.Plugins.Templates.ITemplateResolver extension point where you was able to rewrite the template path for the request.
In Litium 7 version you need to decorate the Litium.Web.Routing.PageRouteResolver and change the template on the return object instead.

Thanks Patric! We’ll try this.

@patric.forsgard Could you elaborate on how to implement this or provide some pointers? Tried searching on docs.litium.com but couldn’t find anything.

I don’t think we have any documentation about this on docs-site but maybe this example will help.

        public ActionResult Index(WebsiteModel currentWebsiteModel, CategoryModel currentCategoryModel)
        {
            var model = ...;
            var websiteTemplateSuffix = currentWebsiteModel.GetValue<string>("TemplateSuffix");
            return View(websiteTemplateSuffix == null ? namof(Index) : nameof(Index) + "_" + websiteTemplateSuffix, model);
        }

then the view name should be like Index_[websiteTemplateSuffix].cshtml where [websiteTemplateSuffix] is replaced with the websiteTemplateSuffix-field-value for each website.

And what about the PageRouteResolver that you suggested, how does that figure in this? I thought that we only had to implement that to be able to have different views folders and not have to add logic to the controllers but maybe that’s not doable?

PageRouteResolver is sued if you want to rewrite the template path all together, example change what controller that should be executed for the request. Have not any example how you can do that.

You can always make changes in the base class that the controller is inherited from so you don’t need to add the logic in each of the controller but instead in one common place that will reflect all of them. Se example the ControllerBase in accelerator where we set different masterName depend on the context.

Thanks! Is there a way to get the current website another way than injecting the WebsiteModel in all controller actions? Some way of using e.g. the ControllerContext e.g.? In previous versions Litium you had the Litium.Foundation.Modules.CMS.Routing.Route.RouteUtilities.Parse(HttpContext) method which could be used for this.

So it seems we can use property injection in our base controller class to get a RequestModelAccessor and then simply access the RequestModelAccessor.RequestModel.WebsiteModel. Will this work?

Yes, the RequestModelAccessor is the way to go. You can add that as a property on the base-controller you are building like we are using the MenuViewModelBuilder in the accelerator ControllerBase.

        [FromService]
        public MenuViewModelBuilder MenuViewModelBuilder { get; set; }

The [FromService] is a special attribute we created in the Mvc-part to be able to do property-injection of services so we not was needing to pass that into all controllers and down to the base-controller.