I don't think that it will be easy to modify code above. Problem is that you will need to run all Sitecore pipelines and processors for all renderings.
I can suggest you different approach, how I did something similar some time ago. I wrote extension for Sitecore.MVC that allowed to get by AJAX request not full item presentation, but only part. It allowed to refresh only part of page. E.g., it could be used for refreshing basket on some commerce site without loading whole page.
Sequence, how to do it:
- Create empty layout
- Add your handler that will process request
- Move presentation from Item layout details to some "virtual" presentation detail. Rendering that should be rendered should be placed in placeholder on empty layout.
- Run default Sitecore pipelines to perform rendering.
Idea is to place rendering that you need from real item presentation to new item presentation that is based on empty layout and then call default Sitecore pipelines. This approach will render your rendering and all nested renderings, because default Sitecore pipelines are used. Even more, if there is some personalization or A/B testing, it still will work.
Here is code that does this stuff:
//The second parameter we need to pass is the PresentationId if not present the query if not valid -> don't continue
var presentationId = {UID of presentation item that should be rendered}
if (string.IsNullOrEmpty(presentationId))
{
return;
}
//If the current item is null return
if (Sitecore.Context.Item == null)
{
return;
}
//Let's resolve the sublayout
try
{
//Get the list of rendering for the current item
var renderings = args.PageDefinition.Renderings;
//If found
if (renderings != null && renderings.Any())
{
//Get the first rendering corresponding to the requested one
var rendering = renderings.First(sublayout => sublayout.RenderingItem.ID.ToString().Equals(presentationId));
if (rendering != null)
{
args.PageDefinition.Renderings.Remove(rendering);
//Put this rendering into ajax layout
rendering.Placeholder = Constants.Strings.AjaxPlaceholderKey;
rendering.LayoutId = new Guid(Constants.IDs.AjaxEmptyLayout);
var layout = renderings.First(x => x.RenderingType == "Layout");
if (layout != null)
{
args.PageDefinition.Renderings.Remove(layout);
for ( int i=0; i< args.PageDefinition.Renderings.Count; i++)
{
args.PageDefinition.Renderings[i].Placeholder =
args.PageDefinition.Renderings[i].Placeholder.Split('/').Last();
args.PageDefinition.Renderings[i].LayoutId =
new Guid(Constants.IDs.AjaxEmptyLayout);
}
layout.LayoutId = new Guid(Constants.IDs.AjaxEmptyLayout);
var getRedererArgs = new GetRendererArgs(new Rendering());
getRedererArgs.LayoutItem =
Sitecore.Context.Database.GetItem(Constants.IDs.AjaxEmptyLayout);
if (rendering.Renderer is Sitecore.Mvc.Presentation.ControllerRenderer)
{
RouteValueDictionary routeValueDictionary = new RouteValueDictionary();
foreach (var key in HttpContext.Current.Request.QueryString.AllKeys.Select(x=> x.ToString()))
{
routeValueDictionary.Add(key, HttpContext.Current.Request.QueryString[key]);
}
((Presentation.ControllerRenderer)rendering.Renderer).routeValueDictionary = routeValueDictionary;
}
layout.Renderer = PipelineService.Get().RunPipeline<GetRendererArgs, Renderer>(PipelineNames.GetRenderer, getRedererArgs, a => a.Result);
args.PageDefinition.Renderings.Add(layout);
args.PageDefinition.Renderings.Add(rendering);
}
}
}
}
catch (Exception exception)
{
Log.Warn("Failed to render presentation", exception, this);
}
To see more in details, you can review this GitHub repository.