Umbraco 7 Частичное представление макроса
В Umbraco 7.0.3 я:
- Создан тип данных с именем Macro Container с помощью редактора свойств контейнера Macro.
- Создан тип документа с именем Contact Form со свойством Body с типом макроконтейнер
- Создано частичное представление с именем _contactForm.cshtml (в Views\MacroPartials)
- Создан макрос с названием Contact Form с частичным представлением MVC _contactFrom.cshtml
- Добавлен контент типа контактной формы под названием Связаться с нами
- Добавлен макрос контактной формы в свойство контейнера макроса, которое называется Body, на моей странице контактов
Тогда у меня есть 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);
}
}
Эта настройка почти работает, но проблема в том, что вместо отображаемой формы возвращается:
<!--?UMBRACO_MACRO macroAlias="ContactForm" /-->
Так что теперь мне нужно визуализировать этот макрос \ форма \ частичное представление... Я думаю, что мне, вероятно, нужно сделать это в контроллере, но если я смогу сделать это с другой стороны (через Javascript), это также будет работать. Есть ли функция Umbraco, которую я могу вызвать в контроллере для рендеринга макроса на основе идентификатора страницы и псевдонима макроса?
3 ответа
Поэтому, проведя несколько часов, размышляя о том, как больно глупо 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;
}
}
}
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
команда сделала PublishedContentRequest
конструктор public
, это могло бы быть намного, намного чище. Конечно, возможно, есть лучший способ сделать это, если это так, у меня все уши.
Разве нельзя было использовать umbraco.library.RenderMacroContent?
Ваше имя контроллера должно содержать "Поверхность" в своем имени.
JsSurfaceController
Также добавьте атрибут [HttpPost] в метод ActionResult.
http://our.umbraco.org/documentation/Reference/Mvc/surface-controllers http://our.umbraco.org/documentation/Reference/Mvc/forms