Pages

Friday, March 27, 2009

Create Custom CreatePage.aspx Page

In the publishing template, create custom CreatePage.aspx and have the pages stored in a document library other than the default Pages library:
Found great information here: http://blogs.msdn.com/syedi/archive/2008/07/18/why-should-one-save-publishing-pages-in-pages-list-always-in-moss-bend-it.aspx
Here is the information copied (Just in case the blog moves or goes away)
<!--Begin content copied from http://blogs.msdn.com/syedi/archive/2008/07/18/why-should-one-save-publishing-pages-in-pages-list-always-in-moss-bend-it.aspx -->
The Approval Workflows, Content Management, Authoring all are fair enough for the publishing pages in MOSS. But why should you store the publishing web pages only in the inbuilt "Pages" list when you can have any number of lists enabled with "Page Content Type".
The "Create Page" link from the "Site Action" menu will land you in the "CreatePage.aspx" under layouts directory. You can find the "Pages" list has been hardcoded there as the destination library. Any publishing page you create from the "CreatePage.aspx" will be stored in the "Pages" library. In my support profession i found many of the users wants to bend this behavior of SharePoint and wants to store the publishing pages in varios libraries based on the category. To achieve this either they create individual web application or an extended application under the layouts directory which makes them frustrated due to large development work and sometimes leads to the unsuccessfull attempt because of the limitations in the usage of high secured SharePoint API's outside the SharePoint context.
I don't want to break rules but following them is not really my cup of tea.... So how we can make the other libraries which are enabled with "Page content Type" to be available in the "CreatePage.aspx" and store the publishing pages in the selected library... (You cannot store publishing pages without the page content type enabled with the document library or List !!)
1. Create custom "CreatePage.aspx" - as i already told i don't want to break the rules by modifying the OOB CreatePage.aspx.
2. Modify the "Site Action" menu to navigate to the "Custom Createpage.aspx" to create publishing page - again do it without bending the rules.
Creating the custom createpage.aspx involves the implmentation of following few steps :
a. Copy the "CreatePage.aspx" and place it under the layouts with some custom name , say "CustomCreatepage.aspx"
b. In the "CustomCreatePage.aspx" find the Label <asp:Label ID="parentUrlLabel" runat="server" /> and make the visible property of this label to "False". This is the label where the "Pages" list is hard coded. Don't remove the label from the page as this label reference has been used in the code behind class and will result in Null reference error while creating the page.
c. Add a dropdownlist control <asp:DropDownList ID="ddlDocLib" runat="server"></asp:DropDownList> in the "CustomCreatePage.aspx" after the above said label control.
d. You might be thinking about writing the code behind and compiling a DLL for this custom page but it's not possible as this page already inherits Microsoft.SharePoint.Publishing.Internal.CodeBehind.CreatePagePage class from the Microsoft.SharePoint.Publishing Assembly. There are several methods from this class has been called in the server scripting of this page which makes you to stick to the inheritance of this class for the page directive.
e. Add a server script in the page (In line coding,Wow ASP.NET !!) and override the onload event to populate the dropdownlist with the page content type enabled Lists. The following is the code snippet for the onload event in the server script of the"CustomCreatePage.aspx"
protected override void OnLoad(EventArgs e)

    {
        base.OnLoad(e);
        ddlDocLib.Items.Add("--Select Destination List--");
        SPWeb web = SPContext.Current.Web;
        SPListCollection lists = web.Lists;
       foreach (SPList list in lists)
        {
            SPContentType _cType = list.ContentTypes["Page"];
            if(_cType != null)
            {
                  ddlDocLib.Items.Add(new ListItem(list.Title, list.ID.ToString())); 
             }
        } 
    }
f. Next step is to override the code behind of the create button. Write a server script for the button click event in the "CustomCreatePage.aspx" as follows. We will be using the selected list in the DropDownlist as teh destination library to store the publishing pages.
protected void OnCustomSubmit(Object sender, EventArgs e)
    {
        string newPageUrl = "";
         SPWeb web = SPContext.Current.Web;         
 PublishingWeb publishingWeb = PublishingWeb.GetPublishingWeb(web);
         PageLayout[] layouts = publishingWeb.GetAvailablePageLayouts();
         int layoutItemId = Convert.ToInt32(pageTemplatePicker.SelectedValue);
         PageLayout layout = FindLayoutById(layoutItemId,publishingWeb);         
 string pageName = urlNameTextBox.Text + ".aspx";         
         PublishingPage newPage = publishingWeb.GetPublishingPages().Add(ddlDocLib.SelectedItem + "/" + pageName, layout);
         newPageUrl = web.Url + "/" + newPage.Url; // Here you can append the Querystring if you want to show the created page in the Edit Mode.
         newPage.Title = titleTextBox.Text;         
 newPage.Description = descriptionTextBox.Text;         
 newPage.Update();         
 Response.Redirect(newPageUrl);  
     }
The FindLayoutById method used in the above click event :
protected PageLayout FindLayoutById(int layoutItemId,PublishingWeb localPublishingweb)    
{
    SPListItem itemById = localPublishingweb.Web.Site.RootWeb.GetCatalog(SPListTemplateType.MasterPageCatalog).Items.GetItemById(layoutItemId);    if (itemById == null)
    {
        return null;
    }
    return new PageLayout(itemById);
 }
f. Finally Change the Serverclick property of the create page button to the custom button click event created above as follows

<asp:Button runat="server" class="ms-ButtonHeightWidth" OnClick="OnCustomSubmit" Text="<%$Resources:cms, createpage_createbutton%>" id="buttonCreatePage" AccessKey="<%$Resources:cms,createbutton_accesskey%>"/>
g. Save the "CustomCreatePage.aspx"
UFFFF.... The "CustomCreatePage.aspx" is ready to rock !!!!
Now we need to modify the "Site Action" menu behavior so that it will land you in the "CustomCreatePage.aspx" to create the publishing pages. Click HERE to know that how to replace the OOB "Create Page" link with your custom create page link in the "Site Action".
Once you replaced the console node link for the "CustomCreatePage.aspx" in the "Site Action" then the customization is complete to bend the behavior of publishing page storage in MOSS publishing site. Now you can store the publishing pages in any of the list in your sharepoint site which are enabled with the Page content type.
<!--end content copied from http://blogs.msdn.com/syedi/archive/2008/07/18/why-should-one-save-publishing-pages-in-pages-list-always-in-moss-bend-it.aspx -->

No comments:

Post a Comment