🌐 Website Implementation
Icontent Interfaces
📖 Docs

IContent, Classes and Interfaces - Optimizely CMS 12

Exam Area: Content Area 3 – Website Implementation & Delivery (25%)
Reference: https://docs.developers.optimizely.com/content-management-system/docs/content


1. IContent Interface

IContent is the core interface for all content in the CMS.

public interface IContent
{
    ContentReference ContentLink { get; set; }  // Unique ID
    string Name { get; set; }                    // Display name
    ContentReference ParentLink { get; set; }   // Parent
    Guid ContentGuid { get; set; }               // Stable GUID
    int ContentTypeID { get; set; }              // Type ID
    bool IsDeleted { get; set; }                 // Trash
}

2. Content Class Hierarchy

IContent
  ├── ContentData (base implementation)
  │     ├── PageData
  │     │     └── CustomPageType : PageData
  │     ├── BlockData
  │     │     └── CustomBlockType : BlockData
  │     └── MediaData (abstract)
  │           ├── ImageData
  │           ├── VideoData
  │           └── BlobData
  └── IVersionable (versioning support)

3. PageData

// Important PageData properties
public class PageData : ContentData, IVersionable, ILocalizable, IRoutable
{
    // Page name
    public string PageName { get; set; }
    
    // URL segment
    public string URLSegment { get; set; }
    
    // Navigation
    public bool VisibleInMenu { get; set; }
    
    // SEO
    public string PageTitle { get; set; }
    public string PageDescription { get; set; }
    
    // Publish control
    public DateTime? StartPublish { get; set; }
    public DateTime? StopPublish { get; set; }
    
    // Version info
    public VersionStatus Status { get; }
    public int Version { get; }
}

4. BlockData

// BlockData is the base for all blocks
public abstract class BlockData : ContentData, ILocalizable
{
    // Properties declared in subclass
}

// Custom block
[ContentType(DisplayName = "My Block", GUID = "...")]
public class MyBlock : BlockData
{
    public virtual string Title { get; set; }
}

5. ContentReference

// ContentReference – the ID of a content item
var reference = new ContentReference(5);          // By ID
var reference2 = new ContentReference(5, 3);      // By ID + WorkID (version)
var reference3 = ContentReference.StartPage;       // Start page
var reference4 = ContentReference.RootPage;        // Root

// Comparison
bool areEqual = reference.CompareToIgnoreWorkID(reference2); // Ignore version
bool isSame = ContentReference.IsNullOrEmpty(reference);     // Null check

// Convert
int id = reference.ID;
string str = reference.ToString();  // "5_3"
ContentReference parsed = ContentReference.Parse("5_3");

6. IContentRepository - CRUD Operations

public class ContentService
{
    private readonly IContentRepository _contentRepository;

    public ContentService(IContentRepository contentRepository)
    {
        _contentRepository = contentRepository;
    }

    // READ
    public T GetContent<T>(ContentReference link) where T : IContentData
    {
        return _contentRepository.Get<T>(link);
    }

    // CREATE
    public ContentReference CreatePage(ContentReference parent)
    {
        var newPage = _contentRepository.GetDefault<ArticlePage>(parent);
        newPage.Name = "New Article";
        newPage.Heading = "My Heading";
        
        return _contentRepository.Save(newPage, SaveAction.Publish, AccessLevel.NoAccess);
    }

    // UPDATE
    public void UpdatePage(ContentReference link)
    {
        var page = _contentRepository.Get<ArticlePage>(link);
        var writablePage = (ArticlePage)page.CreateWritableClone();
        writablePage.Heading = "Updated Heading";
        
        _contentRepository.Save(writablePage, SaveAction.Publish);
    }

    // DELETE
    public void DeletePage(ContentReference link)
    {
        _contentRepository.MoveToWastebasket(link);
        // or permanent delete:
        _contentRepository.Delete(link, true);
    }

    // LIST
    public IEnumerable<ArticlePage> GetChildren(ContentReference parent)
    {
        return _contentRepository.GetChildren<ArticlePage>(parent);
    }
}

7. SaveAction Enum

// SaveAction values
SaveAction.Save             // Save as draft (do not publish)
SaveAction.Publish          // Save and publish immediately
SaveAction.CheckIn          // Check in version
SaveAction.CheckOut         // Check out for editing
SaveAction.RequestApproval  // Submit for approval
SaveAction.ScheduleForPublish // Schedule for future publish
SaveAction.Reject           // Reject

8. IContentLoader (Read-Only, Performance)

// Use for read-only operations (more efficient than IContentRepository)
public class MyService
{
    private readonly IContentLoader _contentLoader;

    public MyService(IContentLoader contentLoader)
    {
        _contentLoader = contentLoader;
    }

    public ArticlePage GetArticle(ContentReference link)
    {
        return _contentLoader.Get<ArticlePage>(link);
    }

    public IEnumerable<ArticlePage> GetAllArticles(ContentReference parent)
    {
        return _contentLoader.GetChildren<ArticlePage>(parent);
    }
}

9. IVersionable Interface

public interface IVersionable
{
    VersionStatus Status { get; set; }
    DateTime? StartPublish { get; set; }
    DateTime? StopPublish { get; set; }
    bool IsPendingPublish { get; }
}

VersionStatus:

VersionStatus.CheckedOut           // Draft
VersionStatus.CheckedIn            // Checked in
VersionStatus.DelayedPublish       // Scheduled
VersionStatus.Published            // Live
VersionStatus.PreviouslyPublished  // Old version
VersionStatus.Rejected             // Rejected

10. Filter by Visitor / Access Control

// FilterForVisitor – Filter content based on the current user's permissions
using EPiServer.Filters;

var pages = _contentLoader.GetChildren<PageData>(parent);
var filteredPages = pages.Where(p => 
    _contentAccessEvaluator.HasAccess(p, User, AccessLevel.Read));

// Or use FilterForVisitor
var filter = new FilterForVisitor();
filter.Filter(ref pages);

Review Questions

  1. What is IContent? (The core interface for all content in the CMS)
  2. What is the difference between IContentRepository and IContentLoader? (Repository: CRUD; Loader: Read-only, optimized for performance)
  3. How do you create a writable clone of content? (content.CreateWritableClone())
  4. What does SaveAction.Publish do? (Saves and publishes immediately)
  5. What does ContentReference.StartPage point to? (The start page of the current site)