feat: Add custom branding functionality with CSS and JSON configuration
- Introduced custom branding CSS styles in `custom-branding.css`. - Created example JSON configuration for custom branding in `custom-branding.example.json`. - Implemented branding configuration logic in `BrandingConfig.ts` to normalize and validate branding settings. - Developed CSS loader to manage loading and unloading of custom stylesheets in `BrandingCssLoader.ts`. - Added DOM rendering capabilities for branding elements in `BrandingDomRenderer.ts`. - Defined types and interfaces for branding elements and configurations in `BrandingTypes.ts`. - Included localization support for German in `de-de.js`. - Added unit tests for branding configuration, CSS loader, and DOM renderer. - Validated project structure and static assets with new validation scripts.
This commit is contained in:
196
README.md
196
README.md
@@ -1,20 +1,110 @@
|
||||
# Custom Branding
|
||||
# CustomBranding
|
||||
|
||||
Custom Branding ist ein SPFx-1.4.1-Application-Customizer fuer SharePoint Server Subscription Edition. Die Solution laedt zentral konfigurierte Stylesheets und kann strukturierte Inhalte in den oberen und unteren SharePoint-Placeholder rendern.
|
||||
CustomBranding 3.0 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`.
|
||||
|
||||
## Version
|
||||
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.
|
||||
|
||||
`1.0.4.0`
|
||||
## 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
|
||||
|
||||
Die Konfiguration wird in den `ClientSideComponentProperties` der aktiven UserCustomAction gespeichert und zentral ueber PortalSettings gepflegt:
|
||||
Das aktuelle Konfigurationsschema hat die Version 2:
|
||||
|
||||
```json
|
||||
{
|
||||
"cssfiles": [],
|
||||
"schemaVersion": 2,
|
||||
"enabled": true,
|
||||
"debug": false,
|
||||
"allowedCssHosts": [],
|
||||
"cssfiles": [
|
||||
{
|
||||
"path": "~sitecollection/SiteAssets/branding/custom-branding.css",
|
||||
"media": "all"
|
||||
}
|
||||
],
|
||||
"placeholdertop": {
|
||||
"elements": []
|
||||
"elements": [
|
||||
{
|
||||
"type": "section",
|
||||
"attributes": {
|
||||
"class": "custom-branding-banner",
|
||||
"role": "region",
|
||||
"aria-label": "Portalhinweis"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "strong",
|
||||
"content": "Willkommen im Portal"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"placeholderbottom": {
|
||||
"elements": []
|
||||
@@ -22,22 +112,92 @@ Die Konfiguration wird in den `ClientSideComponentProperties` der aktiven UserCu
|
||||
}
|
||||
```
|
||||
|
||||
## Build
|
||||
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`.
|
||||
|
||||
Die Legacy-SPFx-Toolchain benoetigt Node.js 8.17.0:
|
||||
### 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 install
|
||||
npm run package
|
||||
npm run build:classic
|
||||
```
|
||||
|
||||
Das Paket wird unter `sharepoint/solution/custom-branding.sppkg` erzeugt.
|
||||
Danach `classic/dist/custom-branding-classic.js` nach beispielsweise `/SiteAssets/custom-branding/` hochladen und zentral registrieren:
|
||||
|
||||
## Installation
|
||||
```powershell
|
||||
.\deployment\add-custombranding.ps1 `
|
||||
-SiteUrl 'http://clshp001/sites/portal' `
|
||||
-ClassicScriptUrl '~sitecollection/SiteAssets/custom-branding/custom-branding-classic.js'
|
||||
```
|
||||
|
||||
1. `custom-branding.sppkg` in den App Catalog laden beziehungsweise ersetzen.
|
||||
2. Die App im Root Web der Site Collection installieren oder aktualisieren.
|
||||
3. Beim Aktivieren wird der Custom Branding Application Customizer automatisch web-scoped registriert.
|
||||
4. PortalSettings mit `Strg+F5` neu laden und den Tab **Custom Branding** konfigurieren.
|
||||
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`.
|
||||
|
||||
Das Skript `deployment/add-custombranding.ps1` bleibt fuer automatisierte Rollouts oder eine ausdruecklich site-scoped Registrierung verfuegbar.
|
||||
## PortalSettings v3
|
||||
|
||||
CustomBranding funktioniert unabhängig von PortalSettings. Das geplante PortalSettings-v3-Webpart kann die Action anhand folgender Werte erkennen und die Properties schemaerhaltend bearbeiten:
|
||||
|
||||
- Component ID: `035ba968-6488-4d42-86b3-0470ffcc95b9`
|
||||
- Location: `ClientSideExtension.ApplicationCustomizer`
|
||||
- Scope: `SPSite.UserCustomActions`
|
||||
- Schema: `schemaVersion: 2`
|
||||
|
||||
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.0.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.
|
||||
|
||||
Reference in New Issue
Block a user