Loading...

Loading...

This article serves as both a complete usage tutorial for matery theme content tag plugins and an automated test sandbox.
The theme’s native tags are registered in themes/matery/scripts/tags/ (unified registration via index.js).
Automated tests assert the rendered markers indicated below.


1. Note

Purpose

Colored callout blocks inside posts, for warning / success / info / danger emphasis.

Syntax

{% note color %}content{% endnote %}
  • Color (optional, default default): default / primary / success / info / warning / danger
  • Alias: {% subnote %} (secondary note)

All Colors Example

default default note — plain hint

primary primary note — key emphasis

success success note — operation complete

info info note — supplementary

warning warning note — caution

danger danger note — serious warning

Effect

Colored rounded cards with a left color bar + icon (success ✓ / warning ⚠ / danger ✕).

Test assertion: page contains class="note" marker (6 colors, one each).


2. Timeline

Purpose

Show events / version records / growth history in chronological order.

Syntax

{% timeline title,color %}
<!-- timeline time-node -->
- event content (Markdown supported)
<!-- endtimeline -->
{% endtimeline %}
  • Title: overall timeline title
  • Color (optional): green / blue / red / orange etc.
  • Time nodes: <!-- timeline date --> separates each event

Example

Theme Feature Evolution

2026-08

  • Added content tag test page (note/timeline/tabs/label complete tutorial)
  • Gallery data refactor (galleries.yml three forms)
  • Unified lightGallery image viewer library

2026-07

  • Comment architecture optimization (comment: waline)
  • Fixed href=/ MIME style error

Effect

Vertical timeline with dot markers, color themes supported, titles rendered with Markdown.

Test assertion: page contains timeline marker + 3 time nodes.


3. Tabs

Purpose

Multi-tab content switching, great for categorized display / step-by-step instructions / comparisons.

Syntax

{% tabs unique-name,active-index %}
<!-- tab tab-title -->
content (Markdown and inline tags supported)
<!-- endtab -->
{% endtabs %}
  • Unique name: required, used to generate ids (spaces become -)
  • Active index: optional, default 1 (first tab activated)
  • Tab titles: <!-- tab title --> defines each tab

Example (first tab active by default)

  • Full-featured: content tags cover 10+ plugins
  • Flexible config: every feature independently toggleable
  • Performance: lazy loading + CLS placeholders
  • Many config options, learning curve at first
  • Some features depend on external CDN
  • Tech blogs: code / tutorials / comparisons
  • Personal blogs: galleries / projects / history

Effect

Materialize tabs style, click to switch, active tab highlighted.

Test assertion: page contains nav-tabs marker + 3 tabs.


4. Label

Purpose

Inline colored mini labels for keywords / status / category annotations.

Syntax

{% label color@text %}
  • Color (optional, default default): default / primary / success / info / warning / danger
  • ★ Note the parameter order: color BEFORE @, text AFTER @ (source uses split('@'), classes=args[0], text=args[1])

All Colors Example

Default Primary Success Info Warning Danger

Effect

Inline rounded colored labels, text on white or colored background.

Test assertion: page contains class="label" marker (6 colors).


5. Button

Purpose

CTA buttons inside posts, for links / downloads / action entries.

Syntax

{% button link,text,icon,title %}
  • ★ Link is the FIRST argument (source: url=args[0], text=args[1])
  • Link: required, target URL (relative path / allowed)
  • Text: button display text
  • Icon (optional): Font Awesome icon name (e.g. home, github; fa fa- prefix auto-added)
  • title (optional): hover tooltip text (not a color!)
  • Alias: {% btn %}

Example

Home GitHub About Text-only button

Effect

Materialize-style buttons with icon + ripple click effect.

Test assertion: page contains btn marker (≥4 buttons).


6. GitHub Card

Purpose

Show a GitHub repo info card (repo name / description / stars / forks).

Syntax

{% githubCard user:username repo:repo-name %}
  • user: required, GitHub username
  • repo: required, repository name
  • Optional params (advanced): width / height / theme / align

Example

Effect

Repo card: name + description + stars / forks, click to visit the repo. Depends on GitHub API (falls back to a link on failure).

Test assertion: page contains github-card or repo name link marker.


