Created
October 27, 2020 21:31
-
-
Save LucGosso/5b80acab3a9d8dcf0dd1a3c6c2db712e to your computer and use it in GitHub Desktop.
Render Episerver Blocks and ContentArea for use in web api https://devblog.gosso.se/?p=1463
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using EPiServer; | |
using EPiServer.Core; | |
using EPiServer.DataAbstraction; | |
using EPiServer.Framework.Web; | |
using EPiServer.Globalization; | |
using EPiServer.Logging; | |
using EPiServer.ServiceLocation; | |
using EPiServer.Web; | |
using EPiServer.Web.Mvc; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Web; | |
using System.Web.Mvc; | |
using System.Web.Routing; | |
namespace Gosso.Business.Services | |
{ | |
public class ContentRendererService | |
{ | |
private readonly ITemplateResolver _templateResolver; | |
private readonly IContentLoader _contentLoader; | |
private readonly IContentRenderer _contentRenderer; | |
public ContentRendererService(ITemplateResolver templateResolver, IContentLoader contentLoader, IContentRenderer contentRenderer) | |
{ | |
_templateResolver = templateResolver; | |
_contentLoader = contentLoader; | |
_contentRenderer = contentRenderer; | |
} | |
public string Render(ContentReference contentReference, IEnumerable<string> tags = null) | |
{ | |
//Find the content in question | |
IContent matchedContent = _contentLoader.Get<IContent>(contentReference); | |
if (matchedContent == null) | |
throw new ContentNotFoundException("Content was not found"); | |
//Resolve the right Template based on Episervers own templating engine | |
TemplateModel model = _templateResolver.Resolve(HttpContext.Current, matchedContent.GetOriginalType(), TemplateTypeCategories.MvcPartial | TemplateTypeCategories.MvcPartialController | TemplateTypeCategories.MvcController, tags ?? new string[0]); | |
//Resolve the controller | |
ControllerBase contentController = null; | |
if (model.TemplateType != null) | |
contentController = ServiceLocator.Current.GetInstance(model.TemplateType) as ControllerBase; | |
if (contentController == null) // if view without controller | |
contentController = new CustomController(model.Name); | |
//Mimic the routing of our rendition | |
RouteData routeData = new RouteData(); | |
routeData.Values.Add("currentContent", matchedContent); | |
routeData.Values.Add("controllerType", model.TemplateType); | |
routeData.Values.Add("language", ContentLanguage.PreferredCulture.Name); | |
routeData.Values.Add("controller", model.Name.Replace("Controller", "")); | |
routeData.Values.Add("action", "Index"); | |
routeData.Values.Add("node", matchedContent.ContentLink.ID); | |
routeData.DataTokens["contextmode"] = ContextMode.Default;//important to declare that the rendering should not be "edit"-mode, we dont want that, and it will crash | |
//Create a fake context, that can be executed based on the route | |
ViewContext viewContext = new ViewContext(new ControllerContext(new HttpContextWrapper(HttpContext.Current), routeData, contentController), new FakeView(), new ViewDataDictionary(), new TempDataDictionary(), new StringWriter()); | |
HtmlHelper helper = new HtmlHelper(viewContext, new ViewPage()); | |
//Render in our fake context | |
_contentRenderer.Render(helper, new PartialRequest(), matchedContent, model); | |
//helper.RenderContentData(matchedContent, false);//another way to execute it | |
//Derive the output based on our template and view engine | |
return viewContext.Writer.ToString(); | |
} | |
public IEnumerable<string> RenderContentToHtml(IEnumerable<ContentAreaItem> filteredItems) | |
{ | |
foreach (var item in filteredItems) | |
{ | |
var tag = item.LoadDisplayOption()?.Tag; | |
if (tag != null) | |
{ | |
yield return Render(item.ContentLink, new string[1] { tag }); | |
} | |
else | |
{ | |
yield return Render(item.ContentLink); | |
} | |
} | |
} | |
} | |
public class FakeView : IView | |
{ | |
public void Render(ViewContext viewContext, TextWriter writer) | |
{ | |
} | |
} | |
public class CustomController : Controller | |
{ | |
private readonly string name; | |
public CustomController(string name) | |
{ | |
this.name = name; | |
} | |
public ActionResult Index() | |
{ | |
return PartialView(name); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment