Sitecore Publish Selected Sublayouts using WebDeploy

On our Multisite Sitecore instance, we have thousands of sublayouts. So, content authors or developers should be able to modify and publish selected sublayouts. Means, only selected sublayout should be deployed to CD servers along with the items.

We achieved this using Web Deploy, that can be configurable as guided is Sitecore Scalability Guide.

What approach we chose to conditionally sync Sublayouts?

  1. On CM environment, we have all sublayouts stored in a folder SiteSublayouts, now on publishing if sync this folder with CD server's relevant folder, then all sublayouts will get synced instead of just publishing the selected one. So, we applied an idea create another directory PublishedSublayouts on same level.
  2. So, on publishing a sublayout, it will be first copied from SiteSublayouts to PublishedSublayouts folder and then invoke WebDeploy. So,this will sync all sublayouts from PublishedSublayouts (Actually published or publishable sublayouts) to live server's SiteSublayouts folder.
Note: Here, we created SiteSublayouts and PublishedSublayouts folders outside the Webroot to ease of use.

How we implemented this approach?

  1. Configured WebDeploy settings in Sitecore. Enable App_Config\Include\Webdeploy.config file and do changes as below.
    <?xml version="1.0" encoding="utf-8" ?>
    <configuration>
      <sitecore>
        <events>
          <event name="publish:begin">
            <handler type="SitecoreTactics.SublayoutPublish, SitecoreTactics" method="SublayoutPublish">
              <tasks hint="list:AddTask">
                <default type="Sitecore.Publishing.WebDeploy.Task">
                  <!-- Publishing to the target database will trigger this deployment task. -->
                  <!-- You should prefer to write here first publishing target (if have multiple target DBs) -->
                  <targetDatabase>web</targetDatabase>
    
                  <!-- Target server is where we want to send sublayouts. If omitted, operation is performed on the local server. -->
                  <targetServer>x.x.x.x</targetServer>
    
                  <!-- userName and password are optional. If omitted, local user identity or credentials saved in Windows Vault will be used to connect to the server. -->
                  <userName>Administrator</userName>
                  <password>Password</password>
    
                  <!-- localRoot is optional. If omitted, the website root is used. -->
                  <localRoot>E:\CMS\Sitecore\PublishedSublayouts</localRoot>
    
                  <!-- remoteRoot is physical path where sublayouts are stored on remote server -->
                  <remoteRoot>E:\CMS\Sitecore\SiteSublayouts</remoteRoot>
                  
                  <!-- Paths, relative to the localRoot, which will be deployed to the remote location. -->
                  <items hint="list:AddPath">
                    <media>SiteSublayouts/</media>
                  </items>
                  
                </default>
              </tasks>
            </handler>
          </event>
        </events>
      </sitecore>
    </configuration>
    
    Here, we synced the PublishedSublayouts folder of CM server with relevant SiteSublayouts folder of CD server using Web Deploy. And we customized Sitecore's default WebDeploy handler for copying sublayouts mentioned in step 2. 
  2. Create a class as below by inheriting with Sitecore.Publishing.WebDeploy.PublishHandler as below. Here, when any sublayout is started publishing, on begin:publish event we defined in step 1, we copy the sublayout from SiteSublayouts folder to PublishedSublayouts folder and invoke WebDeploy as below code.
  3. namespace SitecoreTactics
    {
     public class SublayoutPublish : Sitecore.Publishing.WebDeploy.PublishHandler
     {
      string SourceFolder = "E:\CMS\Sitecore\SiteSublayouts";
      string DeployFolder = "E:\CMS\Sitecore\PublishedSublayouts";
    
      protected void DeploySublayout(object Sender, EventArgs args)
       {
       Item RootItem = ((Sitecore.Publishing.Publisher)(((Sitecore.Events.SitecoreEventArgs)(args)).Parameters[0])).Options.RootItem;
         if (RootItem.Paths.Path.ToLower().IndexOf("/sitecore/layout/sublayouts/") >= 0)
       {
        string sublayoutSourceFolder = SourceFolder + <Relative Path of the sublayout>;
        string sublayoutDeployFolder = DeployFolder + <Relative Path of the sublayout>;
    
        // Copy publishing sublayout to Deployable folder   
        File.Copy(sublayoutSourceFolder, sublayoutDeployFolder);
    
        // Invoke WebDeploy to sync published sublayouts
        base.OnPublish(Sender, args);
       }
      }
     }
    }
  4. We have multiple CM servers, so we replicated all these published sublayouts with help of DFS across all servers.
It's done! We can also use the same approach for publishing file based media items.

Very soon I will post few leanings we had after implementing sublayouts publishing!