How Ghost's themes work under the hood
Ghost's theme system is a powerful and flexible framework that allows users to customize the appearance and functionality of their Ghost-powered websites. Under the hood, it combines templating engines, structured data flow, and modular design to enable deep customization. Below is a detailed breakdown of how it works:
1. Templating Engine: Handlebars.js
Ghost uses Handlebars.js as its core templating engine. Handlebars allows developers to create dynamic HTML templates by embedding placeholders (e.g., {{title}}
) that are replaced with actual data at runtime. Key features include:
- Template Files: Each page type (e.g., homepage, post, tag archive) corresponds to a
.hbs
file (e.g.,index.hbs
,post.hbs
). - Context-Aware Rendering: Templates are rendered with specific data contexts. For example,
post.hbs
receives apost
object with properties liketitle
,content
, andpublish_date
. - Helpers: Ghost extends Handlebars with custom helpers (e.g.,
{{#has tag="news"}}
to conditionally render content) and output helpers (e.g.,{{content}}
to render sanitized HTML).
2. Theme Structure
A Ghost theme is a directory with a strict file/folder structure:
my-theme/
├── assets/ # CSS, JS, images (compiled/minified)
├── partials/ # Reusable components (e.g., header.hbs, footer.hbs)
├── templates/ # Main page templates (index.hbs, post.hbs, etc.)
├── default.hbs # Base layout wrapping all templates
├── package.json # Metadata (name, version, engines.ghost)
└── locales/ # Translation files for i18n (optional)
default.hbs
: The root layout that wraps every page. Includes boilerplate HTML and injection points like{{{body}}}
(where page content is inserted) and{{ghost_head}}
/{{ghost_foot}}
(for Ghost-generated scripts/styles).- Templates: Follow naming conventions (e.g.,
tag.hbs
for tag archives). Custom templates can be assigned via the Ghost admin panel. - Partials: Reusable snippets included via
{{> partial-name}}
.
3. Data Flow & Content API
- Data Sources: Ghost themes pull content from the Ghost Content API (v3 or v4). When a page is requested, the server fetches data (posts, authors, tags) from the database and injects it into the template context.
- Template Contexts: Each template has access to specific data:
post.hbs
: Receives apost
object withtitle
,excerpt
,feature_image
, etc.author.hbs
: Gets anauthor
object and their associated posts.- Global data like
@site
(site title, URL) and@config
(theme settings) is available everywhere.
4. Customization & Configuration
config.json
: Defines theme settings (e.g., color pickers, dropdowns) editable via the Ghost admin. These settings are accessible in templates via@custom.property_name
.- CSS Custom Properties: Themes often use CSS variables (e.g.,
var(--primary-color)
) linked toconfig.json
options, allowing dynamic styling without template edits. - i18n Support: Localization files in
locales/
enable multilingual themes using{{t "key"}}
helpers.
5. Asset Pipeline
- Preprocessing: Ghost supports CSS preprocessors (Sass, Less) and JS bundling via build tools (Webpack, Gulp). Developers often use
gscan
(Ghost's theme validator) during development. - Asset Helpers: The
{{asset}}
helper generates URLs for compiled assets (e.g.,{{asset "css/screen.css"}}
). - Image Optimization: The
{{img_url}}
helper generates responsive images withsrcset
and optimizes them via Ghost's image service.
6. Routing & Template Hierarchy
Ghost maps URLs to templates using a predefined hierarchy:
- Custom Templates: Assign specific templates to posts/pages via the admin panel.
- Context-Specific Files: For example,
tag.hbs
handles/tag/:tag/
routes. - Fallbacks: If no template matches, Ghost uses
index.hbs
as the default.
7. Hooks & Integrations
{{ghost_head}}
/{{ghost_foot}}
: Injection points for Ghost-generated code (SEO metadata, member scripts, or integration snippets).- Apps & Hooks: Themes can interact with third-party services via Ghost's Apps framework, which injects code at predefined hooks.
8. Development & Debugging
- Ghost CLI: Developers use
ghost install
andghost start
to run a local instance. Theghost doctor
tool checks for issues. - Theme Checks:
gscan
validates themes for compatibility and security. - Caching: Compiled templates are cached in production. Cache is disabled in development for real-time previews.
9. Security & Sanitization
- Output Sanitization: Content rendered via
{{content}}
is sanitized to prevent XSS attacks. - Strict Sandboxing: Themes run in a restricted environment—they can’t execute server-side code or directly access the database.
10. Updates & Maintenance
- Marketplace Updates: Themes installed via Ghost's marketplace receive version checks and one-click updates.
- Backward Compatibility: Ghost ensures theme API stability across versions, isolating core changes to prevent breakage.
11. Headless Mode (Decoupled Frontends)
For headless setups, Ghost's Content API delivers JSON data, allowing themes to be rebuilt with frameworks like React or Vue.js while retaining Ghost's backend.
Under the Hood Workflow
- Request Handling: When a user visits a URL, Ghost determines the appropriate template and data context.
- Data Fetching: Content is retrieved from the database/API.
- Template Rendering: Handlebars compiles the template, merges it with data, and executes helpers.
- Asset Injection: CSS/JS assets and Ghost scripts are added via helpers.
- Response: Final HTML is sent to the client.
By combining these elements, Ghost themes offer a balance of flexibility, performance, and ease of use, empowering both developers and content creators.