Saturday, June 26, 2010

Adding a custom control to the SharePoint 2010 Team Site Wiki Page Template ( wkpstd.aspx ) programmatically

Topic

This is maybe my last post about the Team Site Wiki Page customization with the aim of exceeding its limitations. This time we are going to customize the unique template ( wkpstd.aspx) by replacing the control that renders the editable content by a custom one.
In this post example, we will take advantage of the use of this custom control to render not editable additional contents, for instance, a header and a footer that could be the same for a specific Wiki Page Library. Of course, we are not going to really customize the template, but we are going to use a delegate control to replace the control at runtime.

Here are the screen shots of the result:

We can see a non editable Header and Footer on the Team Site Wiki Page

In edit mode these additional contents are not rendered, but we can add new content as usual

And of course, after having saved the page, the new content is rendered wtih the non editable Header and Footer.

Steps required  

If you look at the Team Site Wiki Page template, wkpstd.aspx, you can see the control that is rendering the editable content/

<SharePoint:EmbeddedFormField ID="WikiField" FieldName="WikiField" ControlMode="Display" runat="server" />

We are first going to create a custom EmbeddedFormField control

Then, we are going to use a delegate control to replace the native EmbeddedFormField control by the custom one in order to have the control on the wiki page content rendering.

1 - Creating a custom EmbeddedFormField control

Here is the screen shot of the Visual Studio solution:

and the custom control source code:

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Linq;

using System.Text;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using Microsoft.SharePoint;

using Microsoft.SharePoint.WebControls;

using Microsoft.SharePoint.Security;

using System.Security.Permissions;

using System.Diagnostics;

 

namespace CustomControls

{

    [SharePointPermission(SecurityAction.LinkDemand, ObjectModel = true), AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal), SharePointPermission(SecurityAction.InheritanceDemand, ObjectModel = true), AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]

    public class EmbeddedFormFieldCustom : FormField

    {

        public EmbeddedFormFieldCustom()

        {

            Debug.WriteLine("EmbeddedFormFieldCustom: " + "constructor...");

        }

 

        private string _header = "";

        private string _footer = "";

 

        public string Footer

        {

            get { return _footer; }

            set { _footer = value; }

        }

 

        public string Header

        {

            get { return _header; }

            set { _header = value; }

        }

 

        [PersistenceMode(PersistenceMode.InnerDefaultProperty)]

        public string Content

        {

            get

            {

                SPFieldMultiLineText field = base.Field as SPFieldMultiLineText;

                if (field != null)

                {

                    Debug.WriteLine("EmbeddedFormFieldCustom: " + "SPFieldMultiLineText ok");

                    return field.GetFieldValueAsHtml(this.ItemFieldValue, base.ListItem);

                }

 

                Debug.WriteLine("EmbeddedFormFieldCustom: " + "SPFieldMultiLineText non ok");

                return base.Field.GetFieldValueAsHtml(this.ItemFieldValue);

            }

            set

            {

                Debug.WriteLine("EmbeddedFormFieldCustom: " + "set Content");

                this.ItemFieldValue = value;

            }

        }

 

        [SharePointPermission(SecurityAction.Demand, ObjectModel = true)]

        protected override void Render(HtmlTextWriter output)

        {

            Debug.WriteLine("EmbeddedFormFieldCustom: " + "rendering..");

            output.AddAttribute(HtmlTextWriterAttribute.Id, this.ClientID);

            output.Write(_header);

            output.RenderBeginTag(HtmlTextWriterTag.Div);

            base.Render(output);

            output.Write(_footer);

            output.RenderEndTag();

        }

    }

}

 

 

2 - Replacing the standard control by the custom one by using a delegate control

 Here is the delegate control source code:

<%@ Control Language="C#" ClassName="WikiPageCustomLink" %>

<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"

    Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Assembly Name="CustomControls, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0f4e5a441a5ac20c" %>

<%@ Import Namespace="Microsoft.SharePoint" %>

<%@ Import Namespace="System.Diagnostics" %>

 

    <!--delegate control begin -->

 

