Files
CustomBranding/README.md
T

216 lines
8.2 KiB
Markdown

# CustomBranding
CustomBranding 3.0.3 ist ein zentraler SPFx-1.4.1-Application-Customizer für SharePoint Server Subscription Edition. Die Solution lädt freigegebene Stylesheets und rendert eine kontrollierte Komponentenstruktur im oberen oder unteren SharePoint-Placeholder. Moderne und klassische Seiten verwenden dieselben `ClientSideComponentProperties`.
Die Konfiguration liegt in genau einer `SPSite.UserCustomAction` pro Site Collection. Es werden weder eine versteckte Liste noch ein Property Bag benötigt. Dadurch gilt das Branding automatisch für das Root Web, vorhandene Subwebs und später angelegte Subwebs.
## Architektur
```text
App Catalog
└── zentral bereitgestelltes SPFx-Bundle
Site Collection
├── SPSite.UserCustomAction mit ClientSideComponentProperties
├── moderne Seiten: SPFx Application Customizer
└── klassische Seiten: optionaler SPSite ScriptLink
CustomHeader
├── CustomBrandingTopHost
└── MegaMenuHost (wird nicht verändert)
CustomFooter
└── CustomBrandingBottomHost
```
CustomBranding verändert nur seine eigenen Host-Elemente. Das MegaMenu und andere Erweiterungen im selben Placeholder bleiben bei Navigation und erneutem Rendern erhalten.
## Voraussetzungen und Build
- SharePoint Server Subscription Edition
- SPFx 1.4.1
- Node.js 8.17.0
- npm 6.13.4
- lokale Gulp-Version 3.9.1
```powershell
npm install
npm test
npm run package
```
`npm run package` führt zuerst die Tests und den Classic-Build aus. Das SharePoint-Paket entsteht unter `sharepoint/solution/custom-branding.sppkg`. Die Classic-Dateien liegen anschließend unter `classic/dist`.
Die alte SPFx-Toolchain lässt sich mit aktuellen Node-Versionen nicht zuverlässig paketieren. Der abschließende Ship-Build muss deshalb mit Node.js 8.17.0 erfolgen.
## Installation und zentrale Registrierung
1. `custom-branding.sppkg` im App Catalog hochladen oder ersetzen und zentral bereitstellen.
2. Das Skript in der SharePoint Management Shell ausführen.
3. Eine moderne Seite mit `Strg+F5` neu laden.
```powershell
.\deployment\add-custombranding.ps1 `
-SiteUrl 'http://clshp001/sites/portal' `
-CssPath '~sitecollection/SiteAssets/branding/custom-branding.css'
```
Das Skript arbeitet idempotent: Es erhält vorhandene Properties, entfernt doppelte oder alte web-scoped Registrierungen und erzeugt genau eine site-scoped Action. Ein bewusstes Zurücksetzen erfolgt nur mit `-ResetConfiguration`.
Weitere Optionen:
```powershell
# Debug-Ausgaben einschalten und einen externen HTTPS-CSS-Host freigeben
.\deployment\add-custombranding.ps1 `
-SiteUrl 'http://clshp001/sites/portal' `
-EnableDebug `
-AllowedCssHost 'cdn.example.org'
# Extension deaktivieren, Konfiguration aber erhalten
.\deployment\add-custombranding.ps1 `
-SiteUrl 'http://clshp001/sites/portal' `
-Disable
```
## Konfiguration
Das aktuelle Konfigurationsschema hat die Version 2:
```json
{
"schemaVersion": 2,
"portalSettings": {
"providerKey": "custombranding",
"contractVersion": 1,
"minimumPortalSettingsVersion": "3.0.0"
},
"enabled": true,
"debug": false,
"allowedCssHosts": [],
"cssfiles": [
{
"path": "~sitecollection/SiteAssets/branding/custom-branding.css",
"media": "all"
}
],
"placeholdertop": {
"elements": [
{
"type": "section",
"attributes": {
"class": "custom-branding-banner",
"role": "region",
"aria-label": "Portalhinweis"
},
"children": [
{
"type": "strong",
"content": "Willkommen im Portal"
}
]
}
]
},
"placeholderbottom": {
"elements": []
}
}
```
Bestehende 1.x-Konfigurationen mit einem Root-Array `elements` werden weiterhin als Top-Inhalt gelesen. Unbekannte Properties ignoriert die Runtime. Das vollständige Beispiel liegt unter `examples/custom-branding.example.json`.
Ist `placeholderbottom.elements` leer oder fehlt die Eigenschaft, rendert CustomBranding automatisch den bisherigen
**Portal Settings**-Link auf `~sitecollection/SitePages/PortalSettings.aspx`. Sobald eigene Footer-Elemente konfiguriert
sind, ersetzen sie diesen Standard.
### Sicherheitsgrenzen
Erlaubte Elemente:
`div`, `span`, `p`, `a`, `button`, `img`, `h1`, `h2`, `h3`, `strong`, `em`, `nav`, `section`
Attribute und Styles werden pro Element über feste Allowlisten geprüft. Insbesondere gelten folgende Regeln:
- `script`, `iframe`, alle `on*`-Attribute, `javascript:`, `data:` und CSS mit `url()` oder `expression()` werden verworfen.
- Bilder benötigen immer ein `alt`; dekorative Bilder verwenden `alt: ""`.
- Leere Links und Buttons sind nicht erlaubt; Buttons erhalten immer `type="button"`.
- Links mit `target="_blank"` erhalten automatisch `rel="noopener noreferrer"`.
- Relative CSS-Pfade und CSS derselben Origin sind erlaubt. Fremde Quellen benötigen HTTPS und einen Eintrag in `allowedCssHosts`.
- Maximal 20 Stylesheets, 200 Elemente, acht Ebenen und 100.000 Zeichen Konfiguration werden verarbeitet.
Unsichere Teilwerte werden kontrolliert verworfen, ohne die SharePoint-Seite zu blockieren. Details erscheinen nur bei `debug: true` in der Browserkonsole mit dem Präfix `[CustomBranding]`.
## Classic SharePoint
Der SPFx Application Customizer selbst läuft nicht auf klassischen Seiten. Version 3.0 enthält deshalb eine separate ES5-Runtime mit demselben Sicherheits- und Konfigurationsmodell.
```powershell
npm run build:classic
```
Danach `classic/dist/custom-branding-classic.js` nach beispielsweise `/SiteAssets/custom-branding/` hochladen und zentral registrieren:
```powershell
.\deployment\add-custombranding.ps1 `
-SiteUrl 'http://clshp001/sites/portal' `
-ClassicScriptUrl '~sitecollection/SiteAssets/custom-branding/custom-branding-classic.js'
```
Der site-scoped ScriptLink gilt auch für später angelegte Subwebs. Entfernen lässt er sich mit `-RemoveClassicScriptLink`. Weitere Hinweise stehen in `classic/classic-deployment.md`.
## PortalSettings v3
CustomBranding funktioniert unabhängig von PortalSettings. PortalSettings ab Version 3.0.1 kann die zentrale Action anhand folgender Werte erkennen, die Properties schemaerhaltend bearbeiten und eine noch fehlende Action beim ersten Speichern selbst anlegen:
- Component ID: `035ba968-6488-4d42-86b3-0470ffcc95b9`
- Location: `ClientSideExtension.ApplicationCustomizer`
- Scope: `SPSite.UserCustomActions`
- Schema: `schemaVersion: 2`
- Provider-Marker: `portalSettings.providerKey: custombranding`
Ist noch keine Action vorhanden, erscheint CustomBranding in PortalSettings als **Bereit zur Aktivierung**. Voraussetzung ist lediglich, dass `custom-branding.sppkg` bereits im App Catalog bereitgestellt wurde. Der Button **CustomBranding aktivieren** erzeugt anschließend genau eine site-scoped Action. Das PowerShell-Skript bleibt für automatisierte Rollouts und Classic-ScriptLink-Registrierungen verfügbar.
Ein Editor muss unbekannte Properties erhalten und vor dem Speichern dieselben Element-, Attribut-, URL- und CSS-Grenzen beachten.
## Diagnose
Zentrale Registrierung prüfen:
```powershell
$site = Get-SPSite 'http://clshp001/sites/portal'
$site.UserCustomActions | Where-Object {
$_.ClientSideComponentId -eq [Guid]'035ba968-6488-4d42-86b3-0470ffcc95b9'
} | Select-Object Id, Title, Location, ClientSideComponentProperties
$site.Dispose()
```
Browserkonsole auf einer modernen Seite:
```javascript
performance.getEntriesByType('resource')
.map(function (entry) { return entry.name; })
.filter(function (url) { return url.toLowerCase().indexOf('custom-branding') >= 0; });
({
header: !!document.getElementById('CustomHeader'),
branding: !!document.getElementById('CustomBrandingTopHost'),
megaMenu: !!document.getElementById('MegaMenuHost')
});
```
Classic-Diagnose:
```javascript
typeof window.CustomBrandingClassic
window.CustomBrandingClassic.reload()
```
## Upgrade von 1.x
1. Paket im App Catalog durch Version `3.0.1.0` ersetzen und bereitstellen.
2. `add-custombranding.ps1` einmal pro Site Collection ausführen; bestehende Properties bleiben erhalten.
3. Moderne und gegebenenfalls klassische Seiten testen.
4. Erst nach erfolgreicher Abnahme alte web-scoped Aktionen als bereinigt bestätigen.
Ein Downgrade sollte nur zusammen mit einer Sicherung der `ClientSideComponentProperties` erfolgen.