2014-02-20 2 views
2

В Umbraco 7.0.3 I:Umbraco 7 Частичный вид Macro Rendering

  1. Создано тип данных называется Macro Контейнер с редактором имущества Macro контейнера
  2. создания Тип документа называется формой обратной связи с вызываемым Property Body с типом Макро Контейнер
  3. Создано Частичный вид называется _contactForm.cshtml (в Views \ MacroPartials)
  4. Созданный макрос называется Контактный формуляр с MVC частичным видом _contactFrom.cshtml
  5. Добавлено Co ntent из типа Контактная форма называется Обратная связь
  6. Добавлено Контактный формуляр макрос Макрос Container собственности под названием Body в моей странице Контакты

Я тогда Surface Controller, что я называю с некоторыми AJAX, чтобы отобразить страницу (более в частности, свойство тела страницы):

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); 
    } 
} 

Эта установка почти работает, но проблема в том, что вместо того, оказанной формы, что возвращает:

<!--?UMBRACO_MACRO macroAlias="ContactForm" /--> 

Так что теперь мне нужно отобразить этот макрос \ form \ partial view ... Я думаю, что мне, вероятно, нужно сделать это в контроллере, но если я смогу сделать это с другой стороны (через Javascript), который будет работать как Что ж. Есть ли функция Umbraco, которую я могу вызвать в контроллере для отображения макроса на основе идентификатора страницы и псевдонима макроса?

ответ

5

Так, проведя несколько часов дымящей, как больно глупый Umbraco команда сделала этот процесс, чтение темы как this и this, я, наконец, понял, довольно уродливый, но рабочий путь ... все было бы так гораздо проще если конструктор класса 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; 
     } 
    } 
} 

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(); 
} 

Это работает, но это довольно хакерский материал. Если команда Umbraco сделала конструктор PublishedContentRequestpublic, это могло быть намного, намного чище. Конечно, есть, вероятно, лучший способ сделать это, если так, я все уши.

+0

Конструктор класса «PublishedContentRequest» теперь опубликован в новых версиях Umbraco, но я не нашел подходящего использования для этого варианта использования. –

-3

Ваше имя контроллера должно содержать «Поверхность» в его названии.

JsSurfaceController 

Также добавьте атрибут [HttpPost] к методу ActionResult.

http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers http://our.umbraco.org/documentation/Reference/Mvc/forms

+2

Ни одно из этих предложений не требуется и даже ошибочно. '[HttpPost]' понадобится только в том случае, если у меня было 2 метода с одним и тем же именем или я пытался предотвратить трафик GET, которого я не знаю, и на самом деле у него есть только трафик GET ... «Поверхность», сделка - это предложение только ... на самом деле это не требуется. –

0

не было возможно использовать umbraco.library.RenderMacroContent?

+0

Комментарий без примера проверенного кода не очень полезен. –

Смежные вопросы