SharePoint Development Basics: Site Definitions

In dieser Reihe beschäftigen wir uns mit den Grundlagen, die jeder SharePoint Entwickler kennen sollte, die aber oft und gerne übersehen werden.

Weil man als Entwickler nunmal alles gerne direkt selbst programmiert, werden oft SharePoint OOB Konzepte umgangen und einfach in Custom Code “nachprogrammiert”. Das ist nicht gut –

1. Weil man das Rad nicht neu erfinden sollte – “DON’T REPEAT YOURSELF”

2. Weil SharePoint eine grosse Platform ist, die gewartet und eventuell auch migriert und upgedated werden muss (oft von mehrerern Dienstleistern beim selben Kunden), und man sich um den Aufwand gering zu halten, tunlichst soweit möglich an die SharePoint Standards halten sollte.

Darum beginnen wir hier mit den grundlegenden “Building Blocks” einer SharePoint Applikation – Site Definitions. Sie können sehr viel Programmieraufwand ersparen und erleichtern das Deployment extrem.

Was ist eine Site Definition?

Wie so oft in SharePoint eine eine XML Datei Smile - aber die hats in sich. Site Definitions umfassen alle Elemente einer kompletten Site.

Folgende Elemente kann eine Site Definition enthalten:

  • Top Navigation
  • Quick Launch Navigation
  • Listenvorlagen
  • Listeninstanzen
  • Dokumentenbibliotheken (klar ergibt sich aus Listen)
  • Dokumentenvorlagen
  • Features (Die automatisch aktiviert werden)
  • Module
  • WebParts (auch Custom WebParts)

Eine SiteDefinition besteht physisch aus 2 Dateien. Der webtemp_[Name].xml Datei und der onet.xml Datei. Die webtemp_[Name].xml wandert beim Deployment in den 14\TEMPLATE\[LCID]\XML Ordner. Je nach Sprache gibt es mehrere Ordner, jeder mit seiner Locale ID. Standardmässig in englischen Systemen ist die LCID 1033, bei deutschen Systemen 1031. Hat man eine deutsche Site Definition, sollte man sie auch unter 1031 ablegen, da sonst beim Ersellen, alle Systemmenüs englisch erscheinen (zB “Site Settings”).

Die webtemps Datei enthält nur einen Verweis auf die eigentliche Site Definition. Sie dient dazu, damit in der Zentraladministration ein neues Template überhaupt erst zur Auswahlt erscheint. Die folgende webtemps Datei bewirkt, dass, wie in Abbildung 2 ersichtlich, eine Site basierend auf einer neuen Vorlage erstellt werden kann. In Abb.2 ist auch ersichtlich, dass die Vorlagensprache Englisch ist (Datei liegt unter 14\TEMPLATE\1033\XML)

    1: <Templates xmlns:ows="Microsoft SharePoint">   2:  <Template Name="MAPortal_Site" ID="100050">   3:  <Configuration ID="0" Title="Mitarbeiterportal"    4:     Hidden="FALSE"    5:     ImageUrl="/_layouts/images/customlogo.gif"    6:     Description="Stellt das Mitarbeiterportal zur Verfügung"    7:     DisplayCategory="MA Portal" />    8:  </Template>   9: </Templates>

Abbildung 1 – WebTemps Datei

20110401 (2)

Abbildung 2 – Vorlagenauswahl in der ZA unter “Create Site Collection”

Wichtig dabei ist: Der Name in der Datei – webtemps_MAPortal_Site.xml muss dem Name Attribut im Template Element entsprechen, sowie dem Title Attribut in der onet.xml Datei (kommt weiter unten). Mit Visual Studio 2010 ist das alles keine Hexerei, da es eine Vorlage namens “Basic Site Definition” gibt – welche die webtemps und onet.xml Dateien erzeugt – die müssen dann nur noch weiter befüllt und angepasst werden.