<script runat="server">   

    Control ctrlTofind = null;

    CustomControls.EmbeddedFormFieldCustom myCustomEmbeddedFormField = null;

 

    protected void FindControl(Control aControl, string ID)

    {

        if (aControl.HasControls())

        {

            foreach (Control aControl2 in aControl.Controls)

            {

                if (aControl2.ID == ID)

                {

                    ctrlTofind = aControl2;

                }

                else

                {

                    FindControl(aControl2, ID);

                }

            }

        }

        else

        {

            if (aControl.ID == ID)

            {

                ctrlTofind = aControl;

            }

        }

    }

 

    protected override void OnInit(EventArgs e)

    {

        if (!IsPostBack)

        {

            Debug.WriteLine("onInit");

            if (Page.TemplateControl.ToString().Contains("ASP.WKPSTD_ASPX"))

            {

                try

                {

                    int ctrlNumber = this.Page.Controls.Count;

                    foreach (Control aControl in this.Page.Controls)

                    {

                        FindControl(aControl, "WikiField");

                    }

 

                    myCustomEmbeddedFormField = new CustomControls.EmbeddedFormFieldCustom();

 

                    myCustomEmbeddedFormField.Header = "<span style='color:red;font-size:12pt' >This is my Custom header, not editable</span>";

                    myCustomEmbeddedFormField.Footer = "<span style='color:red;font-size:12pt' >This is my Custom footer, not editable</span>";

 

                    Control updatePannelContentTemplateContainer = ctrlTofind.Parent;

 

                    UpdatePanel myUpdatepannel = (UpdatePanel)updatePannelContentTemplateContainer.Parent;

 

                    int index = 0;

                    for (int i = 0; i < updatePannelContentTemplateContainer.Controls.Count; i++)

                    {

                        if (updatePannelContentTemplateContainer.Controls[i].ID == "WikiField")

                        {

                            index = i;

                        }

                    }

                    updatePannelContentTemplateContainer.Controls.Remove(ctrlTofind);

                    updatePannelContentTemplateContainer.Controls.AddAt(index, myCustomEmbeddedFormField);

                    myCustomEmbeddedFormField.FieldName = "WikiField";

                    myCustomEmbeddedFormField.ID = "WikiField";

                    myCustomEmbeddedFormField.ControlMode = Microsoft.SharePoint.WebControls.SPControlMode.Display;

                }

                catch (Exception ex)

                {

                    Response.Write("<br>error : <br>" + ex.Message);

                    Response.Write("<br>error : <br>" + ex.StackTrace);

                }

            }

        }

        base.OnInit(e);

    }

 

</script>

    <!--delegate control end -->

 

 The secret is to load the custom control only if it is not a post back, since the embedded control itself seems to be used only for displaying the content.

 Conclusion

Of course this trick could be used to add an additional custom control, a web part zone, etc... to no more be limited by the unique wkpstd.aspx template features. I let you explore the possibilities...

This is maybe my last post on the Team Site Wiki Page customization.

  1. We have already explored the customizations linked to the CSS, and the way to add a delegate control in these posts:

    Managing the Styles and the Markup Styles Menus for the Wiki Pages of a SharePoint 2010 Team Site
    Themable CSS Registration and Rendering for SharePoint 2010

  2. We have explained how to provision custom content in a Wiki Page in this one:

    Provisioning a custom Wiki Page within a SharePoint 2010 Team Site

  3. And this is the general post on the SharePoint 2010 Team Site Wiki Pages Branding and Customizations that also shows how to debug the Ribbon

    Customizing and branding the SharePoint 2010 wiki pages

I think I can now keep exploring the SharePoint 2010 wiki cuztomizations, but in the SharePoint 2010 Server version and try to use a custom SPFieldMultiLineText.

Friday, June 18, 2010

Provisioning a custom Wiki Page within a SharePoint 2010 Team Site

Topic

I have explained in my generic post about Wiki Page customization within a SharePoint 2010 Team Site that the Wiki Page of the Team Site are based on an unique template that cannot be customized.
However, there is a way of customizing a Wiki Page by provisioning a page in a Wiki Library. I do not speak here to use a SharePoint 2010 Feature, but provisioning a custom prepopulated Wiki Page as you can create a blank Wiki Page by using the "New Page" menu item within the Site Actions menu or the "New Wiki Page" menu item in the "New Document" menu item in a Wiki Page Document Library.

This process is already present in SharePoint 2010 when you create a new team site and the product is provisioning the Home Page of the team site or when you create an new Wiki Library and the product is provisioning the Welcome Page that is pre populated with explanation about the Wiki Libraries.

