This is Toha, a personal portfolio theme for the Hugo static site generator.
- Goal: Showcase skills, experience, and thoughts (blog) with elegance and simplicity.
- Core Philosophy: Configuration over Code. Users should control the site via
data/andhugo.yamlwithout touching HTML/CSS. - Tech Stack: Hugo (Extended), SCSS, Vanilla JavaScript, Hugo Pipes.
We use mise for deterministic tooling and task management. Use brew install mise to install mise.
- Initialize: Run
mise run installto setup tools and dependencies. - Dev Server: Run
mise run example-site.- This will install all dependencies (root & exampleSite) automatically.
- Serves the site at
localhost:1313.
- Verify Changes: Run
mise run checkto execute both linters and a production build.
Toha differs from standard Hugo themes. The structure of the homepage and sidebar is primarily driven by JSON/YAML files in the data/ directory, not just the content/ directory.
data/: The source of truth for the site's layout configuration. Example data can be found underexampleSite/data.layouts/partials/: Contains the reusable UI components.assets/styles/: Styling. We use SCSS.
assets/images/: Theme-specific static images.scripts/: Vanilla JS files. Must be processed via Hugo Pipes.styles/: Stylesheets organized according to components, layouts, sections etc.
layouts/_default/Where base structure of pages are defined.partials/: Where the core logic lives. Break complex logic into partials.shortcodes/: Custom markdown components for users.
i18n/: Localization files. All user-facing text must be tokenized here.exampleSite/: The integration test bed.hugo.yaml: Main configuration.data/: Defines layout configurations.content/: Blog posts and markdown content.
- Semantics: Use semantic HTML5 (
<section>,<article>,<nav>). - Partials: If a block of code is used more than once, extract it to
layouts/partials. - IDs/Classes: Use meaningful kebab-case class names.
- Safe HTML: Use
safeHTMLonly when absolutely necessary and verified safe.
- No Inline CSS: All styles must reside in
assets/scss. - Variables: Use SCSS variables for colors and fonts (check
assets/styles/variables.scssfirst). - Responsiveness: Mobile-first approach is preferred, but ensure desktop elegance.
- Vanilla JS: Avoid adding libraries (jQuery, etc.) unless strictly necessary.
- Fingerprinting: All JS resources in templates must be fingerprinted for cache busting.
- Example:
$js := resources.Get "js/script.js" | fingerprint
- Example:
- DOM Manipulation: Ensure DOM elements exist before attaching listeners.
- Backward Compatibility: NEVER break existing
configordatastructures. - Configurability: Every new visual feature must be toggleable via
hugo.yamlordata/files. - Defaults: New features must be disabled by default.
- Localization: Do not hardcode English strings. Use
{{ i18n "string_id" }}.
- Create the partial in
layouts/partials/sections/. - Add the styling in
assets/styles/sections/. - Add the entry logic in
layouts/partials/<section-name>.html(or relevant parent). - Define the data schema in
exampleSite/data/<language code>/sections/<section-name>.yaml. - Wrap the rendering in a conditional check (e.g.,
if .Site.Params.features.newSection.enable).
- Reproduce it in
exampleSite. - Fix the logic in the theme
layoutsorassets. - Verify the fix by running
mise run check.