In Part 1 of this series I looked at replacing the “NewFormUrl”, “EditFormUrl” and “DisplayFormUrl” properties of the Content Type object to change the forms that SharePoint uses to display list item information. In this second part I will discuss how we can replace the actual Rendering Templates to achieve the same goals.
This is how Rendering Templates work:
Each item in a SharePoint list is of a certain Content Type. In most cases items are either an “Item” Content Type or a “Document” Content Type depending on the Base Type of the list. Usually as developers and customisers we create additional Content Types that make sense to the business, for example Invoices, Quotes, Proposals, etc.
Each Content Type has “New”, “Edit” and “Display” forms for displaying and collecting data related to the content type item. Each one of these 3 forms has a “Form Rendering Template” that defines the HTML markup and controls that will render for the forms.
These Rendering Templates are defined in the _CONTROLTEMPLATES folder. Most other objects in SharePoint have Rendering Templates which are defined in DefaultTemplates.ascx, check out the Toolbar, ListFieldIterator, etc. The DocumentLibraryForm is defined in DefaultTemplates.ascx:
<SharePoint:RenderingTemplate ID="DocumentLibraryForm" runat="server">
<Template>
<SharePoint:InformationBar runat="server"/>
<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbltop"
RightButtonSeparator="" runat="server">
<Template_RightButtons>
<SharePoint:SaveButton runat="server"/>
<SharePoint:GoBackButton runat="server"/>
</Template_RightButtons>
</wssuc:ToolBar>
<SharePoint:FormToolBar runat="server"/>
<SharePoint:FormComponent TemplateName="DocumentLibraryFormCore"
runat="server"/>
</Template>
</SharePoint:RenderingTemplate>
This rendering template calls other “FormCompontent” objects and their Rendering Tempaltes – very similar to PHP…
Our goal is to replace these Rendering Templates with our own, so we modify what end users see in the New, Edit and Display scenarios.
We can “tell” Content Types to use our own Rendering Tempaltes by two ways: including XML in the Content Type Definition, or Using code.
Option 1:
Content Type definitions in features allow you to set XmlDocument elements:
<!-- Document Content Type -->
<ContentType ID="0x0101006BD6DAD38F7947799A6F2EE72F5C3C24"
Name="TemporaryContentType"
Group="Custom Content Types"
Description="">
<FieldRefs>
<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" />
</FieldRefs>
<XmlDocuments>
<XmlDocument
NamespaceURI="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<FormTemplates
xmlns="http://schemas.microsoft.com/sharepoint/v3/contenttype/forms">
<Display>MyCustomForm</Display>
<Edit>MyCustomForm</Edit>
<New>MyCustomForm</New>
</FormTemplates>
</XmlDocument>
</XmlDocuments>
</ContentType>
With the above FormTemplates element under XmlDocument I have specified that the custom content type should use the custom Rendering Template MyCustomForm for rendering the New, Edit and Display forms.
To create this Rendering Template, create your own ASCX file to store it, use a feature to deploy it to the CONTROLTEMPLATES folder, and then add the XmlDocuments element to your Content Type definition as demonstrated above. Here is a basic Rendering Template that should go in a custom ASCX file, you can name it however you wish, SharePoint will “crawl” the folder for all Rendering Templates during the Application Pool start-up sequence.
<SharePoint:RenderingTemplate ID="MyCustomForm" runat="server">
<Template>
Hello
</Template>
</SharePoint:RenderingTemplate>
You can include your own custom ASCX controls in your rendering templates and completely change the SharePoint experience.
In part 1 I explained how the ListFormWebPart gets added to our form pages that get provisioned with the list. This web part is what actually does the work in both options. During load time it checks the Rendering Template name specified in the properties and builds its markup based on that template.
Here is a shot of the TemplateName property where the web part checks the current Content Type and gets its template names:
This leads us to our next option: changing the Template names in code.
Option 2: Using code to change a Content Types Rendering Template.
It’s quite simple – the SPContentType object exposes 3 properties so we can set the template names:
cType.NewFormTemplateName = “MyCustomForm”;
cType.EditFormTemplateName = “MyCustomForm”;;
cType.DisplayFormTemplateName = “MyCustomForm”;
cType.Update(true);
This essentially achieves the same as Option 1 above, but keep in mind that you should most likely push the changes down to child content types – call .Update(true); instead of .Update();
All the best.