As a picture is worth than long explanations, here is that I propose to show in this post:

Imgine a new Wiki Page Library where you could find a "Custom Wiki Page" button in the "New" group of the SharePoint 2010 Ribbon. 

Then, when clicking on this button, a custom dialog, redesigned, would invite you to create a custom Wiki Page.

When having typed the title and submited the dialog, you would be redirected to your new Custom Wiki page prepopulated with the typed title of the page, plus your name and your photo.

Much more! When editing the page, you would notice a new Text Layout, that is not provided by the default SharePoint 2010 Text Layout menu items.

Of course the page could be Saved properly...

 

To be able to mount such a solution, several steps has to be performed:

  1. First you have to create a new Button within the SharePoint 2010 Ribbon.
  2. Second, you need to create the custom application page that will provision the custom Wiki Page in this custom Document Library


So let us do all this now... but before some little explanations about Content Types for the Team Site Wiki Pages Library are to be provided

1 - You CANNOT add Content Types to a Team Site Wiki Library

Now that you have seen what I wanted to do, you might be thinking "wait a minute, why he has not created a new content type for his custom wiki page so as the "New"  menu of the Wiki Library will be automatically populated with an item to create a custom page?".

I tried, tried very much, but as I discovered a first limitation of the Team Site Wiki Library that does not allow them to create pages based on several templates, I have now discovered that you cannot add new content types to a Team Site Wiki Library.

When you try to add a content type to a Wiki Library you may be surprised because, by default, a Wiki Library is not configured to support Content Types. It is normal since the original goal is not to create other document than a native SharePoint 2010 Wiki Page for a Team Site. Here is an excerpt of the Microsoft documentation on the topic (How to: Add a Content Type to a List):

[...
Before you can add a content type to a list definition, you must be sure that the list is configured to support content types. The first thing to check is the template from which the list instance is created. If the ListTemplate element has an attribute named DisallowContentTypes and the attribute is set to TRUE, then the list does not support content types. If the attribute is set to FALSE or is missing, then the list does support content types.

The next thing to check is whether content types are enabled on the list instance. The Schema.xml file that defines the list instance has a List element. This element must include an attribute named EnableContentTypes, and the attribute must be set to TRUE. Setting the attribute to TRUE is equivalent to selecting Yes under Allow management of content types? in the Advanced Settings section of List Settings.
..]

So first, I tried to  to created a new Custom Wiki Library  with a new type and changed the schema configuration, then created a new Wiki Page Content Type and added it to the library, and it worked, this new library accepted a new Wiki Page content type, and I had a new menu entry in my New Document menu : Wiki Custom Page - Create a new wiki page.


But just after that, when trying to create the page, it failed, and I had the following error message : "You cannot create a Wiki Page in a Library that is not a Wiki Library".

Ok, then I tried to create a custom Wiki Page library with the same type (119), even if it is idiot, since we cannot see the difference after and that time, although I had configured and test several times the configuration, the library just did not show the UI entries corresponding to the possibility to add new Content Types.
So, the conclusion is the following:

You cannot add new Content Types to the Team Site Wiki Page Libraries in SharePoint 2010.
You cannot create Wiki Pages in a custom Team Site Wiki Page Library.

Ok, no trouble then, I will create my custom pages from a new button within the Ribbon. ( I also tried many hours to add a new entry in the New Document menu using a Custom Action feature, even tried to create first a new section in the menu, but no way. If somebody finds it, let me know...)

2 - Creating a "New Document" custom button in the Ribbon


There is a lot of documentation now on the Internet about how to create a custom button in SharePoint 2010 so here is just the code and a few comments:

<?xml version="1.0" encoding="utf-8"?>

<Feature xmlns="http://schemas.microsoft.com/sharepoint/"

        Id="afe52f83-a20e-42d4-8aa7-35d8c5fdfc50"

        Title="Ribbon New Button"

        Scope="Web"

        Description="Add a new menu button to a Wiki Page Library to provision custom Wiki Pages"

        >

       <ElementManifests>

             <ElementManifest Location="newButton.xml"/>

       </ElementManifests>

</Feature>

 

 

<?xml version="1.0" encoding="utf-8"?>

