Wednesday, April 20, 2016

Pipeline

What is Pipeline in Sitecore?
A pipeline is a discrete set of steps, executed in order. It is an architectural design you can employ for certain cases in your applications. If we have a series of tasks which need to be performed to accomplish a task, then a pipeline may be the way to go. A pipeline will execute the steps in order, so we could use a pipeline for our ordered tasks as well as our unordered tasks (as the order doesn’t matter we don’t care that it was executed in order).
Pipelines define a sequence of processors that implement a function, such as defining the Sitecore context for an HTTP request or generating a list of messages in the Content Editor.
Whenever the HTTP request comes to server  how sitecore handles the request is depicted in the below diagram .


So in the above image we can see that every single request to sitecore it straight goes to Pipeline. Then the pipeline will determine that which are the steps need to be execute in order . Pipeline also determine whether the request is match with standard MVC route or not . If the request match with MVC route then go for MVC application else Sitecore will try to resolve particular item's layout. Lastly we can see in the image that is there any layout define for the particular item , If yes then layout will will check for MVC extension settings or not . If it match mvc extension then indeed a MVC request comes from HTTP request else it is a web form request .

What is the Purpose of Pipeline ?
From above discussion we can see the importance of pipeline in Sitecore application . In a one word I would like to say that Pipelines are used to control most of Sitecore's functionality. For e.g. processes ranging from authentication to request handling to publishing to indexing etc all are controlled through the pipeline in Sitecore.
Generally Pipelines are defined in the Web.config and in the Sitecore Patch files . Sitecore separates the pipelines in to two groups . In the web.config we can see . 
  • <pipelines> 
    
    Those defined under this tend to use system processes .

  • <processors
    In this node used to define the pipelines that operate for UI requests and can be interact with users .
Some commonly used pipelines are given below. These are unlikely you will ever call any of them directly but it is not unusual to extend these below pipelines .
Pipeline NameGenerally Defined inArgs typeSmall Description
 <initialize>
Web.configPipelineArgsWhenever the IIS application pool is started this will run . Processors handles initalization of task that need to run once
<httpRequestBegin>
Web.configHttpRequestArgsThis handles Httprequest , including task such as resolving the context item , device , presentation settings etc.
<insertRenderings>
Web.configInsertRenderingsArgs Determines the presentation components to include when rendering an item .
 
<renderField>
Web.configRenderFieldArgsRuns when the FieldRenderer is used to render a Field value .

If you are not bale to find any of the above mentioned Pipeline name in the Web.config file , then please have a look under Sitecore.config file , may be there has been defined.

How to create Own Pipeline ?
I would like to say instead of modifying any of the sitecore defined pipeline , it will be better to create a new custom pipeline for any of our business requirement . In this post I will create new pipeline for dummy purpose . I would like to create a custom button . While click on this my custom pipeline will going to define the steps to validate that the user input value from the prompt is the current year. For e.g. Current year is 2016 , so while button click one pop-up will ask the user "What is the Current year?" , If the user input value is match with current year then will say Thank You, else will show a message  with wrong value and ask to try once again.
Now I  have open the sitecore website in browser . Login the site with admin credentials . I go to desktop mode . First change my database from master to core , because it contains the definition for the Sitecore User interface. I need to create a custom button to show in sitecore ribbon .
Step 1 : In the content Editor , just go to Applications–>  Content Editor–> Ribbons–> Chunks–> Sorting–> Right click in Sorting select insert option (Insert from Template)
Choose the template System/Ribbon/Large Button , name the Item Test Button. Then hit Insert.
Step 2: Insert the following values to the fields . Header = "Test Button" , Icon ="Applications/32x32/desktop.png", Click="testbutton:click" , Tooltip ="Run a custom UI pipeline.'

Step 3: I have move the Test Button at the last child of the Sorting Item.
Step 4: Now click on save and come out from core database to master and see the button is showing in the ribbon .
Step 5: Now it is time to write down little code in Visual Studio. Lets open Visual Studio Solution , I have set up my solutions with sitecore website , so that after complete developing the custom pipeline if I publish then it should work. We shall write code for this test button , so that while click on it user can enter the value (Current Year)
I have create a Class in VS Solution in the name of TestCommand , this class will derived from Sitecore.Shell.Framework.Commands.Command .Through this class Execute method we shall start our custom pipeline.
namespace WebApplication.Custom_Command
{
    public class TestCommand : Command
    {
        public override void Execute(CommandContext context)
        {
            //
            //parameters provide a way to pass values to the pipeline
            NameValueCollection parameters = new NameValueCollection();
            parameters["year"] = DateTime.Now.Year.ToString();
 
            //custom args class provides another way to pass values to the pipeline
            TestArgs args = new TestArgs(context.Items[0], parameters);
            Sitecore.Context.ClientPage.Start("testPipeline", args);
        }
    }
}
Step 6: Now I shall create a that will handles to pass the values to pipeline processors . I have mark the class as serializable. Other than that the code allows a sitecore item to be store as a property. Below is the code .
namespace WebApplication.CustomPipeline
{
    [Serializable]
    public class TestArgs : ClientPipelineArgs
    {
        public TestArgs(Item item)
            : base()
        {
            this.m_Item = item;
        }
 
