Loading...

Loading...

Directory Structure & Content Management

1. Blog Directory Structure

A typical Hexo + matery site layout (this blog as reference):

blog/
├── _config.yml              # Site config (Hexo core + all plugin configs)
├── package.json             # Dependencies and npm scripts
├── source/                  # ★ Content and standalone pages
│   ├── _posts/              #   Posts (Markdown)
│   ├── _drafts/             #   Drafts (render_drafts: false, not rendered by default)
│   ├── _data/               #   Data files (friends/galleries/sidebar etc., single source)
│   ├── _template/           #   Reusable Markdown fragments
│   ├── about/               #   Standalone pages (one directory + index.md each)
│   ├── tags/
│   ├── categories/
│   ├── friends/
│   ├── galleries/
│   └── ...                  #   Other standalone pages (msg, nav, docs etc.)
├── scaffolds/               # Templates used by hexo new (post/page/draft/gallery)
├── themes/
│   └── matery/              # Theme (layout templates + source static assets + scripts)
├── tools/                   # CI/CD scripts and toolchain (customized for this blog)
├── userConfig/              # User config and build templates (customized for this blog)
└── public/                  # Build output (generated by hexo generate, don't edit)

Key conventions:

  • Every Markdown file under source/ is rendered to HTML; standalone pages need layout in front-matter (e.g. layout: about), otherwise they render with the default post layout
  • public/ is build output, deleted by hexo clean — never edit it manually
  • Some paths in this blog (nav/, docs/, js/, libs/ etc.) are copied as-is via skip_render

2. Post Management

Create a Post

hexo new post "Post title"          # creates source/_posts/post-title.md
hexo new post --path 2026/xxx title # custom path

Quote the title if it contains spaces; filenames are auto-lowered (filename_case: 1). After creation, edit the Markdown file.

Drafts

hexo new draft "Unfinished idea"     # creates in source/_drafts/
hexo publish "Unfinished idea"       # publish: move to _posts/ and set the date

render_drafts: false in _config.yml means drafts are not generated by default. To preview drafts locally use hexo server --draft or hexo generate --draft.

Cache Notes After Changing Config/Data

  • After changing theme config or scripts/ scripts: hexo clean && hexo generate (rm -rf public is not enough — it misses hexo’s internal cache)
  • After changing source/_data/*.yml data files: delete db.json before generating, otherwise stale data may be read

Default permalink format:

# _config.yml
permalink: posts/:abbrlink/

The hexo-abbrlink plugin generates a short code per post with crc32 + hex (e.g. posts/40300608/). writeback: false (disabled since 2026-09-22 to prevent a resident server from clobbering source files) means the plugin does not write back — abbrlink is written into the front-matter on first generation and stays fixed:

---
title: My post
abbrlink: a1b2c3d4   # written on first generation, don't edit manually
---

Once generated, abbrlink is fixed — renaming the file or changing the title won’t affect the URL, which keeps external links stable. Configuration:

abbrlink:
  alg: crc32    # algorithm: crc16 / crc32
  rep: hex      # representation: dec / hex
  drafts: false # generate for drafts
  force: false  # force recompute (changes existing URLs, use with care)

4. Front-matter Quick Reference

Front-matter is the YAML block at the top of a post (wrapped in ---), defining post metadata. Common fields used by the matery theme:

FieldDescriptionDefault
titlePost titlefilename
dateCreation datefile creation time
updatedUpdate datefile modification time
layoutLayout: post / page / about / tags etc.post
categoriesCategories (array, supports nesting [parent, child])-
tagsTags (array)-
keywordsSEO keywords-
excerptHomepage excerpt (plain text)-
imgPost cover image (shown on homepage cards)-
topPin to homepagefalse
hideFully hide: not in homepage list, not in carouselfalse
coverEnter homepage carousel (ineffective when hide: true)false
coverImgCustom carousel image (takes priority over default)-
tocShow table of contentstrue
tochideHide the TOC sidebar by defaultfalse
mathjaxLoad MathJax for math formulasfalse
mermaidLoad Mermaid for diagramsfalse
echartsLoad EChartsfalse
commentsEnable commentstrue
commentComment engine (e.g. waline; false disables)theme default
passwordPost encryption password (for per-post encryption)-
reprintPolicyCopyright policy (e.g. cc_by_nc_sa)-
abbrlinkPermalink short codewritten on first generation (no writeback)

Example:

---
title: Example post
date: 2026-08-16 12:00:00
categories: [Tutorial]
tags:
  - hexo
  - matery
img: /medias_webp/cover/write.webp
top: false
hide: false
toc: true
mathjax: false
mermaid: true
comments: true
comment: waline
---

When creating a post, scaffolds/post.md brings in the template fields above — add or remove as needed.

5. Data Files (_data)

source/_data/ holds the single sources of truth the theme reads, avoiding scattered duplicate data. Hexo auto-loads yml/yaml/json files in this directory — the filename (minus extension) becomes the key, accessible in templates via site.data.<filename>.

5.1 File Inventory

FilePurposeConsumer
friends.ymlFriend link data — each entry has name / avatar / introduction / url / title (optional)friends.ejs template, site.data.friends
galleries.ymlGallery data — top-level galleries: array; each gallery has name / cover / description / photos (supports single-image objects, path strings, and directory scanning)galleries.ejs template, site.data.galleries
tutorial-sidebar.ymlTutorial wiki sidebar navigationwiki.js helper’s wiki_sidebar()
api-sidebar.ymlAPI wiki sidebar navigationsame
dev-sidebar.ymlDev wiki sidebar navigation (also has encrypt_password and other encryption metadata at the top, not part of navigation)same
docs-sidebar.ymlDocs wiki sidebar navigationsame

5.2 Sidebar File Structure

The four *-sidebar.yml files share a uniform structure:

# Language-agnostic page tree (section → page → html path)
structure:
  getting_started:
    overview: index.html
    features: features.html
  guides:
    layout: guide/layout.html
# Per-language display text (key = preference.lang_meta namespace)
i18n:
  zh-cn:
    getting_started: 开始使用
    overview: 概述
  en:
    getting_started: Getting Started
    overview: Overview
  • structure: defines the navigation hierarchy and page paths, contains no language-specific text
  • i18n: display text grouped by language; keys correspond to preference.lang_meta in languages/*.yml
  • encrypt_* (only in dev-sidebar.yml): top-level metadata controlling wiki encryption (encrypt_password required, encrypt_message / encrypt_placeholder optional); not used in navigation rendering

The consumer is themes/matery/scripts/helpers/wiki.js’s wiki_sidebar() function, which reads site.data[wiki + '-sidebar'] and merges i18n text.

5.3 How to Add

ActionSteps
Add a friend linkAppend a - name: xxx block at the end of friends.yml, fill in all 5 fields
Add a galleryAppend an entry to the galleries: array in galleries.yml; also create source/galleries/<name>/index.md with layout: gallery
Add a wiki sidebar entryAdd a key + html path in the structure of the relevant {wiki}-sidebar.yml, and add translations in i18n for each language

5.4 Cache Notes

After modifying _data/*.yml, you must delete db.json before rebuilding (rm -f db.json && hexo generate), otherwise Hexo’s incremental cache may serve stale data, causing blank pages. The tools/cicd.sh -d build handles this automatically.

Next Steps

Comments
Data Loading...