7. Mermaid Diagrams

Purpose

Render Mermaid diagrams (flowcharts / sequence diagrams / class diagrams etc.).

Front-matter Config (important)

mermaid: true    # Enable in post front-matter (otherwise Mermaid won't render)

Also requires enabling in the theme _config.yml:

post:
  mermaid:
    enable: true

Syntax

{% mermaid %}
graph TD
    A --> B
{% endmermaid %}

Example 1: Flowchart (graph)


graph TD
    A[Build] --> B{Test}
    B -->|Pass| C[Deploy]
    B -->|Fail| D[Fix]
    D --> B
    C --> E[Monitor]

Example 2: Sequence Diagram (sequenceDiagram)


sequenceDiagram
    participant U as User
    participant S as Server
    participant D as Database
    U->>S: Send request
    S->>D: Query data
    D-->>S: Return result
    S-->>U: Respond with page

Example 3: Class Diagram (classDiagram)


classDiagram
    class User {
        +String name
        +login()
    }
    class Blog {
        +String title
        +publish()
    }
    User --> Blog

Effect

Mermaid renders to SVG diagrams, adapting to dark mode (theme already handles it).

Test assertion: page contains class="mermaid" marker (≥3 diagrams).


8. PDF Embed

Purpose

Embed a PDF file viewer inside a post.

Syntax

{% pdf file-URL %}
  • File URL: PDF address (local or remote)

Example

{% pdf /medias_webp/docs/sample.pdf %}

Effect

PDF.js viewer (page flip / zoom / download).

Test assertion: page contains pdf-related container marker.


9. Insert Fragment (insertmd)

Purpose

Insert Markdown template fragments from source/_template/ for content reuse.

Syntax

{% insertmd 'filename.md' %}
  • Filename: file under source/_template/ (including .md extension)

Example

{% insertmd 'disclaimer.md' %}

Effect

Renders the template fragment content at the current position (async loading, supports nesting).

Test assertion: rendered output contains template fragment content.


10. WeChat Dialog Card

Purpose

Render a WeChat chat interface card, for dialog examples / support scenarios.

Syntax

{% wechat_dialog %}
User: what the user says
Assistant: the AI/support reply
{% endwechat_dialog %}
  • Line format: lines starting with User: = right-side user bubble; Assistant: = left-side assistant bubble
  • Supports: multi-line content, Markdown rendering (bold / lists etc.)
  • Alias: {% wd %} equals {% wechat_dialog %}

Example

User

Hi, I'd like to learn about the matery theme

Assistant

Sure, how can I help?

User

What features does the theme support?

Assistant

Content tags, galleries, search, comments and 20+ more features

Effect

WeChat-style chat bubbles, left/right split, avatar + bubble.

Test assertion: page contains WeChat dialog container marker (.chat-container).


11. Group Image

Purpose

Display multiple images in a row/column grid layout (auto column splitting).

Syntax

{% groupimage count layout %}
![caption 1](image-URL-1)
![caption 2](image-URL-2)
{% endgroupimage %}
  • First parameter: number of images (2–10)
  • Second parameter (optional): layout (e.g. 2-1 means 2 on the first row, 1 on the second)
  • Images: standard Markdown image syntax inside the tag body
  • Alias: {% gi %} equals {% groupimage %}

Example (3 images, 2+1 layout)

cover 1
cover 2
cover 3

Effect

Image grid layout (2+1 columns), zoom on hover.

Test assertion: page contains group-image container marker.


12. URL Card (cardurl)

Purpose

Show a summary card for a link (title, description, icon), for recommended links / cited resources.

Syntax

{% cardurl [url=target-link] [title=title] [desc=description] [avatar=icon-URL] %}
  • Params: bracket [key=value] format
    • url required, target link
    • title optional, card title (defaults to url)
    • desc optional, description text
    • avatar optional, icon image URL

Example

Effect

Link card: site icon + title + description, click to jump.

Test assertion: page contains URL card container marker (.card-url-wrapper).


13. Admonition (markdown-it-container)

Purpose

Render callout containers using the ::: type syntax via the markdown-it-container plugin (warning / note / info / attention / error), distinct from the note tag.

Syntax