        public TestArgs(Item item, NameValueCollection parameters)
            : base(parameters)
        {
            this.m_Item = item;
        }
 
        public TestArgs(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            m_ItemId = info.GetString("itemid");
            m_DatabaseName = info.GetString("databasename");
        }
 
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            info.AddValue("itemid", m_ItemId);
            info.AddValue("databasename", m_DatabaseName);
            base.GetObjectData(info, context);
        }
 
        private string m_ItemId = null;
        private string m_DatabaseName = null;
 
        private Item m_Item = null;
 
        public Item Item
        {
            get
            {
                if (m_Item == null)
                {
                    if (!string.IsNullOrEmpty(m_ItemId) && !string.IsNullOrEmpty(m_DatabaseName))
                    {
                        Database database = Factory.GetDatabase(m_DatabaseName);
                        if (database != null)
                        {
                            m_Item = database.GetItem(new ID(m_ItemId));
                        }
                    }
                }
                return m_Item;
            }
        }
    }
}

Step 7: Now we shall create a custom processors . I have said in the top of this post that a Pipeline is a set of processors that will run in specific order . A processor is just like a method . A processors class can have multiple methods but for simplicity I have create only one method in this class.
namespace WebApplication.CustomPipeline
{
    public class TestProcessor
    {
        public void ConfirmYear(TestArgs args)
        {
            if (args.IsPostBack)
            {
                //args.Result will be "null" if the cancel button is clicked
                if (String.IsNullOrEmpty(args.Result) || (args.Result == null) || (args.Result == "null") || args.Result == "undefined")
                {
                    args.AbortPipeline();
                    SheerResponse.ClosePopups(false);
                    return;
                }
               
                //if the user didn't enter the correct year, prompt again
                if (args.Result != args.Parameters["year"])
                {
                    SheerResponse.Input("Is the current year is '" + args.Result + "'?, please try again", args.Result);
                    args.AddMessage("Worng Year");
                    args.WaitForPostBack();
                    return;
                }
                SheerResponse.Alert("Thanks You"true);
            }
            else
            {
                //prompt the user for the year
                SheerResponse.Input("What year is it?""");
                args.WaitForPostBack();
            }
        }
    }
}
Step 8: Last step we need to define our custom pipeline in config file in sitecore website. Before that I would concise up to now what I have done . I just create a custom button in ribbon, then call the click command, this will open a pop up that allows user to enter the current year value. If the value is matched with current year will show thank you message else throw warning message to user. So , lets define our custom pipeline in the config file so that our test button functionality could be started  .
We shall create a config file under ..\App_config\Include\ folder , since the namespace I have used WebApplication , so I will create a config file in the name of WebApplication.Config. The following XML is added in this file .
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
  <sitecore>
    <processors>
      <testPipeline>
        <processor type="WebApplication.CustomPipeline.TestProcessor, WebApplication" method="ConfirmYear" />
      </testPipeline>
    </processors>
    <commands>
      <command name="testbutton:click" type="WebApplication.Custom_Command.TestCommand, WebApplication"/>
    </commands>
  </sitecore>
</configuration>
 
Step 9: Now  build the solution in Visual Studio and hit publish . It is the time for testing our custom pipeline processor. So I have login in our Sitecore website , go to the content editor and click in the test button . This will show a prompt like below image

Now I have enter a value for e.g. abcd , obviously the current year is not abcd, so this should throw a warning message to user and let them to try once again. below is the Image.

Now I have enter a correct current year which 2016 at this time , and see the thank you message .

So , I have create my custom pipeline that will confirm the current year value with user input value , hope this simple excersice cab able to clear the concept of sitecore pipelines basics, for more details can be found over John West blog and Sitecore documents , please comment below if anything have you seen in this post wrong or need to modify , Thanks for your time to read my post.

http://www.sitecore.net/learn/blogs/technical-blogs/morten-ljungberg-sitecore-whats-new/posts/2015/08/adding-a-custom-button-to-the-ribbon.aspx



No comments:

Post a Comment