Showing posts with label Pipelines. Show all posts
Showing posts with label Pipelines. Show all posts

Wednesday, September 17, 2014

Sitecore MVC Request Pipeline Execution Lifecycle

When I looked for description of Sitecore.MVC pipelines I faced with great post of David Morrison where was shown Sitecore MVC request pipeline execution lifecycle. I extended this diagram with Sitecore Analytics pipelines.

Sitecore.Mvc

When you’ll look at your showconfig.aspx you’ll find out that you have more Sitecore Mvc pipeline processors. Diagram does not include Sitecore Mvc pipelines for Experience Editor.

Thursday, September 4, 2014

AJAX Lazy Loading with Sitecore MVC

There was request to implement search with lazy loading for Sitecore MVC project. Unfortunately there is no such option in Sitecore out of the box. But I found great article how it could be done on Sitecore project with web forms. That idea works fine for web forms, but it does not work for MVC.

I modified processor proposed in article to work with MVC layouts.

var url = "http://myurl/myItem?UseAjax=true&PresentationId=BACBFEE1-C0BB-4D8E-BA1A-D9F50CCA5B7F";  

$.ajax({
type: 'GET',
url: url
}).done(function (data) {
//Your code
});

We will also need a MVC layout for the ajax queries (in the following code the MY_AJAX_LAYOUT_ID is the id of this layout) and this layout will only contain one placeholder (MY_AJAX_PLACEHOLDER in the code)

Now here is the custom layout resolver (look at the comments into the code):

namespace MyNamespace
{
using System;
using System.Linq;
using System.Web;
using Sitecore.Diagnostics;
using Sitecore.Mvc.Pipelines;
using Sitecore.Mvc.Pipelines.Response.GetPageRendering;
using Sitecore.Mvc.Pipelines.Response.GetRenderer;
using Sitecore.Mvc.Presentation;
using System.Web.Routing;

public class GetAjaxLayoutRendering : GetPageRenderingProcessor

{
public override void Process(GetPageRenderingArgs args)

{
bool useAjax;
//First of all let's check if we are in ajax mode or not if not don't continue
var result = bool.TryParse(HttpContext.Current.Request.Params["UseAjax"], out useAjax);
if (!result || !useAjax)
{
return;
}

//The second parameter we need to pass is the PresentationId if not present the query if not valid -> don't continue
var presentationId = HttpContext.Current.Request.Params["PresentationId"];
if (string.IsNullOrEmpty(presentationId))
{
return;
}

//If the current item is null return
if (Sitecore.Context.Item == null)
{
return;
}

//Let's resolve the rendering
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(r => r.RenderingItem.ID.ToString().Equals(presentationId));

if (rendering != null)
{
args.PageDefinition.Renderings.Remove(rendering);
//Put this rendering into ajax layout
rendering.Placeholder = "MY_AJAX_PLACEHOLDER";

rendering.LayoutId = new Guid(JetstreamShops.Business.Constants.Ids.AjaxLayoutItemId);
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(MY_AJAX_LAYOUT_ID);
}
layout.LayoutId = new Guid(MY_AJAX_LAYOUT_ID);
var getRedererArgs = new GetRendererArgs(new Rendering());
getRedererArgs.LayoutItem =
Sitecore.Context.Database.GetItem(MY_AJAX_LAYOUT_ID);

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("Cannot render this!", exception, this);
}
}
}
}

Configuration will look in next way:
<mvc.getPageRendering>
<processor patch:after="*[@type='Sitecore.Mvc.Pipelines.Response.GetPageRendering.GetLayoutRendering, Sitecore.Mvc']" type="MyNamespace.GetAjaxLayoutRendering, MyAssembly"/>
</mvc.getPageRendering>
Many thanks to Vangansewinkel Benjamin whose idea was modified. 

Wednesday, August 27, 2014

Configuration Visibility of Profile Cards Button in Content Editor

Usually visibility of buttons in Sitecore content editor is configured via QueryState of command, but there are few exceptions. One of this exceptions is Profile Cards button that allows you to edit the Profile Cards associated with item.chart_radar

Despite there is command declared for this button:

<command name="item:personalize" type="Sitecore.Shell.Applications.WebEdit.Commands.PersonalizeItem,Sitecore.Client"/>

and there is overridden method QueryState which usually is used to control command visibility.

But this method is not used for showing this button in content editor. Instead of it, button is rendered directly as control by Sitecore.Shell.Applications.ContentManager.Editor.RenderProfileCards . This method checks visibility by calling getItemPersonalizationVisibility pipeline.

So, if you need to show/hide Profile Cards button in Sitecore Content Editor then overriding of QueryState for item:personalize command will not take any effect. You should write you own processor for getItemPersonalizationVisibility pipeline.