::: warning
*put warning content here*
:::
  • Types: warning / note / info / attention / error etc.

Example

This is a warning container — content that needs attention!

This is a note container — supplementary info.

This is an info container — informational.

This is an attention container — caution.

This is an error container — serious error.

Effect

Callout containers with a left color bar + icon + light background.

Test assertion: page contains admonition container marker.


14. Encrypt Fragment Tag ({% encrypt %})

Purpose

Encrypt a segment of markdown content within a post. Enter the password to decrypt and reveal the content. Each fragment has its own independent password.

Syntax

{% encrypt password "title" "description" %}
encrypted markdown (can contain nested tags like note/timeline)
{% endencrypt %}
ParameterRequiredDescription
password✅Decryption password (Hexo auto-strips quotes)
title (second quoted param)❌Prompt text shown above the password input
description (third quoted param)❌Placeholder text shown inside the input field

Example (test fragment)

Private Content

Effect

  • After rendering, the segment becomes an encrypted container (password input); enter test-secret to decrypt and reveal
  • Nested tag support: fragments can contain {% note %} and other tags (Method Y: after_post_render secondary rendering, verified working)
  • No plaintext leakage: the rendered HTML contains no segment plaintext (encryption happens on the final HTML)
  • No re-entry needed: after decryption, refreshing within 1 day skips the password prompt (stores derived dk, not the password, with TTL mechanism)

Automated Testing

Encryption unit tests tools/tests/unit/unit-encrypt.test.js + unit/unit-encrypt2.test.js cover: AES-GCM + PBKDF2 round-trip / fragment decryption / internal note rendering / markdown bold / dk storage without password; post-decrypt runtime behaviour is verified by gate layer L2y.

Wiki Full-Page Encryption (docs-sidebar)

Wiki document pages (layout/wiki.ejs) support full-page encryption: configure encrypt_password in the sidebar data source (source/_data/docs-sidebar.yml) to encrypt all pages under that wiki, enter password to decrypt and render.

# source/_data/docs-sidebar.yml
encrypt_password: "your-password"    # Required, encrypts entire wiki section
encrypt_message: This page is encrypted      # Optional, prompt text
encrypt_placeholder: Enter password   # Optional, input placeholder

Cross-page sharing: after decryption, the derived key (dk) is stored in localStorage; other pages under the same wiki auto-decrypt without re-entering the password.

Test assertion: L2y (wiki encrypted page decryption) + L8 8c (encrypted wiki accessible).

Unified Post-Decryption Refresh

After decrypting encrypted content, page components need re-initialization (before decryption the DOM contains only ciphertext). The unified trigger point: hbe-bundle onSuccess callback (shared across post / gallery / wiki / fragment); each listener keeps only its specific handling; config keys with the encrypt_ prefix are skipped during sidebar rendering (not shown as table of contents items).

ComponentPost-Decryption Action
Code blockscodeWidget() scans new pre elements and generates toolbar
Image lightboxarticleInit() wraps img elements → lightGallery
Mermaidevents.refresh() re-renders (idempotent)
LayoutrefreshLayout() re-arranges

See the Layout chapter §8 “Unified Post-Decryption Refresh” for the full table. Test assertion: L2y (post-decryption component initialization).


15. Math Formulas (MathJax / KaTeX dual channel)

Purpose

LaTeX formula rendering in the body + formulas embedded in mind maps; MathJax and KaTeX coexist as a dual channel.

Configuration (root _config.yml + theme _config.yml)

# Root _config.yml: markdown-it-mathjax3 (Node-side SSR outputs MathJax SVG)
markdown:
  plugins:
    - name: markdown-it-mathjax3
      options:
        tex:
          inlineMath: [['$', '$']]
          displayMath: [['$$', '$$']]
          processEscapes: true

# Theme _config.yml: post.math engine (Fluid style, pick one)
post:
  math:
    enable: false          # When enabled, posts can use math by default
    specific: true         # When true, requires front-matter `math: true` to activate
    engine: mathjax        # Options: mathjax | katex
  • engine: mathjax (default): $...$ inline / $$...$$ block (mathjax3 5.x hardcodes $/$$, \(...\) not supported)
  • engine: katex: when switching, comment out markdown-it-mathjax3 and enable texmath — supports $...$/$$...$$ + \(...\)/\[...\] (brackets must be standalone blocks), frontend loads KaTeX CSS (SSR already rendered, no JS needed)
  • markmap mind map embedded formulas: hexo_markmap.features includes math → formulas inside mind maps render via KaTeX (.katex)