Soweit relativ einfach. Das Interessante ist aber die onet.xml Datei, sie gibt die Inhalte einer Site Definition an. Folgendes Snippet zeigt eine beispielhafte onet.xml

    1: <?xml version="1.0" encoding="utf-8"?>   2: <Project Title="MAPortal_Site" SiteLogoUrl="/_layouts/images/MaPortal/noelkhlogo.png" Revision="2" ListDir="" xmlns:ows="Microsoft SharePoint" xmlns="https://schemas.microsoft.com/sharepoint/">   3:   <NavBars>   4:     <!--  Top Nav  -->   5:     <NavBar Name="Home" Separator="&amp;nbsp;&amp;nbsp;&amp;nbsp;" Url="#URL#" ID="1002">   6:     </NavBar>   7:     <!-- Quick Launch -->   8:     <NavBar Name="Lists" Url="Lists" ID="1004">   9:         <NavBarLink Name="Vorlagen" Url="Lists/EmailTemplates" />  10:     </NavBar>  11:   </NavBars>  12:   <Configurations>  13:     <Configuration ID="0" Name="Mitarbeiterportal" Title="Mitarbeiterportal" ImageUrl="/_layouts/images/MaPortal/logo.png" MasterUrl="_catalogs/masterpage/MaPortal_Master.master" CustomMasterUrl="_catalogs/masterpage/MaPortal_Master.master" >  14:       <ListTemplate Name="Def_EmailTemplates" Type="10016" BaseType="0" OnQuickLaunch="FALSE" SecurityBits="11" Sequence="410" DisplayName="Email Templates" Description="Vorlagen für Emailnachrichten" Image="/_layouts/images/itgen.png"/>  15:       <Lists>  16:         <List Type="10016" Title="EmailTemplates" Url="Lists/EmailTemplates" FeatureId="be5b914c-12f3-4bff-899c-e44b77bb2ff2" Description="Stellt Listenvorlagen für Email aus Workflows zur Verfügung" />  17:       </Lists>  18:       <SiteFeatures>  19:         <!-- Basic WebParts -->  20:         <Feature ID="00bfea71-1c5e-4a24-b310-ba51c3eb7a57" />  21:         <!--  Workflows -->  22:         <Feature ID="c845ed8d-9ce5-448c-bd3e-ea71350ce45b" />  23:         <!-- Standard Site Collection Features -->  24:         <Feature ID="b21b090c-c796-4b0f-ac0f-7ef1659c20ae" />  25:         <!--  publishing infrastructure -->  26:         <Feature ID="f6924d36-2fa8-4f0b-b16d-06b7250180fa" />  27:         <!-- MA Portal Workflows -->  28:         <Feature ID="9044c1b5-9df5-45fe-a458-37e71f50820a"/>  29:         <!-- MA Portal Base-->  30:         <Feature ID="be5b914c-12f3-4bff-899c-e44b77bb2ff2"/>  31:         <!-- MA Portal Tasks-->  32:         <Feature ID="bda5efff-8229-4c64-a2a2-1cb3a5f0027e"/>  33:         <!-- MA Portal Announcements -->  34:         <Feature ID="7b213bcb-6b61-4b6a-8796-41b3e95d6f84"/>  35:         <!-- Post Site Scoped Features (CT)-->  36:         <Feature ID="b992a5a3-0ec4-47c4-9e1a-32c42a8cd08c" />  37:         <!-- Ma Portal Memo -->  38:         <Feature ID="0d6cd54b-9003-4dee-b78a-6d740e652de0" />  39:       </SiteFeatures>  40:       <WebFeatures>  41:         <!--  Standard Web Features -->  42:         <Feature ID="99fe402e-89a0-45aa-9163-85342e865dc8" />  43:         <Feature ID="541F5F57-C847-4e16-B59A-B31E90E6F9EA">  44:           <Properties xmlns="https://schemas.microsoft.com/sharepoint/">  45:             <Property Key="IncludeSubSites" Value="true" />  46:           </Properties>  47:         </Feature>  48:       </WebFeatures>  49:       <Modules>  50:         <Module Name="MasterPages"/>  51:         <Module Name="DefaultBlank" />  52:       </Modules>  53:     </Configuration>  54:   </Configurations>  55:   <Modules>  56:     <Module Name="DefaultBlank" Url="" Path="">  57:       <!--Overview Page-->  58:       <File Url="default.aspx">  59:         <!-- Announcement WebPart-->  60:         <AllUsersWebPart ID="AnnouncementOverview" WebPartZoneID="Top" WebPartOrder="1">  61:           <![CDATA[   62:             <webParts>  63:               <webPart xmlns="https://schemas.microsoft.com/WebPart/v3">  64:               <metaData>  65:                 <type name="MaPortal.Features.Common.WebParts.Announcements.Announcements, MaPortal.Features, Version=1.0.0.0, Culture=neutral, PublicKeyToken=7e79f463b7614c02" />  66:                 <importErrorMessage>Cannot import this Web Part.</importErrorMessage>  67:               </metaData>  68:               <data>  69:                 <properties>  70:                   <property name="Title" type="string">Ankündigungen</property>  71:                   <property name="Description" type="string">Zeigt Globale, Bereichs- und Abteilungsweite Ankündigen an</property>  72:                 </properties>  73:               </data>  74:             </webPart>  75:             </webParts>  76:           ]]>  77:         </AllUsersWebPart>  78:        </File>  79:     </Module>  80:     <!-- Masterpage -->  81:     <Module Name="MasterPages" Url="_catalogs/masterpage" Path="" RootWebOnly="TRUE">  82:       <File Url="MaPortal_Master.master" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE">  83:         <Property Name="ContentType" Value="$Resources:cmscore,contenttype_masterpage_name;" />  84:         <Property Name="Title" Value="$Title$" />  85:         <Property Name="PublishingPreviewImage" Value="$PublishingPreviewImage$" />  86:         <Property Name="MasterPageDescription" Value="$MasterPageDescription$" />  87:       </File>  88:     </Module>  89:   </Modules>  90: </Project>

