Полная кастомизация узла Wiki
Всю процедуру по созданию собственного шаблона узла и полную кастомизацию внешнего вида можно разбить на 5 пунктов:
1. Создание SiteDefinition
2. Создание Feature
3. Создание своего html шаблона для WIKI страниц
4. Изменение функционала по созданию новой wiki-страницы
5. Изменение внешнего вида кнопок
Создание SiteDefinition
1. Скопировать из ..\12\TEMPLATE\SiteTemplates папку Wiki, переименовать её например в MyWiki.
2. В папке MyWiki открыть файл onet.xml изменить там добавить или удалить оттуда необходимые фичи (секции SiteFeatures и WebFeatures).
3. Удалить все секции Module и сохранить onet.xml
4. В папке языковой локализации (в данном случае русский) ..\12\TEMPLATE\1049\XML создать файл webtempMyWiki.xml следующего содержания:
<?xml version="1.0" encoding="utf-8" ?>
<Templates>
<Template Name="MyWiki" ID="10111">
<Configuration
ID="0"
Title="Вики"
ImageUrl="/_layouts/images/stsprev.png"
Description=""
SubWebOnly="TRUE"
DisplayCategory="Мои шаблоны"
/>
</Template>
</Templates>
Создание Feature
1. В папке \12\TEMPLATE\FEATURES создадим новую feature MyWikiFeature
2. Создадим файл feature.xml следюущего содержания:
<?xml version="1.0" encoding="utf-8" ?>
<Feature Id="BA51868B-AED8-4662-B091-B9A8F8BB6630"
Title=”Вики”
Description=""
Version="1.0.0.0"
Scope="Web"
xmlns="http://schemas.microsoft.com/sharepoint/"
ReceiverAssembly="MyPortal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c5bb9526235c6eae, processorArchitecture=MSIL"
ReceiverClass="MyPortal.FeaturesActivator.WikiFeatureInstaller"
>
<ElementManifests>
<ElementManifest Location="Elements.xml"/>
</ElementManifests>
</Feature>
Feature receiver мы создадим чуть позже. Незабудьте указать потом правильный PublicKeyToken.
3. Создадим файл elements.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ListInstance
FeatureId="00BFEA71-C796-4402-9F2F-0EB9A6E71B18"
Title="$Resources:core,WikiWebLibPages;"
Description=""
TemplateType="119"
Url="$Resources:core,WikiWebLibPages_Folder;" />
<Module Name="Versions" Url="$Resources:cmscore,List_Pages_UrlName;" Path="Pages">
<File Url="VersionDiff.aspx" Type="Ghostable">
</File>
</Module>
<Module Name="WikiTemplate" Url="wikitemplate" Path="Pages">
<File Url="wiki_template.aspx" Type="Ghostable">
</File>
<File Url="default_wiki_template.aspx" Type="Ghostable">
</File>
</Module>
<Module Name="DefaultWikiPages" List="119" Url="$Resources:core,WikiWebLibPages_Folder;" Path="Pages" >
<File Url="default.aspx" Name="$Resources:core,nav_Home;.aspx" Type="GhostableInLibrary">
<Property Name="Title" Value="$Resources:core,nav_Home;" />
<Property Name="WikiField" Value=" " />
<NavBarPage Name="$Resources:core,nav_Home;" ID="1002" Position="Start" />
<NavBarPage Name="$Resources:core,nav_Home;" ID="1010" Position="Start" />
</File>
</Module>
</Elements>
В этом файле мы описали что при активации фичи на узле необходимо создать библиотеку wiki страниц, а так же указали где будут находиться основные страницы и шаблон с внешним видом wiki страниц.
4. wiki_template.aspx – файл шаблона с внешним видом wiki страниц. При создании новой вики страницы она будет выглядеть так, как описано в этом файле
5. VersionDiff.aspx – страница с перечислением всех версий wiki страницы. Т.е. мы можем кастомизировать и страницу со списком версий
6. Default.aspx – главная страница wiki узла.
Примечание: если не хотите чтобы на странице по умолчанию был какой-то текст то просто поставьте пробел в поле “WikiField”. Если этого не сделать, то при необходимости, версии WIKI страницы будут восстанавливаться не корректно и не спрашивайте меня почему.
Создание своего html шаблона для WIKI страниц
1. В папке MyWikiFeature создадим папке Pages в которой будем заготавливать страницы.
2. Скопируем в папку Pages файл ..\12\TEMPLATE\DocumentTemplates\wkpstd.aspx. Именно он и используется в качестве шаблона по которому создаются wiki страницы. Скопированный файл можно переименовать например в wiki_template.aspx и изменить так как вам это надо.
3. Скопируем файл wiki_template.aspx и переименуем его в default.aspx. Это и будет наша главная страница.
4. Скопируем в папку Pages файл ...\12\TEMPLATE\LAYOUTS\VersionDiff.aspx и изменим так как нам нужно.
5. Скопируем в папку Pages файл ...\12\TEMPLATE\LAYOUTS\CreatePage.aspx, переименуем его и изменим так как нам нужно. Скопированный файл назовем MyCreatePage.aspx
Изменение функционала по созданию новой wiki страницы (MyCreatePage.aspx)
Этот шаг нам нужен для того, чтобы все последующие wiki страницы которые может создать пользователь на узле создавались по шаблону описанному в wiki_template.aspx, а не по стандартному шаблону.
1. Создадим code behind файл для CreatePage.aspx следующего содержания:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.ApplicationPages;
using System.Web.UI.WebControls;
using System.Web.UI;
namespace MyPortal.PageHandlers
{
public class MyCreateWebPage : Page
{
protected TextBox Name;
protected ListFieldIterator fieldIterator;
protected UrlNameValidator CusValSiteName;
protected Label Error;
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
if (Request.QueryString["Name"] != null)
Name.Text = Request.QueryString["Name"];
}
protected void SubmitBtn_Click(object sender, EventArgs args)
{
Error.Text = string.Empty;
CusValSiteName.Validate();
if (!CusValSiteName.IsValid)
return;
using (SPWeb web = fieldIterator.Web)
{
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite site = new SPSite(web.Url))
{
using (SPWeb webElevated = site.OpenWeb())
{
string wikiFieldValue = fieldIterator.ListItem[fieldIterator.ListItem.Fields.GetFieldByInternalName("WikiField").Id].ToString();
if (string.IsNullOrEmpty(wikiFieldValue))
wikiFieldValue = " ";
SPFile template = GetSPFileTemplate(webElevated);
SPDocumentLibrary docLib = ((SPDocumentLibrary)fieldIterator.List);
Hashtable props = new Hashtable();
props[fieldIterator.ListItem.Fields.GetFieldByInternalName("WikiField").Title] = wikiFieldValue;
SPFile file = null;
try
{
file = fieldIterator.List.RootFolder.Files.Add(Name.Text + ".aspx", template.OpenBinary(), props);
}
catch (Exception exc)
{
}
if (file != null)
{
SPListItem item = fieldIterator.Web.Lists[fieldIterator.List.ID].Items.GetItemById(file.Item.ID);
if (item != null)
{
item[item.Fields.GetFieldByInternalName("WikiField").Id] = wikiFieldValue;
item.UpdateOverwriteVersion();
}
}
}
}
}
);
if(Error.Text ==string.Empty)
Response.Redirect(fieldIterator.List.ParentWebUrl + "/" + fieldIterator.List.RootFolder.Url + "/" + Name.Text + ".aspx");
}
}
public SPFile GetSPFileTemplate(SPWeb web)
{
SPFile template = null;
foreach (SPFile file in web.RootFolder.SubFolders["wikitemplate"].Files)
{
if (file.Name == "wiki_template.aspx")
{
template = file;
break;
}
}
return template;
}
}
}
2. Откроем MyCreatePage.aspx и укажем только что созданный класс
<%@ Assembly Name="MyPortal, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c5bb9526235c6eae"%>
<%@ Page Language="C#" Inherits="MyPortal.PageHandlers.MyCreateWebPage" MasterPageFile="~/_layouts/application.master"%>
<%@ Import Namespace="Microsoft.SharePoint.ApplicationPages" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="Utilities" Namespace="Microsoft.SharePoint.Utilities" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Import Namespace="Microsoft.SharePoint" %>
<%@ Register TagPrefix="wssuc" TagName="InputFormSection" src="~/_controltemplates/InputFormSection.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="InputFormControl" src="~/_controltemplates/InputFormControl.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ButtonSection" src="~/_controltemplates/ButtonSection.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBar" src="~/_controltemplates/ToolBar.ascx" %>
<%@ Register TagPrefix="wssuc" TagName="ToolBarButton" src="~/_controltemplates/ToolBarButton.ascx" %>
<%@ Register Tagprefix="wssawc" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ID="Content1" contentplaceholderid="PlaceHolderPageTitle" runat="server">
<SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,webpagecreation_newwk_pagetitle%>" EncodeMethod='HtmlEncode'/>
</asp:Content>
<asp:content ID="Content2" contentplaceholderid="PlaceHolderPageTitleInTitleArea" runat="server">
<SharePoint:EncodedLiteral runat="server" text="<%$Resources:wss,webpagecreation_newwk_pagetitle%>" EncodeMethod='HtmlEncode'/>
</asp:Content>
<asp:content ID="Content3" contentplaceholderid="PlaceHolderAdditionalPageHead" runat="server">
<SharePoint:ScriptLink name="form.js" language="javascript" runat="server" />
<style type="text/css">
.ms-bodyareaframe {
background-color: #ffffff;
padding: 8px;
border: none;
width: 0%;
}
.ms-rightareacell {
width: 100%;
}
</style>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderId="PlaceHolderPageImage" runat="server"/>
<asp:Content ID="Content5" ContentPlaceHolderId="PlaceHolderMain" runat="server">
<TABLE cellpadding=0 cellspacing=0 width=100% style="padding-top: 7px"><tr><td width=100%>
<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTblTop" RightButtonSeparator=" " runat="server">
<Template_RightButtons>
<asp:button ID="btnCreateTop"
text="<%$Resources:wss,multipages_createbutton_text%>"
AccessKey="<%$Resources:wss,multipages_createbutton_accesskey%>"
CssClass="ms-ButtonHeightWidth"
OnClick="SubmitBtn_Click" runat="server"/>
<SharePoint:GoBackButton ControlMode="New" runat="server" />
</Template_RightButtons>
</wssuc:ToolBar>
</td></tr></TABLE>
<TABLE class="ms-formtable" style="margin-top: 8px;" border=0 cellpadding=0 cellspacing=0 id="formTbl" width=100%>
<TR>
<TD valign="top" class="ms-formbody" width="625px">
<b><label for="<%=Name.ClientID%>"><SharePoint:FieldLabel FieldName="FileLeafRef" ControlMode="New" runat="server"/></label></b>
<asp:TextBox id="Name" name="Name" runat="server" /> <SPAN class="ms-authoringcontrols"></SPAN>
<span class="ms-formvalidation"><wssawc:UrlNameValidator ID="CusValSiteName" ControlToValidate="Name" runat="server"/>
<br /><asp:Label id="Error" name="Error" runat="server" /></span>
</TD>
</TR>
<SharePoint:ListFieldIterator TemplateName="WideFieldListIterator" ExcludeFields="FileLeafRef" ID="fieldIterator" ControlMode="New" runat="server"/>
</TABLE>
<table cellpadding=0 cellspacing=0 width=100%><tr><td class="ms-formline"><IMG SRC="/_layouts/images/blank.gif" width=1 height=1 alt=""></td></tr></table>
<TABLE cellpadding=0 cellspacing=0 width=100% style="padding-top: 7px"><tr><td width=100%>
<wssuc:ToolBar CssClass="ms-formtoolbar" id="toolBarTbl" RightButtonSeparator=" " runat="server">
<Template_RightButtons>
<asp:button ID="btnCreate"
text="<%$Resources:wss,multipages_createbutton_text%>"
AccessKey="<%$Resources:wss,multipages_createbutton_accesskey%>"
CssClass="ms-ButtonHeightWidth"
OnClick="SubmitBtn_Click" runat="server"/>
<SharePoint:GoBackButton ControlMode="New" runat="server" />
</Template_RightButtons>
</wssuc:ToolBar>
</td></tr></TABLE>
<script id="onetidPageTitleAreaFrameScript">
document.getElementById("onetidPageTitleAreaFrame").width="";
document.getElementById("onetidPageTitleAreaTable").width="";
</script>
</asp:Content>
<asp:Content ID="Content6" ContentPlaceHolderId="PlaceHolderTitleAreaSeparator" runat="server"/>
3. Не забудем скопировать файл MyCreatePage.aspx обратно в папку ...\12\TEMPLATE\LAYOUTS\
4. На этом наши мучения не закончились. Теперь необходимо подменить стандартную страницу для создания Wiki страниц нашей разработанной страницей.
Для этого мы создадим HttpModule следующего содержания:
using System;
using System.Web;
using System.Web.UI;
using System.IO;
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing;
using Microsoft.SharePoint.WebControls;
namespace MyPortal.Modules
{
public class WikiPageModule : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreRequestHandlerExecute += new EventHandler(context_PreRequestHandlerExecute);
}
void context_PreRequestHandlerExecute(object sender, EventArgs e)
{
if (HttpContext.Current.Request.Url.ToString().ToLower().Contains("/_layouts/createwebpage.aspx"))
{
HttpContext.Current.Response.Redirect(SPContext.Current.Web.Url + "/_layouts/mycreatewebpage.aspx" + HttpContext.Current.Request.Url.Query);
}
}
public void Dispose()
{
}
}
}
Внимание, не забудьте прописать HttpModule в web.config
Изменение внешнего вида кнопок
Не устраивает расположение и внешний вид кнопок на создающихся wiki страницах?
1. Открывает wiki_template.aspx из нашего примера или ..\12\TEMPLATE\DocumentTemplateswkpstd.aspx, ищем там нужный вам элемент управления и смотрим, что написано у него в свойстве TemplateName.
2. Создаем ascx файл, например MyDefaultTemplates.aspx.
3. Копируем в MyDefaultTemplates.aspx найденный в файле ...\12\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.aspx по TemplateName шаблон.
4. Меняем скопированные RenderTemplate не забыв изменить ID.
5. Копируем файл MyDefaultTemplates.aspx в папку ...\12\TEMPLATE\CONTROLTEMPLATES.
6. Еще раз открываем файл wiki_template.aspx и пишем в свойство TemplateName для элемента управления то же самое, что мы указывали как RenderTemplate ID.