Exam Area: Content Area 5 – Content Models (25%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/content-approvals
Content Approvals is a feature that lets you define approval sequences (review workflows) before content is published. Editors must request approval → reviewers approve/reject → content is published.
Editor saves/requests approval
│
├── Step 1: Approver 1 (e.g., Marketing Lead)
│ └── Approved? → Next step
│
├── Step 2: Approver 2 (e.g., Legal Team)
│ └── Approved? → Next step
│
└── Step N: Final Approver
└── Approved? → Content Published
using EPiServer.Approvals;
public class ApprovalSetupService
{
private readonly IApprovalDefinitionRepository _approvalRepository;
private readonly IContentRepository _contentRepository;
public ApprovalSetupService(
IApprovalDefinitionRepository approvalRepository,
IContentRepository contentRepository)
{
_approvalRepository = approvalRepository;
_contentRepository = contentRepository;
}
public async Task SetupApprovalAsync(ContentReference contentLink)
{
// Create approval definition
var definition = new ContentApprovalDefinition
{
ContentLink = contentLink,
Steps = new List<ApprovalDefinitionStep>
{
new ApprovalDefinitionStep
{
Name = "Marketing Review",
Approvers = new List<ApprovalDefinitionReviewer>
{
new ApprovalDefinitionReviewer
{
Name = "marketing-team", // Role or username
Type = ApprovalDefinitionReviewerType.Role
}
}
},
new ApprovalDefinitionStep
{
Name = "Legal Approval",
Approvers = new List<ApprovalDefinitionReviewer>
{
new ApprovalDefinitionReviewer
{
Name = "legal.reviewer@company.com",
Type = ApprovalDefinitionReviewerType.User
}
}
}
}
};
await _approvalRepository.SaveAsync(definition);
}
}
using EPiServer.Approvals;
public class ApprovalManagementService
{
private readonly IApprovalRepository _approvalRepository;
public ApprovalManagementService(IApprovalRepository approvalRepository)
{
_approvalRepository = approvalRepository;
}
// Get all pending approvals for current user
public async Task<IEnumerable<Approval>> GetPendingApprovalsAsync()
{
return await _approvalRepository.ListAsync(
new ApprovalQuery
{
Status = ApprovalStatus.InReview
});
}
// Approve a content item
public async Task ApproveAsync(int approvalId, string comment = null)
{
await _approvalRepository.ApproveAsync(approvalId, comment);
}
// Reject a content item
public async Task RejectAsync(int approvalId, string reason)
{
await _approvalRepository.RejectAsync(approvalId, reason);
}
}
public enum ApprovalStatus
{
Unknown = 0,
InReview = 1, // Awaiting approval
Approved = 2, // Has been approved
Rejected = 3, // Rejected
Cancelled = 4, // Cancelled
Aborted = 5 // Aborted
}
[InitializableModule]
public class ApprovalEventHandler : IInitializableModule
{
private IContentEvents _contentEvents;
public void Initialize(InitializationEngine context)
{
_contentEvents = context.Locate.Advanced.GetInstance<IContentEvents>();
_contentEvents.RequestingApproval += OnRequestingApproval;
_contentEvents.PublishedContent += OnPublished;
}
public void Uninitialize(InitializationEngine context)
{
_contentEvents.RequestingApproval -= OnRequestingApproval;
_contentEvents.PublishedContent -= OnPublished;
}
private void OnRequestingApproval(object sender, ContentEventArgs e)
{
// Notify approvers - can use INotificationRepository
var contentLink = e.ContentLink;
// Send notification to reviewers...
}
private void OnPublished(object sender, ContentEventArgs e)
{
// Content approved and published
if (e.Action == SaveAction.Publish)
{
// Post-publish actions...
}
}
}
/episerver/cms/admin → Content Approvals
→ View approval sequences
→ Setup sequences per content item or tree
→ Manage approvers
Edit View:
→ When editor clicks "Request Approval"
→ Notification sent to reviewers
→ Reviewers access the Approvals gadget/notification
// CMS automatically sends notifications when:
// 1. Editor requests approval
// 2. Reviewer approves/rejects
// 3. Content is published
// Custom notification - see 04_Framework_Components\08_notifications.md
IApprovalDefinitionRepository do? (Creates/manages approval sequences)ApprovalStatus.InReview mean? (Content is awaiting approval)