Giangnb.Optimizely.Plugin.TrimContentVersionPlugin 1.0.0.1

dotnet add package Giangnb.Optimizely.Plugin.TrimContentVersionPlugin --version 1.0.0.1
                    
NuGet\Install-Package Giangnb.Optimizely.Plugin.TrimContentVersionPlugin -Version 1.0.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Giangnb.Optimizely.Plugin.TrimContentVersionPlugin" Version="1.0.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Giangnb.Optimizely.Plugin.TrimContentVersionPlugin" Version="1.0.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Giangnb.Optimizely.Plugin.TrimContentVersionPlugin" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Giangnb.Optimizely.Plugin.TrimContentVersionPlugin --version 1.0.0.1
                    
#r "nuget: Giangnb.Optimizely.Plugin.TrimContentVersionPlugin, 1.0.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Giangnb.Optimizely.Plugin.TrimContentVersionPlugin@1.0.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Giangnb.Optimizely.Plugin.TrimContentVersionPlugin&version=1.0.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Giangnb.Optimizely.Plugin.TrimContentVersionPlugin&version=1.0.0.1
                    
Install as a Cake Tool

Trim Content Version

An Optimizely CMS plugin

The repository proposes a plugin or a scheduled job to clean up excessive content versions.

Static Badge Static Badge


⚠ Important

Before continuing, please be advised that: This is not Optimizely's official plugin. Do back up your database before using and use for production purposes at your own risk!

Acceptable usage:

  • Local/Dev/Staging environments,
  • Database is backed up regularly and is ready to revert at any time if needed,
  • Slowness, performance issues, data loss, anddown time are tolerated.

Considerations when using this for Production purposes:

  • Problem factor: The issue is carefully examined, and there is no better solution to clean up excessive versions.
  • Acceptance: The plugin has been tested at Dev, Integration and Preproduction/Staging environments, and the result is acceptable.
  • Database: Database is backed up (both full and incremental backup) and is scaled up to execute resource-intensive tasks.
  • Web app: (1) Do not enable the plugin's scheduled job; (2) Configure the plugin carefully; (3) Choose a suitable execution time to minimize the impacts.
  • Recover plan: The plugin won't do anything if all task configurations are disabled. If the web app is inaccessible, the plugin can be disabled by setting the environment variable TrimContentVersionPlugin__Enabled = false

Table of contents

  1. Background
  2. Comparison
  3. Installation guide
  4. How to use

Background

Because of the flexibility of Optimizely CMS and Commerce PaaS, developers can update contents programmatically or periodically. This results in a huge amount of content versions and content activity logs retained in the database. This data is usually not useful and significantly increases the storage costs.

Comparison

Feature Built-in Trim Content Version job Trim Content Version plugin
Commerce contents
Custom ContentProvider ✅ (Needs a custom JobExecutor)
Custom content sources (EF, custom tables) ✅ (Needs a custom JobExecutor)
Select the parent content node
Select the language to process
Clean up old Draft versions
Select content types to process
Configurable SQL execution timeout ❌ (Only in connection string config)
Performance-wise controls
Rebuild SQL indexes ✅ (Configurable)

Installation guide

  1. Install NuGet package
  2. Configure service dependencies:
    services.AddTrimContentVersionPlugin(IConfiguration);
  3. Configure request pipeline:
    app.UseTrimContentVersionPlugin(IConfiguration); (Add after UseAuthorization and UseAuthentication extension methods)

How to use

  1. In the CMS Settings (Admin), find the section Trim Content Versions,
  2. Under the tab Tasks configurations, tasks are listed on the left column,
  3. Add or edit tasks by filling out the form and clicking the "Save" button to make changes,
  4. Under the tab Scheduled job, there are detailed logs for each task. One execution of the CMS Scheduled job can execute multiple tasks.

Programmability

  • JobExecutor Abstract class to define a custom executor. SQL output logs can be accessed using JobExecutor.OutputMessage.
  • IJobExecutorRegistry Registers and initializes custom-named JobExecutor objects.
  • IJobConfigurationRepository Manages JobConfiguration items, a relay layer of CMS DDS.
  • TrimContentVersionPluginOptions Singleton object with Options pattern. This can be used as a utility service to quickly access CMS and Commerce SQL connection strings.

Options pattern TrimContentVersionPluginOptions

The class TrimContentVersionPluginOptions follows ASP.NET Options Pattern at rest. It is accessible as a singleton or using IOptions<T>.

Options class can be configured in appsettings.json:

    "TrimContentVersionPlugin": {
        "Enabled": true,
        "BatchSize": 1000
    }

or in code services.PostConfigure<TrimContentVersionPluginOptions>(o => o.BatchSize = 1000);,
or with environment variable (such as Azure App Service configurations) TrimContentVersionPlugin__BatchSize = 1000.

Custom executor

Creating custom executor can be useful when you're having a custom SQL database, a custom ContentProvider or a custom DB table that needs to be cleaned up frequently.

  1. Create a class implements TrimContentVersionPlugin.Data.JobExecutor,
  2. Set values for ConnectionString and Execution fields within the constructor method,
  3. Register the executor by IJobExecutorRegistry.Register<T>(name);.

Example implementation:

    public class MyJobExecutor : TrimContentVersionPlugin.Data.JobExecutor
    {
    	public CmsJobExecutor(TrimContentVersionPluginOptions options) : base(options)
        {
            ConnectionString = "custom_connection_string_goes_here";
            Execution = MyExecution;
        }
        private void MyExecution()
        {
            Connection.Open();
            // To-do: Create SqlCommand and execute custom SQL using the existing SqlConnection Connection
	    using (var command = new SqlCommand(queryText, Connection) { CommandTimeout = Options.DatabaseTimeout }) ...
	    // To-do: Logic to add parameters and execute SqlCommand
            Connection.Close();
        }
    }
    [ModuleDependency(typeof(EPiServer.Cms.Shell.InitializableModule))]
    public class MyInitializationModule : IInitializableModule
    {
        public void Initialize(InitializationEngine context) 
        {
            context.Locate.Advanced.GetInstance<IJobExecutorRegistry>().Register<MyJobExecutor>("CustomExecutorName");
        }
    }

SQL command suggestion:

  • Properties of JobExecutor.Options can be used to make the SQL more efficient.
  • The executor logs the SQL output, you can use PRINT or THROW queries to record logs from SQL-side.
    Example: PRINT CONCAT('Rows deleted: ', @@ROWCOUNT).
Product Compatible and additional computed target framework versions.
.NET net6.0 is compatible.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.0.1 114 12/28/2025

Feature release.