Template Inheritance and Resolution

On this page

Aether Template Resolution System

Aether uses a sophisticated template resolution system that follows a hierarchical approach to determine which template file to use for rendering different types of content. The system prioritizes specificity and provides multiple fallback layers to ensure content always renders properly.

Template Resolution Flow

When Aether needs to render a page, it follows this resolution order:

  1. Custom templates first: Check for specialized templates in custom/ directory
  2. Content-specific templates: Look for templates matching the content type
  3. Generic fallbacks: Use increasingly generic templates
  4. Final fallback: Always fall back to layout.html

Visual Template Inheritance Tree

layout.html (baseline for all pages)
├── content.html (generic content pages)
│   ├── post.html (blog posts)
│   ├── page.html (standard pages)
│   ├── category.html (category archive pages)
│   ├── tag.html (tag archive pages)
│   └── taxonomy.html (generic taxonomy fallback)
└── custom/*.html (specialized override templates)
    ├── homepage.html (home page override)
    ├── contact.html (custom contact page)
    ├── blog.html (custom blog listing with pagination)
    ├── categories.html (category taxonomy counts)
    ├── tags.html (tag taxonomy counts)
    ├── category.html (overrides templates/category.html)
    ├── category-<slug>.html (specific category pages)
    ├── tag.html (overrides templates/tag.html)
    └── tag-<slug>.html (specific tag pages)
🚨
Important: Custom templates in the custom/ directory always take precedence over templates in the templates/ directory. The system checks custom templates first before falling back to the standard template hierarchy.

Route-Specific Template Resolution

1. Homepage

Route: /

  • Route behavior: Loads recent posts for homepage display
  • Template resolution:
    1. custom/homepage.html (custom homepage template)
    2. templates/layout.html (fallback)

2. Posts

Route: /post/:slug

  • Route behavior: Displays individual blog post with navigation and related posts
  • Template resolution:
    1. templates/post.html (post-specific template)
    2. templates/content.html (generic content template)
    3. templates/layout.html (fallback)

3. Pages

Route: /page/:slug

  • Route behavior: Displays individual pages (redirects custom pages to direct URLs)
  • Template resolution:
    1. templates/page.html (page-specific template)
    2. templates/content.html (generic content template)
    3. templates/layout.html (fallback)

4. Categories

Route: /category/:slug

  • Route behavior: Lists posts in a category with pagination
  • Template resolution:
    1. custom/category-<slug>.html (slug-specific category template)
    2. custom/category.html (general custom category template)
    3. templates/taxonomy.html (generic taxonomy template)
    4. templates/category.html (category-specific template)
    5. templates/content.html (generic content template)
    6. templates/layout.html (fallback)

5. Tags

Route: /tag/:slug

  • Route behavior: Lists posts with a tag with pagination
  • Template resolution:
    1. custom/tag-<slug>.html (slug-specific tag template)
    2. custom/tag.html (general custom tag template)
    3. templates/taxonomy.html (generic taxonomy template)
    4. templates/tag.html (tag-specific template)
    5. templates/content.html (generic content template)
    6. templates/layout.html (fallback)

6. Custom Pages

Routes: /:path, /:path/:subpath, /:path/:subpath/:subSubPath

  • Route behavior: Handles nested custom pages with breadcrumbs and sibling navigation
  • Reserved paths: aether, api, post, page, rss, rss.xml, sitemap, sitemap.html, sitemap.xml are skipped
  • Template resolution:
    1. custom/<full-pattern>.html (exact match, e.g., docs-api-examples.html)
    2. custom/<parent-pattern>.html (parent fallback, e.g., docs-api.html)
    3. custom/<grandparent>.html (grandparent fallback, e.g., docs.html)
    4. templates/content.html (generic content template)
    5. templates/layout.html (fallback)

Template Resolution Priority

Step Condition Template Tried Notes
1 contentType === "home" custom/homepage.html Homepage-specific custom template
2 isCustomPage && slug custom/<slug>.html Custom page by exact slug match
Nested slug (contains hyphens) custom/<parent-slug>.html Parent template for nested pages
Deeply nested (multiple hyphens) custom/<grandparent>.html Grandparent template fallback
3 isTaxonomy === true custom/<contentType>-<slug>.html Slug-specific custom taxonomy (e.g., custom/category-tech.html)
custom/<contentType>.html General custom taxonomy (e.g., custom/category.html)
templates/taxonomy.html Generic taxonomy template (important fallback)
4 All content types templates/<contentType>.html Content-specific template (e.g., templates/post.html, templates/category.html)
5 Fallback templates/content.html Generic content template
6 Final fallback templates/layout.html Base layout template (always available)

Key Template Resolution Rules

Specificity Wins

  • More specific templates always override generic ones
  • Custom templates always override standard templates
  • Slug-specific templates override type-specific templates

Taxonomy Special Behavior

For category and tag pages, templates/taxonomy.html serves as an intermediate fallback that is checked before the specific taxonomy templates (templates/category.html, templates/tag.html). This allows themes to:

  • Use taxonomy.html for shared category/tag styling
  • Override specific behavior in category.html or tag.html when needed

Nested Custom Page Resolution

Custom pages support hierarchical template inheritance:

  • /docs/api/examples → tries custom/docs-api-examples.html
  • If not found → tries custom/docs-api.html (parent)
  • If not found → tries custom/docs.html (grandparent)
  • Supports up to 3 levels of nesting

Reserved Paths

The following paths are reserved by the system and will not trigger custom page resolution:

  • aether (admin interface)
  • api (API endpoints)
  • post (blog posts)
  • page (standard pages)
  • rss, rss.xml (RSS feed)
  • sitemap, sitemap.html, sitemap.xml (sitemaps)

Special Template Features

Pagination Templates

Custom pages with these slugs automatically receive pagination data and post listings:

  • blog - Blog listing with pagination
  • archive - Archive listing with pagination
  • articles - Article listing with pagination
  • news - News listing with pagination
  • search - Search results with pagination

Template data includes: posts (paginated), pagination object with navigation URLs

Taxonomy Count Templates

Custom pages with these slugs automatically receive taxonomy statistics:

  • categories - Lists all categories with post counts
  • tags - Lists all tags with post counts
  • topics - Lists all topics with post counts

Template data includes: taxonomies array, taxonomyType string, hasTaxonomyData boolean

Template Data Context

Each template receives appropriate data based on its context:

  • Posts: Content, metadata, navigation (prev/next), related posts
  • Pages: Content, metadata, parent/sibling navigation (for nested custom pages)
  • Taxonomies: Posts list, pagination, taxonomy metadata
  • Custom pages: Content, metadata, breadcrumbs, sibling navigation, optional post lists/taxonomy data
  • Pagination templates: Posts array, pagination object with URLs
  • Taxonomy templates: Taxonomy arrays with counts, type information

Performance Considerations

The template resolution system is optimized for performance:

  • File existence checks use Node.js existsSync()
  • Template paths are resolved once per request
  • The system stops at the first matching template found
  • Fallback chain ensures content always renders
  • Reserved paths are checked early to avoid unnecessary processing

This hierarchical approach provides theme developers with maximum flexibility while maintaining predictable fallback behavior and optimal performance.