# Create Custom Skeletons URL: /bengal/docs/0.5.1/extending/custom-skeletons/ Section: extending Tags: skeleton, yaml, scaffolding, templates -------------------------------------------------------------------------------- Create Custom Skeletons Skeleton YAML files (skeleton.yaml) define reusable site structures. Drop one into a site-template directory and Bengal materializes it whenever you run bengal new site with that template. When to Use Custom Skeletons Team standards: Enforce consistent site architecture across projects Repeatable patterns: Scaffold the same structure without copy-paste Onboarding: New team members get a working structure immediately Experiments: Quickly test different information architectures Skeleton Anatomy A skeleton has two sections: metadata and structure. # Metadata name: My Custom Skeleton description: What this skeleton creates version: "1.0" # Global cascade (optional) cascade: type: doc # Page structure structure: - path: _index.md props: title: Home content: | # Welcome Build a Skeleton Step by Step 1Define Metadataname: API Documentation description: OpenAPI-style docs with endpoints and schemas version: "1.0" 2Add Global CascadeCascade settings apply to all pages unless overridden: cascade: type: doc draft: false 3Define Root Pagesstructure: - path: _index.md props: title: API Reference description: Complete API documentation weight: 100 content: | # API Reference Welcome to the API documentation. ## Sections - [Authentication](/authentication) - [Endpoints](/endpoints) - [Schemas](/schemas) 4Add Sections with Nested PagesUse pages to nest content under a section: - path: endpoints/_index.md props: title: Endpoints weight: 20 cascade: type: doc content: | # API Endpoints All available endpoints. pages: - path: users.md props: title: Users weight: 10 content: | # Users Endpoint `GET /api/users` Returns a list of users. - path: posts.md props: title: Posts weight: 20 content: | # Posts Endpoint `GET /api/posts` Returns a list of posts. 5Install and BuildPlace the manifest as skeleton.yaml inside a template directory (built-in templates live under bengal/scaffolds/<name>/skeleton.yaml; custom templates can be registered at runtime with bengal.scaffolds.register_template). Bengal materializes it when you scaffold a site from that template: # Scaffold a new site from your template bengal new site my-docs --template api-docs # Serve cd my-docs bengal serve Complete Example: API Documentation Skeleton name: API Documentation description: REST API docs with authentication, endpoints, and schemas version: "1.0" cascade: type: doc structure: - path: _index.md props: title: API Reference description: Complete API documentation weight: 100 content: | # API Reference This documentation covers all available API endpoints. ## Quick Links - [Authentication](/authentication) - API keys and OAuth - [Endpoints](/endpoints) - Available endpoints - [Schemas](/schemas) - Request/response formats - [Errors](/errors) - Error codes and handling - path: authentication.md props: title: Authentication weight: 10 content: | # Authentication All API requests require authentication. ## API Keys Include your API key in the header: ```bash curl -H "Authorization: Bearer YOUR_API_KEY" \ https://api.example.com/v1/users ``` ## OAuth 2.0 For user-authenticated requests, use OAuth 2.0. - path: endpoints/_index.md props: title: Endpoints weight: 20 content: | # API Endpoints All available REST endpoints. pages: - path: users.md props: title: Users weight: 10 content: | # Users ## List Users ```http GET /api/v1/users ``` ## Get User ```http GET /api/v1/users/{id} ``` ## Create User ```http POST /api/v1/users ``` - path: posts.md props: title: Posts weight: 20 content: | # Posts ## List Posts ```http GET /api/v1/posts ``` ## Get Post ```http GET /api/v1/posts/{id} ``` - path: schemas/_index.md props: title: Schemas weight: 30 content: | # Data Schemas Request and response formats. pages: - path: user.md props: title: User Schema content: | # User Schema ```json { "id": "string", "email": "string", "name": "string", "created_at": "datetime" } ``` - path: post.md props: title: Post Schema content: | # Post Schema ```json { "id": "string", "title": "string", "body": "string", "author_id": "string", "published_at": "datetime" } ``` - path: errors.md props: title: Error Handling weight: 40 content: | # Error Handling ## Error Response Format ```json { "error": { "code": "string", "message": "string" } } ``` ## Common Error Codes | Code | Description | |------|-------------| | 400 | Bad Request | | 401 | Unauthorized | | 404 | Not Found | | 429 | Rate Limited | | 500 | Server Error | Props Reference Common frontmatter fields for props: Field Type Description title string Page title (required) description string SEO description weight number Sort order (lower = first) date string Publication date (ISO format) tags list Taxonomy tags draft boolean Exclude from production type string Content type (doc, blog, etc.) variant string Visual presentation variant (e.g., editorial, wide) nav_title string Short title for navigation Custom props are accessible in templates via page.props.fieldname. Dynamic Placeholders Use {{ date }} for the current date: - path: posts/new-post.md props: title: New Post date: "{{date}}" content: | # New Post Written on {{date}}. Cascade Patterns Section-Level Cascade Apply settings to all pages in a section: - path: blog/_index.md props: title: Blog cascade: type: blog author: Default Author pages: - path: post-1.md props: title: First Post # Inherits type: blog, author: Default Author Override Cascade Child pages can override cascaded values: - path: docs/_index.md cascade: type: doc draft: false pages: - path: wip.md props: title: Work in Progress draft: true # Overrides cascade Tips Tip Version Your Skeletons Include version in metadata. When you update the skeleton, increment the version: name: Team Docs version: "2.0" # Breaking changes from 1.x Tip Organize by Purpose Create separate skeletons for different use cases: skeletons/ ├── api-docs.yaml ├── blog.yaml ├── landing-page.yaml └── product-docs.yaml Tip Validate Before Shipping A skeleton is materialized during bengal new site --template <name>. Scaffold into a throwaway directory first to confirm the structure renders as expected: bengal new site /tmp/skeleton-check --template my-skeleton Troubleshooting Files Not Created Symptom: bengal new site reports 0 files created when scaffolding from your template. Cause: The target directory already exists, so Bengal refuses to overwrite it. Fix: Scaffold into a fresh directory (or remove the existing one): rm -rf my-docs bengal new site my-docs --template my-skeleton Content Not Rendering Symptom: YAML content appears as raw text. Cause: Incorrect indentation in content block. Fix: Use | for multiline content and indent consistently: content: | # Title Paragraph text. - List item Cascade Not Applied Symptom: Child pages don't inherit cascade settings. Cause: cascade is at the wrong level. Fix: Place cascade inside the parent page definition, not inside props: # Correct - path: docs/_index.md cascade: type: doc # Wrong - path: docs/_index.md props: cascade: # This won't work type: doc Next Steps Skeleton YAML Quickstart — Copy-paste examples Scaffold Tutorial — Full walkthrough Site Templates Reference — Built-in templates -------------------------------------------------------------------------------- Metadata: - Author: lbliii - Word Count: 1036 - Reading Time: 5 minutes