Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/dotnet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v2
with:
dotnet-version: 6.0.x
dotnet-version: 10.0.x
- name: Restore dependencies
run: dotnet restore src/Stott.Optimizely.RobotsHandler.sln
- name: Build
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
MIT License

Copyright (c) 2025 Mark Stott
Copyright (c) 2026 Mark Stott

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
2 changes: 1 addition & 1 deletion Opal/Discovery.http
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
###

# Variables - Change these as needed
@baseUrl = https://localhost:44344
@baseUrl = https://localhost:5000
@apiPath = /stott.robotshandler/opal

# Test 1: Basic Discovery API call (IIS Express)
Expand Down
10 changes: 5 additions & 5 deletions Opal/Llms.http
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@
###

# Variables - Change these as needed
@baseUrl = https://localhost:44344
@baseUrl = https://localhost:5000
@apiPath = /stott.robotshandler/opal
@token = put-bearer-token-here
@testHostName = localhost:44344
@token = X7hMZuo3idXCkgElP4iHrIdNnyY5WYNz
@testHostName = localhost:5000

# For production testing, uncomment these instead:
# @baseUrl = https://test-cms.stott.pro
Expand Down Expand Up @@ -50,7 +50,7 @@ Authorization: Bearer {{token}}

{
"parameters": {
"hostName": "example.com"
"hostName": "www.example.com"
}
}

Expand Down Expand Up @@ -78,7 +78,7 @@ Authorization: Bearer {{token}}

{
"parameters": {
"llmsId": "d994532b-02df-42dd-93ef-18bee7c3346f",
"llmsId": "1b0349f2-c352-4d9f-b7d3-285389d02c53",
"llmsTxtContent": "# LLMS.TXT\n\n# Model Information\nmodel-name: GPT-4\nmodel-version: 2024-03\ntraining-data-cutoff: 2023-04\n\n# Usage Guidelines\nallowed-uses: content-generation, code-assistance, research\nrestricted-uses: personal-data-processing, medical-diagnosis\n\n# Contact Information\ncontact: ai-team@example.com\nwebsite: https://example.com/ai-policy"
}
}
Expand Down
10 changes: 5 additions & 5 deletions Opal/Robots.http
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
###

# Variables - Change these as needed
@baseUrl = https://localhost:44344
@baseUrl = https://localhost:5000
@apiPath = /stott.robotshandler/opal
@token = put-bearer-token-here
@testHostNameOne = localhost:44344
@testHostNameTwo = localhost:44347
@token = X7hMZuo3idXCkgElP4iHrIdNnyY5WYNzq
@testHostNameOne = localhost:5000
@testHostNameTwo = localhost:5002

# For production testing, uncomment these instead:
# @baseUrl = https://test-cms.stott.pro
Expand Down Expand Up @@ -78,7 +78,7 @@ Authorization: Bearer {{token}}

{
"parameters": {
"robotsId": "3cd8ebcd-3733-4774-8c67-8bd28b440ca7",
"robotsId": "1a1543cd-78ce-4b38-9ae1-c63a4ff5c60e",
"robotsTxtContent": "User-agent: *\nDisallow: /admin/\nDisallow: /private/\n\nSitemap: https://example.com/sitemap.xml"
}
}
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# Stott.Optimizely.RobotsHandler

