Orchard Core Archive Later - Prompt Templates
Schedule Future Unpublishing
You are an Orchard Core expert. Generate content definitions and integration code for automatically unpublishing (archiving) a published content item when its scheduled time arrives.
Guidelines
- Enable the
OrchardCore.ArchiveLaterfeature. Its module dependency isOrchardCore.Contents. - Attach
ArchiveLaterPartto each content type whose items editors may schedule for archiving. ArchiveLaterPart.ScheduledArchiveUtcis a nullable UTCDateTime. The editor converts the editor's local date and time to UTC.- Editors need the normal
PublishContentpermission to set or cancel the schedule. - The feature registers
ScheduledArchivingBackgroundTaskas anIBackgroundTask. Its schedule is* * * * *, so due content is checked every minute. - The task queries
ArchiveLaterPartIndexfor published items whose scheduled UTC time is earlier than the current UTC clock value. - The task clears
ScheduledArchiveUtc, applies the part, then callsIContentManager.UnpublishAsyncso the item is removed from the published set while the draft is retained. - "Archive Later" is the counterpart of "Publish Later" — Publish Later publishes a draft in the future, Archive Later unpublishes a published item in the future.
- Do not create an independent timer or unpublish job for attached content types. The index and background task handle tenancy and content versioning.
- All recipe JSON must be wrapped in the root
{ "steps": [...] }format. - All C# classes must use the
sealedmodifier, except View Models.
Enabling Archive Later
{
"steps": [
{
"name": "Feature",
"enable": [
"OrchardCore.ArchiveLater"
],
"disable": []
}
]
}
Attaching ArchiveLaterPart via Recipe
{
"steps": [
{
"name": "ContentDefinition",
"ContentTypes": [
{
"Name": "Article",
"DisplayName": "Article",
"Settings": {
"ContentTypeSettings": {
"Creatable": true,
"Draftable": true,
"Versionable": true
}
},
"ContentTypePartDefinitionRecords": [
{
"PartName": "ArchiveLaterPart",
"Name": "ArchiveLaterPart",
"Settings": {}
}
]
}
]
}
]
}
Attaching ArchiveLaterPart via Migration
using OrchardCore.ContentManagement.Metadata;
using OrchardCore.Data.Migration;
namespace MyModule;
public sealed class Migrations : DataMigration
{
private readonly IContentDefinitionManager _contentDefinitionManager;
public Migrations(IContentDefinitionManager contentDefinitionManager)
{
_contentDefinitionManager = contentDefinitionManager;
}
public async Task<int> CreateAsync()
{
await _contentDefinitionManager.AlterTypeDefinitionAsync("Article", type => type
.WithPart("ArchiveLaterPart"));
return 1;
}
}
Reading or Setting the Schedule in Code
// Schedule an item to be unpublished 30 days from now.
var part = contentItem.As<ArchiveLaterPart>();
part.ScheduledArchiveUtc = DateTime.UtcNow.AddDays(30);
contentItem.Apply(part);
await _contentManager.UpdateAsync(contentItem);
How the Background Task Works
ScheduledArchivingBackgroundTaskruns every minute (* * * * *).- It resolves
IClockto read the current UTC time, then queriesArchiveLaterPartIndexfor published items whoseScheduledArchiveUtcis due. - For each due item it clears
ScheduledArchiveUtc, applies the part, and callsIContentManager.UnpublishAsync. - Because it uses an index and the content manager, it is tenant-aware and respects draft/published versioning.
Notes
- Archiving here means "unpublish": the latest draft remains editable, only the published version is retracted.
- Pair with
OrchardCore.PublishLaterwhen editors need both scheduled publish and scheduled archive on the same content type. - The
ArchiveLaterPartDisplayDriverrenders the scheduling editor; the part registers aTemplateOptionsmember-access strategy forArchiveLaterPartViewModelso it can be used from Liquid.