Umbraco 7局部视图宏观渲染

Ser*_*gan 2 c# ajax asp.net-mvc-4 umbraco7 surface-controller

在Umbraco 7.0.3中我:

  1. 使用宏容器的属性编辑器创建了一个名为Macro Container的数据类型
  2. 创建的文档类型称为Contact Form with Property,名为Body with Type Macro Container
  3. 创建名为_contactForm.cshtml的部分视图(在Views\MacroPartials中)
  4. 创建宏名为Contact Form with MVC Partial view _contactFrom.cshtml
  5. 添加了名为联系我们的联系表格类型的内容
  6. 将Contact Form宏添加到"我的联系我们"页面中名为Body的Macro Container属性中

然后我有一个Surface Controller我打电话AJAX来显示页面(更具体地说是页面的Body属性):

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这个设置几乎可以工作,但问题是,而不是渲染的表单,返回的是:

<!--?UMBRACO_MACRO macroAlias="ContactForm" /-->
Run Code Online (Sandbox Code Playgroud)

所以现在我需要渲染这个宏\ form\partial视图...我认为我可能需要在Controller中执行它,但是如果我可以在另一端(通过Javascript)这样做也可以.是否有一个Umbraco函数我可以在控制器中调用基于页面ID和宏别名渲染宏?

Ser*_*gan 5

所以花费几个小时在如何痛苦愚蠢的发烟后Umbraco球队取得这个过程中,像读线程这个这个,我终于想通了一个相当难看,但工作方式......事情会一直这样简单得多,如果PublishedContentRequest类的构造函数是不internal!

无论如何,这就是我必须要做的事情:1)延伸 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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

2)重定向到使用此属性修饰的操作,该操作重定向回我的GetPage操作并PCR从中检索Session.现在我们可以渲染我们的宏:

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();
}
Run Code Online (Sandbox Code Playgroud)

这是有效的,但这是一些非常hacky的东西.如果Umbraco团队制作了PublishedContentRequest构造函数public,那么这可能会更加清晰.当然,有可能有更好的方法来做到这一点,如果是这样,我全都听见了.