Skip to content

sredevopsorg/sredevopsorg-ghost-theme

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

100 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SREDevOps.org Ghost Theme (v2 WiP)

Ghost v6 Theme for SREDevOps.org — Multi-locale, Tailwind CSS v3, responsive, dark-mode first and tag-based language filtering.

License: MIT Ghost Compatibility Node Engine


v2 To Do

  • Fix primary menu navigation, mobile views and small screens doesn't render correctly
  • Improve responsive design for secondary navigation menu
  • Create login and search forms for the main navigation menu, as optional features (Ghost Docs: https://docs.ghost.org/themes/custom-settings)

🌐 Multi-Locale Architecture

This theme implements a template inheritance + tag-based routing strategy to serve distinct content per locale without requiring separate Ghost instances. This approach aligns with community workarounds discussed in the Ghost Forum.

Template Inheritance Pattern

┌─────────────────────────────────────┐
│ routes.yaml                          │
│ • /en/* → home-en.hbs               │
│ • /es/* → home-es.hbs               │
│ • /br/* → home-br.hbs               │
└─────────┬───────────────────────────┘
          │
          ▼
┌─────────────────────────────────────┐
│ home-*.hbs (collection template)    │
│ • Defines collection query/filter   │
│ • Renders post list via partials    │
│ • {{!< default-*.hbs}} inheritance  │
└─────────┬───────────────────────────┘
          │
          ▼
┌─────────────────────────────────────┐
│ custom-*.hbs (post/page template)   │
│ • Locale-specific post layout       │
│ • Localized metadata, TOC, comments │
│ • {{!< default-*.hbs}} inheritance  │
└─────────┬───────────────────────────┘
          │
          ▼
┌─────────────────────────────────────┐
│ default-*.hbs (layout shell)        │
│ • <html lang="*"> attribute         │
│ • Common <head>, assets, footer     │
│ • {{{body}}} injection point        │
└─────────────────────────────────────┘

💡 Key Insight: Each locale uses its own default-*.hbs layout shell to ensure proper lang attributes, meta tags, and localized UI strings. The {{{body}}} Handlebars placeholder in default-*.hbs receives the rendered output from custom-*.hbs or home-*.hbs.

Language Routing & Tag Filtering

Locale URL Pattern Required Tags Exclusion Tags Layout Shell
English (default) / or /en/{slug}/ en, hash-en -es, -br default.hbs
Spanish /es/{slug}/ es, hash-es -en, -br default-es.hbs
Portuguese (BR) /br/{slug}/ br, hash-br -en, -es default-br.hbs

⚠️ Critical: The default locale (English) is configured in Ghost Admin → Settings → General → Publication language. All root-level routes (/, /page/2/, etc.) serve English content unless explicitly routed otherwise.

routes.yaml Core Configuration

collections:
  /es/:
    template: home-es
    permalink: /es/{slug}/
    filter: tag:es+tag:-en+tag:-br
    data: tag.es

  /en/:
    template: home-en
    permalink: /en/{slug}/
    filter: tag:en+tag:-es+tag:-br
    data: tag.en

  /br/:
    template: home-br
    permalink: /br/{slug}/
    filter: tag:br+tag:-es+tag:-en
    data: tag.br

# Fallback: English as default locale (configured in Ghost Admin)
taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

Why this works: Ghost's filter syntax supports boolean logic (+ for AND, - for NOT), enabling precise content segregation per locale while maintaining a single content database. The template directive ensures each collection uses its locale-specific layout chain.


📋 Table of Contents


🔧 Prerequisites

Dependency Version Purpose
Node.js >=22 Runtime for build tooling
Yarn >=1.22 Package management (preferred over npm)
Ghost >=6.0 Local development server
Docker (optional) Latest Run Ghost via official container

🐳 Ghost Local Setup: Follow the official Docker guide for a reproducible dev environment.


🚀 Installation

1. Clone & Install

# Clone the repository
git clone https://github.com/sredevopsorg/sredevopsorg-ghost-theme.git
cd sredevopsorg-ghost-theme

# Install dependencies (Yarn required)
yarn install

2. Configure Ghost

  1. Start your local Ghost instance:

    # If using Docker Compose (recommended)
    docker compose up -d
    
    # Or via Ghost-CLI
    ghost start
  2. Upload routes.yaml to Ghost Admin → Settings → Routing

  3. Upload the theme:

    • Via Admin: Settings → Design → Upload theme

    • Or symlink for development:

      ln -s /path/to/sredevopsorg-ghost-theme \
        /path/to/ghost/content/themes/sredevopsorg-ghost-theme
  4. Critical: Set your default locale in Ghost Admin → Settings → General → Publication language (e.g., en for English). This determines which templates serve root-level routes.

  5. Activate the theme in Ghost Admin → Design

3. Start Development Server

yarn dev

This triggers:

  • Tailwind CSS compilation with @tailwindcss/forms and @tailwindcss/typography
  • Asset bundling via Gulp
  • LiveReload for template/CSS changes

🔁 Hot reload is enabled for .hbs, .css, and .js files. Browser refreshes automatically on save.


✍️ Locale Content Authoring

Tagging Posts for Language Filtering

When creating content in Ghost Admin or via Markdown import:

---
title: "My Post Title"
slug: "my-post-slug"
tags:
  - en          # Primary language slug (required)
  - hash-en     # Required for filter consistency
  - Kubernetes  # Topic tags
  - SRE
---

⚠️ Critical: Omitting either en/es/br or its hash-* counterpart will cause the post to not appear in locale-specific collections due to the filter logic in routes.yaml.

Template Resolution Flow

graph LR
    A[Request: /es/my-post/] --> B[routes.yaml filter]
    B --> C{tag:es AND NOT en/br?}
    C -->|Yes| D[home-es.hbs]
    D --> E[Inherits default-es.hbs]
    E --> F[Render html lang='es']
    F --> G[Inject body from custom-es.hbs]
Loading

Creating Locale-Specific Templates

  1. Copy the base template:

    cp default.hbs default-es.hbs
    cp custom.hbs custom-es.hbs
    cp home.hbs home-es.hbs
  2. Update the layout shell (default-es.hbs):

    <!DOCTYPE html>
    <html lang="es"> {{!-- Critical for SEO/accessibility --}}
    <head>
      <meta charset="utf-8">
      <title>{{meta_title}}</title>
      {{!-- Spanish-specific OG tags --}}
      <meta property="og:locale" content="es_CL">
      {{ghost_head}}
    </head>
    <body class="{{body_class}}">
      {{>"components/nav-es"}} {{!-- Optional: localized nav --}}
      {{{body}}} {{!-- Injects custom-es.hbs content --}}
      {{>"components/footer"}}
    </body>
    </html>
  3. Customize content templates (custom-es.hbs):

    • Localize UI strings ("Autor", "Publicado", "Índice")
    • Adjust date formats ({{date published_at format="DD MMM YYYY"}})
    • Conditionally render locale-specific components

🏗️ Template Architecture Reference

File Role Inheritance Locale Scope
default.hbs Base HTML shell for English None (root) English (default)
default-es.hbs Base HTML shell for Spanish None (root) Spanish
default-br.hbs Base HTML shell for Portuguese None (root) Portuguese (BR)
custom.hbs Post/page content layout {{!< default}} English
custom-es.hbs Post/page content layout {{!< default-es}} Spanish
home.hbs Collection/listing template {{!< default}} English
home-es.hbs Collection/listing template {{!< default-es}} Spanish
post-card-es.hbs Post preview partial Standalone Spanish

🔄 Inheritance Syntax: {{!< filename}} at the top of a template tells Ghost: "Render this file's content inside the {{{body}}} placeholder of filename".


⚙️ Theme Configuration (To be implemented)

Customize behavior via Ghost Admin → Settings → Theme:

Option Type Default Description
background_color Color #0f172a Base background for dark theme
lazy_images Boolean false Enable native lazy-loading on homepage
share_buttons Boolean true Show social share UI on posts
show_langs Boolean false Display language switcher in sidebar
show_sso Boolean false Show SSO login option in sidebar

Image Size Presets

Configured in package.jsonconfig.image_sizes:

"image_sizes": {
  "xs": { "width": 100 },
  "s":  { "width": 220 },
  "m":  { "width": 300 },
  "l":  { "width": 600 },
  "xl": { "width": 900 }
}

Use in templates: {{img_url feature_image size="l"}}


🧪 Testing & Validation

Local Testing

# Build production assets
yarn build

# Validate theme against Ghost spec
yarn test:dev    # Verbose output
yarn test:ci     # Fail on warnings (for CI)

Locale-Specific Validation

# Test Spanish routing locally
curl -I http://localhost:2368/es/ | grep "lang"
# Expected: <html lang="es">

Lighthouse Audits

The theme targets:

  • ✅ Performance ≥ 90 (with lazy loading enabled)
  • ✅ Accessibility ≥ 95 (proper lang attributes per locale)
  • ✅ SEO ≥ 100 (with localized meta tags and hreflang)

Run via Chrome DevTools


🚢 Deployment

Option 1: Ghost Admin Upload

  1. Build assets:

    yarn build
  2. Zip the theme:

    zip -r sredevopsorg-ghost-theme.zip . \
      -x "*.git*" "node_modules/*" ".github/*"
  3. Upload via Ghost Admin → Design → Upload theme

Option 2: GitHub Actions (Recommended)

This repo includes a Deploy Ghost Theme Action that:

  • Builds assets on push to main
  • Deploys via Ghost Admin API
  • Supports environment-specific config (staging/prod)

Configure secrets:

  • GHOST_ADMIN_API_URL
  • GHOST_ADMIN_API_KEY

🤝 Contributing

We welcome contributions aligned with our Code of Conduct.

Development Guidelines

  • Branching: Use feature branches (feat/locale-switcher, fix/og-tags-es)
  • Commits: Follow Conventional Commits
  • PRs: Include screenshots for UI changes; update README if behavior changes
  • Testing: Run yarn test:ci before submitting

Adding a New Locale (e.g., pt for Portugal)

  1. Create layout shell:

    cp default.hbs default-pt.hbs
    # Edit: <html lang="pt">, OG locale, localized strings
  2. Create content templates:

    cp custom.hbs custom-pt.hbs
    cp home.hbs home-pt.hbs
    # Localize UI text, date formats, component partials
  3. Update routes.yaml:

    /pt/:
      template: home-pt
      permalink: /pt/{slug}/
      filter: tag:pt+tag:-en+tag:-es+tag:-br
      data: tag.pt
  4. Update documentation:

  5. Test thoroughly:

    • Verify lang="pt" in rendered HTML
    • Confirm tag filtering excludes other locales
    • Validate SEO meta tags with og:locale="pt_PT"

📜 License

  • Code: MIT License — use, modify, distribute freely
  • Content: CC BY 4.0 (for SREDevOps.org editorial content)
  • Third-party assets: Respect upstream licenses (Tailwind CSS: MIT, Ghost: MIT)

🙏 Credits


This theme was built in Chile 🇨🇱 with a proud latin American identity and fully committed to the principles and philosophy of FLOSS (Free/Libre and Open Source Software) — We ought to minimize external dependencies, optimized asset delivery, and community-driven localization patterns. For questions about deploying in Chile/Argentina/Brazil contexts, open an issue or reach out via SREDevOps.org.

Last updated: July 2026 | Ghost v6 compatible

About

Ghost v6 Theme for SREDevOps.org — Multi-locale, Tailwind CSS v3, responsive, dark-mode first, top navigation, and tag-based language filtering.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

10 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors