SharePoint 2013: Auslesen des WebTemplates nach Erstellung der Site

12394062_blogSharePoint bietet diverse Vorlagen, um die verschiedensten Prozesse abzubilden. Das reicht von Inhaltstypen, über Bibliotheken und Listen bis zu Websites. Bei Websites ist die Nutzung von WebTemplates bzw. SiteTemplates zielführend. Nun möchte man mitunter wissen, auf Grundlage welcher Vorlage die aktuelle Website erstellt wurde. Hierzu existieren zwei mögliche Wege, es herauszufinden: clientseitig und serverseitig. Da sich die Varianten nur in der Schreibweise, aber nicht im Ergebnis unterscheiden, beschränke ich mich auf die serverseitige Variante.

Wir gehen davon aus, dass die individuelle Vorlage über den „Save site as template“-Link unter SiteSettings erstellt wurde. Dadurch liegt nun ein SiteTemplate im SolutionStore und wir können dieses erstellen. Wichtig ist hierbei die klare Trennung von WebTemplate und SiteTemplate. Site Template wird über den Link erstellt und ein WebTemplate kann ich über das Visual Studio erstellen. Die erste Variante ist aber vor allem für Endnutzer interessant, weshalb diese hier betrachtet wird.

Schaut man sich die MSDN-Dokumentation zur Klasse SPWeb an, findet man die ziemlich aussagekräftigen Eigenschaften WebTemplate und WebTemplateId, die das versprechen, was wir uns wünschen – sie geben uns die Vorlage zurück, mit der die Site erstellt wurde. Die Nutzung der Eigenschaften ist simpel, weshalb ich mir einen Codeausschnitt spare. Im Fall einer TeamSite erhalte ich die Zeichenkette „STS“ und „1“. Wer meine vorherigen Posts gelesen hat, vor allem den zur Erstellung einer Site auf Grundlage eines Custom WebTemplate, wird sofort erkennen, dass genau das die Zeichenkette ist, die wir zur Erstellung einer Site benötigen und die wir in Verbindung mit dem Anzeigenamen bringen können. Die Methode Add an der Eigenschaft „Webs“ am jeweiligen SPWeb ermöglicht uns die Übergabe des Template, welches zur Erstellung genutzt werden kann. Schlussendlich ist „Webs“ ja nur eine Collection. Folgender C#-Codeausschnitt kann also verwendet werden, um ein Web per Code hinzuzufügen:

Bild 1

Die Methode ist größtenteils selbsterklärend. Der für uns wichtige fünfte Parameter bestimmt die zu verwendende Vorlage. Die Zeichenkette hat dabei immer denselben Aufbau: [TEMPLATE]#[WEBTEMPLATEID]. Im Falle eines Standardtemplates wie der TeamSite kann natürlich auch die Klasse SPWebTemplate genutzt werden. Auch für CustomTemplates ist das möglich. Die SiteCollection besitzt die beiden Methoden GetWebTemplates und GetCustomWebTemplates. Zu verwenden sind diese recht einfach:

Bild 2

Über die beiden Methoden erhalte ich die installierten WebTemplates/SiteTemplates bzw. schon gleich nur die CustomTemplates. Dort kann ich dann meine entsprechende Vorlage herausfiltern und der Methode übergeben. Das ist wesentlich dynamischer als die Übergabe einer potenziell hart codierten Zeichenkette. Der Übergabeparameter für ein CustomTemplate würde am Beispiel wie folgt aussehen:

„{BB375F4C-23A1-4D53-9E31-61615FE74860}#TemplateName“

