diff --git a/.github/clean-blocklist-workaround.md b/.github/clean-blocklist-workaround.md deleted file mode 100644 index 8ec72c50..00000000 --- a/.github/clean-blocklist-workaround.md +++ /dev/null @@ -1,172 +0,0 @@ -# Package Fix Scripts - -This directory contains documentation for the Umbraco BlockList label workaround. - -## BlockList Label Fix (PowerShell) - -**The fix is now implemented directly in PowerShell** within `.github/workflows/powershell/CreateNuGetPackages.ps1`. No external dependencies or manual steps required! - -Automates the workaround for the Umbraco BlockList label export bug tracked at [umbraco/Umbraco-CMS#20801](https://github.com/umbraco/Umbraco-CMS/issues/20801). - -### Problem - -When creating and downloading packages from the Umbraco backoffice, the `package.xml` file doesn't include label configurations for BlockList data types, even though these labels are present in the original system. - -### Solution - -The PowerShell build script (`CreateNuGetPackages.ps1`) automatically: -1. Downloads package.zip from Umbraco API -2. Extracts the package -3. Reads label data from `template/Clean.Blog/uSync/v17/DataTypes/BlockListMainContent.config` -4. Adds missing labels to the `[BlockList] Main Content` DataType in package.xml -5. Repacks the package.zip -6. Continues with the normal build process - -### How It Works - -The fix runs automatically during: -- ✅ **PR builds** (before publishing to GitHub Packages) -- ✅ **Release builds** (before publishing to NuGet.org) - -No manual intervention needed - just run the build script as normal! - -### What Gets Fixed - -Adds labels to the `[BlockList] Main Content` DataType for: -- Rich Text blocks -- Image blocks -- Video blocks -- Code Snippet blocks -- Image Carousel blocks -- Article List blocks - -### Implementation Details - -The fix is implemented as a PowerShell function `Fix-BlockListLabels` in `CreateNuGetPackages.ps1`: -- Parses XML and JSON natively in PowerShell -- Strips markdown formatting from labels -- Unicode-escapes single quotes to match Umbraco format -- HTML-encodes for XML attributes -- No external dependencies required - -## Disabling or Removing the Fix - -### Quick Disable - -To temporarily disable the fix without removing code: - -1. Open `.github/workflows/powershell/CreateNuGetPackages.ps1` -2. Change line 13 to: `$FixBlockListLabels = $false` - - -## Why This is Temporary - -This is a workaround for a known Umbraco bug: [umbraco/Umbraco-CMS#20801](https://github.com/umbraco/Umbraco-CMS/issues/20801) - -Once Umbraco releases a fix, this entire workaround can be removed. All code sections are clearly marked with comments: -- `TEMPORARY WORKAROUND - Remove when Umbraco fixes issue #20801` - -### Complete Removal - -# How to Remove the BlockList Label Workaround - -When Umbraco fixes issue [#20801](https://github.com/umbraco/Umbraco-CMS/issues/20801), follow these steps to remove the workaround: - -## Quick Disable (for testing) - -To quickly test without the fix: - -1. Open `.github/workflows/powershell/CreateNuGetPackages.ps1` -2. Change line 13 from: - ```powershell - $FixBlockListLabels = $true - ``` - to: - ```powershell - $FixBlockListLabels = $false - ``` - -## Complete Removal - -### Step 1: Remove from PowerShell Script - -**File:** `.github/workflows/powershell/CreateNuGetPackages.ps1` - -**Delete lines 6-97** (feature flag and function): -```powershell -# ============================================================================ -# TEMPORARY WORKAROUND - Remove when Umbraco fixes issue #20801 -# https://github.com/umbraco/Umbraco-CMS/issues/20801 -# -# Set to $false to disable the BlockList label fix -# Delete this entire section when Umbraco releases a fix -# ============================================================================ -$FixBlockListLabels = $true - -function Fix-BlockListLabels { - # ... [entire function] ... -} -# ============================================================================ -``` - -**Delete the workaround block** (search for "BEGIN TEMPORARY WORKAROUND"): -```powershell -# ======================================================================== -# BEGIN TEMPORARY WORKAROUND - Umbraco issue #20801 -# Remove this entire block when Umbraco fixes BlockList label export -# ======================================================================== -if ($FixBlockListLabels) { - # ... [entire block] ... -} -# ======================================================================== -# END TEMPORARY WORKAROUND -# ======================================================================== -``` - -### Step 2: Optional - Remove Scripts Directory - -If you want to completely clean up: - -```bash -# Remove the entire scripts directory (optional) -rm -rf scripts/ -``` - -Or keep the directory for future use and just remove the workaround files: -```bash -rm scripts/fix-package-blocklist-labels.py -rm scripts/test_fix_script.py -rm scripts/REMOVAL-GUIDE.md -rm scripts/README.md -``` - -## Verification - -After removal, test that packages still build correctly: - -1. Run the package build: - ```powershell - ./.github/workflows/powershell/CreateNuGetPackages.ps1 -Version "7.0.0-test.1" - ``` - -2. Verify the package downloads successfully -3. Check that Umbraco now includes labels in the exported package.xml - -## Tracking the Umbraco Fix - -Monitor the Umbraco CMS repository for fixes: -- Issue: https://github.com/umbraco/Umbraco-CMS/issues/20801 -- Watch for releases that mention BlockList label fixes -- Check release notes for Umbraco CMS updates - -## Need Help? - -If you're unsure whether Umbraco has fixed the issue: - -1. Download a fresh package from Umbraco backoffice -2. Extract and inspect `package.xml` -3. Look for the `[BlockList] Main Content` DataType -4. Check if the `blocks` array contains `"label"` properties - -If labels are present, the bug is fixed and you can safely remove this workaround! - diff --git a/.github/clean-documentation.md b/.github/clean-documentation.md index d372c873..be56f4f9 100644 --- a/.github/clean-documentation.md +++ b/.github/clean-documentation.md @@ -98,16 +98,6 @@ Documentation related to GitHub Actions workflows and automation: --- -## Technical References - -Technical documentation for specific issues and workarounds: - -### BlockList Label Workaround - -- **[BlockList Label Workaround](clean-blocklist-workaround.md)** - Documentation for the temporary workaround for Umbraco BlockList label export issue (#20801) - ---- - ## Additional Resources ### External Resources diff --git a/.github/clean-headless-api.md b/.github/clean-headless-api.md index b2104e84..5f87f2c2 100644 --- a/.github/clean-headless-api.md +++ b/.github/clean-headless-api.md @@ -16,6 +16,19 @@ The Clean starter kit includes full support for headless implementations. To ena } ``` +Update your `program.cs`: + +```csharp +builder.CreateUmbracoBuilder() + .AddBackOffice() + .AddWebsite() + .AddDeliveryApi() + .AddComposers() + .Build(); +``` + +Once the Content Delivery API is enabled, the next step is to rebuild the Delivery API content index **DeliveryApiContentIndex**. This can be done using the Examine Management dashboard in the Settings section of the Umbraco Backoffice. + ## Next.js Revalidation To enable automatic revalidation of content in Next.js applications, configure the following in your `appsettings.json`: diff --git a/.github/general-contributing.md b/.github/general-contributing.md index 32c95803..7c50d3dc 100644 --- a/.github/general-contributing.md +++ b/.github/general-contributing.md @@ -88,20 +88,18 @@ This means: The uSync configuration files are located in: ``` template/Clean.Blog/uSync/ -├── v16/ # Umbraco 16 configuration -├── v17/ # Umbraco 17 configuration -│ ├── Content/ # Content nodes -│ ├── ContentTypes/ # Document Types -│ ├── DataTypes/ # Data Type definitions -│ ├── Dictionary/ # Dictionary items for translations -│ ├── Languages/ # Language configurations -│ ├── Media/ # Media items -│ ├── MediaTypes/ # Media Type definitions -│ ├── MemberTypes/ # Member Type definitions -│ ├── RelationTypes/ # Relation Type definitions -│ ├── Templates/ # Razor templates -│ └── usync.config # uSync version metadata -└── v17-backup/ # Backup configuration +└── v18/ # Umbraco 18 configuration + ├── Content/ # Content nodes + ├── ContentTypes/ # Document Types + ├── DataTypes/ # Data Type definitions + ├── Dictionary/ # Dictionary items for translations + ├── Languages/ # Language configurations + ├── Media/ # Media items + ├── MediaTypes/ # Media Type definitions + ├── MemberTypes/ # Member Type definitions + ├── RelationTypes/ # Relation Type definitions + ├── Templates/ # Razor templates + └── usync.config # uSync version metadata ``` ## Database Changes and uSync @@ -382,6 +380,7 @@ The Clean Starter Kit supports multiple versions of Umbraco: | 5.x | 15 | .NET 9 | STS | | 6.x | 16 | .NET 9 | STS | | 7.x | 17 | .NET 10 | LTS | +| 8.x | 18 | .NET 10 | STS | When contributing: - **Target the appropriate version** for your changes diff --git a/.github/script-create-nuget-packages.md b/.github/script-create-nuget-packages.md index 87fddf0b..aaef840b 100644 --- a/.github/script-create-nuget-packages.md +++ b/.github/script-create-nuget-packages.md @@ -2,7 +2,7 @@ ## Overview -This comprehensive script creates NuGet packages by starting Umbraco, downloading the package via API, applying BlockList label fixes (temporary workaround), updating .csproj versions, and building all packages in dependency order. +This comprehensive script creates NuGet packages by starting Umbraco, downloading the package via API, updating .csproj versions, and building all packages in dependency order. ## Script Location @@ -10,7 +10,7 @@ This comprehensive script creates NuGet packages by starting Umbraco, downloadin ## Purpose -Orchestrates the entire package creation process including running Umbraco, downloading content package, fixing BlockList labels, updating versions, and building all NuGet packages. +Orchestrates the entire package creation process including running Umbraco, downloading content package, updating versions, and building all NuGet packages. ## When It's Used @@ -30,20 +30,11 @@ Orchestrates the entire package creation process including running Umbraco, down 4. **Starts Umbraco** - Runs Clean.Blog project 5. **Waits for API** - Polls until Umbraco responds 6. **Downloads Package** - Gets package.zip via API -7. **Fixes BlockList Labels** - Applies workaround for Umbraco issue #20801 -8. **Updates Versions** - Sets version in all .csproj files -9. **Builds Packages** - In dependency order: Core → Headless → Clean → Template +7. **Updates Versions** - Sets version in all .csproj files +8. **Builds Packages** - In dependency order: Core → Headless → Clean → Template ## Key Features -### BlockList Label Fix (Temporary) - -Workaround for [Umbraco issue #20801](https://github.com/umbraco/Umbraco-CMS/issues/20801): -- Extracts package.zip -- Reads BlockList config from uSync -- Adds labels to package.xml -- Repacks package.zip - ### Dependency Order Building 1. **Clean.Core** - Base package @@ -86,12 +77,10 @@ Packages created in `.artifacts/nuget/`: ## Related Documentation - [workflow-versioning-releases.md](workflow-versioning-releases.md) - Parent workflow -- BlockList issue: https://github.com/umbraco/Umbraco-CMS/issues/20801 ## Notes -- **Most complex script** in the workflow (831 lines) -- **Temporary BlockList fix** - remove when Umbraco fixes issue +- **Most complex script** in the workflow - **Builds in dependency order** to avoid package resolution errors - **Uses local NuGet source** for intermediate packages - **Supports both PowerShell 5.x and Core 6+** diff --git a/.github/script-create-packages.md b/.github/script-create-packages.md index 9e4ee76c..ca7d51f5 100644 --- a/.github/script-create-packages.md +++ b/.github/script-create-packages.md @@ -2,7 +2,7 @@ ## Overview -The `CreateNuGetPackages.ps1` script automates the process of creating NuGet packages for the Clean Umbraco starter kit. It handles version management, package creation, and includes a temporary workaround for Umbraco BlockList label export issues. +The `CreateNuGetPackages.ps1` script automates the process of creating NuGet packages for the Clean Umbraco starter kit. It handles version management and package creation. **Location:** `.github/workflows/powershell/CreateNuGetPackages.ps1` @@ -124,7 +124,6 @@ sequenceDiagram Umbraco-->>Script: Bearer token Script->>Umbraco: Create package via API Umbraco-->>Script: package.zip - Script->>Script: Fix BlockList labels (workaround) Script->>Script: Update .csproj versions Script->>Script: Build & pack all projects Script-->>PR: 4 .nupkg files in .artifacts/nuget @@ -151,7 +150,6 @@ sequenceDiagram Umbraco-->>Script: Bearer token Script->>Umbraco: Create package via API Umbraco-->>Script: package.zip - Script->>Script: Fix BlockList labels (workaround) Script->>Script: Update .csproj versions Script->>Script: Build & pack all projects Script-->>Release: 4 .nupkg files in .artifacts/nuget @@ -206,23 +204,7 @@ The `update-packages.yml` workflow does NOT use this script. It uses `UpdateThir - Downloads the package from: `/umbraco/management/api/v1/package/created/{packageId}/download/` - Saves the package as `package.zip` in the output folder -### 5. BlockList Labels Fix (Temporary Workaround) - -**Status:** Temporary workaround for [Umbraco Issue #20801](https://github.com/umbraco/Umbraco-CMS/issues/20801) - -**What it does:** -- Extracts the downloaded `package.zip` to a temporary location -- Reads the `package.xml` file -- Reads the uSync configuration from `template/Clean.Blog/uSync/v17/DataTypes/BlockListMainContent.config` -- Extracts BlockList label mappings from the uSync configuration -- Injects the missing labels into the `[BlockList] Main Content` DataType configuration in `package.xml` -- Re-packs the package with the fixed configuration - -**To disable:** Set `$FixBlockListLabels = $false` at the top of the script - -**When to remove:** Delete the entire workaround section when Umbraco releases a fix for issue #20801 - -### 6. Version Updates in .csproj Files +### 5. Version Updates in .csproj Files **Target files:** All `.csproj` files except: - `Clean.Blog.csproj` @@ -234,12 +216,12 @@ The `update-packages.yml` workflow does NOT use this script. It uses `UpdateThir - **AssemblyVersion:** Set to base version without suffix (e.g., `7.0.0`) - **PackageReference for Clean.* packages:** Updated to match the new version -### 7. Clean Build Environment +### 6. Clean Build Environment - Empties all `bin` folders in the repository (excluding `.vs` folders) - Ensures a clean build environment for package creation -### 8. NuGet Package Building +### 7. NuGet Package Building **Build order** (to satisfy dependencies): 1. **Clean.Core** - Built and packed first @@ -254,16 +236,15 @@ The `update-packages.yml` workflow does NOT use this script. It uses `UpdateThir - Copies intermediate packages to the local NuGet source immediately after packing - Removes the temporary local source after all builds complete -### 9. Package Collection +### 8. Package Collection - Finds all `.nupkg` files in `Release` folders matching the version - Copies all packages to `.artifacts/nuget` - Displays the list of generated packages -### 10. Cleanup +### 9. Cleanup - Stops the Umbraco process -- Removes temporary extraction folders - Removes the temporary local NuGet source ## Generated Packages @@ -287,18 +268,7 @@ All packages are copied to: `.artifacts/nuget/` ## Known Issues and Workarounds -### 1. Umbraco BlockList Label Export (Issue #20801) - -**Problem:** Umbraco doesn't export BlockList labels when creating packages via the Management API. - -**Workaround:** The script includes the `Fix-BlockListLabels` function that: -- Reads labels from the uSync configuration -- Injects them into the package.xml -- Removes markdown bold markers (`**`) from labels - -**Status:** Temporary - Remove when Umbraco fixes the issue - -### 2. SSL Certificate Validation +### 1. SSL Certificate Validation **Problem:** CI/CD environments may use self-signed certificates. @@ -337,16 +307,6 @@ All packages are copied to: `.artifacts/nuget/` - Ensure the local NuGet source is added correctly - Check that intermediate packages are being copied to `.artifacts/nuget` -### BlockList labels not applied - -**Symptoms:** Package.xml doesn't contain BlockList labels - -**Solutions:** -- Verify `$FixBlockListLabels = $true` -- Check that the uSync config exists at the expected path -- Ensure the `package.xml` contains the `[BlockList] Main Content` DataType -- Review verbose output for warnings - ### Version not updated in .csproj files **Symptoms:** Some projects still have old version numbers @@ -363,7 +323,6 @@ All packages are copied to: `.artifacts/nuget/` - Umbraco startup status - API authentication status - Package download confirmation -- BlockList label fix details (before/after comparison) - List of updated .csproj files - Build and pack status for each project - List of generated NuGet packages @@ -394,19 +353,14 @@ All packages are copied to: `.artifacts/nuget/` **When to update this script:** -1. **Remove BlockList workaround** when Umbraco fixes issue #20801 - - Delete the `Fix-BlockListLabels` function (lines 15-113) - - Delete the workaround section (lines 474-523) - - Set `$FixBlockListLabels = $false` or remove the variable - -2. **Update API credentials** if the Umbraco configuration changes - - Update `client_id` and `client_secret` in the `$tokenBody` (lines 405-408) +1. **Update API credentials** if the Umbraco configuration changes + - Update `client_id` and `client_secret` in the `$tokenBody` -3. **Add new projects** to the build order - - Add project discovery (similar to lines 690-700) +2. **Add new projects** to the build order + - Add project discovery - Add build/pack step in the appropriate order -4. **Change port or URL** if the Umbraco project configuration changes +3. **Change port or URL** if the Umbraco project configuration changes - Update all references to `https://localhost:44340` ## Related Files @@ -420,7 +374,6 @@ All packages are copied to: `.artifacts/nuget/` - `README.md` - Updated with version numbers - `umbraco-marketplace-readme.md` - Umbraco marketplace README, updated with version numbers - `umbraco-marketplace-readme-clean.md` - Umbraco marketplace README for Clean package, updated with version numbers -- `template/Clean.Blog/uSync/v17/DataTypes/BlockListMainContent.config` - Source of BlockList labels ## Support diff --git a/.github/umbraco-18-upgrade-plan.md b/.github/umbraco-18-upgrade-plan.md new file mode 100644 index 00000000..69da8313 --- /dev/null +++ b/.github/umbraco-18-upgrade-plan.md @@ -0,0 +1,115 @@ +# Umbraco 18 Beta Upgrade Plan for Clean + +Investigation of Umbraco 18 beta breaking changes and the plan to make Clean +compatible. Target: Umbraco `18.0.0-beta2`, Clean package version `8.0.0-beta1`. + +## Current state + +All 5 projects (`Clean`, `Clean.Core`, `Clean.Headless`, `Clean.Blog`, +`Clean.Models`) target `net10.0` and reference Umbraco `17.1.0`. Package +version is stamped at `7.0.5`. Compatible extras: `uSync 17.0.1` and +`uSync.Command.Setup 16.1.0`. + +## Decisions + +- **Target Umbraco version**: `18.0.0-beta2` (latest beta as of 2026-05-14). +- **Clean package version**: bump to `8.0.0-beta1` (matches the existing + convention: Umbraco 17 → Clean 7, Umbraco 18 → Clean 8). +- **uSync**: keep current pins (`uSync 17.0.1`, `uSync.Command.Setup 16.1.0`) + in `Clean.Blog`. No v18-compatible release exists yet on NuGet; expect a + follow-up bump once Kevin Jump publishes one. + +## Breaking changes that affect Clean + +### 1. OpenAPI: Swashbuckle removed, replaced by `Microsoft.AspNetCore.OpenApi` + +- `template/Clean.Headless/Startup/ConfigureSwaggerGenOptions.cs` uses + `IConfigureOptions` + `SwaggerDoc(...)` — rewrite using + `builder.Services.AddOpenApi("clean-starter", options => + options.AddDocumentTransformer(...))`, setting + `Title = "Clean starter kit"`, `Version = "Latest"`, + `Description = "Contains headless endpoints for search, dictionaries and forms"`, + plus `AddOpenApiDocumentToUi("clean-starter", "Clean starter kit")`. +- `template/Clean.Headless/Startup/WorkshopComposer.cs` (line 11) — replace + the `ConfigureOptions()` call with the new + registration. The `ConfigureSwaggerGenOptions` class can collapse into the + composer or be kept as a small helper. +- The Swagger UI URL changes from `/umbraco/swagger` to `/umbraco/openapi`. + +### 2. `IPublishedContent.Parent` / `.Children` properties removed + +Both are now extension methods in `Umbraco.Extensions` (already imported via +`_ViewImports.cshtml`). Razor views need `()` added: + +- `template/Clean.Blog/Views/Author.cshtml:8` — + `Model.Parent as AuthorList` → `Model.Parent() as AuthorList` +- `template/Clean.Blog/Views/Partials/mainNavigation.cshtml:21` — + `homePage.Children.Where(...)` → `homePage.Children().Where(...)` +- `template/Clean.Blog/Views/Partials/xmlSitemap.cshtml:14,16,29` — three + `.Children` references → `.Children()` + +Existing `Children()` calls in `Partials/authors.cshtml` and +`latestArticlesRow.cshtml` are already method calls and don't need changes. + +### 3. csproj package bumps + +For every csproj, bump `Umbraco.Cms.*` from `17.1.0` to `18.0.0-beta2`: + +- `template/Clean.Models/Clean.Models.csproj` +- `template/Clean.Core/Clean.Core.csproj` +- `template/Clean.Headless/Clean.Headless.csproj` +- `template/Clean/Clean.csproj` (also bump the two `Clean.Core` / + `Clean.Headless` PackageReferences to `8.0.0-beta1`) +- `template/Clean.Blog/Clean.Blog.csproj` (bump `Umbraco.Cms` and + `Umbraco.Cms.DevelopmentMode.Backoffice`; leave uSync untouched) + +Bump ``, ``, `` from `7.0.5` +to `8.0.0-beta1` on the four packaged projects (`Clean.Models` is unversioned). + +## Confirmed NOT broken (do not change) + +- **`IEmailSender`** — interface remains; only obsolete `SendAsync` overloads + without an `expires` parameter were removed. Current call + `_emailSender.SendAsync(message, emailType: "Contact")` still binds to the + surviving overload. No change needed in `ContactSurfaceController.cs` or + `ContactV1Controller.cs`. +- **`IContentTypeBaseServiceProvider`** in `ImportPackageXmlMigration.cs` — + the `Provider` variant survived; only `IContentTypeBaseService` (without + "Provider") was removed. +- **`AsyncPackageMigrationBase`** — kept in v18; only the sync + `MigrationBase` and `PackageMigrationBase` were removed. +- **`IDictionaryItemService.GetAtRootAsync()`** in + `DictionaryApiV1Controller.cs` and `PackageController.cs` — a different + API from the removed `GetAtRoot()` (which was on `UmbracoHelper`, + `IPublishedContentCache`, `IUmbracoContext.Content`). + +## Phased execution + +1. **Phase 1 — packaged libraries**: bump `Umbraco.Cms.*` to + `18.0.0-beta2` in all 5 csproj files. Rewrite `ConfigureSwaggerGenOptions.cs` + and update `WorkshopComposer.cs`. Bump package `` to + `8.0.0-beta1`. +2. **Phase 2 — `Clean.Blog` test host**: bump `Umbraco.Cms` and + `Umbraco.Cms.DevelopmentMode.Backoffice`. Update the four Razor views to + call `Parent()` / `Children()`. +3. **Phase 3 — verification + docs**: local `dotnet build`, smoke test + (login, publish home, hit OpenAPI UI at `/umbraco/openapi`). Add an + "Umbraco 18" install section to `README.md`. + +## Risks and open items + +- **uSync 17 against Umbraco 18 may fail at runtime.** The pins are kept per + the chosen strategy; expect a follow-up bump when + [uSync](https://www.nuget.org/packages/uSync) ships a v18 build (see + [KevinJump/uSync releases](https://github.com/KevinJump/uSync/releases)). +- **Workflows** under `.github/workflows/` (e.g. + `test-umbraco-latest-nuget.yml`, `update-packages.yml`) may need a separate + look if they pin to non-prerelease versions — out of scope for this plan. + +## Sources + +- [Breaking Changes Overview — CMS 18.latest (Beta)](https://docs.umbraco.com/umbraco-cms/18.latest/get-started/upgrading-and-migrating/version-specific) +- [Umbraco-CMS v18.0.0 release notes](https://releases.umbraco.com/release/umbraco/Umbraco-CMS/18.0.0) +- [API versioning and OpenAPI — CMS 18.latest](https://docs.umbraco.com/umbraco-cms/18.latest/extend-your-project/server-side-extensions/api-versioning-and-openapi) +- [Umbraco.Cms on NuGet](https://www.nuget.org/packages/Umbraco.Cms) +- [uSync on NuGet](https://www.nuget.org/packages/uSync) diff --git a/.github/workflow-pr.md b/.github/workflow-pr.md index 652ccd2d..f89b1dad 100644 --- a/.github/workflow-pr.md +++ b/.github/workflow-pr.md @@ -488,7 +488,7 @@ flowchart TD GetVersion --> ShowVersion[5. Display Version Info
Show base version, build number, full version] - ShowVersion --> CreatePackages[6. Create NuGet Packages
Start Umbraco
Download package via API
Fix BlockList labels
Update .csproj versions
Build in dependency order] + ShowVersion --> CreatePackages[6. Create NuGet Packages
Start Umbraco
Download package via API
Update .csproj versions
Build in dependency order] CreatePackages --> UploadArtifacts[7. Upload Package Artifacts
Save .nupkg files to workflow] diff --git a/.github/workflow-versioning-releases.md b/.github/workflow-versioning-releases.md index 41817821..d9f1f99d 100644 --- a/.github/workflow-versioning-releases.md +++ b/.github/workflow-versioning-releases.md @@ -265,6 +265,7 @@ The Clean packages maintain version alignment with Umbraco CMS: | 5.x.x | 15.x | STS | .NET 9 | | 6.x.x | 16.x | STS | .NET 9 | | 7.x.x | 17.x | LTS | .NET 10 | +| 8.x.x | 18.x | STS | .NET 10 | **Versioning Guidelines**: - Major version changes when targeting new Umbraco major version @@ -556,7 +557,7 @@ flowchart TD ShowVersion --> UpdateREADME[5. Update README Files
Map Clean version to Umbraco
Update installation commands] - UpdateREADME --> CreatePackages[6. Create NuGet Packages
Start Umbraco
Download package via API
Fix BlockList labels
Update .csproj versions
Build in dependency order] + UpdateREADME --> CreatePackages[6. Create NuGet Packages
Start Umbraco
Download package via API
Update .csproj versions
Build in dependency order] CreatePackages --> UploadArtifacts[7. Upload Package Artifacts
Save .nupkg files to workflow] diff --git a/.github/workflows/powershell/CreateNuGetPackages.ps1 b/.github/workflows/powershell/CreateNuGetPackages.ps1 index f3ec9bd0..ce868283 100644 --- a/.github/workflows/powershell/CreateNuGetPackages.ps1 +++ b/.github/workflows/powershell/CreateNuGetPackages.ps1 @@ -436,7 +436,7 @@ try { # Paths $packageXmlPath = Join-Path $tempExtractPath "package.xml" - $usyncConfigPath = Join-Path $CurrentDir "template\Clean.Blog\uSync\v17\DataTypes\BlockListMainContent.config" + $usyncConfigPath = Join-Path $CurrentDir "template\Clean.Blog\uSync\v18\DataTypes\BlockListMainContent.config" if ((Test-Path $packageXmlPath) -and (Test-Path $usyncConfigPath)) { # Call the PowerShell function to fix labels diff --git a/.github/workflows/powershell/Get-UsyncKeys.ps1 b/.github/workflows/powershell/Get-UsyncKeys.ps1 index 814b6b5d..f4ac9ad1 100644 --- a/.github/workflows/powershell/Get-UsyncKeys.ps1 +++ b/.github/workflows/powershell/Get-UsyncKeys.ps1 @@ -3,7 +3,7 @@ Extracts content keys from uSync configuration files. .DESCRIPTION - This script reads uSync configuration files from the v17 directory structure + This script reads uSync configuration files from the v18 directory structure and extracts the Key (GUID) values for published content items. .PARAMETER WorkspacePath @@ -41,7 +41,7 @@ Write-Host "uSync File Type: $UsyncFileType" -ForegroundColor Yellow Write-Host "Published Only: $PublishedOnly" -ForegroundColor Yellow # Construct path to uSync directory -$usyncPath = Join-Path $WorkspacePath "template\Clean.Blog\uSync\v17\$UsyncFileType" +$usyncPath = Join-Path $WorkspacePath "template\Clean.Blog\uSync\v18\$UsyncFileType" if (-not (Test-Path $usyncPath)) { Write-Host "ERROR: uSync directory not found at: $usyncPath" -ForegroundColor Red diff --git a/.github/workflows/powershell/Write-PlaywrightTestScript.ps1 b/.github/workflows/powershell/Write-PlaywrightTestScript.ps1 index 939296d4..ffdd6025 100644 --- a/.github/workflows/powershell/Write-PlaywrightTestScript.ps1 +++ b/.github/workflows/powershell/Write-PlaywrightTestScript.ps1 @@ -290,11 +290,6 @@ const path = require('path'); '-content-' + contentKey + '.png'; - const elementScreenshotName = - counter.toString().padStart(2, '0') + - '-content-tab-' + - contentKey + - '.png'; await page.screenshot({ path: path.join(screenshotsDir, screenshotName), fullPage: true, @@ -303,11 +298,6 @@ const path = require('path'); console.log('Screenshot saved: ' + screenshotName); console.log(''); - const element = page.locator('#splitViews #main').nth(2); - await element.screenshot({ - path: path.join(screenshotsDir, elementScreenshotName), - }); - counter++; } catch (error) { console.error( diff --git a/.gitignore b/.gitignore index e9426ecd..5246a195 100644 --- a/.gitignore +++ b/.gitignore @@ -23,4 +23,4 @@ /template/Clean.Headless/obj .artifacts/ template/Clean.Blog/wwwroot/media/created-packages/Clean/package.zip -.claude/settings.local.json +.claude/ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..155b2ef2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,23 @@ +# Changelog + +## [8.0.0] - 2026-06-25 + +### Changed +- Upgraded to Umbraco 18 (STS) +- Migrated uSync seed data to v18 folder structure +- Regenerated ModelsBuilder models for Umbraco 18 + +### Fixed +- Resolved build errors introduced by Umbraco 18 breaking changes +- Fixed block list labels not rendering correctly in Umbraco 18 +- Fixed Rich Text block label showing `[object Object]` +- Fixed Image Carousel count display in block list labels +- Restored block list label workaround for Umbraco issue #20801 + +### Added +- API client provisioning at startup with package migration support +- Delivery API setup documentation + +## [7.0.6] - 2026-05-14 + +See [GitHub Releases](https://github.com/prjseal/Clean/releases) for earlier release notes. diff --git a/README.md b/README.md index f263de7b..bee5c804 100644 --- a/README.md +++ b/README.md @@ -6,28 +6,19 @@ [![License](https://img.shields.io/github/license/prjseal/Clean?label=License)](https://github.com/prjseal/Clean/blob/main/LICENSE) [![GitHub Stars](https://img.shields.io/github/stars/prjseal/Clean?label=Stars)](https://github.com/prjseal/Clean/stargazers) -A modern, clean, and fully-featured starter kit for Umbraco CMS that provides a ready-to-use blog theme with headless/API capabilities. Built with Bootstrap and designed to get you up and running quickly with Umbraco 17. +A modern, clean, and fully-featured starter kit for Umbraco CMS that provides a ready-to-use blog theme with headless/API capabilities. Built with Bootstrap and designed to get you up and running quickly with Umbraco 18. -## Features +Clean targets **Umbraco 18 (STS)**. For complete version mapping for previous versions, see the [Versioning and Releases](https://github.com/prjseal/Clean/blob/main/.github/workflow-versioning-releases.md#version-mapping) documentation. -- **Modern Blog Theme**: Clean, responsive design built with Bootstrap -- **Pre-configured Content Types**: Blog posts, categories, tags, and more -- **Headless/API Support**: Full Content Delivery API integration with Next.js revalidation support -- **API Endpoints**: Built-in endpoints for dictionary, search, and contact functionality -- **OpenAPI Documentation**: Swagger UI for exploring and testing API endpoints -- **SQLite by Default**: Quick setup with SQLite database for development - -Clean targets **Umbraco 17 (LTS)**. For complete version mapping for previous versions, see the [Versioning and Releases](.github/workflow-versioning-releases.md#version-mapping) documentation. - -For detailed information about the package architecture and the different NuGet packages, see the [Package Architecture](.github/clean-packages.md) documentation. +For detailed information about the package architecture and the different NuGet packages, see the [Package Architecture](https://github.com/prjseal/Clean/blob/main/.github/clean-packages.md) documentation. ## Documentation -For detailed documentation about this package and the repository, please see the [docs](.github/clean-documentation.md). +For detailed documentation about this package and the repository, please see the [docs](https://github.com/prjseal/Clean/blob/main/.github/clean-documentation.md). ### GitHub Workflows and Automation -The project uses automated workflows for continuous integration and deployment. Please see the workflow [worflow docs](.github/clean-documentation.md#workflow-documentation) +The project uses automated workflows for continuous integration and deployment. Please see the [workflow docs](https://github.com/prjseal/Clean/blob/main/.github/clean-documentation.md#workflow-documentation). ## Installation @@ -37,13 +28,13 @@ Download and install the latest [.NET 10 SDK](https://dotnet.microsoft.com/en-us --- -## Umbraco 17 (LTS) +## Umbraco 18 (STS) ### NuGet Package Method ```powershell # Ensure we have the version specific Umbraco templates -dotnet new install Umbraco.Templates::17.1.0 --force +dotnet new install Umbraco.Templates::18.0.0 --force # Create solution/project dotnet new sln --name "MySolution" @@ -51,7 +42,7 @@ dotnet new umbraco --force -n "MyProject" --friendly-name "Administrator" --emai dotnet sln add "MyProject" # Add Clean package -dotnet add "MyProject" package Clean --version 7.0.6 +dotnet add "MyProject" package Clean --version 8.0.0 # Run the project dotnet run --project "MyProject" @@ -65,14 +56,14 @@ dotnet run --project "MyProject" ```powershell dotnet remove "MyProject" package Clean -dotnet add "MyProject" package Clean.Core --version 7.0.6 +dotnet add "MyProject" package Clean.Core --version 8.0.0 ``` ### dotnet Template Method ```powershell # Install the Clean Starter Kit template -dotnet new install Umbraco.Community.Templates.Clean::7.0.6 --force +dotnet new install Umbraco.Community.Templates.Clean::8.0.0 --force # Create a new project using the template dotnet new umbraco-starter-clean -n MyProject @@ -85,10 +76,17 @@ dotnet run --project "MyProject.Blog" # Login with admin@example.com and 1234567890 # Save and publish the home page and save one of the dictionary items in the translation section -# The site should now be running and visible on the front -``` +# The site should now be running and visible on the front end +``` + +> **✨ Note**: As of version 8.0.0, the template now supports periods in project names (e.g., `Company.Website`). + +## Umbraco 17 (LTS) + +If you need to use Clean with Umbraco 17 (LTS), use the latest `7.x` release. The `dev/v7` branch on GitHub is where ongoing Umbraco 17 development takes place. -> **✨ Note**: As of version 7.0.0, the template now supports periods in project names (e.g., `Company.Website`). Previous versions had a limitation that prevented using periods due to internal class naming conflicts, which has been resolved. +- **NuGet**: `dotnet add package Clean --version 7.0.7` +- **Branch**: [dev/v7](https://github.com/prjseal/Clean/tree/dev/v7) ## Umbraco 13 (LTS) @@ -96,7 +94,7 @@ dotnet run --project "MyProject.Blog" ```powershell # Ensure we have the version specific Umbraco templates -dotnet new install Umbraco.Templates::17.0.0-rc4 --force +dotnet new install Umbraco.Templates::13.14.0 --force # Create solution/project dotnet new sln --name "MySolution" @@ -104,7 +102,7 @@ dotnet new umbraco --force -n "MyProject" --friendly-name "Administrator" --emai dotnet sln add "MyProject" # Add Clean package -dotnet add "MyProject" package Clean --version 7.0.0-rc4 +dotnet add "MyProject" package Clean --version 4.2.2 # Run the project dotnet run --project "MyProject" @@ -118,14 +116,14 @@ dotnet run --project "MyProject" ```powershell dotnet remove "MyProject" package Clean -dotnet add "MyProject" package Clean.Core --version 7.0.0-rc4 +dotnet add "MyProject" package Clean.Core --version 4.2.2 ``` ### dotnet Template Method ```powershell # Install the Clean Starter Kit template -dotnet new install Umbraco.Community.Templates.Clean::7.0.0-rc4 --force +dotnet new install Umbraco.Community.Templates.Clean::4.2.2 --force # Create a new project using the template dotnet new umbraco-starter-clean -n MyProject @@ -173,4 +171,3 @@ After installation, you'll need to: ## Legacy Versions Looking for Clean for Umbraco V9-12? Visit the [Clean Starter Kit for Umbraco v9](https://github.com/prjseal/Clean-Starter-Kit-for-Umbraco-v9) repository. -test diff --git a/template-pack.csproj b/template-pack.csproj index 27131e74..9fc93719 100644 --- a/template-pack.csproj +++ b/template-pack.csproj @@ -1,6 +1,6 @@ - 7.0.6 + 8.0.0 Template Umbraco.Community.Templates.Clean Umbraco.Community.Templates.Clean @@ -20,8 +20,8 @@ https://github.com/prjseal/Clean git MIT - 7.0.6 - 7.0.6 + 8.0.0 + 8.0.0 diff --git a/template/Clean.Blog/App_Plugins/Contentment/Lang/da.xml b/template/Clean.Blog/App_Plugins/Contentment/Lang/da.xml deleted file mode 100644 index a6a98b69..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/Lang/da.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - Chriztian Steinmeier - https://greystate.dk - - - Contentment - - - Er du sikker på, at du vil fjerne denne element? - Ja, fjern - - - Dette element er ikke længere tilgængeligt - Fjern venligst konfigurationen og vælg et andet element. - - - Vælg og konfigurer en visningstype - Vælg og konfigurer en elementtype - - Kopier alle blokke - Rediger værdi - - Kopier indholdselement - Opret indholdsskabelon... - - - Vælg og konfigurer en datakilde - Vælg og konfigurer en liste - Vælg og konfigurer en datakilde og en listeeditor, tak. - Vælg og konfigurer en datakilde, tak. - Vælg og konfigurer en liste, tak. - Datakilden returnerede ingen elementer til forhåndsvisning. - - Tjek alle - Fjern markeringen af ​​alle - - Indtast nøgleord (tryk på Enter efter hvert nøgleord)... - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/Lang/en.xml b/template/Clean.Blog/App_Plugins/Contentment/Lang/en.xml deleted file mode 100644 index a3f69ba8..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/Lang/en.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - Lee Kelleher - https://leekelleher.com - - - Contentment - - - Are you sure you want to remove this item? - Yes, remove - - - This item is no longer available - Please remove this configuration and select another item. - - - Select and configure a display mode - Select and configure an element type - - Copy all blocks - Edit raw value - - Copy content block - Create content template... - - This content is not supported for this configuration. - - - Data source - List editor - Select and configure a data source - Select and configure a list editor - Please select and configure a data source and list editor. - Please select and configure a data source. - Please select and configure a list editor. - The data source returned no items to preview. - - Check all - Uncheck all - - Type to select an item... - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/Lang/es.xml b/template/Clean.Blog/App_Plugins/Contentment/Lang/es.xml deleted file mode 100644 index 84edcbf9..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/Lang/es.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - Alex Freire - https://github.com/Happy-reindeer007 - - - Contentment - - - ¿Estás seguro de que quieres eliminar este elemento? - Sí, eliminar - - - Este elemento ya no está disponible - Por, favor, elimina esta configuración y selecciona otro elemento. - - - Selecciona y configura un modo de visualización - Selecciona y configura un tipo de elemento - - Copiar todos los bloques - Editar valor original - - Copiar bloque de contenido - Crear plantilla de contenido... - - - Selecciona y configura una fuente de datos - Selecciona y configura un editor de listas - Por favor, selecciona y configura una fuente de datos y un editor de listas. - Por favor, selecciona y configura una fuente de datos. - Por favor, selecciona y configura un editor de listas. - La fuente de datos no devolvió ningún elemento que previsualizar. - - Seleccionar todo - Deseleccionar todo - - Escribe para seleccionar un elemento... - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/Lang/fr.xml b/template/Clean.Blog/App_Plugins/Contentment/Lang/fr.xml deleted file mode 100644 index d059348b..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/Lang/fr.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - Michaël Latouche - https://github.com/mikecp - - - Contentment - - - Etes-vous certain.e de vouloir supprimer cet élément? - Oui, supprimer - - - Cet élément n'est plus disponible - Veuillez supprimer cette configuration et sélectionner un autre élément. - - - Sélectionnez et configurez un mode d'affichage - Sélectionnez et configurez un type d'élément - - Copier tous les blocs - Modifier la valeur brute - - Copier le bloc de contenu - Créer un modèle de contenu... - - - Sélectionnez et configurez une source de données - Sélectionnez et configurez un éditeur de liste - Veuillez sélectionner et configurer une source de données et un éditeur de liste. - Veuillez sélectionner et configurer une source de données. - Veuillez sélectionner et configurer un éditeur de liste. - La source de données n'a retourné aucun élément à prévisualiser. - - Tout sélectionner - Tout désélectionner - - Ecrivez pour sélectionner un élément... - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/Lang/nl.xml b/template/Clean.Blog/App_Plugins/Contentment/Lang/nl.xml deleted file mode 100644 index d98bc3b6..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/Lang/nl.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - Erik-Jan Westendorp - https://twitter.com/ewestendorp - - - Contentment - - - Weet je zeker dat je dit item wilt verwijderen? - Ja, verwijder - - - Dit item is niet langer beschikbaar - Verwijder deze configuratie en selecteer een ander item. - - - Selecteer en configureer een weergavemodus - Selecteer en configureer een elementtype - - Kopieer alle blokken - Ruwe waarde bewerken - - Inhoudsblok kopiëren - Inhoudssjabloon maken... - - - Selecteer en configureer een gegevensbron - Selecteer en configureer een lijsteditor - Selecteer en configureer een gegevensbron en lijsteditor. - Selecteer en configureer een gegevensbron. - Selecteer en configureer een lijsteditor. - De gegevensbron heeft geen items geretourneerd om te bekijken. - - Alles selecteren - Alles deselecteren - - Typ om een item te selecteren... - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/Lang/pt.xml b/template/Clean.Blog/App_Plugins/Contentment/Lang/pt.xml deleted file mode 100644 index 04346101..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/Lang/pt.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - Renan Domingues, Leonardo Bottaro - https://github.com/RenanOD - - - Contentment - - - Tem certeza que deseja remover este item? - Sim, remover - - - Este item não está mais disponível - Por favor remova esta configuração e selecione outro item. - - - Selecionar e configurar o modo de exibição - Selecionar e configurar o tipo de elemento - - Copiar todos os blocos - Alterar o valor original - - Copiar o conteúdo do bloco - Criar modelo de conteúdo... - - - Selecionar e configurar uma origem de dados - Selecionar e configurar um editor de lista - Por favor selecione e configure uma origem de dados e um editor de lista. - Por favor selecione e configure uma origem de dados. - Por favor selecione e configure um editor de lista. - A fonte de dados não retornou nenhum item para visualização. - - Marcar todos - Desmarcar todos - - Digite para selecionar um item... - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/Lang/sv.xml b/template/Clean.Blog/App_Plugins/Contentment/Lang/sv.xml deleted file mode 100644 index db206fa4..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/Lang/sv.xml +++ /dev/null @@ -1,41 +0,0 @@ - - - - Markus Johansson - https://twitter.com/markusjoha - - - Contentment - - - Är du säker på att du vill radera? - Ja, radera - - - Denna är inte längre tillgänglig - Vänligen radera denna konfiguration och välj en annan. - - - Välj och konfigurera visningsläge - Välj och konfigurera elementtyp - - Kopiera alla block - Redigera underliggande värde - - Kopiera innehållsblock - Skapa en innehållsmall... - - - Välj och konfigurera en data källa - Välj och konfiguera en list editor. - Vänligen välj och konfigurera en datakälla eller list editor. - Vänligen välj och konfigurera en datakälla. - Vänligen välj och konfigurera en list editor. - Datakällan returnerade inget resultat att visa. - - Markera alla - Avmarkera alla - - Skriv för att välja... - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/index.html b/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/index.html deleted file mode 100644 index 38f1068a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/index.html +++ /dev/null @@ -1,105 +0,0 @@ - - -
- - - -
-
-
- -
-
-
-
-
-
-
-
- - - -
- -
- - - - - - - - -
-
-

Whilst Contentment is a free and open-source package, I have invested a huge amount of time and effort into its product design, development and maintenance. If you enjoy using these powerful property-editors and want to see me continue my efforts with more quality editors, please consider supporting my development with a GitHub sponsorship.

-

I'd like to say heartfelt thank you to all my existing sponsors, I appreciate your support.

-
-
- -
-
-
-
- - - - - - - -
-
Telemetry
-

By default, the package sends telemetry data about which property-editors are being used (from Contentment only). For more details about the data being captured and transparency on the analysis, please visit leekelleher.com/umbraco/contentment/telemetry.

-

If you would prefer to opt-out and disable the telemetry feature, you can find a code snippet on the telemetry documentation page.

-
-
-
Telemetry
-

The telemetry feature has been disabled. 🤐

-
- -
- -
-
Tree dashboard
-

If you would like to remove this page and tree item from the Settings section, you can find a code snippet on the tree dashboard documentation page.

-
- -
-
- -
- -
- - - - - - -
-
- -
-
- -
-
-
-
-
-
-
- -
- -
- -
- -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/kilroy.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/kilroy.svg deleted file mode 100644 index 60b95c53..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/kilroy.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/lee-was-here.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/lee-was-here.svg deleted file mode 100644 index bae77c79..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/contentment/lee-was-here.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-contentment.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-contentment.svg deleted file mode 100644 index 9e0afbfa..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-contentment.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-discord.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-discord.svg deleted file mode 100644 index 109dfd7e..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-discord.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-facebook.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-facebook.svg deleted file mode 100644 index a73a432e..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-facebook.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-github.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-github.svg deleted file mode 100644 index 039f2174..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-github.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-instagram.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-instagram.svg deleted file mode 100644 index 2b58df4d..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-instagram.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-linkedin.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-linkedin.svg deleted file mode 100644 index 9a52af2e..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-linkedin.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-mastodon.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-mastodon.svg deleted file mode 100644 index 47467524..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-mastodon.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-threads.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-threads.svg deleted file mode 100644 index b98ed113..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-threads.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-tiktok.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-tiktok.svg deleted file mode 100644 index 7ca6e98a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-tiktok.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-twitter.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-twitter.svg deleted file mode 100644 index c13d476c..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-twitter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-x-twitter.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-x-twitter.svg deleted file mode 100644 index f5feed78..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-x-twitter.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-youtube.svg b/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-youtube.svg deleted file mode 100644 index 44915408..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/backoffice/icons/icon-youtube.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/components/blocks-editor.html b/template/Clean.Blog/App_Plugins/Contentment/components/blocks-editor.html deleted file mode 100644 index 69fc5ae5..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/components/blocks-editor.html +++ /dev/null @@ -1,60 +0,0 @@ - - -
-
-
-
- -
- -
- -
- -
- -
- -
- - -
-
-
- -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/components/cards-editor.html b/template/Clean.Blog/App_Plugins/Contentment/components/cards-editor.html deleted file mode 100644 index b96f878a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/components/cards-editor.html +++ /dev/null @@ -1,57 +0,0 @@ - - -
-
-
-
-
- - -
-
-
-
-
-
-
- - -
-
- -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/components/list-editor.html b/template/Clean.Blog/App_Plugins/Contentment/components/list-editor.html deleted file mode 100644 index d0eea3aa..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/components/list-editor.html +++ /dev/null @@ -1,29 +0,0 @@ - - -
-
- - -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/components/stack-editor.html b/template/Clean.Blog/App_Plugins/Contentment/components/stack-editor.html deleted file mode 100644 index e445adb7..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/components/stack-editor.html +++ /dev/null @@ -1,56 +0,0 @@ - - -
-
-
- -
-
- - -
-
-
- -
-
-
- -
-
-
- -
- -
    -
  • - -
  • -
  • - -
  • -
  • - -
  • -
- -
-
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/contentment.css b/template/Clean.Blog/App_Plugins/Contentment/contentment.css deleted file mode 100644 index 9e384b1b..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/contentment.css +++ /dev/null @@ -1 +0,0 @@ -.contentment.lk-buttons .umb-button{margin-bottom:5px}.contentment.lk-buttons .umb-button--selected .umb-button__button{background-color:#f5c1bc}.contentment.lk-buttons .umb-button__button{padding-left:20px;padding-right:20px}.contentment.lk-buttons .umb-button__button[disabled]{opacity:.5}.contentment.umb-checkboxlist ul.toggle-all{margin-bottom:15px}.contentment.umb-checkboxlist ul li label{margin-bottom:8px}.contentment .umb-form-check__text .icon{padding-right:2px}.contentment .umb-form-check__text small{display:block;padding-top:0}.umb-editor--small .contentment .form-horizontal .umb-control-group .control-header{float:none;width:100%}.umb-editor--small .contentment .form-horizontal .controls{margin-left:0}.umb-editor--small .contentment .form-horizontal .control-label{float:none;width:100%}.umb-editor--small .contentment .form-horizontal .umb-readonlyvalue .alert{margin-bottom:10px}.lk-content-blocks__container{max-width:845px}.lk-content-blocks__block{display:flex;flex-direction:row;flex-wrap:nowrap;margin-bottom:10px}.lk-content-blocks__block .lk-content-blocks__preview{flex:1;position:relative}.lk-content-blocks__block .lk-content-blocks__preview:after{content:"";background:rgba(225,225,225,.5);border-radius:3px;box-shadow:0 1px 1px 0 rgba(33,33,66,.2);position:absolute;top:0;bottom:0;left:0;right:0;transition:opacity .12s}.lk-content-blocks__block .lk-content-blocks__preview:hover:after{opacity:.66}.lk-content-blocks__block .lk-content-blocks__preview .lk-content-blocks__preview--left{background-color:#fff;border-radius:3px;display:flex;flex-direction:row;font-size:12px;padding:0 5px;position:absolute;top:5px;left:5px;z-index:20}.lk-content-blocks__block .lk-content-blocks__preview .lk-content-blocks__preview--left .icon{padding-top:4px;padding-right:4px}.lk-content-blocks__block .lk-content-blocks__preview .lk-content-blocks__preview--default{text-align:center;padding:30px 10px 15px}.lk-content-blocks__block .lk-content-blocks__preview .lk-content-blocks__preview--default .icon{font-size:40px}.lk-content-blocks__block .lk-content-blocks__preview .lk-content-blocks__preview--default h5{font-size:14px}.lk-content-blocks__block .lk-content-blocks__preview .lk-content-blocks__preview--markup pre.error{margin:35px 10px 10px 10px}.lk-content-blocks__block .lk-content-blocks__preview .lk-content-blocks__preview--markup pre.error code{font-size:small;white-space:pre-wrap}.lk-content-blocks__block .lk-content-blocks__actions{flex:0 0 34px;padding:10px 0 0 7px;margin:0;list-style:none}.lk-content-blocks__block .lk-content-blocks__actions .lk-content-blocks__action--item .icon{color:#1b264f;font-size:18px;padding:5px 10px}.lk-content-blocks__block .lk-content-blocks__actions .lk-content-blocks__action--item .icon:hover{color:#2152a3}.lk-content-blocks__block .lk-content-blocks__actions .lk-content-blocks__action--item>button{background:none;border:none;font-size:18px;cursor:pointer;color:#162335;margin:0;padding:7px 0}.lk-content-blocks__block .lk-content-blocks__actions .umb-property-actions{position:relative;display:inline-block;float:none;margin:3px 0 0 7px}.lk-content-blocks__block .lk-content-blocks__actions .umb-property-actions .umb-property-actions__menu,.lk-content-blocks__block .lk-content-blocks__actions .umb-property-actions .umb-property-actions__menu-open-toggle{right:0}.lk-content-blocks__block .lk-content-blocks__actions .umb-property-actions__toggle{opacity:1;background-color:transparent}.lk-content-blocks__block .lk-content-blocks__actions .umb-property-actions__toggle:hover{background-color:#f9f6f5}.lk-content-blocks .umb-node-preview-add{margin-right:45px}.contentment button.lk-content-blocks__edit{background:transparent;border:none;position:absolute;top:0;bottom:0;left:0;width:100%;z-index:25}.contentment.umb-block-list .umb-block-list__wrapper{max-width:800px}.contentment .lk-data-list-item{max-width:770px;display:flex;align-items:center;padding:10px 15px;background:#f3f3f5;margin-bottom:1px}.contentment .lk-data-list-item:last-of-type{margin-bottom:0}.contentment .lk-data-list-item .lk-data-list-item__handle{font-size:14px;color:#d8d7d9;margin-right:15px}.contentment .lk-data-list-item .lk-data-list-item__icon{margin-right:1rem}.contentment .lk-data-list-item .lk-data-list-item__icon>button{border:1px solid #d8d7d9;background:#fff;font-size:30px;padding-top:5px;width:50px;height:50px}.contentment .lk-data-list-item .lk-data-list-item__text{flex:1;margin-right:1rem}.contentment .lk-data-list-item .lk-data-list-item__remove{position:relative;cursor:pointer}.contentment .lk-data-list-item .lk-data-list-item__remove>button:focus{outline:auto}.contentment .well.well--limit-width{max-width:760px}.contentment .well.well-small.well--limit-width{max-width:780px}.contentment .well.well-large.well--limit-width{max-width:760px}.contentment.umb-readonlyvalue.editor-note .umb-icon{padding:0 20px 0 10px;height:48px;width:48px}.contentment.umb-readonlyvalue.editor-note p:last-child{margin-bottom:.25rem}.contentment.umb-readonlyvalue.editor-note.alert-info>.umb-icon .color-black,.contentment.umb-readonlyvalue.editor-note.alert-success>.umb-icon .color-black,.contentment.umb-readonlyvalue.editor-note.alert-warning>.umb-icon .color-black,.contentment.umb-readonlyvalue.editor-note.alert-error>.umb-icon .color-black{color:#fff !important}.contentment.umb-readonlyvalue.editor-note h5{color:inherit}.umb-editor--infiniteMode .contentment.umb-readonlyvalue.editor-note .umb-icon{height:32px;width:32px}.contentment .lk-icon-picker-small{border:1px dashed #d8d7d9;color:#d8d7d9;display:inline-block;height:20px;padding:5px 0;text-align:center;width:30px}.contentment .lk-icon-picker-small:focus,.contentment .lk-icon-picker-small:hover{border-color:#2152a3;color:#2152a3;text-decoration:none}.contentment .lk-icon-picker-small i.color-black{color:#000}.contentment .umb-mediapicker .umb-sortable-thumbnails__wrapper>.icon{font-size:50px}.contentment .umb-mediapicker .umb-sortable-thumbnails__wrapper>small{text-align:center}.contentment.lk-overlay .umb-panel .form-search{margin-bottom:15px}.contentment .umb-card-grid .umb-card-grid-item{padding-top:20%;padding-bottom:20%}.contentment .umb-action-link .umb-checkmark{margin-right:15px;min-width:30px}.contentment .umb-action-link .menu-label{margin-left:15px;padding-left:0;white-space:normal}.contentment.lk-overlay .umb-action.-disabled{opacity:.5}.contentment.lk-overlay .umb-action.-disabled .umb-card-grid-item,.contentment.lk-overlay .umb-action.-disabled .umb-action-link,.contentment.lk-overlay .umb-action.-disabled .umb-checkmark{cursor:not-allowed}.contentment.lk-overlay .umb-action.-disabled .umb-checkmark:hover{border-color:#bbbabf;color:#1b264f}.contentment.lk-overlay .umb-action.-disabled .umb-checkmark.icon-check:before{content:""}.contentment.lk-overlay .umb-action:not(.-disabled) .umb-checkmark:not(.umb-checkmark--checked).icon-check:before{content:none}.contentment .umb-card-grid .alert{flex:none;font-size:inherit;text-align:inherit;width:100%;max-width:100%}.contentment.umb-readonlyvalue{max-width:100%;word-break:break-word}.umb-readonlyvalue details summary{cursor:pointer}.umb-readonlyvalue details summary+*{margin-top:.5rem}.umb-readonlyvalue .well{margin-bottom:10px}.umb-readonlyvalue .well blockquote p{font-size:16px;margin-bottom:10px}.umb-readonlyvalue .well hr{border-bottom:1px solid #e0e0e5;margin:15px 0}.contentment.umb-radiobuttons ul.unstyled li{margin-bottom:5px}.contentment .umb-tags .tag{user-select:text}.contentment .umb-tags .tag .icon{color:#fff !important}.contentment .umb-tags .tag .btn-reset{line-height:14px}.contentment .umb-tags .tag .icon-trash{bottom:0}.contentment.templated-list button.btn.disabled{cursor:not-allowed !important;opacity:.5}.contentment .text-input{width:100%;max-width:800px}.contentment .text-input.input-prepend .umb-textstring,.contentment .text-input.input-append .umb-textstring{width:calc(100% - 36px)}.contentment .text-input.input-prepend.input-append .umb-textstring{width:calc(100% - 72px)}.contentment .text-input .add-on:hover{border-color:#d8d7d9;color:#1b264f}[class].icon-fa{font-family:FontAwesome;text-align:center}.umb-tree-icon.icon-fa{width:20px}.alert-form a{color:#1b264f}.contentment .umb-box-content p{line-height:1.5rem}.contentment .umb-tags-editor .tt-menu.tt-open{z-index:1001 !important}.contentment .umb-block-card ._\5fshowcase{background-color:rgba(0,0,0,.25);background-size:cover}.contentment .umb-block-card ._\5finfo ._\5fname,.contentment .umb-block-card ._\5finfo ._\5fsubname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-right:10px}.contentment .umb-block-card._\5f fade,.contentment .umb-block-list__block._\5f fade>.umb-block-list__block--view{opacity:.5}.contentment .umb-block-card._\5fno-edit{cursor:move}.contentment .umb-block-card ._\5f actions>button{padding-top:3px}.contentment .umb-block-card ._\5finfo ._\5fsubname{margin-right:16px}.umb-group-panel--hide{all:unset;background:none;box-shadow:none !important}.umb-group-panel--hide .umb-group-panel__header{display:none}.umb-group-panel--hide .umb-group-panel__content{padding:0}.umb-group-panel--hide .umb-box-content{padding:0} \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/contentment.js b/template/Clean.Blog/App_Plugins/Contentment/contentment.js deleted file mode 100644 index 8c71478f..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/contentment.js +++ /dev/null @@ -1 +0,0 @@ -angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.Buttons.Controller",["$scope",function(n){function u(){n.model.value=n.model.value||i.defaultValue;Array.isArray(n.model.value)===!1&&(n.model.value=[n.model.value]);t.multiple=Object.toBoolean(i.enableMultiple);t.multiple===!1&&n.model.value.length>0&&n.model.value.splice(1);t.hideIcon=i.labelStyle==="text";t.hideName=i.labelStyle==="icon";t.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias;t.size=i.size;t.defaultIcon=i.defaultIcon;t.iconExtras=(t.hideName===!1?" mr2 ":" mr0 ")+{s:"small",m:"medium",l:"large"}[i.size];t.items=[];i.items.forEach(i=>{var r=Object.assign({},i);r.selected=n.model.value.indexOf(r.value)>-1;t.items.push(r)});t.select=e;n.umbProperty&&(t.propertyActions=[],Object.toBoolean(i.allowClear)===!0&&t.propertyActions.push({labelKey:"buttons_clearSelection",icon:"trash",method:f}),t.propertyActions.length>0&&n.umbProperty.setPropertyActions(t.propertyActions))}function f(){n.model.value=[];t.items.forEach(n=>n.selected=!1);r()}function e(i){i.selected=i.selected===!1;n.model.value=[];t.items.forEach(r=>{t.multiple===!1&&(r.selected=r.value===i.value),r.selected&&n.model.value.push(r.value)});r()}function r(){n.propertyForm&&n.propertyForm.$setDirty()}var i=Object.assign({},{allowClear:0,defaultIcon:"icon-science",defaultValue:[],items:[],enableMultiple:0,labelStyle:"both",size:"m"},n.model.config),t=this;u()}]);angular.module("umbraco.filters").filter("formatBytes",function(){return function(n,t){if(n===0||t===undefined)return"0 Bytes";const i=parseInt(t.kilo)||1024,u=parseInt(t.decimals)||0,r=Math.floor(Math.log(n)/Math.log(i));return parseFloat((n/Math.pow(i,r)).toFixed(u))+" "+["Bytes","KB","MB","GB","TB","PB","EB","ZB","YB"][r]}});angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.CascadingDropdownList.Controller",["$scope","$q","$http",function(n,t,i){function f(){var h,f,s,o;if(n.model.value=n.model.value||u.defaultValue,r.dropdowns=[],u.apis.length>0){for(r.loading=!0,h=[],f=0;ff&&(r.loading=!0,e=u.apis[f].replace(/{(\d+)}/g,function(t,i){return typeof n.model.value[i]!="undefined"?n.model.value[i]:t}),i({method:"GET",url:e}).then(function(n){r.dropdowns[f]={options:n.data};r.loading=!1}));o()}function o(){n.propertyForm&&n.propertyForm.$setDirty()}if(!n.model.hasOwnProperty("contentTypeId")){var u=Object.assign({},{apis:[],defaultValue:[""]},n.model.config),r=this;f()}}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.CheckboxList.Controller",["$scope","localizationService",function(n,t){function f(){n.model.value=n.model.value||r.defaultValue;Array.isArray(n.model.value)===!1&&(n.model.value=[n.model.value]);i.items=[];r.items.forEach(t=>{var r=Object.assign({},t);r.checked=n.model.value.indexOf(r.value)>-1;i.items.push(r)});i.showDescriptions=Object.toBoolean(r.showDescriptions);i.showIcons=Object.toBoolean(r.showIcons);i.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias;i.changed=e;i.labelCheckAll="Check all";i.labelUncheckAll="Uncheck all";t.localizeMany(["contentment_checkboxListCheckAll","contentment_checkboxListUncheckAll"]).then(function(n){i.labelCheckAll=n[0];i.labelUncheckAll=n[1]});i.toggleAll=Object.toBoolean(r.checkAll);i.toggleAll&&(i.toggle=o,i.toggleChecked=i.items.every(n=>n.checked))}function e(){i.toggleChecked=i.items.every(n=>n.checked);n.model.value=[];i.items.forEach(t=>{t.checked&&n.model.value.push(t.value)});u()}function o(){n.model.value=[];i.items.forEach(t=>{t.disabled||(t.checked=i.toggleChecked,t.checked&&n.model.value.push(t.value))});u()}function u(){n.propertyForm&&n.propertyForm.$setDirty()}var r=Object.assign({},{items:[],checkAll:0,showDescriptions:0,showIcons:0,defaultValue:[]},n.model.config),i=this;f()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.CodeEditor.Controller",["$scope",function(n){function u(){i.cssClasses=n.model.labelOnTop?[]:["umb-property-editor--limit-width"];i.readonly=Object.toBoolean(t.readonly);i.options={autoFocus:!1,showGutter:Object.toBoolean(t.showGutter),useWrapMode:Object.toBoolean(t.useWrapMode),showInvisibles:Object.toBoolean(t.showInvisibles),showIndentGuides:Object.toBoolean(t.showIndentGuides),useSoftTabs:Object.toBoolean(t.useSoftTabs),showPrintMargin:Object.toBoolean(t.showPrintMargin),disableSearch:Object.toBoolean(t.disableSearch),theme:t.theme,mode:t.mode,firstLineNumber:t.firstLineNumber,advanced:{fontSize:t.fontSize,enableSnippets:Object.toBoolean(t.enableSnippets),enableBasicAutocompletion:Object.toBoolean(t.enableBasicAutocompletion),enableLiveAutocompletion:Object.toBoolean(t.enableLiveAutocompletion),minLines:t.minLines,maxLines:t.maxLines,wrap:Object.toBoolean(t.useWrapMode)}}}var r={showGutter:1,useWrapMode:1,showInvisibles:0,showIndentGuides:0,useSoftTabs:1,showPrintMargin:0,disableSearch:0,theme:"chrome",mode:"javascript",firstLineNumber:1,fontSize:"small",enableSnippets:0,enableBasicAutocompletion:0,enableLiveAutocompletion:0,readonly:0,minLines:undefined,maxLines:undefined},t=Object.assign({},r,n.model.config),i=this;u()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.ConfigurationEditorInline.Controller",["$scope","formHelper",function(n){function r(){t.editor=Object.assign({},i.editor);n.model.value=n.model.value||{key:t.editor.key,value:t.editor.defaultValues||{}};n.model.value.key!==t.editor.key&&(n.model.value.key=t.editor.key);t.editor.fields&&t.editor.fields.length>0&&t.editor.fields.forEach(t=>{t.alias=t.key,n.model.value.value.hasOwnProperty(t.key)&&(t.value=n.model.value.value[t.key])});n.$on("formSubmitting",function(){t.editor.fields&&t.editor.fields.length>0&&t.editor.fields.forEach(t=>{n.model.value.value[t.key]=t.value})})}var i=Object.assign({},{editor:{}},n.model.config),t=this;r()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.ConfigurationEditor.Controller",["$scope","$interpolate","$timeout","editorService","eventsService","localizationService","overlayService","Umbraco.Community.Contentment.Services.DevMode",function(n,t,i,r,u,f,e,o){function v(){n.model.value=n.model.value||[];Array.isArray(n.model.value)===!1&&(n.model.value=[n.model.value]);n.model.value.forEach(n=>{n.hasOwnProperty("type")&&(n.key=n.type,delete n.type)});Number.isInteger(s.maxItems)===!1&&(s.maxItems=Number.parseInt(s.maxItems)||l.maxItems);s.itemLookup={};s.allowEdit={};s.expressions={};s.missingItem={};s.items.forEach(n=>{if(s.itemLookup.hasOwnProperty(n.key)===!1&&(s.itemLookup[n.key]=n),s.allowEdit.hasOwnProperty(n.key)===!1&&(s.allowEdit[n.key]=n.fields&&n.fields.length>0),s.expressions.hasOwnProperty(n.key)===!1&&(s.expressions[n.key]={},n.nameTemplate&&(s.expressions[n.key].name=t(n.nameTemplate)),n.descriptionTemplate&&(s.expressions[n.key].description=t(n.descriptionTemplate)),n.expressions))for(let[r,i]of Object.entries(n.expressions))i&&(s.expressions[n.key][r]=t(i))});f.localizeMany(["contentment_missingItemName","contentment_missingItemDescription"]).then(n=>{s.missingItem.name=n[0],s.missingItem.description=n[1],s.missingItem.icon="icon-alert"});h.allowAdd=s.maxItems===0||n.model.value.lengths.allowEdit[n.key];h.allowRemove=Object.toBoolean(s.allowRemove);h.allowSort=Object.toBoolean(s.disableSorting)===!1&&s.maxItems!==1;h.displayMode=s.displayMode||"list";h.sortableOptions={axis:"y",containment:"parent",cursor:"move",disabled:h.allowSort===!1,opacity:.7,scroll:!0,tolerance:"pointer",stop:()=>{c()}};h.addButtonLabelKey=s.addButtonLabelKey||"general_add";h.add=y;h.edit=p;h.populate=w;h.remove=b;h.propertyActions=[];Object.toBoolean(s.enableDevMode)&&h.propertyActions.push({labelKey:"contentment_editRawValue",icon:"brackets",method:()=>o.editValue(n.model,k)});i(()=>a(),100)}function y(){var t=Object.toBoolean(s.allowDuplicates)?s.items:s.items.filter(t=>n.model.value.some(n=>t.key===n.key)===!1);r.open({view:s.overlayView,size:s.items.length===1?s.items[0].overlaySize:"small",config:{mode:"select",autoSelect:s.items.length===1,label:n.model.label,items:t,enableFilter:Object.toBoolean(s.enableFilter),orderBy:s.orderBy,help:s.help,cacheKey:n.model.alias},value:{},submit:function(t){n.model.value.push(t);s.maxItems!==0&&n.model.value.length>=s.maxItems&&(h.allowAdd=!1);c();r.close()},close:function(){r.close()}})}function p(t){var i=n.model.value[t],u=s.itemLookup[i.key];r.open({view:s.overlayView,size:u.overlaySize,config:{mode:"edit",editor:u,cacheKey:n.model.alias},value:i,submit:function(i){n.model.value[t]=i;c();r.close()},close:function(){r.close()}})}function a(){u.emit("contentment.config-editor.model",n.model)}function w(n,t,i){var f="",r,u;return s.itemLookup.hasOwnProperty(n.key)===!1&&s.missingItem?s.missingItem[i]||i:(s.expressions.hasOwnProperty(n.key)===!0&&(r=s.expressions[n.key],r.hasOwnProperty(i)===!0&&(u=r[i],u&&(n.value.$index=t+1,f=u(n.value),delete n.value.$index))),f||s.itemLookup[n.key][i])}function b(t){f.localizeMany(["contentment_removeItemMessage","general_remove","general_cancel","contentment_removeItemButton"]).then(function(i){e.open({title:i[1],content:i[0],closeButtonLabel:i[2],submitButtonLabel:i[3],submitButtonStyle:"danger",submit:function(){n.model.value.splice(t,1);(s.maxItems===0||n.model.value.length=s.maxItems?!1:!0;c()}function c(){n.propertyForm&&n.propertyForm.$setDirty();a()}var l={addButtonLabelKey:"general_add",allowDuplicates:0,allowRemove:1,disableSorting:0,displayMode:"list",enableDevMode:0,enableFilter:0,help:null,items:[],maxItems:0,orderBy:"name",overlayView:""},s=Object.assign({},l,n.model.config),h=this;v()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.Overlays.ConfigurationEditor.Controller",["$scope","formHelper",function(n){function e(){if(t.mode=i.mode,t.mode==="select")i.autoSelect&&i.items.length===1?u(i.items[0]):(t.title="Select "+i.label.toLowerCase()+"...",t.help=i.help,t.items=i.items,t.enableFilter=i.enableFilter,t.orderBy=i.orderBy,t.select=u,t.cacheKey=i.cacheKey);else if(t.mode==="edit"&&i.editor){var f=n.model.value||{key:"",value:{}};r(i.editor,f)}t.close=o}function r(i,r){i.overlaySize&&n.model.size!==i.overlaySize&&(n.model.size=i.overlaySize);r.value||(r.value={});t.title="Configure "+i.name;t.editor=Object.assign({},i);t.editor.fields&&t.editor.fields.length>0&&t.editor.fields.forEach(n=>{n.alias=n.key,n.value=r.value[n.key]});t.save=f}function u(n){Array.isArray(n.fields)&&n.fields.length>0?(t.mode="edit",r(n,{value:n.defaultValues||{}})):f(n)}function o(){n.model.close&&n.model.close()}function f(t){n.$broadcast("formSubmitting",{scope:n});var i={key:t.key,value:{}};t.fields&&t.fields.forEach(n=>{i.value[n.key]=n.value});n.model.submit&&n.model.submit(i)}var i=Object.assign({},{mode:"select",autoSelect:!0,label:"",items:[],editor:null,enableFilter:!1,orderBy:"name",help:null,cacheKey:null},n.model.config),t=this;e()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.ContentBlocks.Controller",["$scope","$q","$http","$interpolate","clipboardService","contentResource","editorService","editorState","localizationService","notificationsService","overlayService","umbRequestHelper","Umbraco.Community.Contentment.Services.DevMode",function(n,t,i,r,u,f,e,o,s,h,c,l,a){function tt(){var t,i;for(v.currentPage=n.node||o.getCurrent(),v.currentPageId=v.currentPage.id>0?v.currentPage.id:v.currentPage.parentId,v.currentPageId||(v.currentPageId=-1),n.model.value=n.model.value||[],n.model.value===""&&(n.model.value=[]),Array.isArray(n.model.value)===!1&&(n.model.value=[n.model.value]),Number.isInteger(v.maxItems)===!1&&(v.maxItems=Number.parseInt(v.maxItems)||g.maxItems),v.elementTypeScaffoldCache={},v.elementTypeLookup={},v.missingItem={name:"This content is not supported for this configuration.",icon:"icon-alert"},v.nameTemplates={},v.contentBlockTypes.forEach(n=>{v.elementTypeLookup[n.key]=n,v.nameTemplates[n.key]=r(n.nameTemplate||"Item {{ $index }}")}),s.localizeMany(["contentment_missingElementType"]).then(n=>{v.missingItem.name=n[0]}),y.addButtonLabelKey=v.addButtonLabelKey||"grid_addElement",y.displayMode=v.displayMode,y.enablePreview=Object.toBoolean(v.enablePreview),y.allowAdd=v.maxItems===0||n.model.value.lengthb(),y.disabled={},y.previews=[],y.blockActions={},t=0;tp(n)}),Object.toBoolean(v.allowCreateContentTemplate)===!0&&t.push({labelKey:"contentment_createContentTemplate",icon:"blueprint",method:()=>ot(n)}),t}function it(){e.open({config:{elementTypes:v.contentBlockTypes,enableFilter:v.enableFilter,currentPage:v.currentPage,currentPageId:v.currentPageId},size:v.contentBlockTypes.length===1?v.contentBlockTypes[0].overlaySize:"small",value:null,view:v.overlayView,submit:function(t){n.model.value.push(t);var i=n.model.value.length-1;y.blockActions[t.key]=nt(i);w(i);v.maxItems!==0&&n.model.value.length>=v.maxItems&&(y.allowAdd=!1);d();e.close()},close:function(){e.close()}})}function p(i){var e=n.model.value[i],r=v.elementTypeLookup[e.elementType],o=k(e,i),s=v.elementTypeScaffoldCache.hasOwnProperty(r.alias)===!1?f.getScaffold(v.currentPageId,r.alias):t.when(v.elementTypeScaffoldCache[r.alias]);s.then(n=>{var i,s,f,t;if(v.elementTypeScaffoldCache.hasOwnProperty(r.alias)===!1&&(v.elementTypeScaffoldCache[r.alias]=n),n.name=o,n.variants[0].name=o,e.value)for(i=0;i{n&&n.elementKey&&n.markup&&(y.previews[n.elementKey]={loading:!1,markup:n.markup})}))}}function b(){if(y.enablePreview===!0)for(var t=0;t{c.open({title:i[1],content:i[0],closeButtonLabel:i[2],submitButtonLabel:i[3],submitButtonStyle:"danger",submit:function(){var i=n.model.value[t];n.model.value.splice(t,1);delete y.blockActions[i.key];b();(v.maxItems===0||n.model.value.length{var r=n.model.value[t],u=k(r,t),e=v.elementTypeLookup[r.elementType];c.open({disableBackdropClick:!0,title:s.tokenReplace(i[0],[u]).replace("","'").replace("<\/em>","'"),description:i[1],blueprintName:u,view:"/App_Plugins/Contentment/editors/content-blocks.blueprint.html",closeButtonLabel:i[4],submitButtonLabel:i[5],submitButtonStyle:"action",submit:function(n){delete n.error;n.submitButtonState="busy";var t={save:!0,name:n.blueprintName,tabs:[{properties:Object.entries(r.value).map(n=>({id:0,alias:n[0],value:n[1]}))}]},o={action:"saveNew",id:0,parentId:-1,contentTypeAlias:e.alias,expireDate:null,releaseDate:null,templateAlias:null,variants:[Object.assign({},t,{save:!0})]};f.saveBlueprint(o,!0,[],!1).then(t=>{n.submitButtonState="success",h.success(i[2],s.tokenReplace(i[3],[u])),e.blueprints.push({id:t.id,name:t.variants[0].name}),c.close()},t=>{n.submitButtonState="error",n.error=t.data.ModelState.Name[0]})},close:function(){c.close()}})})}function d(){n.propertyForm&&n.propertyForm.$setDirty()}var g={addButtonLabelKey:"grid_addElement",allowCopy:1,allowCreateContentTemplate:0,allowEdit:1,allowRemove:1,contentBlockTypes:[],disableSorting:0,displayMode:"blocks",enableDevMode:0,enableFilter:0,enablePreview:0,maxItems:0,overlayView:""},v=Object.assign({},g,n.model.config),y=this;tt()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.Overlays.ContentBlocks.Controller",["$scope","blueprintConfig","clipboardService","contentResource",function(n,t,i,r){function h(){u.submit=y;u.close=p;u.contentNodeModel=f.currentPage||{variants:[]};f.elementType&&n.model.value?s(f.elementType,n.model.value):(u.mode="select",u.items=f.elementTypes,u.selectedElementType=null,u.clipboardItems=typeof i.retrieveDataOfType=="function"?i.retrieveDataOfType("elementType",f.elementTypes.map(n=>n.alias)):i.retriveDataOfType("elementType",f.elementTypes.map(n=>n.alias)),f.elementTypes.length>1||u.clipboardItems.length>0?(u.title="Add content",u.description="Select a content type...",u.icon="icon-page-add",u.selectBlueprint=!1,u.enableFilter=Object.toBoolean(f.enableFilter),u.select=o,u.paste=v,u.clearClipboard=c,u.prompt=!1,u.showPrompt=l,u.hidePrompt=a):f.elementTypes.length===1&&o(f.elementTypes[0]))}function c(){u.clipboardItems=[];i.clearEntriesOfType("elementType",f.elementTypes.map(n=>n.alias))}function l(){u.prompt=!0}function a(){u.prompt=!1}function o(n){n.blueprints&&n.blueprints.length>0?n.blueprints.length===1&&t.skipSelect?e(n,n.blueprints[0]):(u.title="Add content",u.description="Select a content blueprint...",u.icon="icon-blueprint",u.selectBlueprint=!0,u.selectedElementType=n,u.blueprintAllowBlank=t.allowBlank,u.create=e):e(n)}function e(t,i){n.model.size=t.overlaySize;u.mode="edit";u.loading=!0;u.title="Edit content";u.description=t.name;u.icon=t.icon;u.content={elementType:t.key,key:String.CreateGuid()};var e=i&&i.id>0?r.getBlueprintScaffold(f.currentPageId,i.id):r.getScaffold(f.currentPageId,t.alias);e.then(n=>{Object.assign(u.content,n.variants[0]),u.loading=!1})}function v(t){var e=f.elementTypes.find(n=>n.alias===t.contentTypeAlias),o,i,h,r,u;if(n.model.size=e.overlaySize,o={elementType:e.key,key:String.CreateGuid(),value:{}},t.variants.length>0)for(i=0;i{var i,e,r,f;if(t.value)for(i=0;i0)for(t=0;t{u(n),r.loading=!1})):r.node=null;r.showHelp=!1;r.showSearch=!1;r.pick=e;r.remove=o;r.show=s;r.hide=h;r.help=c;r.clear=l}function e(){t.treePicker({idType:"udi",section:"content",treeAlias:"content",multiPicker:!1,submit:function(i){var r=i.selection[0];u(r);n.model.value=r.udi;t.close()},close:function(){t.close()}})}function o(){n.model.value=null;r.node=null}function s(){r.showSearch=!0}function h(){r.showSearch=!1}function c(){r.showHelp=!r.showHelp}function l(){r.showSearch=!1;n.model.value=null}function u(n){r.node=n;i.getUrl(n.id,"Document").then(n=>{r.node.path=n})}var a=Object.assign({},{},n.model.config),r=this;f()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.DataList.Editor.Controller",["$scope","editorService","localizationService","overlayService","Umbraco.Community.Contentment.Services.DevMode",function(n,t,i,r,u){function l(){n.model.value=n.model.value||[];Number.isInteger(f.maxItems)===!1&&(f.maxItems=Number.parseInt(f.maxItems)||s.maxItems);f.confirmRemoval=Object.toBoolean(f.confirmRemoval);e.allowAdd=f.maxItems===0||n.model.value.lengtho()};e.notes=f.notes;e.add=a;e.blur=v;e.edit=h;e.open=y;e.remove=p;Object.toBoolean(f.enableDevMode)===!0&&n.umbProperty&&n.umbProperty.setPropertyActions([{labelKey:"contentment_editRawValue",icon:"brackets",method:h},{labelKey:"clipboard_labelForRemoveAllEntries",icon:"trash",method:()=>{n.model.value=[]}}])}function a(){e.focusName=e.hideIcon===!0;n.model.value.push({icon:f.defaultIcon,name:"",value:"",description:""});f.maxItems!==0&&n.model.value.length>=f.maxItems&&(e.allowAdd=!1);o()}function v(n){(n.name&&n.value==null||n.value==="")&&(n.value=n.name.toCamelCase())}function h(){u.editValue(n.model,()=>{})}function y(n){var i=n.icon.split(" ");t.iconPicker({icon:i[0],color:i[1],submit:function(i){n.icon=[i.icon,i.color].filter(n=>n).join(" ");e.focusName=!0;o();t.close()},close:function(){t.close()}})}function p(n){if(f.confirmRemoval===!0)i.localizeMany(["contentment_removeItemMessage","general_remove","general_cancel","contentment_removeItemButton"]).then(t=>{r.open({title:t[1],content:t[0],closeButtonLabel:t[2],submitButtonLabel:t[3],submitButtonStyle:"danger",submit:function(){c(n);r.close()},close:function(){r.close()}})});else c(n)}function c(t){n.model.value.splice(t,1);(f.maxItems===0||n.model.value.length{u.tabs.forEach(n=>n.active=!1),u.activeTab=n.alias,n.active=!0};u.changeTab(u.tabs[0]);var t=[];t.push(i.on("contentment.config-editor.model",(n,t)=>{f[t.alias]=t.value,o()}));n.$on("$destroy",()=>{for(var n in t)i.unsubscribe(t[n])})}function o(){_.isEmpty(f.dataSource)===!1&&_.isEmpty(f.listEditor)===!1?(u.state="loading",u.property=null,r.resourcePromise(t.post("backoffice/Contentment/DataListApi/GetPreview",f),"Failed to retrieve data list preview.").then(n=>{u.property=n,u.state=n.config.items&&n.config.items.length>0?"loaded":"noItems",u.tabs[1].label="Data source items ("+n.config.items.length+")"})):u.state=_.isEmpty(f.dataSource)===!1?"dataSourceConfigured":_.isEmpty(f.listEditor)===!1?"listEditorConfigured":"init"}var f=Object.assign({alias:n.model.alias},n.model.config),u=this;e()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.DataListSource.Preview.Controller",["$scope","$http","eventsService","umbRequestHelper",function(n,t,i,r){function e(){u.property={};u.state="loading";u.tabs=[{label:"Data source items",alias:"dataSource",active:!1},{label:"JSON",alias:"rawJson",active:!1}];u.changeTab=n=>{u.tabs.forEach(n=>n.active=!1),u.activeTab=n.alias,n.active=!0};u.changeTab(u.tabs[0]);var t=[];t.push(i.on("contentment.config-editor.model",(n,t)=>{f[t.alias]=t.value,o()}));n.$on("$destroy",()=>{for(var n in t)i.unsubscribe(t[n])})}function o(){_.isEmpty(f.dataSource)===!1?(u.state="loading",u.items=null,r.resourcePromise(t.post("backoffice/Contentment/DataListApi/GetDataSourceItems",f),"Failed to retrieve data source items.").then(n=>{u.items=n.config.items,u.state=u.items&&u.items.length>0?"loaded":"noItems",u.tabs[0].label="Data source items ("+u.items.length+")"})):u.state="init"}var f=Object.assign({},n.model.config),u=this;e()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.DataPicker.Controller",["$scope","$http","editorService","editorState","localizationService","overlayService","umbRequestHelper","Umbraco.Community.Contentment.Services.DevMode",function(n,t,i,r,u,f,e,o){function v(){s.currentPage=n.node||r.getCurrent();s.currentPageId=s.currentPage.id>0?s.currentPage.id:s.currentPage.parentId;s.currentPageId||(s.currentPageId=-1);n.model.value=n.model.value||s.defaultValue;Array.isArray(n.model.value)===!1&&(n.model.value=[n.model.value]);Array.isArray(s.displayMode)===!0&&(s.displayMode=s.displayMode[0]);Number.isInteger(s.maxItems)===!1&&(s.maxItems=Number.parseInt(s.maxItems)||l.maxItems);Array.isArray(s.overlaySize)===!0&&(s.overlaySize=s.overlaySize[0]);h.itemLookup={};h.loading=!1;s.missingItem={cardStyle:{"background-color":"#f0ac00"},description:"This item is no longer available.",icon:"icon-alert"};a();h.allowAdd=s.maxItems===0||n.model.value.lengtho.editValue(n.model,b)})}function y(){i.open({view:s.overlayView,size:s.overlaySize||"medium",config:{currentPageId:s.currentPageId,dataTypeKey:n.model.dataTypeKey,enableMultiple:s.maxItems!==1,listType:s.displayMode,pageSize:s.pageSize},submit:function(t){t&&Object.entries(t).forEach(t=>{h.itemLookup[t[0]]=t[1],n.model.value.push(t[0])});s.maxItems!==0&&n.model.value.length>=s.maxItems&&(h.allowAdd=!1);c();i.close()},close:function(){i.close()}})}function a(){n.model.value.length&&(h.loading=!0,e.resourcePromise(t.post("backoffice/Contentment/DataPickerApi/GetItems?id="+s.currentPageId,n.model.value,{params:{dataTypeKey:n.model.dataTypeKey}}),"Failed to retrieve item data.").then(function(n){h.itemLookup=n;h.loading=!1}))}function p(n,t,i){if(h.itemLookup.hasOwnProperty(n)===!1)return i==="name"?n:s.missingItem[i]||null;if(i==="cardStyle"){var r=h.itemLookup[n].image;return r?{"background-image":`url('${r}')`}:null}return i==="iconStyle"?null:i==="icon"?h.displayMode==="cards"&&h.itemLookup[n].image?null:h.itemLookup[n][i]||h.defaultIcon:h.itemLookup[n][i]||n}function w(t){u.localizeMany(["contentment_removeItemMessage","general_remove","general_cancel","contentment_removeItemButton"]).then(function(i){f.open({title:i[1],content:i[0],closeButtonLabel:i[2],submitButtonLabel:i[3],submitButtonStyle:"danger",submit:function(){n.model.value.splice(t,1);(s.maxItems===0||n.model.value.lengthn.$apply(f),500);o()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.DataTable.Controller",["$scope","Umbraco.Community.Contentment.Services.DevMode",function(n,t){function e(){n.model.value=n.model.value||[];Number.isInteger(r.maxItems)===!1&&(r.maxItems=Number.parseInt(r.maxItems)||f.maxItems);i.headings=r.fields.map(n=>n.label);i.items=[];n.model.value.forEach((t,u)=>{var f=[];r.fields.forEach((i,r)=>{f.push(Object.assign({alias:[n.model.alias,u,r].join("_"),value:t[i.key]},i))});i.items.push(f)});i.styleTable={"max-width":Object.toBoolean(r.restrictWidth)?"800px":"100%","background-color":"#f6f4f4"};i.styleButton=Object.toBoolean(r.restrictWidth)?{}:{"max-width":"100%"};i.usePrevalueEditors=Object.toBoolean(r.usePrevalueEditors)?!0:null;i.allowAdd=r.maxItems===0||i.items.length tr",opacity:.7,scroll:!0,tolerance:"pointer",stop:()=>u()};i.showPrompt=c;i.hidePrompt=l;i.add=o;i.remove=h;n.umbProperty&&n.umbProperty.setPropertyActions([{labelKey:"contentment_editRawValue",icon:"brackets",method:function(){t.editValue(n.model,()=>{})}},{labelKey:"clipboard_labelForRemoveAllEntries",icon:"trash",method:function(){s()}}])}function o(){i.items.push(angular.copy(r.fields));r.maxItems!==0&&i.items.length>=r.maxItems&&(i.allowAdd=!1);u()}function s(){i.items=[];n.model.value=[];u()}function h(n){i.items.splice(n,1);(r.maxItems===0||i.items.length{var i={};t.forEach(n=>{i[n.key]=n.value});n.model.value.push(i)})});n.$on("$destroy",()=>a());e()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.DictionaryPicker.Controller",["$scope","dictionaryResource","editorService",function(n,t,i){function o(){n.model.value=n.model.value||[];Number.isInteger(r.maxItems)===!1&&(r.maxItems=Number.parseInt(r.maxItems)||f.maxItems);u.addButtonLabelKey=r.addButtonLabelKey||"general_add";u.defaultIcon="icon-book-alt";u.displayMode="list";u.allowAdd=r.maxItems===0||r.maxItems==="0"||n.model.value.length=r.maxItems&&(u.allowAdd=!1);e();i.close()})},close:function(){i.close()}})}function h(t){n.model.value.splice(t,1);(r.maxItems===0||n.model.value.length0?n.model.value[0]:i.defaultValue);i.showEmpty===!1&&!n.model.value&&t.items.length>0&&(n.model.value=t.items[0].value);t.showEmpty=i.showEmpty===!0&&t.items.some(t=>t.value===n.model.value);t.htmlAttributes=i.htmlAttributes;t.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias;t.change=u}function u(){t.showEmpty=i.showEmpty===!0&&t.items.some(t=>t.value===n.model.value)}var i=Object.assign({},{items:[],allowEmpty:1,defaultValue:"",htmlAttributes:[]},n.model.config),t=this;r()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.EditorNotes.Controller",["$scope",function(n){function r(){i.alertType=t.alertType;i.icon=t.icon;i.heading=t.heading;i.message=t.message;i.hidePropertyGroup=n.model.hasOwnProperty("contentTypeId")===!1&&Object.toBoolean(t.hidePropertyGroup)}var t=Object.assign({},{hidePropertyGroup:0},n.model.config),i=this;r()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.IconPicker.Controller",["$scope","editorService",function(n,t){function f(){n.model.value=n.model.value||r.defaultIcon;Array.isArray(r.size)===!0&&(r.size=r.size[0]);i.label=n.model.value.replace(" ","
");i.size=r.size;i.allowAdd=n.model.value==="";i.pick=e;i.remove=o}function e(){var f=n.model.value.split(" "),e={icon:f[0],color:f[1],hideColors:Object.toBoolean(r.hideColors),submit:function(r){n.model.value=[r.icon,r.color].filter(n=>n).join(" ");i.label=n.model.value.replace(" ","
");i.allowAdd=!1;u();t.close()},close:function(){t.close()}};t.iconPicker(e)}function o(){n.model.value="";i.label="";i.allowAdd=!0;u()}function u(){n.propertyForm&&n.propertyForm.$setDirty()}var r=Object.assign({},{defaultIcon:"",hideColors:0,size:"large"},n.model.config),i=this;f()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.ItemPicker.Controller",["$scope","editorService","focusService","localizationService","overlayService",function(n,t,i,r,u){function l(){if(n.model.value=n.model.value||f.defaultValue,Array.isArray(n.model.value)===!1&&(n.model.value=[n.model.value]),Number.isInteger(f.maxItems)===!1&&(f.maxItems=Number.parseInt(f.maxItems)||h.maxItems),Array.isArray(f.overlaySize)===!0&&(f.overlaySize=f.overlaySize[0]),f.confirmRemoval=Object.toBoolean(f.confirmRemoval),f.enableMultiple=Object.toBoolean(f.enableMultiple)&&f.maxItems!==1,e.defaultIcon=f.defaultIcon,e.displayMode=f.displayMode||"list",e.allowAdd=f.maxItems===0||n.model.value.length{n.model.value=e.items.map(n=>n.value)},e.items=[],n.model.value.length>0&&f.items.length>0){var t=[];n.model.value.forEach(n=>{var i=f.items.find(t=>t.value===n);i?e.items.push(Object.assign({},i)):t.push(n)});t.length>0&&(n.model.value=_.difference(n.model.value,t),(f.maxItems===0||n.model.value.length0&&n.umbProperty.setPropertyActions(e.propertyActions))}function a(){i.rememberFocus();var r=Object.toBoolean(f.allowDuplicates)?f.items:f.items.filter(n=>e.items.some(t=>n.value===t.value)===!1);t.open({config:{title:"Choose...",enableFilter:Object.toBoolean(f.enableFilter),enableMultiple:f.enableMultiple,defaultIcon:f.defaultIcon,items:r,listType:f.listType,orderBy:f.overlayOrderBy,maxItems:f.maxItems===0?f.maxItems:f.maxItems-e.items.length},view:f.overlayView,size:f.overlaySize||"small",submit:function(i){i.forEach(t=>{e.items.push(angular.copy(t)),n.model.value.push(t.value)});f.maxItems!==0&&n.model.value.length>=f.maxItems&&(e.allowAdd=!1);t.close();o();s()},close:function(){t.close();s()}})}function v(){e.items=[];n.model.value=[];o()}function y(n){if(i.rememberFocus(),f.confirmRemoval===!0)r.localizeMany(["contentment_removeItemMessage","general_remove","general_cancel","contentment_removeItemButton"]).then(t=>{u.open({title:t[1],content:t[0],closeButtonLabel:t[2],submitButtonLabel:t[3],submitButtonStyle:"danger",submit:function(){c(n);u.close()},close:function(){u.close();s()}})});else c(n)}function c(t){e.items.splice(t,1);n.model.value.splice(t,1);(f.maxItems===0||n.model.value.lengthn.selected===!0).length,t.allowSubmit=t.itemCount>0&&(i.maxItems===0||t.itemCount<=i.maxItems)):(n.model.value=u,r()))}function r(){if(n.model.submit){var i=[];t.enableMultiple===!0?t.items.forEach(n=>{n.selected&&(delete n.selected,i.push(n))}):i.push(n.model.value);n.model.submit(i)}}function e(){n.model.close&&n.model.close()}var i=Object.assign({},{title:"Select...",enableFilter:!1,enableMultiple:!1,defaultIcon:"icon-science",items:[],listType:"grid",orderBy:"name",maxItems:0},n.model.config),t=this;u()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.MacroPicker.Controller",["$scope","entityResource","editorService","localizationService","overlayService",function(n,t,i,r,u){function s(){n.model.value=n.model.value||[];e.defaultIcon="icon-settings-alt";e.displayMode="list";e.allowAdd=f.maxItems===0||f.maxItems==="0"||n.model.value.length[n.alias,n.value]))});f.maxItems!==0&&f.maxItems!=="0"&&n.model.value.length>=f.maxItems&&(e.allowAdd=!1);o();i.close()},close:function(){i.close()}})}function c(t){var r=n.model.value[t];i.macroPicker({dialogData:{richTextEditor:!1,macroData:{macroAlias:r.alias,macroParamsDictionary:r.params},allowedMacros:f.availableMacros},submit:function(r){n.model.value[t]={udi:r.selectedMacro.udi,name:r.selectedMacro.name,alias:r.selectedMacro.alias,params:_.object(_.map(r.macroParams,n=>[n.alias,n.value]))};o();i.close()},close:function(){i.close()}})}function l(t){r.localizeMany(["contentment_removeItemMessage","general_remove","general_cancel","contentment_removeItemButton"]).then(i=>{u.open({title:i[1],content:i[0],closeButtonLabel:i[2],submitButtonLabel:i[3],submitButtonStyle:"danger",submit:function(){n.model.value.splice(t,1);(f.maxItems===0||f.maxItems==="0"||n.model.value.lengthi.editValue(n.model,e)}]);u.currentPage=n.node||t.getCurrent();u.hidePropertyGroup=n.model.hasOwnProperty("contentTypeId")===!1&&Object.toBoolean(r.hidePropertyGroup)}function e(){n.propertyForm&&n.propertyForm.$setDirty()}var r=Object.assign({},{enableDevMode:0,hidePropertyGroup:0},n.model.config),u=this;f()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.NumberInput.Controller",["$scope",function(n){function u(){n.model.value!==0&&(n.model.value=n.model.value||t.defaultValue);i.maximum=t.maximum;i.minimum=t.minimum;i.step=t.step;i.pattern=t.umbracoDataValueType==="DECIMAL"?"[-0-9]+([,.][0-9]+)?":"[-0-9]*";i.placeholderText=t.placeholderText;var u={s:"umb-property-editor-tiny",m:"umb-property-editor-small",l:"umb-property-editor--limit-width",xl:"umb-property-editor"};i.sizeClass=u[t.size]||u[r.size];i.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias}var r={placeholderText:null,defaultValue:null,maximum:null,minimum:null,size:"s",step:null,umbracoDataValueType:"INT"},t=Object.assign({},r,n.model.config),i=this;u()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.RadioButtonList.Controller",["$scope",function(n){function r(){n.model.value=n.model.value||i.defaultValue;Array.isArray(n.model.value)&&(n.model.value=n.model.value[0]);t.items=i.items.slice();t.showDescriptions=Object.toBoolean(i.showDescriptions);t.showIcons=Object.toBoolean(i.showIcons);t.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias;n.umbProperty&&(t.propertyActions=[],Object.toBoolean(i.allowClear)===!0&&t.propertyActions.push({labelKey:"buttons_clearSelection",icon:"trash",method:()=>{n.model.value=i.defaultValue,setDirty()}}),t.propertyActions.length>0&&n.umbProperty.setPropertyActions(t.propertyActions))}var i=Object.assign({},{allowClear:0,items:[],showDescriptions:0,showIcons:0,defaultValue:""},n.model.config),t=this;r()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.RenderMacro.Controller",["$scope","$routeParams","macroResource",function(n,t,i){function f(){if(r.loading=!0,Array.isArray(n.model.config.macro)&&n.model.config.macro.length>0){var f=n.model.config.macro[0];Object.assign(f.params,{__propertyAlias:n.model.alias,__propertyLabel:n.model.label,__propertyCulture:n.model.culture,__propertyDataTypeKey:n.model.dataTypeKey,__propertyDescription:n.model.description,__propertyHideLabel:n.model.hideLabel});i.getMacroResultAsHtmlForEditor(f.alias,t.id,f.params).then(n=>{r.html=n,r.loading=!1},n=>{r.error={title:n.data.Message+" "+n.errorMsg,message:n.data.ExceptionMessage},r.loading=!1})}else r.error={title:"Macro not configured",message:"This data type has not been configured. Please ensure that a macro has been selected."},r.loading=!1;r.hidePropertyGroup=Object.toBoolean(u.hidePropertyGroup)}if(!n.model.hasOwnProperty("contentTypeId")){var u=Object.assign({},{hidePropertyGroup:0},n.model.config),r=this;f()}}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.SocialLinks.Controller",["$scope","editorService","localizationService","overlayService","Umbraco.Community.Contentment.Services.DevMode",function(n,t,i,r,u){function a(){n.model.value=n.model.value||[];Number.isInteger(f.maxItems)===!1&&(f.maxItems=Number.parseInt(f.maxItems)||h.maxItems);f.confirmRemoval=Object.toBoolean(f.confirmRemoval);e.allowAdd=f.maxItems===0||n.model.value.length=f.maxItems&&(e.allowAdd=!1);o()}function c(){u.editValue(n.model,function(){})}function y(n){var t=f.lookup[n];return t&&t.icon?t.icon:f.defaultIcon}function p(n){var t=f.lookup[n];return t&&t.backgroundColor&&t.iconColor?{backgroundColor:t.backgroundColor,color:t.iconColor,borderRadius:"5px",paddingTop:0}:{backgroundColor:f.defaultBackgroundColor,color:f.defaultIconColor,borderRadius:"5px",borderStyle:"dashed",paddingTop:0}}function l(t){var i=n.model.value[t];r.open({title:"Select a social network...",config:{items:f.networks},position:"center",size:"small",view:f.overlayView,value:i,hideSubmitButton:!0,submit:function(n){i.network=n.network;i.name===""&&(i.name=n.name);i.url===""&&(i.url=n.url);e.focusIdx=t;o();r.close()},close:function(){i.network===""&&s(t);r.close()}})}function w(n){if(f.confirmRemoval===!0)i.localizeMany(["contentment_removeItemMessage","general_remove","general_cancel","contentment_removeItemButton"]).then(function(t){r.open({title:t[1],content:t[0],closeButtonLabel:t[2],submitButtonLabel:t[3],submitButtonStyle:"danger",submit:function(){s(n);r.close()},close:function(){r.close()}})});else s(n)}function s(t){n.model.value.splice(t,1);(f.maxItems===0||n.model.value.length{t.model.value.forEach(n=>{var t=s.items.find(t=>t.value===n);t&&o.items.push(Object.assign({},t))});o.loading=!1;var n=new Bloodhound({datumTokenizer:Bloodhound.tokenizers.obj.whitespace("name","value"),queryTokenizer:Bloodhound.tokenizers.whitespace,initialize:!1,local:s.items.filter(n=>!n.disabled),identify:n=>n.value});n.initialize().then(()=>{var t={display:"name",minLength:0,source:(t,i)=>{t&&t.length>0?n.search(t,i):i(n.all())}};o.editor=i.find("input.typeahead").typeahead({hint:!0,highlight:!0,minLength:1},t).bind("typeahead:select",h).bind("typeahead:autocomplete",h)})});t.umbProperty&&(o.propertyActions=[],Object.toBoolean(s.allowClear)===!0&&o.propertyActions.push({labelKey:"buttons_clearSelection",icon:"trash",method:y}),o.propertyActions.length>0&&t.umbProperty.setPropertyActions(o.propertyActions))}function h(i,u){r.safeApply(n,function(){o.items.push(Object.assign({},u));t.model.value.push(u.value);o.editor.typeahead("val","");c()})}function y(){o.items=[];t.model.value=[];c()}function p(n){var t,i;n.keyCode==13&&(t=o.editor.data("ttTypeahead"),t&&t.menu&&t.menu.isOpen()===!0&&(i=t.menu.getActiveSelectable()||t.menu.getTopSelectable(),t.menu.trigger("selectableClicked",i),n.preventDefault()))}function w(n,t){(n.keyCode===8||n.keyCode===46)&&l(t)}function l(n){if(s.confirmRemoval===!0)f.localizeMany(["contentment_removeItemMessage","general_remove","general_cancel","contentment_removeItemButton"]).then(t=>{e.open({title:t[1],content:t[0],closeButtonLabel:t[2],submitButtonLabel:t[3],submitButtonStyle:"danger",submit:function(){a(n);e.close()},close:function(){e.close()}})});else a(n)}function a(n){o.items.splice(n,1);t.model.value.splice(n,1);c()}function c(){t.propertyForm&&t.propertyForm.$setDirty()}var s=Object.assign({},{allowClear:0,confirmRemoval:0,defaultValue:[],items:[],showIcons:0},t.model.config),o=this;v()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.TemplatedList.Controller",["$scope",function(n){function u(){n.model.value=n.model.value||i.defaultValue;Array.isArray(n.model.value)===!1&&(n.model.value=[n.model.value]);t.multiple=Object.toBoolean(i.enableMultiple);t.multiple===!1&&n.model.value.length>0&&n.model.value.splice(1);t.items=[];i.items.forEach(i=>{var r=Object.assign({},i);r.selected=n.model.value.indexOf(r.value)>-1;t.items.push(r)});t.htmlAttributes=i.htmlAttributes;t.template=i.template;t.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias;t.select=e;n.umbProperty&&(t.propertyActions=[],Object.toBoolean(i.allowClear)===!0&&t.propertyActions.push({labelKey:"buttons_clearSelection",icon:"trash",method:f}),t.propertyActions.length>0&&n.umbProperty.setPropertyActions(t.propertyActions))}function f(){n.model.value=[];t.items.forEach(n=>n.selected=!1);r()}function e(i){i.selected=i.selected===!1;n.model.value=[];t.items.forEach(r=>{t.multiple===!1&&(r.selected=r.value===i.value),r.selected&&n.model.value.push(r.value)});r()}function r(){n.propertyForm&&n.propertyForm.$setDirty()}var i=Object.assign({},{allowClear:0,defaultValue:[],enableMultiple:0,items:[],template:"{{ item.name }}",htmlAttributes:[]},n.model.config),t=this;u()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.TextboxList.Controller",["$scope","Umbraco.Community.Contentment.Services.DevMode",function(n,t){function u(){n.model.value=n.model.value||{};Utilities.isObject(n.model.value)===!1&&(n.model.value={});i.keys=[];i.icons={};i.names={};i.inputTypes=["color","email","number","password","tel","text","url"];i.hideIcon=r.labelStyle==="text";i.hideName=r.labelStyle==="icon";i.defaultIcon=r.defaultIcon;r.items.forEach(t=>{i.keys.push(t.value),i.names[t.value]=t.name,i.hideIcon===!1&&(i.icons[t.value]=(t.icon||r.defaultIcon)+" medium"),n.model.value.hasOwnProperty(t.value)===!1&&(n.model.value[t.value]="")});Object.keys(n.model.value).forEach(t=>{i.keys.indexOf(t)===-1&&delete n.model.value[t]});i.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias;n.umbProperty&&(i.propertyActions=[],Object.toBoolean(r.enableDevMode)===!0&&i.propertyActions.push({labelKey:"contentment_editRawValue",icon:"brackets",method:()=>t.editValue(n.model,function(){})}),i.propertyActions.length>0&&n.umbProperty.setPropertyActions(i.propertyActions))}var r=Object.assign({},{defaultIcon:"icon-science",items:[],labelStyle:"both",enableDevMode:0},n.model.config),i=this;u()}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.DataEditors.TextInput.Controller",["$scope",function(n){function r(){n.model.value=n.model.value||i.defaultValue;Array.isArray(n.model.value)&&(n.model.value=n.model.value.join(", "));t.inputType=i.inputType;t.autoComplete=Object.toBoolean(i.autocomplete)?"on":"off";t.spellCheck=Object.toBoolean(i.spellcheck)?"true":"false";t.placeholderText=i.placeholderText;t.maxChars=parseInt(0+i.maxChars);t.maxCharsThreshold=t.maxChars*.8;t.prepend=i.prepend;t.append=i.append;t.uniqueId=n.model.hasOwnProperty("dataTypeKey")?[n.model.alias,n.model.dataTypeKey.substring(0,8)].join("-"):n.model.alias;i.items&&i.items.length>0&&(t.dataList=i.items,t.dataListId="dl-"+t.uniqueId)}var i=Object.assign({},{items:[],inputType:"text",autocomplete:0,placeholderText:null,defaultValue:null,prepend:null,append:null,maxChars:500},n.model.config),t=this;r()}]),function(){"use strict";function n(n){return{bindings:{addButtonLabel:"@?",addButtonLabelKey:"0&&r.umbProperty.setPropertyActions(r.propertyActions);r.blockActions&&Object.values(r.blockActions).forEach(n=>{n.forEach(n=>{i.localize(n.labelKey).then(t=>{n.label=t})})})}}],require:{propertyForm:"^form",umbProperty:"^"},template:"<\/ng-include>"}}angular.module("umbraco.directives").component("contentmentItemsEditor",n());angular.module("umbraco.directives").component("contentmentListEditor",n("list"));angular.module("umbraco.directives").component("contentmentStackEditor",n("stack"));angular.module("umbraco.directives").component("contentmentBlocksEditor",n("blocks"));angular.module("umbraco.directives").component("contentmentCardsEditor",n("cards"))}();angular.module("umbraco.services").factory("Umbraco.Community.Contentment.Services.DevMode",["$timeout","editorService",function(n,t){return{editValue:function(i,r){t.open({title:"Edit raw value",value:Utilities.toJson(i.value,!0),ace:{showGutter:!0,useWrapMode:!0,useSoftTabs:!0,theme:"chrome",mode:"javascript",advanced:{fontSize:"14px",wrap:!0},onLoad:function(t){n(()=>t.focus())}},view:"/App_Plugins/Contentment/editors/_json-editor.html",size:"medium",submit:function(n){i.value=Utilities.fromJson(n);r&&r();t.close()},close:function(){t.close()}})}}}]);angular.module("umbraco.directives").component("leeWasHere",{template:'Lee was here'});angular.module("umbraco.directives.html").directive("lkHtmlAttributes",[function(){return{restrict:"A",scope:{attributes:"&lkHtmlAttributes"},link:function(n,t){var i=n.attributes();Array.isArray(i)&&i.length>0&&i.forEach(n=>{n.name==="class"?t.addClass(n.value):t.attr(n.name,n.value)})}}}]);angular.module("umbraco.directives.html").directive("lkBindHtmlTemplate",["$compile",function(n){return{restrict:"A",replace:!0,link:function(t,i,r){t.$watch(function(n){return n.$eval(r.lkBindHtmlTemplate)},function(r){if(r){var u=n(r)(t);i.append(u)}})}}}]);angular.module("umbraco.directives.html").directive("lkHidePropertyGroup",[function(){return{restrict:"A",link:function(n,t,i){var u,f,r;if(i.lkHidePropertyGroup==="true"){if(u=t.closest(".umb-property-editor"),f=u.parent().closest(".umb-property-editor").length>0,f)return;r=t.closest(".umb-group-panel,.umb-box");r&&r.addClass("umb-group-panel--hide")}}}}]);angular.module("umbraco.filters").filter("lkNodeName",["$filter",function(n){return function(t){return Array.isArray(t)===!1?n("ncNodeName")(t):t.map(t=>n("ncNodeName")(t)).join(", ")}}]);angular.module("umbraco.filters").filter("lkGroupBy",[function(){return _.memoize((n,t)=>_.chain(n).sortBy(t).groupBy(t).value(),(n,t,i)=>[i,t,n.length].join("_"))}]);angular.module("umbraco").controller("Umbraco.Community.Contentment.Tree.Controller",["$scope","navigationService",function(n,t){function r(){const u="contentment";var r=Umbraco.Sys.ServerVariables.umbracoPlugins[u];i.title=r.name;i.version="v"+r.version;t.syncTree({tree:u,path:"-1"});n.$emit("$changeTitle",i.title);i.links=[{icon:"icon-fa fa-fw fa-book ",name:"Documentation",description:"How to use each of the property editors.",url:"https://github.com/leekelleher/umbraco-contentment/tree/master/docs"},{icon:"icon-fa fa-youtube",name:"Video demonstrations",description:"Demos, guides and tutorials on YouTube.",url:"https://www.youtube.com/playlist?list=PL8grlRt7-8oVULPYJpqido5QItRsJBt3M"},{icon:"icon-fa fa-fw fa-comments-o",name:"Support forum",description:"Ask for help, the community is your friend.",url:"https://our.umbraco.com/packages/backoffice-extensions/contentment/contentment-feedback/"},{icon:"icon-fa fa-fw fa-code-fork",name:"Source code",description:"See the code, all free and open-source.",url:"https://github.com/leekelleher/umbraco-contentment"},{icon:"icon-fa fa-fw fa-bug",name:"Issue tracker",description:"Found a bug? Suggest a feature? Let me know.",url:"https://github.com/leekelleher/umbraco-contentment/issues/new/choose"},{icon:"icon-fa fa-fw fa-id-card-o",name:"License",description:"Licensed under the Mozilla Public License.",url:"https://opensource.org/licenses/MPL-2.0"}];i.telemetryEnabled=r.telemetry===!0}var i=this;r()}]) \ No newline at end of file diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/_empty.html b/template/Clean.Blog/App_Plugins/Contentment/editors/_empty.html deleted file mode 100644 index 1bfa8275..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/_empty.html +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/_json-editor.html b/template/Clean.Blog/App_Plugins/Contentment/editors/_json-editor.html deleted file mode 100644 index 7054ff3a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/_json-editor.html +++ /dev/null @@ -1,35 +0,0 @@ -
- - - - - - - -
- -
- - - - - - - - - - -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/buttons.html b/template/Clean.Blog/App_Plugins/Contentment/editors/buttons.html deleted file mode 100644 index 3d366117..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/buttons.html +++ /dev/null @@ -1,12 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/cascading-dropdown-list.html b/template/Clean.Blog/App_Plugins/Contentment/editors/cascading-dropdown-list.html deleted file mode 100644 index 4066f9f0..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/cascading-dropdown-list.html +++ /dev/null @@ -1,19 +0,0 @@ -
- -
- -
- -
- - - -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/checkbox-list.html b/template/Clean.Blog/App_Plugins/Contentment/editors/checkbox-list.html deleted file mode 100644 index c8a6c499..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/checkbox-list.html +++ /dev/null @@ -1,40 +0,0 @@ -
-
    -
  • - -
  • -
-
    -
  • - -
  • -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/code-editor.html b/template/Clean.Blog/App_Plugins/Contentment/editors/code-editor.html deleted file mode 100644 index 362adee1..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/code-editor.html +++ /dev/null @@ -1,3 +0,0 @@ -
-
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.html b/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.html deleted file mode 100644 index 7b9d812a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.html +++ /dev/null @@ -1,15 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.inline.html b/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.inline.html deleted file mode 100644 index 564c547d..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.inline.html +++ /dev/null @@ -1,17 +0,0 @@ -
- - -

Unable to find the editor for this configuration value.

-
- - -

There are no fields for this item.

-
- - - - - - - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.overlay.html b/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.overlay.html deleted file mode 100644 index b9941f8d..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/configuration-editor.overlay.html +++ /dev/null @@ -1,105 +0,0 @@ -
- - - - - - - -
- - - - - - - -
-
-
    -
  • - -
  • -
-
- -
- No items found for ''. -
- -
-
- -
-
- -
-
-
- - -

There are no items available to add.

-
- -
- -
- - -

Unable to find the editor for this configuration value.

-
- - -

There are no fields for this item.

-
- - - - - - - - - - - -
- -
- - - - - - - - - - -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.blueprint.html b/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.blueprint.html deleted file mode 100644 index 5909eac6..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.blueprint.html +++ /dev/null @@ -1,20 +0,0 @@ -
- -

- -
- -
- - - - - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.html b/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.html deleted file mode 100644 index bc433c83..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.html +++ /dev/null @@ -1,18 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.overlay.html b/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.overlay.html deleted file mode 100644 index ef8dc6c0..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/content-blocks.overlay.html +++ /dev/null @@ -1,138 +0,0 @@ -
- - - -
-
-
- -
-
-
-
-
-
-
- - - - - - - - - - - - - - -
    -
  • - -
  • -
  • - No items found for ''. -
  • -
- -
    -
  • - -
  • -
  • - -
  • -
- -
-
- - - -
- - - -
-
- -
    -
  • - -
  • -
  • - No items found for ''. -
  • -
-
-
- - -

There are no items available to add.

-
- -
- - - - - - - - - - - - - - - - - -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/content-cards.html b/template/Clean.Blog/App_Plugins/Contentment/editors/content-cards.html deleted file mode 100644 index 2eaaf31a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/content-cards.html +++ /dev/null @@ -1,19 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/content-list.html b/template/Clean.Blog/App_Plugins/Contentment/editors/content-list.html deleted file mode 100644 index 2eaaf31a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/content-list.html +++ /dev/null @@ -1,19 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/content-source.html b/template/Clean.Blog/App_Plugins/Contentment/editors/content-source.html deleted file mode 100644 index 752d86db..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/content-source.html +++ /dev/null @@ -1,74 +0,0 @@ -
- -
- - - -
- -
- -
- - - - -
- -
- - - -
- - - - -
-

Use an XPath query to set a start page. For a context-aware query, you can use one of the pre-defined placeholders.

-

Placeholders find the nearest published content ID and run the XPath query from there. For instance:

-
$site/newsListingPage
-

This query will try to get the current website page (at level 1), then find the first page of type `newsListingPage`.

-
-
Available placeholders:
-
$current - current page or closest ancestor.
-
$parent - parent page or closest ancestor.
-
$root - root page in the content tree.
-
$site - ancestor page located at level 1.
-
-
-

Please note, when using an XPath query, this data source will not work if used within a 'Nested Content' element type. This is a known issue. Please see GitHub issue #30 for details.

-
-
-
- -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/content-stack.html b/template/Clean.Blog/App_Plugins/Contentment/editors/content-stack.html deleted file mode 100644 index 2eaaf31a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/content-stack.html +++ /dev/null @@ -1,19 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/data-list.editor.html b/template/Clean.Blog/App_Plugins/Contentment/editors/data-list.editor.html deleted file mode 100644 index 60671294..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/data-list.editor.html +++ /dev/null @@ -1,48 +0,0 @@ -
- -
- -
-
- - - -
- -
- -
-
- - -
-
- -
-
- -
- -
- -
-
- - - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/data-list.preview.html b/template/Clean.Blog/App_Plugins/Contentment/editors/data-list.preview.html deleted file mode 100644 index 8ffb59e0..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/data-list.preview.html +++ /dev/null @@ -1,66 +0,0 @@ -
-
-
- Please select and configure a data source and list editor. -
-
- Please select and configure a list editor. -
-
- Please select and configure a data source. -
-
- -
-
- The data source returned no items to preview. -
-
- -
-
- There are items avaliable in this data source. -

To avoid an unpleasant editor experience or lagging browser performance, please consider trying the Data Picker property editor, as it has been designed with improved performance in mind, with support for search querying and pagination.

-
-
- - - - -
-
- -
-
-
-
-
-
-
Name
-
Value
-
Description
-
Enabled
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{vm.property.config.items | json}} -
-
-
-
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/data-picker.html b/template/Clean.Blog/App_Plugins/Contentment/editors/data-picker.html deleted file mode 100644 index 900b4b67..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/data-picker.html +++ /dev/null @@ -1,17 +0,0 @@ -
- - - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/data-picker.overlay.html b/template/Clean.Blog/App_Plugins/Contentment/editors/data-picker.overlay.html deleted file mode 100644 index cfae248c..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/data-picker.overlay.html +++ /dev/null @@ -1,101 +0,0 @@ -
- - - - - - - -
- -
- - - -
-
-
-
- -
-
-
-
-
-
-
-
-
- - - -
    -
  • - -
  • -
-
-
- -
- - -
- - - Sorry, we can not find what you are looking for. - - -
- - - - - - - - - - -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/data-source.preview.html b/template/Clean.Blog/App_Plugins/Contentment/editors/data-source.preview.html deleted file mode 100644 index cb81748c..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/data-source.preview.html +++ /dev/null @@ -1,50 +0,0 @@ -
-
-
- Please select and configure a data source. -
-
- -
-
- The data source returned no items to preview. -
-
- - - - -
-
-
-
-
-
-
Name
-
Value
-
Description
-
Enabled
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {{vm.items | json}} -
-
-
-
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/data-table.html b/template/Clean.Blog/App_Plugins/Contentment/editors/data-table.html deleted file mode 100644 index 2aee6b5a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/data-table.html +++ /dev/null @@ -1,41 +0,0 @@ -
- - - - - - - - - - - - - - - -
{{heading}}
- - - - -
- - - -
-
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/dictionary-picker.html b/template/Clean.Blog/App_Plugins/Contentment/editors/dictionary-picker.html deleted file mode 100644 index 35a8e445..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/dictionary-picker.html +++ /dev/null @@ -1,14 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/dropdown-list.html b/template/Clean.Blog/App_Plugins/Contentment/editors/dropdown-list.html deleted file mode 100644 index 1a904a59..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/dropdown-list.html +++ /dev/null @@ -1,10 +0,0 @@ -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/editor-notes.html b/template/Clean.Blog/App_Plugins/Contentment/editors/editor-notes.html deleted file mode 100644 index 1a60c9b1..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/editor-notes.html +++ /dev/null @@ -1,7 +0,0 @@ -
- -
-
-
-
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/icon-picker.html b/template/Clean.Blog/App_Plugins/Contentment/editors/icon-picker.html deleted file mode 100644 index f66b4244..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/icon-picker.html +++ /dev/null @@ -1,31 +0,0 @@ -
-
-
-
    -
  • - - -
    - - -
    -
  • -
  • - -
  • -
-
-
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/item-picker.html b/template/Clean.Blog/App_Plugins/Contentment/editors/item-picker.html deleted file mode 100644 index c193c72f..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/item-picker.html +++ /dev/null @@ -1,15 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/item-picker.overlay.html b/template/Clean.Blog/App_Plugins/Contentment/editors/item-picker.overlay.html deleted file mode 100644 index 86642bca..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/item-picker.overlay.html +++ /dev/null @@ -1,119 +0,0 @@ -
- - - - - - - -
- -
- -
- Too many items selected, please unselect {{vm.itemCount - vm.maxItems}} {{vm.itemCount - vm.maxItems === 1 ? 'item' : 'items'}}. -
- -
-
-
-
- -
-
-
-
-
-
-
-
-
- No items found for ''. -
-
- - - -
    -
  • - -
  • -
  • - No items found for ''. -
  • -
-
-
- - - -
    -
  • - -
  • -
  • - No items found for ''. -
  • -
-
-
- - -

There are no items available to add.

-
- -
- - - - - - - - - - -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/macro-picker.html b/template/Clean.Blog/App_Plugins/Contentment/editors/macro-picker.html deleted file mode 100644 index fd2baf80..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/macro-picker.html +++ /dev/null @@ -1,15 +0,0 @@ -
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/notes.html b/template/Clean.Blog/App_Plugins/Contentment/editors/notes.html deleted file mode 100644 index db668139..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/notes.html +++ /dev/null @@ -1 +0,0 @@ -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/number-input.html b/template/Clean.Blog/App_Plugins/Contentment/editors/number-input.html deleted file mode 100644 index e1168b6a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/number-input.html +++ /dev/null @@ -1,13 +0,0 @@ -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/radio-button-list.html b/template/Clean.Blog/App_Plugins/Contentment/editors/radio-button-list.html deleted file mode 100644 index a57f16a4..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/radio-button-list.html +++ /dev/null @@ -1,21 +0,0 @@ -
-
    -
  • - -
  • -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/readonly-node-preview.html b/template/Clean.Blog/App_Plugins/Contentment/editors/readonly-node-preview.html deleted file mode 100644 index 6eb7c632..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/readonly-node-preview.html +++ /dev/null @@ -1,3 +0,0 @@ -
- -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/render-macro.html b/template/Clean.Blog/App_Plugins/Contentment/editors/render-macro.html deleted file mode 100644 index 40b92fb6..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/render-macro.html +++ /dev/null @@ -1,11 +0,0 @@ -
-
- -
-
-
-
-
-

-

-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/social-links.html b/template/Clean.Blog/App_Plugins/Contentment/editors/social-links.html deleted file mode 100644 index 4a89607b..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/social-links.html +++ /dev/null @@ -1,42 +0,0 @@ -
-
-
- - - -
- -
- -
-
- -
-
- -
-
- -
- -
- -
-
- - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/social-links.overlay.html b/template/Clean.Blog/App_Plugins/Contentment/editors/social-links.overlay.html deleted file mode 100644 index 1ae57d8d..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/social-links.overlay.html +++ /dev/null @@ -1,15 +0,0 @@ -
-
    -
  • - -
  • -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/tags.html b/template/Clean.Blog/App_Plugins/Contentment/editors/tags.html deleted file mode 100644 index 0db8bfb5..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/tags.html +++ /dev/null @@ -1,26 +0,0 @@ -
-
- -
- - - - - - -
-
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/templated-list.html b/template/Clean.Blog/App_Plugins/Contentment/editors/templated-list.html deleted file mode 100644 index 389216c3..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/templated-list.html +++ /dev/null @@ -1,12 +0,0 @@ -
-
- -
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/text-input.html b/template/Clean.Blog/App_Plugins/Contentment/editors/text-input.html deleted file mode 100644 index a9b31783..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/text-input.html +++ /dev/null @@ -1,36 +0,0 @@ -
-
- - - - - - - -
-
-

- {{model.label}} - %0% characters left. -

-
-
-

- {{model.label}} - Maximum %0% characters, %1% too many. -

-
- - - -
diff --git a/template/Clean.Blog/App_Plugins/Contentment/editors/textbox-list.html b/template/Clean.Blog/App_Plugins/Contentment/editors/textbox-list.html deleted file mode 100644 index f251071a..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/editors/textbox-list.html +++ /dev/null @@ -1,22 +0,0 @@ -
-
- -
- -
-
-
diff --git a/template/Clean.Blog/App_Plugins/Contentment/package.manifest b/template/Clean.Blog/App_Plugins/Contentment/package.manifest deleted file mode 100644 index a0c0cb6f..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/package.manifest +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "Contentment", - "id": "Umbraco.Community.Contentment", - "version": "4.5.1", - "css": [ "~/App_Plugins/Contentment/contentment.css" ], - "javascript": [ "~/App_Plugins/Contentment/contentment.js" ] -} diff --git a/template/Clean.Blog/App_Plugins/Contentment/render/ContentBlockPreview.cshtml b/template/Clean.Blog/App_Plugins/Contentment/render/ContentBlockPreview.cshtml deleted file mode 100644 index 5280753b..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/render/ContentBlockPreview.cshtml +++ /dev/null @@ -1,10 +0,0 @@ -@* Copyright © 2019 Lee Kelleher. - * This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this - * file, You can obtain one at https://mozilla.org/MPL/2.0/. *@ -@inherits ContentBlockPreviewView -
- -
@Model.Element.Key
-
- diff --git a/template/Clean.Blog/App_Plugins/Contentment/render/_ViewImports.cshtml b/template/Clean.Blog/App_Plugins/Contentment/render/_ViewImports.cshtml deleted file mode 100644 index bc71ce9b..00000000 --- a/template/Clean.Blog/App_Plugins/Contentment/render/_ViewImports.cshtml +++ /dev/null @@ -1 +0,0 @@ -@using Umbraco.Cms.Web.Common.Views; diff --git a/template/Clean.Blog/Clean.Blog.csproj b/template/Clean.Blog/Clean.Blog.csproj index 8a94821d..2027a32a 100644 --- a/template/Clean.Blog/Clean.Blog.csproj +++ b/template/Clean.Blog/Clean.Blog.csproj @@ -7,13 +7,12 @@ - - - + + + - diff --git a/template/Clean.Blog/Composing/ApiClientSetup.cs b/template/Clean.Blog/Composing/ApiClientSetup.cs new file mode 100644 index 00000000..51057fda --- /dev/null +++ b/template/Clean.Blog/Composing/ApiClientSetup.cs @@ -0,0 +1,102 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Umbraco.Cms.Core; +using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Membership; +using Umbraco.Cms.Core.Services; +using Umbraco.Cms.Core.Services.OperationStatus; +using Umbraco.Cms.Infrastructure.Security; + +namespace Clean.Blog.Composing; + +// Provisions the backoffice API client used by CreateNuGetPackages.ps1 to export +// the package via the management API. This replaces uSync.Command.Setup, which has +// no Umbraco 18 release; content/schema sync itself is handled by uSync. +internal static class ApiClientSetup +{ + public static async Task EnsureAsync(IServiceProvider rootServices, CancellationToken ct = default) + { + using var scope = rootServices.CreateScope(); + var sp = scope.ServiceProvider; + var configuration = sp.GetRequiredService(); + var logger = sp.GetRequiredService>(); + + try + { + if (configuration.GetValue("uSync:Command:AddIfMissing", false) is false) + { + return; + } + + var clientId = configuration.GetValue("uSync:Command:ClientId", string.Empty); + var clientSecret = configuration.GetValue("uSync:Command:Secret", string.Empty); + if (string.IsNullOrWhiteSpace(clientId) || string.IsNullOrWhiteSpace(clientSecret)) + { + logger.LogWarning("Clean.Blog API client setup is enabled but ClientId or Secret is missing from configuration"); + return; + } + + var userService = sp.GetRequiredService(); + if (await userService.FindByClientIdAsync(clientId) is not null) + { + return; + } + + var fallbackEmail = $"{Path.GetFileNameWithoutExtension(Path.GetRandomFileName())}@example.com"; + var userGroupKeys = new HashSet + { + configuration.GetValue("uSync:Command:UserGroupKey", Constants.Security.AdminGroupKey), + }; + + var createAttempt = await userService.CreateAsync( + Constants.Security.SuperUserKey, + new UserCreateModel + { + Email = configuration.GetValue("uSync:Command:Email", fallbackEmail), + UserName = configuration.GetValue("uSync:Command:Username", fallbackEmail), + Kind = UserKind.Api, + Name = configuration.GetValue("uSync:Command:Name", "Clean API User"), + UserGroupKeys = userGroupKeys, + }, + approveUser: false); + + if (createAttempt.Success is false) + { + logger.LogWarning("Could not create the API user: {status}", createAttempt.Status); + return; + } + + var userKey = createAttempt.Result.CreatedUser?.Key; + if (userKey.HasValue is false) + { + logger.LogWarning("Could not create the API user: no key returned"); + return; + } + + var addClientIdStatus = await userService.AddClientIdAsync(userKey.Value, clientId); + if (addClientIdStatus != UserClientCredentialsOperationStatus.Success) + { + logger.LogWarning("Could not attach client id to user: {status}", addClientIdStatus); + return; + } + + var applicationManager = sp.GetService(); + if (applicationManager is null) + { + logger.LogWarning("IBackOfficeApplicationManager is not available; OpenIddict client not registered"); + return; + } + + await applicationManager.EnsureBackOfficeClientCredentialsApplicationAsync(clientId, clientSecret, ct); + await userService.EnableAsync(userKey.Value, new HashSet { userKey.Value }); + + logger.LogInformation("Provisioned API client '{clientId}' for Clean.Blog", clientId); + } + catch (Exception ex) + { + logger.LogError(ex, "Error provisioning the Clean.Blog API client"); + } + } + + private sealed class ApiClientSetupMarker { } +} diff --git a/template/Clean.Blog/Middleware/SecurityHeadersMiddleware.cs b/template/Clean.Blog/Middleware/SecurityHeadersMiddleware.cs index 199dacf4..cbf66220 100644 --- a/template/Clean.Blog/Middleware/SecurityHeadersMiddleware.cs +++ b/template/Clean.Blog/Middleware/SecurityHeadersMiddleware.cs @@ -16,14 +16,15 @@ public class SecurityHeadersMiddleware // Default CSP policy suitable for Umbraco CMS private const string DefaultCspPolicy = "default-src 'self'; " + - "script-src 'self' 'unsafe-inline' 'unsafe-eval'; " + - "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; " + - "font-src 'self' data: https://fonts.gstatic.com; " + + "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://use.fontawesome.com; " + + "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com; " + + "font-src 'self' data: https://cdn.jsdelivr.net https://fonts.gstatic.com; " + "img-src 'self' data: https:; " + - "connect-src 'self'; " + + "connect-src 'self' https://cdn.jsdelivr.net;" + "frame-ancestors 'self'; " + "base-uri 'self'; " + - "form-action 'self'"; + "form-action 'self'; " + + "frame-src https://www.youtube.com;"; public SecurityHeadersMiddleware(RequestDelegate next, IConfiguration configuration) { diff --git a/template/Clean.Blog/Program.cs b/template/Clean.Blog/Program.cs index dc749b7f..2002b7a7 100644 --- a/template/Clean.Blog/Program.cs +++ b/template/Clean.Blog/Program.cs @@ -1,3 +1,4 @@ +using Clean.Blog.Composing; using Clean.Blog.Middleware; WebApplicationBuilder builder = WebApplication.CreateBuilder(args); @@ -12,6 +13,10 @@ await app.BootUmbracoAsync(); +// Provision the backoffice API client before the Kestrel listener accepts +// requests, so CreateNuGetPackages.ps1's first /token call doesn't race startup. +await ApiClientSetup.EnsureAsync(app.Services); + // Add security headers middleware app.UseMiddleware(); diff --git a/template/Clean.Blog/Views/Author.cshtml b/template/Clean.Blog/Views/Author.cshtml index 41b2777c..cd73db54 100644 --- a/template/Clean.Blog/Views/Author.cshtml +++ b/template/Clean.Blog/Views/Author.cshtml @@ -5,7 +5,7 @@ @{ Layout = "master.cshtml"; - var authorListPage = Model.Parent as AuthorList; + var authorListPage = Model.Parent() as AuthorList; } diff --git a/template/Clean.Blog/Views/Partials/blockgrid/items.cshtml b/template/Clean.Blog/Views/Partials/blockgrid/items.cshtml index 2703fa57..677c9aae 100644 --- a/template/Clean.Blog/Views/Partials/blockgrid/items.cshtml +++ b/template/Clean.Blog/Views/Partials/blockgrid/items.cshtml @@ -12,7 +12,7 @@ class="umb-block-grid__layout-item" data-content-element-type-alias="@item.Content.ContentType.Alias" data-content-element-type-key="@item.Content.ContentType.Key" - data-element-udi="@item.ContentUdi" + data-element-key="@item.ContentKey" data-col-span="@item.ColumnSpan" data-row-span="@item.RowSpan" style=" --umb-block-grid--item-column-span: @item.ColumnSpan; --umb-block-grid--item-row-span: @item.RowSpan; "> diff --git a/template/Clean.Blog/Views/Partials/blocklist/Components/richTextRow.cshtml b/template/Clean.Blog/Views/Partials/blocklist/Components/richTextRow.cshtml index c8945582..e8ee09ad 100644 --- a/template/Clean.Blog/Views/Partials/blocklist/Components/richTextRow.cshtml +++ b/template/Clean.Blog/Views/Partials/blocklist/Components/richTextRow.cshtml @@ -14,5 +14,5 @@ }
- @row.Content + @row.RichContent
\ No newline at end of file diff --git a/template/Clean.Blog/Views/Partials/blocklist/default.cshtml b/template/Clean.Blog/Views/Partials/blocklist/default.cshtml index 065b16b7..bbffe989 100644 --- a/template/Clean.Blog/Views/Partials/blocklist/default.cshtml +++ b/template/Clean.Blog/Views/Partials/blocklist/default.cshtml @@ -5,7 +5,7 @@ @foreach (var block in Model) { - if (block?.ContentUdi == null) { continue; } + if (block?.Content == null) { continue; } var data = block.Content; @await Html.PartialAsync("blocklist/Components/" + data.ContentType.Alias, block) diff --git a/template/Clean.Blog/Views/Partials/grid/editors/macro.cshtml b/template/Clean.Blog/Views/Partials/grid/editors/macro.cshtml index a4450d1c..a783259f 100644 --- a/template/Clean.Blog/Views/Partials/grid/editors/macro.cshtml +++ b/template/Clean.Blog/Views/Partials/grid/editors/macro.cshtml @@ -1,15 +1,5 @@ @inherits Umbraco.Cms.Web.Common.Views.UmbracoViewPage - -@if (Model?.value is not null) -{ - string macroAlias = Model.value.macroAlias.ToString(); - var parameters = new Dictionary(); - foreach (var mpd in Model.value.macroParamsDictionary) - { - parameters.Add(mpd.Name, mpd.Value); - } - - - @await Umbraco.RenderMacroAsync(macroAlias, parameters) - -} +@* + Macros were removed in Umbraco 14+. The legacy grid macro editor is no longer + supported. Migrate macro grid content to the Block Grid or Block List editors. +*@ diff --git a/template/Clean.Blog/Views/Partials/mainNavigation.cshtml b/template/Clean.Blog/Views/Partials/mainNavigation.cshtml index 5b216009..8a2df05b 100644 --- a/template/Clean.Blog/Views/Partials/mainNavigation.cshtml +++ b/template/Clean.Blog/Views/Partials/mainNavigation.cshtml @@ -18,7 +18,7 @@ - @foreach (var page in homePage.Children.Where(x => !x.Value("hideFromTopNavigation"))) + @foreach (var page in homePage.Children().Where(x => !x.Value("hideFromTopNavigation"))) {