<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

       <CustomAction

             Id="Ribbon.Library.Actions.AddAButton"

             RegistrationId="119"

             RegistrationType="List"

             Location="CommandUI.Ribbon"

             Sequence="5"

             Title="New Custom Wiki Page">

             <CommandUIExtension>

                    <CommandUIDefinitions>

                           <CommandUIDefinition Location="Ribbon.Documents.New.Controls._children">

                                        <Button

                                        Id="Ribbon.Documents.New.NewCustomWikiPage"

                                        Alt="Add a Custom Wiki Page"

                                        Sequence="5"

                                        Command="CreateCustomWikiPage"

                                         Image16by16="/_layouts/$Resources:core,Language;/images/formatmap16x16.png" Image16by16Top="-48" Image16by16Left="-16"

                                         Image32by32="/_layouts/$Resources:core,Language;/images/formatmap32x32.png" Image32by32Top="0" Image32by32Left="-64"

                                        LabelText="Custom Wiki Page"

                                        Description="Create a new Custom Wiki Page"

                                        TemplateAlias="o1"

                                        />

                           </CommandUIDefinition>

                    </CommandUIDefinitions>

                    <CommandUIHandlers>

                           <CommandUIHandler

                     Command="CreateCustomWikiPage"

                     CommandAction="javascript:OpenCreateWebPageDialog('/_layouts/createCustomWebPage.aspx?List={ListId}');" />

                    </CommandUIHandlers>

             </CommandUIExtension>

       </CustomAction>

</Elements>

 

 You can notice that you have to specify the type of the library in the RegistrationId, so don not mistake when creating a button for a library.
And a fantastic thing is that JavaScript supports the old syntax for the parameter: {ListId}
Do not forget the quotes in the javaScript method.

Now, very important, how to know if the component installtion has worked or failed.

First, as you maybe know, you can also add an item to the Ribbon by using a Web Part. So if you check the html source code of the page, you will see this Web Part that shows the parameters of the native Sharepoint configuration for the Ribbon. You can check this parameters as an example if you want to create a custom control later within the Ribbon.

But if you want to check the installation of a custom control, there will be also available javascript code to be checked, within the dataExtension, and the Command UI Handler objects in json format. If you see them, it will be the confirmation that the installation is successful, and you will also be able to check that the parameters are correct, if something is going wrong:

3 - Provisioning the Team Site Wiki Page 

 

3.1 Implementing the custom Web part

So as the goal of our tutorial was to prepopulate a Wiki Page with some text and a Web Part that can retrieve the name and the picture of the author, let us first implement the Web Part.

I called the assembly MyCompany.Frameworks.SharePoint
I have created a folder to add a WebParts part to the namespace
And the first Web Part of this framework is called GetAuthorInfo

 

using System;

using System.Linq;

using System.Runtime.InteropServices;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using Microsoft.SharePoint;

 

 

namespace MyCompany.Frameworks.SharePoint.WebParts

{

    [Guid("5aa223b6-fd04-48c1-83e6-9531bf45ef19")]

    public class GetAuthorInfo : System.Web.UI.WebControls.WebParts.WebPart

    {

        protected override void CreateChildControls()

        {

            base.CreateChildControls();

 

            string HtmlOutput = string.Empty, pictureUrl ;

 

            Label label = new Label();

            SPWeb myWeb = SPContext.Current.Web;

            SPList myUserInfo = null;

 

            string author = SPContext.Current.Item["Created By"].ToString();

            author = author.Split(new Char[] { '#' })[1].ToLower();

            HtmlOutput += "Author: " + author;

 

            myUserInfo = myWeb.Site.RootWeb.Lists["User Information List"];

            var results = myUserInfo.Items.Cast<SPListItem>().Where(item => Equals(string.Compare(item["Name"].ToString(), author, true), 0));

 

            if (results.Count() > 0)

            {

                pictureUrl = results.First<SPListItem>()["Picture"].ToString().Split(new Char[] { ',' })[0];

                HtmlOutput += "<br/><br/><img src='" + pictureUrl + "' />";

            }

 

            label.Text = HtmlOutput;

 

            this.Controls.Add(label);

        }

    }

}

 

 

notice that if you want the previous code works on SharePoint 2010 you have to configure it for Linq and I have a post for a minimal configuration :

Use Linq inside a Script Block of an Application Page - SharePoint minimal configuration for Linq