Syntax

Inline formula: $E=mc^2$
Block formula:
$$
\int_0^1 x^2 dx = \frac{1}{3}
$$

Example

Inline formula: E=mc2; block formula:

∫0∞e−x2dx=π2

Implementation Effects

  • Body formulas render as MathJax SVG (<mjx-container>), no frontend JS needed (SSR output)
  • Mind map embedded formulas render as KaTeX (.katex)
  • Dark/light theme adaptive

Test assertion: tools/tests/rich-content-integration.test.js (L2o): formula page mjx-container ≥ 10 + katex ≥ 1 (dual channel).


16. Mind Map markmap

Purpose

Render Markdown lists as interactive mind maps (zoom/collapse/links).

Configuration (root _config.yml hexo_markmap)

hexo_markmap:
  CDN: 'jsdelivr'   # 2026-08-24: fastly.jsdelivr.net unreachable, switched to cdn.jsdelivr.net
  features:
    - math          # formulas inside mind maps (KaTeX)
    - prism         # code highlighting
    - zoom          # zoom
  theme: auto

Syntax

{% markmap 350px %}
- Node 1
  - Child node 1.1
  - Child node 1.2
- Node 2
{% endmarkmap %}
  • Height parameter: {% markmap 350px %} (optional, default height)
  • Content: standard Markdown unordered list (supports links / inline code / bold / KaTeX formulas)

Example

Implementation Effects

Markdown lists render as interactive mind maps (.markmap-container svg), supporting zoom/collapse/link jumps, dark-mode adaptive.

Test assertion: tools/tests/rich-content-integration.test.js (L2o): .markmap svg renders.

Coexistence with encrypted segments (important): markmap’s four scripts (d3 / markmap-view / markmap-toolbar / init) are localized by an after_render:html filter. Pages containing {% encrypt %} use a serial onload-chain loader instead of <script defer> — because per the HTML spec a dynamically inserted <script> ignores defer (its async defaults to true). When the hbe decryption flow re-inserts them, they execute in download-completion order, exactly inverting the dependency chain (init at 1.8KB finishes first → window.markmap undefined; d3 at 280KB finishes last → markmap-view throws d3 is not defined). Static pages keep defer (parallel download, better first paint). Full root cause and debugging lessons: docs/EXPERIENCE.md §58.


Appendix: Non-Tag Theme Features

The following three items are not “article-embedded tag plugins” (§1–§16) but rather standalone theme-level features. They are grouped here to distinguish the boundary between tag and non-tag features.

17. Typewriter typing (fun_features)

Purpose

Homepage banner subtitle typewriter animation (same source as subtitle.typed in Interaction & Visual §3, config aggregated under fun_features.typing).

Configuration (theme _config.yml fun_features)

fun_features:
  typing:
    enable: true      # Typewriter switch
    typeSpeed: 70     # Typing speed, larger = slower
    cursorChar: "_"   # Cursor character
    loop: false       # Whether to loop

Implementation Effects

  • Homepage banner subtitle types out character by character + cursor blinks (.typed-cursor)
  • Supports index.slogan.api endpoint for the subtitle (falls back to the text field on request failure)
  • page.subtitle: false disables the typewriter on a single page

Test assertion: tools/tests/rich-content-integration.test.js (L2o): homepage .typed-cursor exists.


18. Social Share sharejs

Purpose

Social share buttons at the bottom of posts (Weibo/WeChat/QQ/Douban, etc.), one-click sharing of the current article.

Configuration (theme _config.yml)

sharejs:
  enable: true
  # Supported order: twitter, facebook, google, qq, qzone, wechat, weibo, douban, linkedin
  sites: twitter,facebook,qq,qzone,wechat,weibo,douban

# addthis alternative (pick one of sharejs / addthis)
addthis:
  enable: false
  pubid: 613a04428f842fe1