Ganz schön umfangreich. Aber als Entwickler lernt man am besten aus Code (oder XML in diesem Fall).

Diese onet.xml enthält das Maximalset an Elemente, wie oben beschrieben. Ein paar kurze erklärende Worte dazu.

Zuerst werden allgemeine Eigenschaft der Site, wie Logo URL, etc gesetzt.

Das <NavBars> Element dient dazu Navigationselement in der Top Navigation und auch im Quick Launch zu erstellen. Wichtig hierbei ist, dass das <NavBar> Element mit der ID 1002 (im obigen Beispiel “Home”) immer die Top Navigation erzeugt, dass <NavBar> Element mit ID=1025 wird zum ersten Knoten des Quick Launch. Diese ID sind fix in der Content Database vergeben für jeweils den 1. Navigationsknoten der entsprechenden Navigationsleiste. Unterhalb der <NavBar> befinden sich die <NavBarLink>, diese stellen die untergeordneten Navigationsknoten dar. Um eine Navigation wie in Abb.3 ersichtlich zu erstellen, genügt somti das folgende XML Fragment.

    1: <NavBar ID="1025" Name="Lists" Url="Lists">   2:     <NavBarLink Url="Lists/Templates" Name="Vorlagen"/>   3: </NavBar>

20110401 (3)
Abbildung 3 – Einfacher Quick Launch

Weiter gehts mit dem <Configuration> Element. Die Configuration stellt, ähnlich eines List Templates, eine Vorlage für eine Site zur Verfügung. Jede Site Definition kann mehrere Configurations enthalten, die Configurations stellen einfach die vordefinierten Templates für neue Subsites dar. So könnte es eine Configuration geben, welche nur als RootWeb einer Site Collection verwendet werden darf und mehrere weitere Configurations welche als im Dialog zum erstellen von Subsites (Webs) erscheinen.

Man kann sich die onet.xml sehr einfach grafisch vorstellen: Wenn ich von oben nach unten im Browserfenster meine SharePoint UI durchgehe, habe ich zuerst die Bereiche welche die Site Collection betreffen – Globale Navigation, Site Logo, BreadCrumb,…danach die Navigationselemente (<NavBars>) und dann kommt die eigentlich Site (das Web).

Im obigen Beispiel wird ein neues Web erstellt und die MasterPage für Systemseiten und auch Seiten welche via Publishing von Usern erstellt werden festgelegt.

Dann kommen die zur Verfügung stehenden Listenvorlagen, das <ListTemplate> Element entspricht der elements.xml Datei einer Listenvorlage. Aus dieser Vorlage wird dann auch eine Listeninstanz angelegt <List> Element.

Weiter gehts mit den Features, meine Lieblingsfunktion im Rahmen der Site Definitions. Hier kann genau angegeben werden welche Site Collection und Site Features aktiviert werden müssen, damit die Site Definition funktioniert. Diese Features werden beim Erstellen natürlich VORHER aktiviert und zwar in der, in der Datei, angegebenen Reihenfolge. Somit kann man auch Abhängigkeite zwischen Features auflösen.

Zu erwähnen hierbei ist im Beispiel das Site Feature mit der ID 541F5F57-C847-4e16-B59A-B31E90E6F9EA - Das SharePoint Navigationsfeature. Im Snippet ist schön ersichtlich, wie man Parameter an die Features übergeben kann. Das Navigationfeature nimmt zum Beispiel Parameter entgegen, die die Darstellung von Elementen in der Navigation steuern. Dies entspricht den Einstellungen, welche unter Site Settings > Navigation modifiziert werden können (Abb.4)

20110401 (4)

Alle diese globalen Navigationseinstellungen können mit entsprechenden Feature Properties und dem Navigationfeature eingestellt werden. Im obigen XML wird mit “IncludeSubSites” eingestellt, dass Subsites automatisch in die Top Navigation aufgenommen werden. Für alle anderen Einstellungen gibt es ebenfalls Properties –> Mehr Details siehe Links am Ende.

Vorerst mal genug – viel Spass beim Experimentieren. Im Folgeartikel sehen wir uns an, wie wir die Site Definition mit Inhalt befüllen (Pages/WebParts) und wie sie mittels Skript erzeugt wird.

Happy SharePoint’ing!