10

I need to get all HTML page content that sitecore generate for an page item. But I need to do it programmatically just for some special tests. I can of course just use URL but it is not good for me. Does LayoutDefinition should work for it ?

4
  • Do you mean you want to have the different renderings on the different pages? Jun 20, 2017 at 13:10
  • no I need get result of rendering, page that end -user could open Jun 20, 2017 at 13:17
  • So you mean, when before the page loads you retrieve the different components that will be rendered on the page? Sorry but I am a bit confused of the requirement. If possible, can you share an example to illustrate it Jun 20, 2017 at 13:20
  • I spent hours looking at this because the accepted solution does not return any presentation details of the item. I implemented this in my project and am calling the extended method directly in my code. jeffdarchuk.com/2015/10/18/render-item-to-string-mvc Apr 5, 2018 at 22:00

2 Answers 2

12

I think AlokBhatt's method is a good start, though I would make use of pipelines throughout. I think this is a better solution because it doesn't involve trying to parse presentation details, and should handle personalization and other Sitecore features. Here's an example that works for me:

public string RenderItem(string itemPath)
{

    var item = Sitecore.Context.Database.GetItem(itemPath);

    var pageContext = new PageContext
    {
        RequestContext = HttpContext.Current.Request.RequestContext,
        Item = item
    };

    ContextService.Get().Push(pageContext);

    var pageDefinition = pageContext.PageDefinition;

    var getPageRenderingArgs = new GetPageRenderingArgs(pageDefinition);

    PipelineService.Get().RunPipeline("mvc.getPageRendering", getPageRenderingArgs);

    var rendering = getPageRenderingArgs.Result;

    var textWriter = new StringWriter();

    var renderRenderingArgs = new RenderRenderingArgs(rendering, textWriter);

    PipelineService.Get().RunPipeline("mvc.renderRendering", renderRenderingArgs);

    ContextService.Get().Pop<PageContext>();

    return textWriter.ToString();
}
10
  • Simply You can get the HTML of the page using Sitecore.Web.WebUtil.ExecuteWebPage("provide url of item")
    – durgar
    Apr 6, 2018 at 10:44
  • 2
    @durgar ExecuteWebPage() makes an actual HTTP request for the item. The method I proposed does not. Arbejdsglæde asked specifically for a solution that does not do a web request. Apr 6, 2018 at 14:12
  • @MatthewFitzGerald-Chamberlain I'm not sure why but this isn't working for me. I don't get any renderings returned even though I can see my renderings are there when debugging and looking at the PageContext object. Is it something to do with final renderings maybe? May 31, 2019 at 16:55
  • @AdamSeabridge This should handle all the determination of which renderings to show based on personalization and all that. The mvc.renderRendering pipeline pipeline will handle then when given the page rendering. Are you getting a page rendering back after calling mvc.getPageRendering? May 31, 2019 at 16:59
  • @MatthewFitzGerald-Chamberlain thanks for clarifying. Yes I get an page rendering back of type 'layout' and it looks ok but the child renderings are 0 and mvc.renderRendering returns nothing May 31, 2019 at 22:54
1

I have worked once created whole page in sitecore and added renderings and settings rendering parameters all programatically. Getting and settings renderings on a page with code is possible. Have a look on something like this https://briancaos.wordpress.com/2013/12/17/get-sitecore-placeholders-and-rendering-hierarchy-from-a-sitecore-item/

You can make an ajax call and get html for a single rendering as a string.you can enhance below for your use case

        private static string GetHtmlFromPlaceholder(string placeholderKey, string returnHtml, PageContext pd, Item targetItem)
    {
        pd.Item = targetItem;
        var renderings = new List<Rendering>();
        var renderingCount = pd.Item.Visualization.GetRenderings(Context.Device, false).ToList();if (renderingCount.Count > 0)
        {
            renderings.AddRange(renderingCount.Select(r => new Rendering
            {
                RenderingItemPath = r.RenderingID.ToString(),
                Parameters = new RenderingParameters(r.Settings.Parameters),
                DataSource = r.Settings.DataSource,
                Placeholder = r.Placeholder,

            }));
            pd.PageDefinition.Renderings.AddRange(renderings);
            if (targetItem.TemplateID.ToString() == VirtualPDPPageTemplateGuid)
            {
                foreach (var r in renderings.Where(r => r.Placeholder.Contains("One-Column-Teaser") || r.Placeholder.Contains("Two-Column-Teaser")))
                {

                    using (var stringWriter = new StringWriter())
                    {
                        PipelineService.Get()
                            .RunPipeline("mvc.renderRendering", new RenderRenderingArgs(r, stringWriter));
                        returnHtml += stringWriter.ToString();
                    }
                }
            }
            else
            {
                foreach (var r in renderings.Where(r => r.Placeholder == placeholderKey))
                {

                    using (var stringWriter = new StringWriter())
                    {
                        PipelineService.Get()
                            .RunPipeline("mvc.renderRendering", new RenderRenderingArgs(r, stringWriter));
                        returnHtml += stringWriter.ToString();
                    }
                }
            }
        }
        return returnHtml;
    }
2
  • yes, but I need just a result rendering - HTML data for full page. Jun 20, 2017 at 13:02
  • I have updated something to get html of one rendering as a string above. you can enhance this for your use.
    – AlokBhatt
    Jun 20, 2017 at 13:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.