Inhaltstyp für Dokumentenmappen anlegen mit zulässigen Inhaltstypen und freigegebenen Spalten
avatar

Möchte man einen Inhaltstyp für Dokumentenmappen mit einer no-code sandboxed Solution bereitstellen, so muss man sich auf Einschränkungen gefasst machen.

In einem Kundenprojekt hatten wir die Anforderung, einen Inhaltstyp für Dokumentenmappen bereitzustellen, welcher weitere Spalten enthält. Außerdem sollen zulässige Inhaltstypen und freigegeben Spalten konfiguriert sein.

Diese Anforderung ist leider nicht nur mit XML umsetzbar.

Die Website-Spalten sehen wie folgt aus:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field
ID="{0FA37CC9-724E-493A-AF4A-DD177164C9F1}"
Name="ProjectManagement_Status"
StaticName="ProjectManagement_Status"
DisplayName="Status"
Type="Choice"
Required="FALSE"
Group="Projektraum">
<CHOICES>
<CHOICE>offen</CHOICE>
<CHOICE>in Bearbeitung</CHOICE>
<CHOICE>zurückgestellt</CHOICE>
<CHOICE>abgeschlossen</CHOICE>
</CHOICES>
</Field>
<Field
ID="{2F9E67E0-44C8-408A-B928-5D146F24DBCF}"
Name="ProjectManagement_ProjectNumber"
StaticName="ProjectManagement_ProjectNumber"
DisplayName="Projektnummer"
Type="Text"
Required="FALSE"
Group="Projektraum">
</Field>
</Elements>

Der Inhaltstyp wird wie gewohnt über das XML angelegt:

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- Parent ContentType: Document Set (0x0120D520) -->
<ContentType ID="0x0120D52000A5B3446518A746CFAD20C0F1D7858BB6" Name="Projektmanagement Mappe" Group="Projektraum" Description="" Inherits="TRUE" Overwrite="TRUE" Version="0">
<FieldRefs>
<FieldRef ID="{0FA37CC9-724E-493A-AF4A-DD177164C9F1}" DisplayName="Status" Required="FALSE" Name="ProjectManagement_Status" />
<FieldRef ID="{2F9E67E0-44C8-408A-B928-5D146F24DBCF}" DisplayName="Projektnummer" Required="FALSE" Name="ProjectManagement_ProjectNumber" />
</FieldRefs>
</ContentType>
</Elements>

Das Problem an dieser Stelle ist, dass die zulässigen Inhaltstypen und freigegebenen Spalten nicht festgelegt sind. Selbst, wenn man diese im XML angibt, werden sie von SharePoint ignoriert.
Da hilft nur die Verwendung von Code, in unserem Fall PowerShell und CSOM:

$context = New-Object Microsoft.SharePoint.Client.ClientContext($WebUrl)
$web = $context.Web

# Getting document set template for content type "Projektmanagement Mappe"...
$documentSetContentType = $web.ContentTypes.GetById($ProjectManagementDocumentSetContentTypeId)
$context.Load($documentSetContentType)
$context.ExecuteQuery()

$documentSetTemplate = [Microsoft.SharePoint.Client.DocumentSet.DocumentSetTemplate]::GetDocumentSetTemplate($context, $documentSetContentType)
$context.Load($documentSetTemplate)
$context.Load($documentSetTemplate.AllowedContentTypes)
$context.Load($documentSetTemplate.SharedFields)
$context.ExecuteQuery()

# Removing allowed content types...
$deleteList = @()
foreach ($ct in $documentSetTemplate.AllowedContentTypes) {
$deleteList += $ct
}

foreach ($ct in $deleteList) {
$documentSetTemplate.AllowedContentTypes.Remove($ct)
}
$documentSetTemplate.Update($true)
$context.ExecuteQuery()

# Adding allowed content types...
$documentContentType = $web.ContentTypes.GetById($ProjectManagementDocumentContentTypeId)
$context.Load($documentContentType)
$context.ExecuteQuery()

$documentSetTemplate.AllowedContentTypes.Add($documentContentType.Id)
$documentSetTemplate.Update($true)
$context.ExecuteQuery()

# Removing shared fields...
$deleteList = @()
foreach ($field in $documentSetTemplate.SharedFields) {
$deleteList += $field
}

foreach ($field in $deleteList) {
$documentSetTemplate.SharedFields.Remove($field)
}
$documentSetTemplate.Update($true)
$context.ExecuteQuery()

# Adding shared fields...
$StatusField = $web.Fields.GetById($StatusFieldId)
$context.Load($StatusField)
$context.ExecuteQuery()

$ProjectNumberField = $web.Fields.GetById($ProjectNumberFieldId)
$context.Load($ProjectNumberField)
$context.ExecuteQuery()

$documentSetTemplate.SharedFields.Add($StatusField)
$documentSetTemplate.SharedFields.Add($ProjectNumberField)
$documentSetTemplate.Update($true)
$context.ExecuteQuery()

Alternativ kann man auch im XML des Inhaltstyps den Schalter Inherits auf False setzen. Dies führt dazu, dass man im XML die zulässigen Inhaltstypen und freigegebenen Spalten festlegen kann.
Allerdings führt das dazu, dass SharePoint nicht mehr die Ressourcen der übergeordneten Inhaltstypen beachtet.
Somit wird beispielsweise nicht die docsethomepage.aspx für den Inhaltstyp erstellt. Diese könnte man dann aber selbst anlegen (über die Solution oder Code) oder eine bestehende mittels Code kopieren.

Da dies etwas invasiv ist, empfehle ich persönlich den ersten Weg.

Schreibe einen Kommentar