Until now except some minor differences with SharePoint 2007, we were in a known land, it is now that it becomes interesting since we are going to discover the SharePoint 2010 wiki pages content new syntax.

 So I will give soon the code of the custom SharePoint 2010 dialog and inside the in line script code to provision the Wiki Page. But before, some indications:

3.2 - to create a wiki page file and get the SPListItem corresponding to the file:

SPListItem listItem = files.Add(strUrl, SPTemplateFileType.WikiPage).GetListItem(new string[] { "WikiField" });


3.3 - to add some content to a wiki page programmatically:

listItem["WikiField"] = content;

listItem.UpdateOverwriteVersion();

3.4 - to add a Web part within this content:


 Give it a storageKey
 add it to the Web part manager

 then use this syntax to place it within the Wiki page content, based on the storage key

string str3 = string.Format(CultureInfo.InvariantCulture, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contentEditable=\"false\"><div class=\"ms-rtestate-read {0}\" id=\"div_{0}\"></div><div style='display:none' id=\"vid_{0}\"/></div>", new object[] { storageKey.ToString("D") });
 

3.5 - Structure of the text layout:

This is the html to store in WikiField field of the WikiPage SPListItem if you want to obtain the same page than this tutorial.

 Notice the nested DIV with the ms-rte-layoutszone-outer and the ms-rte-layoutszone-inner classes. and the <span id="layoutsData" style="display: none">true,false,2</span>

 that is corresponding to the structure (I think the integer is the number of rows), but I have not any clue about the boolean. I had to set the second to false if not my page could not be saved! If somebody finds information about it, let me know...

<table id="layoutsTable" style="width: 100%">

    <tbody>

        <tr style="vertical-align: top">

            <td style="width: 100%">

                <div class="ms-rte-layoutszone-outer" style="width: 100%">

                    <div class="ms-rte-layoutszone-inner" style="min-height: 60px; word-wrap: break-word">

                        <h1 class="ms-rteElement-H1B" style="margin-bottom: 0px;">

                            <span><span>Wiki 1 </span></span>

                        </h1>

                        <p>

                            &#160;</p>

                        <p>

                            &#160;</p>

                        <p>

                            &#160;</p>

                    </div>

                </div>

            </td>

        </tr>

        <tr style="vertical-align: top">

            <td style="width: 100%">

                <div class="ms-rte-layoutszone-outer" style="width: 100%">

                    <div class="ms-rte-layoutszone-inner" style="min-height: 60px; word-wrap: break-word">

                        <p>

                            &#160;</p>

                        <p>

                        </p>

                        <p>

                            &#160;</p>

                        <p>

                            &#160;</p>

                        <p>

                            &#160;</p>

                        <p>

                            &#160;</p>

                        <div class="ms-rtestate-read ms-rte-wpbox" contenteditable="false">

                            <div class="ms-rtestate-read ae26f6c9-8cf4-438c-8a38-26cd309d0ec6" id="div_ae26f6c9-8cf4-438c-8a38-26cd309d0ec6">

                            </div>

                            <div style='display: none' id="vid_ae26f6c9-8cf4-438c-8a38-26cd309d0ec6" />

                        </div>

                        <p>

                            &#160;</p>

                    </div>

                </div>

            </td>

        </tr>

    </tbody>

</table>

<span id="layoutsData" style="display: none">true,false,2</span>

 3.6 - To close the dialog and be redirected to the provisioned page

 window.frameElement.navigateParent(ProvisionedPageUrl);

 4 - Code of the all dialog page (createCustomWebpage.aspx)

 

<%@ Page Language="C#" AutoEventWireup="true" Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase"

    DynamicMasterPageFile="~masterurl/default.master" %>

 

<%@ Assembly Name="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Assembly Name="MyCompany.Frameworks.SharePoint, Version=1.0.0.0, Culture=neutral, PublicKeyToken=11b701f527101e0f" %>

<%@ Register TagPrefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls"

    Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

<%@ Import Namespace="Microsoft.SharePoint" %>

<%@ Import Namespace="System.Text" %>

<%@ Import Namespace="Microsoft.SharePoint.Utilities" %>

<%@ Import Namespace="Microsoft.SharePoint.WebPartPages" %>

<%@ Import Namespace="System.Globalization" %>

<%@ Import Namespace="MyCompany.Frameworks.SharePoint.WebParts" %>

