npx claudepluginhub melodic-software/claude-code-plugins --plugin content-management-systemThis skill is limited to using the following tools:
Design a modular page composition system for block-based content editing.
Designs page hierarchies, templates with zones and inheritance, page sets, and sitemaps for headless CMS using C# models and page tree APIs.
Guides creating custom Page Designer page types and components for Salesforce B2C Commerce, covering file structures, regions, attributes, subfolders, enum pitfalls, and troubleshooting for visual merchandising and Experience API.
Guides design of template aggregation (gallery/hub) and detail pages for programmatic SEO strategies and user-facing template marketplaces in CMS, design tools, website builders, and vibe coding.
Share bugs, ideas, or general feedback.
Design a modular page composition system for block-based content editing.
/cms:design-page-builder --pattern components
/cms:design-page-builder --pattern slots --framework blazor
/cms:design-page-builder --pattern hybrid
Extract pattern type and framework from command.
Use AskUserQuestion to understand:
Invoke relevant skills:
page-structure-design - Page templatescontent-type-modeling - Component content typesComponent Definitions:
components:
# Layout Components
- name: Section
category: Layout
description: Full-width section with background options
props:
background_color: string
background_image: MediaField
padding: enum[none, small, medium, large]
width: enum[full, contained, narrow]
slots:
- name: content
allowed: [Hero, Grid, TextBlock, ImageGallery]
- name: Grid
category: Layout
description: Responsive grid container
props:
columns: enum[2, 3, 4]
gap: enum[small, medium, large]
mobile_stack: boolean
slots:
- name: items
allowed: [Card, Feature, Testimonial]
min: 1
max: 12
# Content Components
- name: Hero
category: Content
description: Hero banner with headline and CTA
props:
headline: TextField
subheadline: TextField
background_image: MediaField
background_video: MediaField
overlay_opacity: number
text_alignment: enum[left, center, right]
height: enum[small, medium, large, full]
slots:
- name: cta
allowed: [Button, ButtonGroup]
max: 1
- name: TextBlock
category: Content
description: Rich text content block
props:
content: HtmlField
alignment: enum[left, center, right, justify]
- name: Card
category: Content
description: Content card with image and text
props:
image: MediaField
title: TextField
description: TextField
link: LinkField
- name: ImageGallery
category: Media
description: Responsive image gallery
props:
images: MediaField[]
layout: enum[grid, masonry, carousel]
columns: number
lightbox: boolean
- name: Testimonial
category: Social Proof
description: Customer testimonial
props:
quote: TextField
author: TextField
role: TextField
avatar: MediaField
rating: number
- name: CallToAction
category: Conversion
description: CTA section with form or button
props:
headline: TextField
description: TextField
button_text: TextField
button_url: LinkField
form: ContentPickerField[Form]
Template with Slots:
templates:
- name: Homepage
description: Main landing page template
slots:
- name: hero
label: Hero Section
allowed: [Hero]
required: true
- name: featured
label: Featured Content
allowed: [Section, Grid]
max: 3
- name: main
label: Main Content
allowed: [Section, TextBlock, ImageGallery, Grid]
- name: testimonials
label: Testimonials
allowed: [Testimonial, Grid]
- name: cta
label: Call to Action
allowed: [CallToAction]
- name: ProductLanding
description: Product landing page
slots:
- name: hero
allowed: [Hero]
required: true
- name: features
allowed: [Grid, Section]
- name: pricing
allowed: [PricingTable]
- name: faq
allowed: [Accordion]
- name: cta
allowed: [CallToAction]
- name: BlogPost
description: Blog article template
slots:
- name: header
allowed: [ArticleHeader]
required: true
- name: content
allowed: [TextBlock, ImageGallery, CodeBlock, Quote]
- name: author
allowed: [AuthorBio]
- name: related
allowed: [RelatedPosts]
EF Core Models:
public class Page
{
public Guid Id { get; set; }
public string Title { get; set; }
public string Slug { get; set; }
public string TemplateId { get; set; }
public PageStatus Status { get; set; }
// JSON column for flexible content
public PageContent Content { get; set; }
}
[Owned]
public class PageContent
{
public Dictionary<string, List<ComponentInstance>> Slots { get; set; }
}
[Owned]
public class ComponentInstance
{
public string Id { get; set; }
public string ComponentType { get; set; }
public Dictionary<string, object> Props { get; set; }
public Dictionary<string, List<ComponentInstance>> NestedSlots { get; set; }
}
// DbContext configuration
modelBuilder.Entity<Page>()
.OwnsOne(p => p.Content, cb =>
{
cb.ToJson();
});
Component Renderer:
@* ComponentRenderer.razor *@
@inject IComponentRegistry Registry
@foreach (var component in Components)
{
<DynamicComponent
Type="@Registry.GetComponentType(component.ComponentType)"
Parameters="@GetParameters(component)" />
}
@code {
[Parameter] public List<ComponentInstance> Components { get; set; }
private Dictionary<string, object> GetParameters(ComponentInstance instance)
{
var parameters = new Dictionary<string, object>(instance.Props);
if (instance.NestedSlots?.Any() == true)
{
parameters["NestedSlots"] = instance.NestedSlots;
}
return parameters;
}
}
Hero Component:
@* Components/Hero.razor *@
<section class="hero @HeightClass" style="@BackgroundStyle">
@if (OverlayOpacity > 0)
{
<div class="hero-overlay" style="opacity: @OverlayOpacity"></div>
}
<div class="hero-content @AlignmentClass">
<h1>@Headline</h1>
@if (!string.IsNullOrEmpty(Subheadline))
{
<p class="hero-subheadline">@Subheadline</p>
}
@if (NestedSlots?.ContainsKey("cta") == true)
{
<div class="hero-cta">
<ComponentRenderer Components="@NestedSlots["cta"]" />
</div>
}
</div>
</section>
@code {
[Parameter] public string Headline { get; set; }
[Parameter] public string Subheadline { get; set; }
[Parameter] public string BackgroundImage { get; set; }
[Parameter] public decimal OverlayOpacity { get; set; }
[Parameter] public string TextAlignment { get; set; } = "center";
[Parameter] public string Height { get; set; } = "medium";
[Parameter] public Dictionary<string, List<ComponentInstance>> NestedSlots { get; set; }
private string HeightClass => $"hero--{Height}";
private string AlignmentClass => $"text-{TextAlignment}";
private string BackgroundStyle =>
!string.IsNullOrEmpty(BackgroundImage)
? $"background-image: url({BackgroundImage})"
: "";
}
Design the page builder editor:
editor:
features:
- drag_drop: true
- inline_editing: true
- live_preview: true
- responsive_preview: [mobile, tablet, desktop]
- undo_redo: true
- component_search: true
- keyboard_shortcuts: true
sidebar:
- components_panel
- settings_panel
- layers_panel
toolbar:
- save
- preview
- publish
- device_toggle
- undo
- redo
page-structure-design - Page templatescontent-type-modeling - Component typesdynamic-schema-design - JSON column storage