It is possible to retrieve the IPage model object from a Component Presentation context. Whether this is a good practice or not, I'm not going to debate it here. In case you need the IPage object, this is how to get it.
From Component Controller
The simplest way to retrieve the IPage model is to have your Component controllers extend TridionControllerBase, then call base method GetComponentPresentation().
The returned object contains a property Page, which gets the IPage model.
This however doesn't always work, namely when the Component Presentation is dynamic is doesn't actually reside on the page.
From ViewContext in Component Controller
This approach relies on the way Component Presentations are rendered by DD4T. Namely, the CPs are rendered from a context of the Page Razor view, by means of calling Html.Action behind the scenes.
This means the Component controller's property ControllerContext has knowledge of the parent ViewContext, which, through the ViewData property could give us the Model representing the IPage model. I say could, because the views and actions could be nested even further, so that it is unclear which view model will be the IPage. In this situation, one can just skip up the parent ViewContext chain until it finds an IPage model.
From HtmlHelper Extension Method
An HtmlHelper object has access to the ViewContext of the current action. Therefore, any extension method of HtmlHelper can access this property as well.
The logic further is very similar to the previous example: one can check the ViewData.Model properties and retrieve the potential IPage model. In case the views/actions are nested further, we can skip up the ParentActionViewContext property to retrieve their model object.
From Component Controller
The simplest way to retrieve the IPage model is to have your Component controllers extend TridionControllerBase, then call base method GetComponentPresentation().
The returned object contains a property Page, which gets the IPage model.
This however doesn't always work, namely when the Component Presentation is dynamic is doesn't actually reside on the page.
public class DeviceController : TridionControllerBase { public ActionResult Index() { IComponentPresentation componentPresentation = GetComponentPresentation(); IPage page = componentPresentation.Page;
From ViewContext in Component Controller
This approach relies on the way Component Presentations are rendered by DD4T. Namely, the CPs are rendered from a context of the Page Razor view, by means of calling Html.Action behind the scenes.
This means the Component controller's property ControllerContext has knowledge of the parent ViewContext, which, through the ViewData property could give us the Model representing the IPage model. I say could, because the views and actions could be nested even further, so that it is unclear which view model will be the IPage. In this situation, one can just skip up the parent ViewContext chain until it finds an IPage model.
public IPage GetPage() { IPage page = null; ViewContext context = ControllerContext.ParentActionViewContext; while (page == null && context != null) { page = context.ViewData.Model as IPage; context = context.ParentActionViewContext; } return page; }
From HtmlHelper Extension Method
An HtmlHelper object has access to the ViewContext of the current action. Therefore, any extension method of HtmlHelper can access this property as well.
The logic further is very similar to the previous example: one can check the ViewData.Model properties and retrieve the potential IPage model. In case the views/actions are nested further, we can skip up the ParentActionViewContext property to retrieve their model object.
private static IPage GetPage(HtmlHelper htmlHelper) { IPage page = htmlHelper.ViewData.Model as IPage; if (page == null) { ViewContext context = htmlHelper.ViewContext; while (page == null && context != null) { page = context.ViewData.Model as IPage; context = context.ParentActionViewContext; } } return page; }
Comments