Implementation Effects

  • .social-share share bar at the bottom of posts (the data-sites attribute controls which platforms show)
  • WeChat share generates a QR code (data-wechat-qrcode-helper hint text)
  • Rendered only on post pages (page.layout == 'post')

Test assertion: tools/tests/rich-content-integration.test.js (L2o): .social-share component exists.


19. Live2D Mascot

Purpose

Live2D mascot in the bottom-right corner (pure static models, no PHP backend), interactive chat / model switching.

Configuration (theme _config.yml)

live2dWidget:
  enable: true

Implementation Effects

  • Mascot container (#live2dcanvas / #waifu) fixed in the bottom-right corner
  • Returning-visitor guard: loads only when localStorage.viewCount > 1 (not on first visit, performance protection)
  • Models are static in source/live2d/ (Cubism2/Cubism5 dual runtime), dark-mode adaptive

Test assertion: tools/tests/rich-content-integration.test.js (L2o): after setting viewCount=3, the mascot container exists.


⚠️ Known Pitfalls

Pitfall 1: Double Section Numbering

Symptom: Headings render as “1. 1. Overview” (two numbers).

Cause: Theme CSS auto-adds numbers to h2–h6 by default; hand-written numbers (e.g. ## 1. Overview) stack on top.

Fix: Pages with hand-written numbering add closeAutoTocNum: true in front-matter; pages without hand-written numbering must not add this field.

This article already correctly sets closeAutoTocNum: true.

Pitfall 5: Config Changes Require Clean Build

Symptom: After modifying tag plugin configuration (e.g. post.mermaid.enable, live2dWidget.enable, sharejs.enable etc.), the page doesn’t update.

Cause: Hexo’s caching mechanism doesn’t auto-detect configuration changes.

Fix: After changing config, you must npm run clean && npm run build.


Appendix: Tag Plugin Quick Reference

PluginSyntaxKey ParamsNeeds frontmatter
note{% note color %}content{% endnote %}6 colorsno
timeline{% timeline title,color %}...{% endtimeline %}title / colorno
tabs{% tabs name,index %}...{% endtabs %}name / indexno
label{% label color@text %}color first, text afterno
button{% button link,text,icon,title %}link first / text secondno
githubCard{% githubCard user:xx repo:yy %}user / repono
mermaid{% mermaid %}...{% endmermaid %}diagram typeyes (mermaid: true)
pdf{% pdf URL %}URLno
insertmd{% insertmd 'file.md' %}filenameno
wechat_dialog{% wechat_dialog %}User:/Assistant: lines{% endwechat_dialog %}User/Assistant linesno
groupimage{% groupimage count layout %}![img](url){% endgroupimage %}count / layoutno
cardurl{% cardurl [url=xx] [title=xx] [desc=xx] %}url / title / descno
admonition::: type content :::warning/note/info/attention/errorno
encrypt{% encrypt password "title" "desc" %}...{% endencrypt %}password / title / descno
math$...$ / $$...$$mathjax3 (SSR SVG) / katex engineyes (mathjax: true)
markmap{% markmap 350px %}list{% endmarkmap %}height / features (math/prism/zoom)no
typewriterfun_features.typingtypeSpeed / cursorChar / loopno
sharesharejs.sitestwitter / wechat / weibo etc.no (post pages only)
Live2Dlive2dWidget.enablereturning-visitor guard viewCount>1no

References

系列教程

全部文章RSS订阅

Hexo 主题功能测试系列


Hexo Theme Feature Test - Content Tags
Posted on
August 7, 2026
reprint policy. If reproduced, please indicate source
Support
Comments
Data Loading...
 Previous

Read More

Hexo Theme Feature Test - Interaction & Visual
Hexo Theme Feature Test - Interaction & Visual Hexo Theme Feature Test - Interaction & Visual
Complete tutorial and test for matery theme interaction & visual features: code block enhancements, image lightbox, type
2026-08-07
Next 

Read More

Hexo Theme Feature Test - Layout & Pages
Hexo Theme Feature Test - Layout & Pages Hexo Theme Feature Test - Layout & Pages
Complete tutorial and test for matery theme layout and page features: post layout features (prev/next navigation, copyri
2026-08-07