Blog Creation Automation Workflow
This document records the complete workflow for letting AI create a new blog post in this repo.
Its relationship with Life Blog Writing Workflow is:
life-blog-writing-workflow.mdremains the source of truth for life blog writing style, image layout, frontmatter,TravelGallery layout="article", and the tag system.- This document describes the execution workflow, from receiving source material to image upload, Chinese and English writing, review pause, TTS, troubleshooting, build verification, and optional git commit.
- When the two documents overlap, the older document answers "what should the article look like," while this document answers "what should AI do, and in what order."
One sentence summary:
When the user says "I want to create a new blog post," AI should enter this standard workflow and ask for the required materials.
Trigger Phrases
Enter this workflow when the user says things like:
- I want to create a new blog post
- I want to write a life blog
- Help me record this meal / outing / exhibition / experience in my blog
- I have a set of photos and want to publish them as a blog post
- Help me write a Chinese and English blog post and generate audio
AI should not start writing immediately. It should first check whether the source material is enough.
If the user only gives one sentence, ask them to prepare the following information.
What the User Should Prepare
Minimum required input:
- Topic:
- Date:
- Place / restaurant / event:
- Core thing to record:
- Image material:
- Whether AI may read original images:
- Whether an English version is needed:
- Whether TTS audio is needed:
Recommended richer input:
- Chinese title:
- English title:
- Preferred filename slug:
- Dish / object / scene list:
- Photo order or thumbnails:
- What each photo roughly corresponds to:
- Details to emphasize:
- Expressions to avoid:
- Tone preference:
- Cover image candidate:
- Whether image upload to OSS is needed:
- Whether version bump and git commit are needed:
For restaurant visits, gatherings, exhibitions, or life-record posts that do not belong under docs/Travel, this is the recommended template:
- Event: eating conveyor-belt sushi at Hama Sushi in Qiyi Plaza
- Date: 2026-05-02
- Place: Hama Sushi, Qiyi Plaza
- Title: 滨寿司:在回转寿司大吃一顿哦~
- English title: Hama Sushi: A Big Conveyor-Belt Sushi Meal
- Dishes:
- Caramel-seared salmon
- Large-cut foie gras
- Onsen egg udon
- Emphasis:
- The ordering tablet has no cart; tapping places the order immediately
- I went late and barely waited
- My favorites were caramel-seared salmon, large-cut foie gras, and onsen egg udon
- Image restriction: only thumbnails may be used; original images must not be read
- English version: yes
- TTS: generate only after article review
Source Material Rules
After receiving material, AI should make decisions first and avoid rushing into writing.
It must confirm:
- Event date, which determines the filename date. Do not use the writing date as a substitute.
- Title. If the user already gave one, use it.
- English title. If the user gave one, do not invent another.
- Whether original images may be read.
- Whether images already have OSS URLs or need uploading.
- Whether images need renaming.
- Whether an English version is needed.
- Whether TTS is needed.
- Whether git commit is needed.
If the user explicitly says original images must not be read, that is a hard constraint.
In that case, AI may only use:
- Thumbnails provided by the user
- Screenshots provided by the user
- User-written descriptions
- Filenames
- Already generated URL lists
AI must not open originals, read EXIF, preview originals again, or use image-processing commands to inspect original image content.
Image Handling and Upload Workflow
If local images need to be handled, use the following order.
1. Build an Image Naming Table First
Default naming format:
YYYY-MM-DD-topic-image-name.jpg
Use lowercase English and connect words with hyphens.
For the Hama Sushi post:
2026-05-02-hamasushi-aburi-caramel-salmon.jpg
2026-05-02-hamasushi-large-cut-foie-gras.jpg
2026-05-02-hamasushi-onsen-egg-udon.jpg
2026-05-02-hamasushi-tempura-platter-01.jpg
If one dish has multiple photos, use -01, -02, and so on.
2. Group Images by Article Structure
Do not put every image into one large array.
Life blog posts should group images by scene:
storePhotos: storefront, queue screen, ordering screen, table condimentssushiPhotos: main sushi plateswarmFoodPhotos: udon, ramen, tempuralateOrderPhotos: items added in the later part of the mealendingPhotos: table overview, receipt, closing images
This gives the article a better rhythm than a single photos array.
3. Upload to a Reasonable OSS Directory
Default path format:
blog/<topic>/<YYYY-MM-DD>/
Example:
blog/hamasushi/2026-05-02/
Published URL:
https://picture.nevergpdzy.cn/blog/hamasushi/2026-05-02/2026-05-02-hamasushi-aburi-caramel-salmon.jpg
After upload, save a URL list for MDX writing and troubleshooting.
4. Choose a Cover Image
Any blog post with images must set image in frontmatter.
Choose the most representative image in the article, not necessarily the storefront. The Hama Sushi post finally used:
image: https://picture.nevergpdzy.cn/blog/hamasushi/2026-05-02/2026-05-02-hamasushi-aburi-caramel-salmon.jpg
The caramel-seared salmon represented the post better than the storefront photo.
Chinese Blog Creation
Chinese is the default language. Put the file under:
blog/YYYY-MM-DD-slug.mdx
Example:
blog/2026-05-02-hamasushi-big-conveyor-belt-sushi-meal.mdx
Life blog posts with images default to .mdx, because they need TravelGallery.
Frontmatter template:
---
title: "滨寿司:在回转寿司大吃一顿哦~"
authors: DingZhiyu
tags: [life, food]
description: 记录一次在学校旁边七一广场滨寿司的大吃一顿,从火炙焦糖三文鱼开始,把最近很火的回转寿司吃成了一篇生活博客。
image: https://picture.nevergpdzy.cn/blog/hamasushi/2026-05-02/2026-05-02-hamasushi-aburi-caramel-salmon.jpg
---
The body must include:
import TravelGallery from "@site/src/components/TravelGallery";- Image arrays containing
src,alt, andcaption - An H1 matching the title
<!--truncate-->at a reasonable point- Multiple
<TravelGallery images={...} layout="article" />blocks
Continue following Life Blog Writing Workflow:
- Do not write it as a restaurant rating or guide.
- Do not include recommendation scores, per-person cost, or star ratings unless the user asks.
- Do not invent dialogue, reactions, or events that did not happen.
- Use real details; do not just list the menu.
- Keep image captions short.
English Blog Creation
Put the English mirror file under:
i18n/en/docusaurus-plugin-content-blog/YYYY-MM-DD-slug.mdx
Example:
i18n/en/docusaurus-plugin-content-blog/2026-05-02-hamasushi-big-conveyor-belt-sushi-meal.mdx
The English translation must follow the Chinese draft closely.
Translate:
titleanddescription- Body text
- Image
altandcaption - Natural language visible to readers
Do not translate:
- URLs
importexport const- Variable names
tagsauthors- slug
- JSX component names and prop names
If the user manually edits the Chinese draft, the English draft must be checked again. Do not guess locally; sync the English version from the final Chinese draft.
Review Pause
This is a hard rule.
After the Chinese and English blog posts are written, stop and ask the user to review them.
Do not generate TTS before the user confirms.
The review handoff should include:
- Chinese MDX path
- English MDX path
- Title
- Cover image
- Whether the user's required points are included
- Any remaining uncertainty
The user may manually edit the Chinese draft. If that happens:
- Re-read the Chinese draft.
- Sync the English draft from the Chinese draft.
- Show both versions to the user again.
- Generate TTS only after confirmation.
The Hama Sushi post followed this pattern: the user edited the Chinese post multiple times, then the English post was rewritten from the updated Chinese version, and only then did TTS generation start.
TTS Generation Workflow
Start TTS only after the user explicitly confirms the Chinese and English drafts.
TTS project path:
D:\Code\tts-blog-generator
1. Dry Run First
Chinese:
cd D:\Code\tts-blog-generator
python generate.py --include hamasushi-big-conveyor-belt-sushi-meal --dry-run
English:
python generate.py --lang en --blog-dir "../Dev-Knowledge-Base/i18n/en/docusaurus-plugin-content-blog" --include hamasushi-big-conveyor-belt-sushi-meal --dry-run
Dry-run checks:
- It should match only the target article.
- slug should be correct.
- Chinese and English manifest keys should be correct.
- chunk count should look reasonable.
- output filenames should match expectations.
2. Generate Chinese Audio
Normal article:
$env:MIMO_API_KEY='your key'
python generate.py --include hamasushi-big-conveyor-belt-sushi-meal --force --article-jobs 1
If the Chinese article is long, or if there has been skipping, missing narration, or suspicious duration, lower the chunk limit:
$env:MIMO_API_KEY='your key'
python generate.py --include hamasushi-big-conveyor-belt-sushi-meal --force --article-jobs 1 --chunk-char-limit 900
The first Chinese audio for the Hama Sushi post skipped a section in the beginning. After confirming that text extraction was complete, it was regenerated with --chunk-char-limit 900, producing 3 chunks and fixing the issue.
3. Generate English Audio
$env:MIMO_API_KEY='your key'
python generate.py --lang en --blog-dir "../Dev-Knowledge-Base/i18n/en/docusaurus-plugin-content-blog" --include hamasushi-big-conveyor-belt-sushi-meal --force --article-jobs 1
Long English posts usually split automatically. The Hama Sushi English audio generated 4 chunks.
4. Copy the Blog-Specific Manifest
Only copy the blog-specific manifest:
Copy-Item output\blog-manifest.json ..\Dev-Knowledge-Base\src\data\blogAudioManifest.json
Copy-Item output\blog-manifest.json ..\Dev-Knowledge-Base\static\audio\blog\manifest.json
Do not copy output/manifest.json into the site. output/manifest.json is the combined manifest and may contain docs audio entries.
5. Check Manifest Entries
Chinese key:
"hamasushi-big-conveyor-belt-sushi-meal"
English key:
"en/hamasushi-big-conveyor-belt-sushi-meal"
If Chinese has 3 chunks, it should look like:
"urls": [
"https://picture.nevergpdzy.cn/Audio/blog/hamasushi-big-conveyor-belt-sushi-meal_001.mp3",
"https://picture.nevergpdzy.cn/Audio/blog/hamasushi-big-conveyor-belt-sushi-meal_002.mp3",
"https://picture.nevergpdzy.cn/Audio/blog/hamasushi-big-conveyor-belt-sushi-meal_003.mp3"
]
TTS Troubleshooting
1. Missing or Skipped Narration
First determine whether text extraction lost the content or the TTS generation skipped it.
Export the extracted text:
cd D:\Code\tts-blog-generator
@'
from pathlib import Path
import generate
slug = "hamasushi-big-conveyor-belt-sushi-meal"
path = Path("../Dev-Knowledge-Base/blog") / "2026-05-02-hamasushi-big-conveyor-belt-sushi-meal.mdx"
text = generate.extract_text(path)
chunks = generate.chunk_text(text, limit=900)
Path("output").mkdir(exist_ok=True)
Path("output/check_zh_hamasushi_text.txt").write_text(
"\n\n".join(
f"=== chunk {i:03d} / {len(chunks)} ({len(chunk)} chars) ===\n{chunk}"
for i, chunk in enumerate(chunks, 1)
),
encoding="utf-8",
)
print(len(text), [len(chunk) for chunk in chunks])
'@ | python -
If the check file is missing content, fix extract_text() or the MDX structure.
If the check file is complete but audio skips content, lower --chunk-char-limit and regenerate.
2. Delete Old Broken Audio
If an old audio file has been replaced by a new manifest entry, clean up the old object too.
Check whether the old URL is still referenced:
rg -n "hamasushi-big-conveyor-belt-sushi-meal\.mp3" src\data\blogAudioManifest.json static\audio\blog\manifest.json
Delete the local old MP3:
Remove-Item -LiteralPath "D:\Code\tts-blog-generator\output\hamasushi-big-conveyor-belt-sushi-meal.mp3" -Force
Also delete the old OSS object, for example:
Audio/blog/hamasushi-big-conveyor-belt-sushi-meal.mp3
After deletion, confirm that the manifest only references the new _001, _002, _003, and later chunk files.
3. Manifest Accidentally Changes Old Article URLs
The generator or copy process may accidentally change old English audio paths, for example from:
Audio/blog/en/en_article.mp3
to:
Audio/blog/en_article.mp3
This is outside the current article scope and must not be committed.
Fix:
- Use the Git HEAD version of the manifest as the base.
- Merge only the current article's Chinese and English entries.
- Diff again and confirm old article URLs did not change.
Common Errors and Fixes
1. Tags [food] are not defined in tags.yml
The article used a new tag in frontmatter, but the tag file does not define it.
Fix:
- Chinese: update
blog/tags.yml - English: update
i18n/en/docusaurus-plugin-content-blog/tags.yml
Example:
food:
label: Food
permalink: food
2. Build Failure
Run:
npm run build
If it fails, first determine whether the failure belongs to the current blog post:
- MDX syntax error
- Broken image array JSX
- Invalid frontmatter YAML
- Undefined tag
- English mirror path or extension mismatch
If the failure comes from an unrelated old page, explain it in the final note and do not casually modify unrelated files.
3. Unrelated Deletions in Git Status
Before committing, always check:
git status --short
If many unrelated files appear as deleted, stop.
Do not include those deletions in the commit.
Fix order:
- Confirm whether it is accidental deletion, directory abnormality, or a script side effect.
- Restore unrelated tracked files with
git restore -- <path>. - Stage only files related to the current task.
During the Hama Sushi follow-up commit, old files under blog/ appeared as deleted. They had to be restored first and were not committed.
4. User Provides a Secret Key
Use a TTS key only as an environment variable for the current process.
Do not write it into repo files.
Do not repeat the full key in the final response.
If the key has appeared in chat, recommend rotating it later.
Release Verification
After Chinese and English posts, audio, and manifests are ready, check at least:
- Chinese MDX path is correct.
- English mirror MDX path is correct.
- Filename date is the event date.
title,authors,tags,description, andimageare correct.- New tags are synced to both Chinese and English
tags.yml. - Every
TravelGalleryuseslayout="article". - Image URLs use
https://picture.nevergpdzy.cn/.... - Cover image represents the article.
- English draft matches the Chinese draft.
- TTS is generated only after user confirmation.
- Manifest contains Chinese and English audio entries.
- Old broken audio is no longer referenced by the manifest.
npm run buildpasses.
Versioning and Git Commit
If the user asks for a commit, read first:
VERSIONING.md
Common judgment:
- Typo fix, workflow doc fix, manifest fix:
PATCH - New public blog post or new non-breaking visible content:
MINOR - Route-breaking change or site structure rewrite:
MAJOR
Run the matching command:
npm run version:patch
npm run version:minor
npm run version:major
Confirm:
package.jsonchangedpackage-lock.jsonchangednpm run buildpassesgit status --shorthas no unrelated files
Commit messages must be real multi-line text.
Recommended format:
feat(blog): add Hama Sushi dining post and audio/新增滨寿司用餐博客与语音
Add a new bilingual blog post about ...
Register the new food blog tag ...
新增一篇关于 ...
在中英文博客标签元数据中 ...
Do not use escaped \n characters to fake a multi-line commit message.
Hama Sushi Case Study
This completed workflow is the reference case for future blog creation.
Key facts:
| Item | Value |
|---|---|
| Chinese title | 滨寿司:在回转寿司大吃一顿哦~ |
| English title | Hama Sushi: A Big Conveyor-Belt Sushi Meal |
| Date | 2026-05-02 |
| slug | hamasushi-big-conveyor-belt-sushi-meal |
| Chinese file | blog/2026-05-02-hamasushi-big-conveyor-belt-sushi-meal.mdx |
| English file | i18n/en/docusaurus-plugin-content-blog/2026-05-02-hamasushi-big-conveyor-belt-sushi-meal.mdx |
| Image directory | blog/hamasushi/2026-05-02/ |
| Cover image | 2026-05-02-hamasushi-aburi-caramel-salmon.jpg |
| Tags | [life, food] |
| Chinese audio | 3 chunks, --chunk-char-limit 900 |
| English audio | 4 chunks |
The most important lessons:
- If the user forbids reading originals, obey it and use only thumbnails and descriptions.
- Stop for user review after the Chinese and English drafts are written.
- If the user edits Chinese, sync English again.
- A successful Chinese TTS run can still skip text; listen to user feedback and inspect extracted text.
- After regenerating audio, delete the old broken local and OSS audio.
- TTS manifest diffs can accidentally change old URLs; inspect before committing.
- New tag
foodmust be added to both Chinese and English tag files. - Check for unrelated deletions before committing.
Default Future Procedure
When the user says "I want to create a new blog post," default to this sequence:
- Ask the user to prepare source material.
- Confirm image-reading permissions and event date.
- Rename and upload images to OSS if needed.
- Create the Chinese MDX file.
- Create the English mirror MDX file.
- Show both drafts to the user for review.
- Generate Chinese and English TTS only after confirmation.
- Copy the blog audio manifest.
- Run
npm run build. - If the user asks, update version according to
VERSIONING.mdand commit.
The most important step is step 6.
No user confirmation, no audio generation.