In this
article I'll tell you how to change standard templates for Edit, Display and
New Forms for List Items and Documents in Sharepoint 2010. You can make it with
Sharepoint Designer or InfoPath for partucular lists. This is described here:
But what
if you need to change all forms of templates in the farms with your custom form
through wsp-package? While I was investigating this question I found many
suggestions to change file 14\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx:
This
template is used for default list edit, display and to create form of list
items:
<SharePoint:RenderingTemplate id="ListForm" runat="server">
<Template>
…
</Template>
</SharePoint:RenderingTemplate>
<Template>
…
</Template>
</SharePoint:RenderingTemplate>
And this
one is used for documents:
<SharePoint:RenderingTemplate id="DocumentLibraryForm" runat="server">
<Template>
…
</Template>
</SharePoint:RenderingTemplate>
<Template>
…
</Template>
</SharePoint:RenderingTemplate>
Yes, if
you change these templates and make iisreset you'll
get what you want — a new template for all forms. So, what if we don't want to change the
system files? Okey, let's look at the control, that manages templates in
CONTROLTEMPLATES folder: SPControlTemplateManager.
Method GetTemplateByName(String) of this
class returns the template of RenderingTemplate
control by its ID. All templates are
loaded to the static HASH-table after the first call of this method. That is
why we should make iisreset after changing DefaultTemplates.ascx
file. So let's see how it works:
private static Hashtable GetTemplateCollection()
{
if ((s_templateTable == null) && (HttpContext.Current != null))
{
lock (InternalSyncObject)
{
if (s_templateTable == null)
{
Hashtable templateTable = new Hashtable();
FileInfo[] files = new DirectoryInfo(HttpContext.Current.Server.MapPath(systemTemplateLocation)).GetFiles("*.ascx");
string controlTemplateFile = systemTemplateLocation + defaultTemplateFile;
string str3 = systemTemplateLocation + mobileDefaultTemplateFile;
LoadControlTemplate(templateTable, controlTemplateFile);
LoadControlTemplate(templateTable, str3);
foreach (FileInfo info2 in files)
{
if (!(info2.Name == defaultTemplateFile) && !(info2.Name == mobileDefaultTemplateFile))
{
controlTemplateFile = systemTemplateLocation + info2.Name;
LoadControlTemplate(templateTable, controlTemplateFile);
}
}
s_templateTable = templateTable;
}
}
}
return s_templateTable;
}
Variables
values:
systemTemplateLocation = "/_controltemplates/";
defaultTemplateFile = "DefaultTemplates.ascx";
As you
see, first, this control loads all templates from DefaultTemplates.ascx
file. Then it gets all files form CONTROLTEMPLATES directory and loads all
templates from them. So if it finds templates with the same name as defined in DefaultTemplates.ascx it replaces them. Okey,
let’s check it. Create a new file in CONTROLTEMPLATE directory and add a
template to it:
<SharePoint:RenderingTemplate id="ListForm" runat="server">
<Template>
<h1>Custom form!</h1>
</Template>
</SharePoint:RenderingTemplate>
<Template>
<h1>Custom form!</h1>
</Template>
</SharePoint:RenderingTemplate>
Make
iisreset, navigate some list and try to
create a new item. You'll see our title instead of form. Okey, it works perfectly for standard templates, but
what if we want to change the template for only one Web Application or
SiteCollection or change the template for DocumentSet display form, which
stores its template in file DocSetTemplates.ascx.
Let's look at ListFormWebPart. This class
has property TemplateName which is used
to get a template name by current context (Edit, Create or Display):
public string TemplateName
{
get
{
if (this.templateName == null)
{
this.EnsureListAndForm();
if (this.ItemContext != null)
{
SPContentType contentType = this.ItemContext.ContentType;
if (contentType != null)
{
switch (this.pageType)
{
case PAGETYPE.PAGE_DISPLAYFORM:
this.templateName = contentType.DisplayFormTemplateName;
break;
case PAGETYPE.PAGE_EDITFORM:
this.templateName = contentType.EditFormTemplateName;
break;
case PAGETYPE.PAGE_NEWFORM:
this.templateName = contentType.NewFormTemplateName;
break;
}
if ((this.templateName != null) && (this.templateName.Length > 0))
{
return this.templateName;
}
}
}
if (this.form != null)
{
this.templateName = this.form.TemplateName;
}
else
{
this.templateName = "ListForm";
}
}
return this.templateName;
}
set
{
this.templateName = value;
}
}
To get
the name of the templates it uses properties of ContentType:
DisplayFormTemplateName, EditFormTemplateName,
NewFormTemplateName. So, we can create a
new template in CONTROLTEMPLATES directory and set its name into all content
types we need with powershell, for example. If we remove our template nothing
happens, because if the template is not found it uses a default ListForm template.
Комментариев нет:
Отправить комментарий