<%@ Import Namespace="System.Web.UI.WebControls.WebParts" %>

<asp:content contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">

       <SharePoint:UIVersionedContent ID="UIVersionedContent1" UIVersion="4" runat="server"><ContentTemplate>

              <SharePoint:CssRegistration runat="server" Name="forms.css" />

       </ContentTemplate></SharePoint:UIVersionedContent>

</asp:content>

<asp:content id="Main" contentplaceholderid="PlaceHolderMain" runat="server">

  

<script language="C#" runat="server">

   

    SPList myList = null;

    SPWeb myWeb = null;

    protected override void OnLoad(EventArgs e)

    {

        isProvisioningFinished.Value = "false";

 

        myWeb = SPContext.Current.Web;

 

        Guid listGuid = new Guid(Request.QueryString["List"]);

        myList = myWeb.Lists[listGuid];

 

        TargetLibrary.Text = "This page will be created in this library: <br/><div style='color:#0072bc;padding-top:3px'>" + myList.Title + "</div>";

        NameDescLabel.Text = "New page name: ";

    }

 

    protected void provision(object sender, EventArgs e)

    {

        SPFolder rootFolder = myList.RootFolder;

        SPWeb parentWeb = myList.ParentWeb;

 

        SPFileCollection files = rootFolder.Files;

 

        string pageName = txtPageName.Text;

 

        string strUrl = rootFolder.ServerRelativeUrl + "/" + pageName + ".aspx";

        if (!parentWeb.GetFile(strUrl).Exists)

        {

            SPListItem listItem = files.Add(strUrl, SPTemplateFileType.WikiPage).GetListItem(new string[] { "WikiField" });

            ProvisionWikiPageHomePage(listItem.File, pageName);

            ProvisionedPageUrl.Value = strUrl;

 

            isProvisioningFinished.Value = "true";

        }

    }

 

    protected void ProvisionWikiPageHomePage(SPFile wikiPage, string pageName)

    {

        if (wikiPage == null)

        {

            throw new ArgumentNullException("wikiPage");

        }

        SPListItem listItem = wikiPage.GetListItem(new string[] { "WikiField" });

        if (listItem == null)

        {

            throw new ArgumentException(SPResource.GetString("OnlyInWikiLibraries", new object[0]));

        }

        SPList parentList = listItem.ParentList;

 

 

        SPWeb parentWeb = parentList.ParentWeb;

        string serverRelativeUrl = parentWeb.ServerRelativeUrl;

        if (serverRelativeUrl.EndsWith("/"))

        {

            serverRelativeUrl = serverRelativeUrl.Substring(0, serverRelativeUrl.Length - 1);

        }

        SPList list = null;

        string str2 = null;

        using (SPLimitedWebPartManager manager = wikiPage.GetLimitedWebPartManager(PersonalizationScope.Shared))

        {

            str2 = RenderListViewWebPartForWikiPage(manager);

        }

 

        StringBuilder builder = new StringBuilder();

        StringBuilder builder2 = new StringBuilder();

        builder.Append("\r\n                <table id=\"layoutsTable\" style=\"width: 100%\">\r\n                    <tbody>\r\n                        <tr style=\"vertical-align:top\">");

        builder.Append("\r\n                            <td style=\"width: 100%\">\r\n        <div class=\"ms-rte-layoutszone-outer\" style=\"width:100%\">\r\n          <div class=\"ms-rte-layoutszone-inner\" style=\"min-height:60px;word-wrap:break-word\">\r\n<h1 class=\"ms-rteElement-H1B\" style=\"margin-bottom:0px;\"><span><span>");

        builder.Append(SPHttpUtility.HtmlEncode(pageName));

        builder.Append("\r\n                                        </span></span></h1>\r\n  ");

        builder.Append("\r\n            <p>&#160;</p>\r\n            <p>&#160;</p>\r\n            <p>&#160;</p>\r\n          </div>\r\n        </div>\r\n      </td>");

        builder.Append("\r\n </tr>");

        builder.Append("\r\n <tr style=\"vertical-align:top\">");

        builder2.Append("\r\n                            <td style=\"width: 100%\">\r\n        <div class=\"ms-rte-layoutszone-outer\" style=\"width:100%\">\r\n          <div class=\"ms-rte-layoutszone-inner\" style=\"min-height:60px;word-wrap:break-word\">\r\n");

        builder2.Append("                                        <p>&#160;</p>\r\n                                        <p>");

        builder2.Append("\r\n                                        </p>\r\n                      <p>&#160;</p>\r\n            <p>&#160;</p>\r\n            <p>&#160;</p>\r\n                                        <p>&#160;</p>");

        if (!string.IsNullOrEmpty(str2))

        {

            builder2.Append(str2);

        }

        builder2.Append("<p>&#160;</p>\r\n     \r\n</div>\r\n        </div>\r\n      </td>");

        builder.Append(builder2.ToString());

        builder.Append("\r\n    </tr>\r\n  </tbody>\r\n</table>\r\n            <span id=\"layoutsData\" style=\"display: none\">true,false,2</span>");

        string result = "";

        result = builder.ToString();

 

        //to see the generated code (user must have the write permission on C drive...)

        //System.IO.File.WriteAllText("c:\\test.html",result);

        listItem["WikiField"] = result;

        listItem.UpdateOverwriteVersion();

    }

 

    protected string RenderListViewWebPartForWikiPage(SPLimitedWebPartManager lwpm)

    {

        if (lwpm == null)

        {

            throw new ArgumentNullException("lwpm");

        }

 

        System.Web.UI.WebControls.WebParts.WebPart webPart = new GetAuthorInfo();

 

        webPart.Title = "Author";

        webPart.ChromeType = PartChromeType.None;

 

        Guid storageKey = Guid.NewGuid();

        webPart.ID = StorageKeyToID(storageKey);

 

        lwpm.AddWebPart(webPart, "wpz", 0);

 

        string str = storageKey.ToString();

        StringBuilder builder = new StringBuilder();

 

        string str3 = string.Format(CultureInfo.InvariantCulture, "<div class=\"ms-rtestate-read ms-rte-wpbox\" contentEditable=\"false\"><div class=\"ms-rtestate-read {0}\" id=\"div_{0}\"></div><div style='display:none' id=\"vid_{0}\"/></div>", new object[] { storageKey.ToString("D") });

        return str3;

    }

 

    internal string StorageKeyToID(Guid storageKey)

    {

        if (!(Guid.Empty == storageKey))

        {

            return ("g_" + storageKey.ToString().Replace('-', '_'));

        }

        return string.Empty;

    }

 

