Reputation: 30208
In Umbraco 7.0.3 I:
I then have a Surface Controller
that I call with some AJAX
to display the page (more specifically the Body property of the page):
public class JsController : SurfaceController
{
public ActionResult GetPage(int id)
{
var page = new Node(id);
if (page == null || page.GetProperty("body") == null)
return Content(@"Hmm, something went wrong. Unable to find what you're looking for.");
return Content(page.GetProperty("body").Value);
}
}
This setup almost works but the problem is that instead of the rendered form, what is returned is:
<!--?UMBRACO_MACRO macroAlias="ContactForm" /-->
So now I need to render this macro\form\partial view...I think that I probably need to do it in the Controller, but if I can do it on the other side (via Javascript) that would work as well. Is there an Umbraco function I can call in the controller to render a macro based on the page id and macro alias?
Upvotes: 2
Views: 8894
Reputation: 30208
So after spending several hours fuming at how painfully stupid the Umbraco
team made this process, reading threads like this and this, I finally figured out a fairly ugly, but working way...things would have been so much more simple if the PublishedContentRequest
class constructor was not internal
!
Anyways, here's what I had to do:
1) Extend EnsurePublishedContentRequestAttribute
public class CreatePublishedContentRequestAttribute
: EnsurePublishedContentRequestAttribute
{
public CreatePublishedContentRequestAttribute() : base(0) { }
protected override void ConfigurePublishedContentRequest(
PublishedContentRequest publishedContentRequest,
ActionExecutedContext filterContext)
{
var contentId = filterContext.RouteData.Values["id"];
int id = 0;
if (contentId != null && int.TryParse(contentId.ToString(), out id))
{
var content = UmbracoContext.ContentCache.GetById(id);
publishedContentRequest.PublishedContent = content;
var defaultLanguage = Language.GetAllAsList().FirstOrDefault();
publishedContentRequest.Culture = (defaultLanguage == null)
? CultureInfo.CurrentUICulture
: new CultureInfo(defaultLanguage.CultureAlias);
publishedContentRequest.ConfigureRequest();
HttpContext.Current.Session["PublishedContentRequest"]
= publishedContentRequest;
}
}
}
2) Redirect to an action decorated with this attribute that redirects back to my GetPage action and retrieve the PCR
from the Session
. Now we can render our macro:
public ActionResult GetPage(int id)
{
var publishedContent = UmbracoContext.ContentCache.GetById(id);
if (publishedContent == null || publishedContent.GetProperty("body") == null)
{ return Content(@"Unable to find what you're looking for."); }
if (UmbracoContext.PublishedContentRequest == null
&& Session["PublishedContentRequest"] == null)
{ return RedirectToAction("CreatePublishedContentRequest", new { id }); }
UmbracoContext.PublishedContentRequest =
(PublishedContentRequest) Session["PublishedContentRequest"];
Session["PublishedContentRequest"] = null;
UmbracoContext.HttpContext.Items["pageID"] = id;
return Content(GetHtmlContent(publishedContent));
}
[CreatePublishedContentRequest]
public ActionResult CreatePublishedContentRequest(int id)
{
return RedirectToAction("GetPage", new { id });
}
private string GetHtmlContent(IPublishedContent publishedContent)
{
string content = publishedContent.GetProperty("body").Value.ToString();
if (string.IsNullOrEmpty(content) || !content.Contains("UMBRACO_MACRO"))
{ return content;}
int startIndex = content.IndexOf("macroAlias=") + 12;
int length = content.LastIndexOf('"') - startIndex;
var macroAlias = content.Substring(startIndex, length);
return (Umbraco.RenderMacro(macroAlias) ?? new HtmlString("")).ToString();
}
This works, but this is some pretty hacky stuff. If the Umbraco
team made the PublishedContentRequest
constructor public
, this could have been much, much cleaner. Of course, there's probably a better way to do this, if so, I'm all ears.
Upvotes: 5
Reputation: 450
Your controller name needs to contain 'Surface' in its name.
JsSurfaceController
Also, add [HttpPost] attribute to the ActionResult method.
http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers http://our.umbraco.org/documentation/Reference/Mvc/forms
Upvotes: -3