[![Platform](https://img.shields.io/badge/Platform-.NET%206-blue.svg?style=flat)](https://docs.microsoft.com/en-us/dotnet/)
[![Platform](https://img.shields.io/badge/Optimizely-%2012-blue.svg?style=flat)](http://world.episerver.com/cms/)
[![Platform](https://img.shields.io/badge/Optimizely-%2012%2C13-blue.svg?style=flat)](http://world.episerver.com/cms/)
[![GitHub](https://img.shields.io/github/license/GeekInTheNorth/Stott.Optimizely.RobotsHandler)](https://github.com/GeekInTheNorth/Stott.Optimizely.RobotsHandler/blob/main/LICENSE.txt)
![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/GeekInTheNorth/Stott.Optimizely.RobotsHandler/dotnet.yml?branch=main)
![Nuget](https://img.shields.io/nuget/v/Stott.Optimizely.RobotsHandler)

This is an admin extension for Optimizely CMS 12+ for managing robots content. Stott Robots Handler is a free to use module, however if you want to show your support, buy me a coffee on ko-fi:
This is an admin extension for Optimizely CMS 12 & 13 for managing robots content. Stott Robots Handler is a free to use module, however if you want to show your support, buy me a coffee on ko-fi:

[![ko-fi](https://ko-fi.com/img/githubbutton_sm.svg)](https://ko-fi.com/V7V0RX2BQ)

Expand Down
11 changes: 9 additions & 2 deletions Sample/OptimizelyTwelveTest.sln
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.10.34928.147
# Visual Studio Version 18
VisualStudioVersion = 18.3.11512.155 d18.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OptimizelyTwelveTest", "OptimizelyTwelveTest\OptimizelyTwelveTest.csproj", "{5D9A020E-AE86-4902-AC8C-94C3A24297BF}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stott.Optimizely.RobotsHandler", "..\src\Stott.Optimizely.RobotsHandler\Stott.Optimizely.RobotsHandler.csproj", "{696A0DB5-92CA-4992-AA55-3C2F570888C2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Stott.Optimizely.RobotsHandler.Test", "..\src\Stott.Optimizely.RobotsHandler.Test\Stott.Optimizely.RobotsHandler.Test.csproj", "{D7D6E33E-542E-46E1-B0C6-BFC4210E47D1}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "OpalTests", "OpalTests", "{B229F2B1-7980-41EE-816E-59813F665803}"
ProjectSection(SolutionItems) = preProject
..\Opal\Discovery.http = ..\Opal\Discovery.http
..\Opal\Llms.http = ..\Opal\Llms.http
..\Opal\Robots.http = ..\Opal\Robots.http
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
using System;
using System.Globalization;
using System.Linq;

using EPiServer;
using EPiServer.Applications;
using EPiServer.Core;
using EPiServer.DataAbstraction.Migration;
using EPiServer.DataAccess;
using EPiServer.Security;
using EPiServer.ServiceLocation;

using OptimizelyTwelveTest.Features.Home;
using OptimizelyTwelveTest.Features.Settings;

namespace OptimizelyTwelveTest.Features.Configuration
{
public class SetupMigrationStep : MigrationStep
{
public override void AddChanges()
{
try
{
var appRepository = ServiceLocator.Current.GetInstance<IApplicationRepository>();
if (!ConfigurationExists(appRepository))
{
var contentRepository = ServiceLocator.Current.GetInstance<IContentRepository>();
SetUpSystem(appRepository, contentRepository, 1, 5000, 5001);
SetUpSystem(appRepository, contentRepository, 2, 5002, 5003);
SetUpHeadlessSystem(appRepository, contentRepository, 3, 5004, 5005);
}
}
catch (Exception ex)
{
Console.WriteLine($"Error encountered during initial configuration: {ex.Message}");
}
}

private static bool ConfigurationExists(IApplicationRepository appRepository)
{
var sites = appRepository.List();
return sites.Any();
}

private static void SetUpSystem(IApplicationRepository appRepository, IContentRepository contentRepository, int siteNumber, int primaryPort, int cmsPort)
{
var culture = new CultureInfo("en");

// Create HomePage
var newHomePage = contentRepository.GetDefault<HomePage>(ContentReference.RootPage, culture);
newHomePage.Name = $"Home {siteNumber}";
newHomePage.Heading = $"Home {siteNumber}";
newHomePage.MetaTitle = $"Home {siteNumber}";

var homePageReference = contentRepository.Save(newHomePage, SaveAction.Publish, AccessLevel.NoAccess);

// Create SiteSettings
var newSiteSettings = contentRepository.GetDefault<SiteSettingsPage>(homePageReference, culture);
newSiteSettings.Name = $"[Site Settings {siteNumber}]";
newSiteSettings.SiteName = $"Site {siteNumber}";

var siteSettingsReference = contentRepository.Save(newSiteSettings, SaveAction.Publish, AccessLevel.NoAccess);

// Update Home Page
var existingHomePage = contentRepository.Get<HomePage>(homePageReference, culture);
var editableHomePage = existingHomePage.CreateWritableClone() as HomePage;
editableHomePage.SiteSettings = siteSettingsReference.ToReferenceWithoutVersion();

homePageReference = contentRepository.Save(editableHomePage, SaveAction.Publish, AccessLevel.NoAccess);

// Create Site
var newSite = new InProcessWebsite($"TestWebsite{siteNumber}", homePageReference.ToReferenceWithoutVersion())
{
DisplayName = $"Test Website {siteNumber}"
};

newSite.Hosts.Add(new ApplicationHost($"localhost:{primaryPort}")
{
PreferredUrlScheme = UrlScheme.Https,
Type = ApplicationHostType.Primary
});

newSite.Hosts.Add(new ApplicationHost($"localhost:{cmsPort}")
{
PreferredUrlScheme = UrlScheme.Https,
Type = ApplicationHostType.Edit
});

appRepository.SaveAsync(newSite).GetAwaiter().GetResult();
}

private static void SetUpHeadlessSystem(IApplicationRepository appRepository, IContentRepository contentRepository, int siteNumber, int primaryPort, int previewPort)
{
var culture = new CultureInfo("en");

// Create HomePage
var newHomePage = contentRepository.GetDefault<HomePage>(ContentReference.RootPage, culture);
newHomePage.Name = $"Home {siteNumber}";
newHomePage.Heading = $"Home {siteNumber}";
newHomePage.MetaTitle = $"Home {siteNumber}";

var homePageReference = contentRepository.Save(newHomePage, SaveAction.Publish, AccessLevel.NoAccess);

// Create SiteSettings
var newSiteSettings = contentRepository.GetDefault<SiteSettingsPage>(homePageReference, culture);
newSiteSettings.Name = $"[Site Settings {siteNumber}]";
newSiteSettings.SiteName = $"Site {siteNumber}";

var siteSettingsReference = contentRepository.Save(newSiteSettings, SaveAction.Publish, AccessLevel.NoAccess);

// Update Home Page
var existingHomePage = contentRepository.Get<HomePage>(homePageReference, culture);
var editableHomePage = existingHomePage.CreateWritableClone() as HomePage;
editableHomePage.SiteSettings = siteSettingsReference.ToReferenceWithoutVersion();

homePageReference = contentRepository.Save(editableHomePage, SaveAction.Publish, AccessLevel.NoAccess);

// Create Site
var newSite = new Website($"TestWebsite{siteNumber}", homePageReference.ToReferenceWithoutVersion())
{
DisplayName = $"Test Website {siteNumber}"
};

newSite.Hosts.Add(new ApplicationHost($"localhost:{primaryPort}")
{
PreferredUrlScheme = UrlScheme.Https,
Type = ApplicationHostType.Primary
});

newSite.Hosts.Add(new ApplicationHost($"localhost:{previewPort}")
{
PreferredUrlScheme = UrlScheme.Https,
Type = ApplicationHostType.Preview
});

appRepository.SaveAsync(newSite).GetAwaiter().GetResult();
}
}
}
35 changes: 9 additions & 26 deletions Sample/OptimizelyTwelveTest/Features/Home/HomePageController.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,17 @@
namespace OptimizelyTwelveTest.Features.Home
{
using System.Threading.Tasks;
namespace OptimizelyTwelveTest.Features.Home;

using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

using OptimizelyTwelveTest.Features.Common;
using Microsoft.AspNetCore.Mvc;

using Stott.Security.Optimizely.Features.Csp.Settings.Service;
using OptimizelyTwelveTest.Features.Common;

public class HomePageController : PageControllerBase<HomePage>
public class HomePageController : PageControllerBase<HomePage>
{
public async Task<IActionResult> Index(HomePage currentPage)
{
private readonly ICspSettingsService _cspSettingsService;

public HomePageController(ICspSettingsService cspSettingsService)
{
_cspSettingsService = cspSettingsService;
}

public async Task<IActionResult> Index(HomePage currentPage, bool resetReportMode)
{
var model = new HomePageViewModel { CurrentPage = currentPage };

if (resetReportMode)
{
var currentSettings = await _cspSettingsService.GetAsync();
currentSettings.IsReportOnly = true;
await _cspSettingsService.SaveAsync(currentSettings, "Mark Stott");
}
var model = new HomePageViewModel { CurrentPage = currentPage };

return View(model);
}
return View(model);
}
}
67 changes: 0 additions & 67 deletions Sample/OptimizelyTwelveTest/Features/Search/SearchPage.cs

This file was deleted.

Loading
Loading