From content-management-system
Designs page hierarchies, templates with zones and inheritance, page sets, and sitemaps for headless CMS using C# models and page tree APIs.
How this skill is triggered — by the user, by Claude, or both
Slash command
/content-management-system:page-structure-designThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Guidance for designing page hierarchies, templates, and modular page composition systems for headless CMS.
Guidance for designing page hierarchies, templates, and modular page composition systems for headless CMS.
public class Page
{
public Guid Id { get; set; }
public string Title { get; set; } = string.Empty;
public string Slug { get; set; } = string.Empty;
// Hierarchy
public Guid? ParentId { get; set; }
public Page? Parent { get; set; }
public List<Page> Children { get; set; } = new();
// Computed path
public string Path { get; set; } = string.Empty; // /about/team/leadership
public int Depth { get; set; }
public int Order { get; set; }
// Template and content
public string Template { get; set; } = string.Empty;
public PageContent Content { get; set; } = new();
}
// Page set for grouping related pages
public class PageSet
{
public Guid Id { get; set; }
public string Name { get; set; } = string.Empty;
public string Slug { get; set; } = string.Empty;
public PageSetType Type { get; set; }
// Configuration
public string ItemTemplate { get; set; } = string.Empty;
public string ListTemplate { get; set; } = string.Empty;
public int ItemsPerPage { get; set; } = 10;
// URL pattern
public string UrlPattern { get; set; } = string.Empty; // /blog/{slug}
}
public enum PageSetType
{
Blog, // Chronological posts
Portfolio, // Project showcase
Team, // Team members
Products, // Product catalog
FAQ, // Q&A collection
Custom // User-defined
}
public class PageTemplate
{
public string Name { get; set; } = string.Empty;
public string DisplayName { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
// Template hierarchy
public string? ParentTemplate { get; set; }
// Available zones for content
public List<TemplateZone> Zones { get; set; } = new();
// Required fields
public List<TemplateField> Fields { get; set; } = new();
// Applicable page types
public List<string> ApplicablePageTypes { get; set; } = new();
}
public class TemplateZone
{
public string Name { get; set; } = string.Empty;
public string DisplayName { get; set; } = string.Empty;
public ZoneType Type { get; set; }
public List<string> AllowedWidgets { get; set; } = new();
public int? MaxWidgets { get; set; }
}
public enum ZoneType
{
Single, // One widget only
Multiple, // Multiple widgets stacked
Grid // Grid layout
}
BaseTemplate
├── Zones: Header, Footer, Sidebar
└── Fields: MetaTitle, MetaDescription
├── HomeTemplate (extends Base)
│ └── Zones: Hero, Features, CTA
│
├── ContentTemplate (extends Base)
│ └── Zones: MainContent, RelatedContent
│
└── LandingTemplate (extends Base)
└── Zones: Hero, Sections (multiple)
public abstract class Widget
{
public Guid Id { get; set; }
public string Type { get; set; } = string.Empty;
public int Order { get; set; }
public Dictionary<string, object?> Settings { get; set; } = new();
}
public class TextWidget : Widget
{
public string Content { get; set; } = string.Empty;
}
public class ImageWidget : Widget
{
public Guid MediaItemId { get; set; }
public string? Alt { get; set; }
public string? Caption { get; set; }
}
public class CallToActionWidget : Widget
{
public string Heading { get; set; } = string.Empty;
public string? Subheading { get; set; }
public string ButtonText { get; set; } = string.Empty;
public string ButtonUrl { get; set; } = string.Empty;
public string? BackgroundImageId { get; set; }
}
public class CardGridWidget : Widget
{
public List<Card> Cards { get; set; } = new();
public int Columns { get; set; } = 3;
}
public class PageContent
{
// Zone-based content storage
public Dictionary<string, List<Widget>> Zones { get; set; } = new();
// Page-level fields
public string? HeroTitle { get; set; }
public string? HeroSubtitle { get; set; }
public Guid? HeroImageId { get; set; }
// SEO
public string? MetaTitle { get; set; }
public string? MetaDescription { get; set; }
public bool NoIndex { get; set; }
}
public class SitemapEntry
{
public string Url { get; set; } = string.Empty;
public DateTime LastModified { get; set; }
public ChangeFrequency ChangeFrequency { get; set; }
public decimal Priority { get; set; }
public List<SitemapAlternate>? Alternates { get; set; }
}
public class SitemapAlternate
{
public string Hreflang { get; set; } = string.Empty;
public string Url { get; set; } = string.Empty;
}
public enum ChangeFrequency
{
Always,
Hourly,
Daily,
Weekly,
Monthly,
Yearly,
Never
}
public class SitemapService
{
public async Task<List<SitemapEntry>> GenerateSitemapAsync()
{
var entries = new List<SitemapEntry>();
// Add pages
var pages = await _pageRepository.GetPublishedPagesAsync();
foreach (var page in pages)
{
entries.Add(new SitemapEntry
{
Url = $"{_baseUrl}{page.Path}",
LastModified = page.ModifiedUtc,
ChangeFrequency = GetChangeFrequency(page),
Priority = CalculatePriority(page)
});
}
// Add page set items (blog posts, products, etc.)
var pageSets = await _pageSetRepository.GetAllAsync();
foreach (var pageSet in pageSets)
{
var items = await _pageSetRepository.GetItemsAsync(pageSet.Id);
foreach (var item in items)
{
var url = GenerateUrl(pageSet.UrlPattern, item);
entries.Add(new SitemapEntry
{
Url = url,
LastModified = item.ModifiedUtc,
ChangeFrequency = ChangeFrequency.Weekly,
Priority = 0.6m
});
}
}
return entries;
}
private decimal CalculatePriority(Page page)
{
// Home page highest priority
if (page.Depth == 0) return 1.0m;
// Decrease by depth
return Math.Max(0.5m, 1.0m - (page.Depth * 0.1m));
}
}
GET /api/pages # Root pages
GET /api/pages/{id} # Single page
GET /api/pages/{id}/children # Child pages
GET /api/pages/path/{*path} # Page by URL path
GET /api/pages/tree # Full page tree
GET /api/sitemap.xml # XML sitemap
GET /api/sitemap.json # JSON sitemap
{
"data": {
"id": "page-123",
"title": "About Us",
"slug": "about",
"path": "/about",
"template": "ContentTemplate",
"depth": 1,
"order": 2,
"children": [
{
"id": "page-456",
"title": "Our Team",
"slug": "team",
"path": "/about/team",
"template": "TeamTemplate",
"children": []
},
{
"id": "page-789",
"title": "Careers",
"slug": "careers",
"path": "/about/careers",
"template": "ContentTemplate",
"children": []
}
]
},
"breadcrumbs": [
{ "title": "Home", "path": "/" },
{ "title": "About Us", "path": "/about" }
]
}
| Pattern | When to Use |
|---|---|
| Flat structure | Simple sites, few pages |
| 2-level hierarchy | Most corporate sites |
| Deep hierarchy | Documentation, large catalogs |
| Page sets | Blog, portfolio, team pages |
DO:
- Keep zones semantic (Header, MainContent, Sidebar)
- Allow flexible widget placement
- Inherit common zones from base template
- Provide sensible defaults
DON'T:
- Create overly specific templates
- Hard-code layout in templates
- Mix content and presentation concerns
- Create deep template inheritance chains
navigation-architecture - Menu and breadcrumb designurl-routing-patterns - URL structure and routingcontent-type-modeling - Page as content typenpx claudepluginhub melodic-software/claude-code-plugins --plugin content-management-systemDesigns modular page builders with components, slots, and hybrid patterns for block-based editing. Supports React, Vue, Blazor frameworks via configurable patterns.
Plans or restructures website hierarchy, navigation, URL patterns, breadcrumbs, and internal linking. Use for mapping pages and site sections, excluding XML sitemaps.
Plans website page hierarchies, navigation, URL patterns, and internal linking. Helps structure sites for user experience and SEO. Invoked for site maps, information architecture, or restructuring.