Wednesday, March 23, 2011

Change PublishingPageLayout of Page Programmatically

After launch of SharePoint 2010 we all came to know that platform is improved heavily in all aspects and some enhancements in web content management too
We can easily change the layout of any Publishing Page using a ribbon in SharePoint 2010
But many of us are still in confusion that how we can achieve this using MOSS 2007? Rather some people think that we cannot change the page layout of page using MOSS 2007, but this is not true
Well, to know how to do this in MOSS 2007, here are some steps
1.    Browse the page for which you want to change page layouts (of course this should be a publishing page)
2.    If you are working with Publishing Site, click on Site Actions and select Show Page editing toolbar (If you are working with custom master pages , and see that this option is grayed out then make sure that you have added PublishingConsole control entry on master page)
3.    Now you will be able to see Page Editing tool bar, now select Page option , a drop down will appear , there you have to select Page Settings and Schedule option
4.    After selecting this you will see a page will be opened, scroll down and find option Page Layout
5.    Now this is where you can apply page layouts to page , select different page layout from dropdown and click ok
I hope now your previous page layout for page gets changed J
but there are some cases I faced where I wanted to change the layout of the page but after doing all these steps when I reached to the page where we can change page layouts , I didn’t find the dropdown filled with other page layouts , so I was not able to change
Now what to do in this case?
Well as developer, we always have code to help us , so decided to do these all using SP object model
And here is the code what I have done, this works for me at least J
Code just tries to open root web, gets collection of pages created with given page layout, searches the given page in this collection, and applies new given page layout the page and done
There can be multiple ways to do this, and code can be modified for more flexibility and according to need


static void Main(string[] args)
{
 #region Variables

 string _siteUrl = string.Empty;
 string _pageName = string.Empty;
 string _pageLayouts = string.Empty;
 string _newPageLayout = string.Empty;
 string _responce = string.Empty;
 PublishingPageCollection _pages = null;

 #endregion

 try
 {
   Console.WriteLine("Site Url: ");
   _siteUrl = Console.ReadLine();

   if (!string.IsNullOrEmpty(_siteUrl))
   {
    SPSecurity.RunWithElevatedPrivileges(delegate()
    {
      using (SPSite site = new SPSite(_siteUrl))
      {
        using (SPWeb web = site.RootWeb)
        {
          if (web != null)
          {
           if (PublishingWeb.IsPublishingWeb(web))
           {
             PublishingWeb pWeb = PublishingWeb.GetPublishingWeb(web);
             Console.WriteLine("Search Pages with Layout: ");
             _pageLayouts = Console.ReadLine();

             if (!string.IsNullOrEmpty(_pageLayouts))
             {
string query = @"<Where><Contains><FieldRef   Name='PublishingPageLayout' /><Value Type='URL'>" + _pageLayouts + "</Value></Contains></Where>";
                 
_pages = pWeb.GetPublishingPages(query);
             }

             do
             {
              if (_pages != null)
              {
               Console.WriteLine();
               Console.WriteLine("Search Page With Name: ");
               _pageName = Console.ReadLine();

               //LINQ to get actual page for processing
PublishingPage _desiredPage = _pages.Where(p => p.Name.ToLower().Contains(_pageName.ToLower())).FirstOrDefault();

                                              

   if (_desiredPage != null)
               {
                if (_desiredPage.ListItem.File.Level != SPFileLevel.Checkout)
                {
                                                        Console.WriteLine("Processing.." + _desiredPage.Name);
                                                        _desiredPage.ListItem.File.CheckOut();

                  Console.WriteLine("which Page Layout to apply?");
                  _newPageLayout = Console.ReadLine();

_desiredPage.ListItem["PublishingPageLayout"] = @"/_catalogs/masterpage/" + _newPageLayout;
                                                        _desiredPage.ListItem.Update();

_desiredPage.ListItem.File.CheckIn(string.Empty);

                  if (pWeb.PagesList.EnableMinorVersions)
                  {
_desiredPage.ListItem.File.Publish("Page Layout Changed..");
                  }
                   if (pWeb.PagesList.EnableModeration)
                   {
_desiredPage.ListItem.File.Approve("Approved by Console Application");
                   }

                   Console.WriteLine("Page Layout Updated");

                   Console.WriteLine("do you want to continue?");
                    _responce = Console.ReadLine();

                  }
                else
                {
Console.WriteLine("Page is already Checked out to user " + _desiredPage.ListItem.File.CheckedOutBy.Name);
                }
               }
               else
               {
                 Console.WriteLine("Page Not Found!!");
               }
              }
             }
while (_responce.ToLower().Equals("y") || _responce.ToLower().Equals("yes"));

            if (pWeb != null)
            {
              pWeb.Close();
            }

           }
          }
        }
       }
      });
     }
     else
     {
      Console.WriteLine("Invalid Site Url");
     }

    }
    catch (Exception ex)
    {
      Console.WriteLine("{0}:{1}", "Error", ex.Message);
    }

     Console.ReadLine();
   }

1 comment:

  1. If you add page layout like below then actually lauout will not be added to page .I have tested it in SP 2010.

    _desiredPage.ListItem["PublishingPageLayout"] = @"/_catalogs/masterpage/" + _newPageLayout;

    ReplyDelete