diff --git a/src/Umbraco.Web/Macros/PartialViewMacroController.cs b/src/Umbraco.Web/Macros/PartialViewMacroController.cs index c01731e989..913a79e61e 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroController.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroController.cs @@ -30,7 +30,11 @@ namespace Umbraco.Web.Macros [ChildActionOnly] public PartialViewResult Index() { - var model = new PartialViewMacroModel(_currentPage.ConvertFromNode(), + var model = new PartialViewMacroModel( + _currentPage.ConvertFromNode(), + _macro.Id, + _macro.Alias, + _macro.Name, _macro.Properties.ToDictionary(x => x.Key, x => (object)x.Value)); return PartialView(_macro.ScriptName, model); } diff --git a/src/Umbraco.Web/Macros/PartialViewMacroPage.cs b/src/Umbraco.Web/Macros/PartialViewMacroPage.cs index a64e48663f..2cf95cca95 100644 --- a/src/Umbraco.Web/Macros/PartialViewMacroPage.cs +++ b/src/Umbraco.Web/Macros/PartialViewMacroPage.cs @@ -1,4 +1,5 @@ using System.Web.Mvc; +using Umbraco.Core.Models; using Umbraco.Web.Models; using Umbraco.Web.Mvc; @@ -9,6 +10,19 @@ namespace Umbraco.Web.Macros /// public abstract class PartialViewMacroPage : UmbracoViewPage { - + protected override void InitializePage() + { + base.InitializePage(); + //set the model to the current node if it is not set, this is generally not the case + if (Model != null) + { + CurrentPage = Model.Content.AsDynamic(); + } + } + + /// + /// Returns the a DynamicPublishedContent object + /// + public dynamic CurrentPage { get; private set; } } } \ No newline at end of file diff --git a/src/Umbraco.Web/Models/PartialViewMacroModel.cs b/src/Umbraco.Web/Models/PartialViewMacroModel.cs index 7d690d30e4..b21b7cdb81 100644 --- a/src/Umbraco.Web/Models/PartialViewMacroModel.cs +++ b/src/Umbraco.Web/Models/PartialViewMacroModel.cs @@ -1,4 +1,6 @@ +using System; using System.Collections.Generic; +using System.ComponentModel; using Umbraco.Core.Models; namespace Umbraco.Web.Models @@ -9,14 +11,38 @@ namespace Umbraco.Web.Models public class PartialViewMacroModel { + public PartialViewMacroModel(IPublishedContent page, + int macroId, + string macroAlias, + string macroName, + IDictionary macroParams) + { + Content = page; + MacroParameters = macroParams; + MacroName = macroName; + MacroAlias = macroAlias; + MacroId = macroId; + } + + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Use the constructor accepting the macro id instead")] public PartialViewMacroModel(IPublishedContent page, IDictionary macroParams) { - CurrentPage = page; + Content = page; MacroParameters = macroParams; } - public IPublishedContent CurrentPage { get; private set; } + [EditorBrowsable(EditorBrowsableState.Never)] + [Obsolete("Use the Content property instead")] + public IPublishedContent CurrentPage + { + get { return Content; } + } + public IPublishedContent Content { get; private set; } + public string MacroName { get; private set; } + public string MacroAlias { get; private set; } + public int MacroId { get; private set; } public IDictionary MacroParameters { get; private set; } } diff --git a/src/Umbraco.Web/Mvc/SurfaceController.cs b/src/Umbraco.Web/Mvc/SurfaceController.cs index 463162694f..b222eb8a39 100644 --- a/src/Umbraco.Web/Mvc/SurfaceController.cs +++ b/src/Umbraco.Web/Mvc/SurfaceController.cs @@ -77,20 +77,50 @@ namespace Umbraco.Web.Mvc { get { - var routeData = ControllerContext.IsChildAction - ? ControllerContext.ParentActionViewContext.RouteData - : ControllerContext.RouteData; - - if (!routeData.DataTokens.ContainsKey("umbraco-route-def")) + var routeDefAttempt = TryGetRouteDefinitionFromAncestorViewContexts(); + if (!routeDefAttempt.Success) { - throw new InvalidOperationException("Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request"); + throw routeDefAttempt.Error; } - var routeDef = (RouteDefinition)routeData.DataTokens["umbraco-route-def"]; + var routeDef = routeDefAttempt.Result; return routeDef.PublishedContentRequest.PublishedContent; } } + /// + /// we need to recursively find the route definition based on the parent view context + /// + /// + /// + /// We may have Child Actions within Child actions so we need to recursively look this up. + /// see: http://issues.umbraco.org/issue/U4-1844 + /// + private Attempt TryGetRouteDefinitionFromAncestorViewContexts() + { + ControllerContext currentContext = ControllerContext; + while (currentContext != null) + { + var currentRouteData = currentContext.RouteData; + if (currentRouteData.DataTokens.ContainsKey("umbraco-route-def")) + { + return new Attempt(true, (RouteDefinition) currentRouteData.DataTokens["umbraco-route-def"]); + } + if (currentContext.IsChildAction) + { + //assign current context to parent + currentContext = currentContext.ParentActionViewContext; + } + else + { + //exit the loop + currentRouteData = null; + } + } + return new Attempt( + new InvalidOperationException("Cannot find the Umbraco route definition in the route values, the request must be made in the context of an Umbraco request")); + } + } } \ No newline at end of file