Skip to main content

Outline

At a glance:
  • Registration core: ContentTypeAttribute handles GUIDs and UI categorization for system-wide consistency across environments
  • Field control: Display and validation attributes govern editor experience, localization, and search indexing behavior
  • Architectural guardrails: AllowedTypes restricts content areas to specific blocks, preventing layout drift and content bloating
  • Rendering choice: Decoupled architecture supports lightweight Partial Views or logic-heavy asynchronous ViewComponents

Configuring block types in Optimizely CMS 12 involves defining metadata, property behavior, and rendering templates to ensure a performant and governed editorial experience. The configuration is primarily handled through .NET attributes, which are processed during system initialization to synchronize the code-defined model with the CMS database.

1. The ContentType Attribute

The ContentTypeAttribute is the primary mechanism for registering a block type with the CMS. It defines how the block appears in the assets pane and how instances are categorized for editors.

Mandatory and Critical Metadata

  • GUID: A unique identifier for the content type. Explicitly defining GUIDs ensures consistency across environment deployments (Integration, Pre-production, Production). Without it, class renames orphan existing content.
  • DisplayName and Description: Provide labels and help text for editors in the "New Block" creation dialog.
  • GroupName: Categorizes block types in the creation UI, facilitating easier discovery in large enterprise systems with many block types.
  • AvailableInEditMode: A critical governance setting. Setting this to false prevents editors from creating standalone shared instances, restricting the block to property-only use on a page.
C#
[ContentType( DisplayName = "High-Impact Teaser", GUID = "f7a2b3c1-4d5e-6f7a-8b9c-0d1e2f3a4b5c", Description = "Used for homepage banners and cross-site promos.", GroupName = "Editorial Components", AvailableInEditMode = true)] public class HighImpactTeaserBlock : BlockData { // Property definitions }

2. Property-Level Configuration

Individual properties within a block are configured through attributes to control data entry, localization, and technical metadata.

Property Configuration Attributes

Select a category to expand and read the details.

The Display Attribute

Controls the presentation of the property in the "All Properties" edit view. All four parameters should be set on every property for a clean, self-documenting editorial experience.

  • Name: The label shown to the editor in the properties panel.
  • Description: Contextual help text or tooltip shown alongside the field.
  • GroupName: Places the property within a specific tab or heading grouping in the UI.
  • Order: Determines the vertical placement of the field within its group.
Localization and Validation
  • [CultureSpecific]: Marks a property as translatable. When enabled, editors can provide distinct values for each enabled language branch.
  • [Required]: Enforces data entry at the database level, preventing save or publish without a value.
  • Searchable(false): Prevents property data from being indexed in Optimizely Search and Navigation. Use this for purely technical or structural properties that should not appear in search results.

The following example combines all three localization and validation attributes on a single heading property:

C#
[CultureSpecific] [Display( Name = "Top Heading", Description = "Capitalized title for the teaser component.", GroupName = SystemTabNames.Content, Order = 10)] [Required] public virtual string Heading { get; set; }

3. Editorial Governance through AllowedTypes

To maintain architectural integrity, it is necessary to restrict which blocks can be placed within specific areas of a page. The AllowedTypesAttribute is applied to ContentArea properties to enforce these rules at the CMS level.

Pro tip: Restricting a ContentArea to only the block types it was designed for prevents "content bloating" and ensures the layout remains consistent with the intended components - even as the block library grows over time.

C#
public class LandingPage : PageData { [Display(Name = "Lead Components")] [AllowedTypes(typeof(HighImpactTeaserBlock), typeof(HeroBannerBlock))] public virtual ContentArea LeadArea { get; set; } }

4. Technical Rendering Configurations

In CMS 12, block rendering is decoupled from the data model. There are two primary patterns for configuring how a block type is displayed to the end user - choose based on the complexity of logic required.

Partial Views (Lightweight)

For blocks that only require basic HTML rendering with no complex logic, a conventional PartialView is the most performant choice. The CMS automatically resolves the view by naming convention matching the block type - for example, _HighImpactTeaserBlock.cshtml placed at /Views/Shared/Blocks/.

ViewComponents (Logic-Driven)

For blocks requiring dependency injection, database lookups, or external API calls, a ViewComponent is required. This enables asynchronous execution and full DI support, which is vital for maintaining high performance in a PaaS environment without blocking the request thread.

C#
public class HighImpactTeaserBlockViewComponent : BlockComponent<HighImpactTeaserBlock> { protected override IViewComponentResult InvokeComponent(HighImpactTeaserBlock currentContent) { var viewModel = new TeaserViewModel(currentContent) { // Logic to calculate dynamic data }; return View(viewModel); } }

5. Metadata and Grouping Best Practices

For enterprise-scale CMS implementations, grouping configurations into logical hierarchies improves both the developer and editor experience.

  • Tab Names: Use constants or SystemTabNames to ensure properties are grouped into logical UI sections such as "Content," "SEO," or "Advanced Settings." String literals are error-prone and break grouping if mistyped.
  • Initialization Modules: For global configurations that apply to multiple block types, use IInitializableModule to programmatically adjust metadata or register custom validation rules during application startup, keeping the individual block classes clean.

Conclusion

Effective block configuration in Optimizely CMS 12 requires a synthesis of metadata definition, strict editorial governance through attributes, and optimized rendering selections. By explicitly defining GUIDs, implementing AllowedTypes restrictions, and utilizing asynchronous ViewComponents for logic-heavy blocks, technical teams can ensure a scalable architecture that remains maintainable as the content model grows.