Friday, July 13, 2012

Replace New Page menu item for publishing sites

Back in SharePoint 2007 when you created a new publishing page in a publishing site you got to a page where you had to enter a title and choose a page layout.


In 2010 you just get a pop-up where you enter the name of the new page.


The new page will get the "default" page layout. If you want to change the layout, which is true in a lot of cases, you have to do that in the ribbon menu after the page has been created. Thank you Microsoft, but this is not how anyone wants to work with their publishing pages. Thankfully there is hope. There is a page in the layouts-folder called CreatePage.aspx, which is the exact same page as in 2007!


So now you, of course, want to hide the old New Page menu item with a HideCustomAction element and add a new menu item with a CustomAction element which just points to CreatePage.aspx. Well... Unfortunately Microsoft has cut some corners implementing the three menu items you get when you enable the publishing feature, i.e. New Page, New Document Library and Manage Content and Structure. Instead of adding them as three independent custom actions they have created one custom action and added the menu items in code behind. This makes it impossible to hide one of the three since all are registered with the same Id.

The solution to this madness is to create a new custom action and change the action for the New Page menu item via the object model in the code behind.

Oh, and another thing. It is impossible to add the new custom action in the exact same spot as the old New Page menu item since Microsoft does not expose the property MenuGroupId in the custom action xml, http://msdn.microsoft.com/en-us/library/ms460194.aspx. So we have to add our new custom action in code behind.

Here is my CustomAction element:

  <CustomAction
    Id="SharePoint.Paradise.CustomActions.NewPage"
    Location="Microsoft.SharePoint.StandardMenu"
    GroupId="SiteActions"
    Rights="AddListItems"
    ControlAssembly="$SharePoint.Project.AssemblyFullName$"
    ControlClass="SharePoint.Paradise.CustomActions.NewPage">
  </CustomAction>

Here is the code behind for the custom action:

namespace SharePoint.Paradise.CustomActions
{
    public class NewPage : WebControl
    {
        // Hide the old "New page" menu item
        // Menu items for the publishing feature is not added properly so we can hide them in Elements.xml with HideCustomAction, thank you Microsoft
        protected override void OnPreRender(EventArgs e)
        {
            ToolBarMenuButton menu = ToolBarMenuButton.GetMenuControl(this);
            MenuItemTemplate item = menu.GetMenuItem("wsaCreatePage");
            if (item != null)
            {
                menu.MenuControl.HiddenMenuItems.Add(item);
            }
        }
        
        // Add a the new "New page" menu item
        // MenuGroupId in not exposed to Elements.xml so we can add "New page" in the same location as the old one, thank you Microsoft
        protected override void CreateChildControls()
        {
            MenuItemTemplate item = new MenuItemTemplate();
            item.Text = HttpContext.GetGlobalResourceObject("wss", "siteactions_createpage", CultureInfo.CurrentUICulture).ToString();
            item.Description = HttpContext.GetGlobalResourceObject("wss", "siteactions_createpagedesc", CultureInfo.CurrentUICulture).ToString();
            item.ImageUrl = SPContext.Current.Web.Url + "/_layouts/images/crtpage.gif";
            item.MenuGroupId = 200;
            item.Sequence = 100;
            item.ClientOnClickNavigateUrl = SPContext.Current.Web.Url + "/_layouts/CreatePage.aspx";

            this.Controls.Add(item);
        }
    }
}

Yet another day in SharePoint paradise...

No comments:

Post a Comment