Die Erstellung einer Website auf Grundlage eines Templates ist also relativ simpel. Nun könnte man annehmen, dass die Eigenschaft WebTemplate und WebTemplateId auch relativ einfach für CustomTemplates genutzt werden können. Die Übergabe der GUID und des Namens durch ein „#“ getrennt erstellt definitiv ein entsprechendes Web. Das Auslesen der Eigenschaft am jeweiligen neu erstellten Web bringt allerdings einige Überraschungen. Es werden nicht die GUID und der Name gespeichert, sondern die Vorlage, die zur Erstellung des SiteTemplate genutzt wurde. Das heißt, wurde die TeamSite als Vorlage genutzt, steht in den Eigenschaft am neu erstellten Web „STS“ und „1“. Daher können wir im Nachhinein codetechnisch nicht mehr eindeutig erkennen, auf welcher Grundlage die Website erstellt wurde.

Das ist für unsere Anforderung katastrophal. Um diese trotzdem zu erfüllen, dient uns das PropertyBag des jeweiligen Webs. Über die Methoden GetProperty und SetProperty können wir KeyValuePairs in das PropertyBag schreiben. Dort hinein schreiben wir schlicht den entsprechenden Wert:

bild 3

Zu holen sind die Eigenschaften wie folgt:

bild 4

So ist es zumindest in der Theorie im Nachhinein möglich, genau festzustellen, auf welcher Grundlage die Website erstellt wurde. Einziges Problem an der Sache ist, dass wir auch während Erstellung einer Website nicht feststellen können, welches SiteTemplate zugrunde liegt. Feature Stapling funktioniert auf Website-Ebene nicht und die vermeintlich aussichtsreiche Variante über die Eventreceiver WebAdding und WebProvisioned die entsprechenden Daten zu ergattern, bleibt ohne Erfolg. Nirgends gibt es einen direkten Hinweis auf das SiteTemplate, welches eigentlich genutzt wird.

Wie erhalte ich nun die Information? Ich muss zugeben: Ich weiß es nicht. Die vorliegende Anforderung scheint dynamisch nicht abdeckbar zu sein. Sicherlich ist es möglich im Vorhinein festzulegen, welche Templates erstellt werden können, wodurch sich der Spielraum vehement einschränkt. Wir können auch anhand verschiedener Parameter festlegen, in welcher SiteCollection welche CustomTemplates erstellt werden können. Schlussendlich sind verschiedenste Ausprägungen möglich, in denen eruiert wird, welches Template erstellt wurde, aber am Ende existiert keine elegante dynamische Variante, mit der wir mit Sicherheit herausfinden können, welches Template genutzt wurde und die zu jeder Zeit funktioniert. Sollte ich mich an dieser Stelle irren, bitte ich um eine Information! J

Einzige ernstzunehmende Alternative ist die Erstellung einer eigenen SiteDefinition. Hier haben wir die Chance im Event „WebProvisioned“ das wirkliche Template auszulesen. Wir kommen also zu dem Schluss: In der Eigenschaft „WebTemplate“ steht der Name der SiteDefinition und nicht der des WebTemplates.

Wer bis zu diesem Absatz gekommen ist, wird sich wahrscheinlich immer noch fragen, ob es das gewesen ist, ob das echt so von Microsoft gewünscht ist. Für diese Leute habe ich ein Zitat aus der MSDN von der Eigenschaft WebTemplate (Abschnitt Remarks):

„When you create a custom site template by saving a site as a template and then create a new site from that template, the WebTemplate property contains the name of the site definition from which the custom template derives, not the name of the custom template. Thus if the site that was used to create a custom template was itself created from the standard team site definition, the WebTemplate property of all sites that are created from the new template will return “STS” (or the value of the constant SPWebTemplate.WebTemplateSTS).“

Man erkennt also: Das beschriebene Verhalten ist kein Bug.

Wichtig ist hierbei die Unterscheidung von SiteTemplate und WebTemplate. Das SiteTemplate wird über den am Anfang beschriebenen Link erstellt. Ein WebTemplate wird im Visual Studio erstellt, ist aber für den Endanwender eher unpraktisch. Einen sehr guten und ausführlichen Artikel gibt es hier.

Autor: Henrik Krumbholz

PT_XING_HKrumbholz_jpg

 

Hinterlasse eine Antwort