</script>

        

<asp:Label ID="Label1" runat="server" Text=""></asp:Label>

       <div style="width:350px; margin-right:auto; margin-left:auto;">

              <br />

              <div style="height:3.75em;">

                     <asp:Label id="TargetLibrary" runat="server" />

              </div>

              <div>

              <br />

              <br />

                     <asp:Label style='padding-bottom:5px;display:block' id="NameDescLabel" runat="server" />

              </div>

              <div>

                     <asp:TextBox id="txtPageName" runat="server" />

              </div>

              <div style="height:3.75em;" class="ms-formvalidation">

                     <asp:Label id="NameErrorLabel" runat="server" />

              </div>

              <div>

            <asp:LinkButton style="border:solid 1px #0072bc;padding:2px" runat="server" Text="Provision the page " OnClick="provision" />

              </div>

            <input type='hidden' runat='server' id='isProvisioningFinished' />

            <input type='hidden' runat='server' id='ProvisionedPageUrl' />

        </div>

        <script type="text/javascript">

 

            var isProvisioningFinishedClientID = '<%=isProvisioningFinished.ClientID%>';

            var ProvisionedPageUrlClientID = '<%=ProvisionedPageUrl.ClientID%>';

 

            var isFinished = "false";

            var ProvisionedPageUrl = "";

 

            isFinished = document.getElementById(isProvisioningFinishedClientID).value;

            ProvisionedPageUrl = document.getElementById(ProvisionedPageUrlClientID).value;

 

 

            if (isFinished == "true") {

 

                isFinished.value = "false";

                window.frameElement.navigateParent(ProvisionedPageUrl);

            }      

           </script>

 

</asp:content>

<asp:content id="PageTitle" contentplaceholderid="PlaceHolderPageTitle" runat="server">

New Custom Wiki Page

</asp:content>

<asp:content id="PageTitleInTitleArea" contentplaceholderid="PlaceHolderPageTitleInTitleArea"

    runat="server">

New Custom Wiki Page

</asp:content>