# AI 產 blog :::info - test ::: :::success - test ::: :::warning - test ::: :::danger - test ::: :::spoiler ==xxxxxxxxxxxxx== ::: fix(articles): support Chinese slugs - Fix slug generation regex in data.ts to support Chinese characters 目前已知需要處理的 hackmd 語法: - highlight - 語法開頭 `==` - 語法結尾 `==` - format to collapse html=`<mark></mark>` - callout section: info, success, warning, danger - 語法開頭 `:::info` - 語法結尾 `:::` - format to html=`<div class='alert alert-info'></div>` - callout section: sopiler - 語法開頭 `:::sopiler callout_title` - 語法結尾 `:::` - format to collapse html=`<details><summary>{callout_title}</summary><p>string</p></details>` 因為無法窮盡 hackmd 語法, 而每當新出現 hackmd 語法都需要補上自定義的解析 function 來轉換, 我想用 hackmd parser 來管理, 每個自定義的解析 function 都單獨一隻.ts檔且只會 export 一個 function, 我想的目錄架構如下 │ ├── lib # 工具函式與資料獲取 │ │ ├── data.ts # 靜態文章資料與獲取邏輯 │ │ ├── markdown-renderer.tsx # customize markdown renderer │ │ ├── hackmd-parser # customize hackmd parsing to html&css │ │ │ └── hackmd-highlight.tsx │ │ │ └── hackmd-callout-section.tsx │ │ │ └── hackmd-callout-section-collapse.tsx # GPT-5.2 ## 使用心得 :::spoiler GPT-5.2 對話紀錄 >[me] >請讀 Spec.md 檔案 >[GPT-5.2] 我會先做計畫。確認後才開始建立專案與檔案。 計畫 >- 釐清需求與路由/頁面對應(home/articles/articles/[slug]/about),整理必要資料模型(文章、標籤、年份/月分群、熱門/最新) >- 規劃技術栈與資料來源流程(HackMD API → 內容抓取/快取 → Markdown 渲染),並補充必要工具(路由、樣式、搜尋、UI 狀態管理) >- 設計前台版型結構:左右分欄、可收合 sidebar、文章卡片區、搜尋彈窗、文章清單樹狀 >- 建立 Next.js 專案骨架與頁面,實作共用元件(Sidebar、PostCard、SearchModal、ArchiveTree) >- 串接資料與渲染:文章列表/單篇頁、URL slug 規則、搜尋模糊比對 >- RWD:mobile sidebar 行為與對應版型 > >若這個計畫 OK,請回覆「同意」或告訴我需要調整的部分。 >[me] >同意 >[GPT-5.2] >run command in bash >``` >npx create-next-app@latest myBlog --ts --no-tailwind --eslint --app --no-src-dir --import-alias >``` >create-next-app 失敗原因有兩個: >1. 目錄內已有 Spec.md,會衝突 >2. 目前 Node 版本是 v17.0.1,但 create-next-app 需要 Node >= 20.9.0 > >請告訴我你要怎麼處理,二選一就好: >1. 我幫你把 Spec.md 暫時移到別處(或改名),並請你升級 Node 至 20.9+,再重跑 >2. 我改在子資料夾建立(例如 my-blog-app/),保留現有檔案不動,並請你升級 Node 至 20.9+,再重跑 > >你偏好哪個?如果你要我幫你處理 Node 升級,也說一聲你使用的版本管理工具(nvm / fnm / asdf / brew / 其他)。 >[me] >我下 node -v 顯示 v20.14.0 >[GPT-5.2] >我這邊在專案目錄下看到的還是 v17.0.1,所以 create-next-app 仍會卡在版本。 >請問你的 Node 20.14.0 是在哪個 shell/環境?如果你用的是 nvm / fnm / asdf / brew,請告訴我,我可以幫你在這個環境切換到 20.14.0 後再繼續。 >或是你也可以先在同一個終端機執行切換,然後告訴我切換完成,我再重跑。 >[me] >我在 ~/Desktop/Learning/AI/ai-generated-blog 下 node -v >[GPT-5.2] >我剛剛在同一個路徑執行 node -v,結果還是 v17.0.1。 >為了確認是 PATH/版本管理問題,請你在 ~/Desktop/Learning/AI/ai-generated-blog 依序跑下面兩個指令,把輸出貼給我: >``` >which node >node -v >``` >如果你是用 nvm/fnm/asdf/brew,也可以直接告訴我用哪一個,我來幫你切換到 20.14.0。 >[me] >我的 which node 顯示 >/Users/suwanya/.nvm/versions/node/v20.14.0/bin/node >你的 which node 顯示什麼? >[GPT-5.2] >我這邊的 which node 是 /usr/local/bin/node,所以在用系統/全域的 v17。 >你那邊是 nvm 的 node。為了讓我這邊跟你一致,我需要在指令裡載入 nvm 的環境。 >請你確認 nvm.sh 存在即可,我接著會用這種方式跑: >``` >. ~/.nvm/nvm.sh && nvm use 20.14.0 && node -v >``` >[me] >不要在全域下指令,你換到 /Users/suwanya/ >[GPT-5.2] >已在 /Users/suwanya/ 切到 nvm 的 Node 20.14.0,確認 which node 與 node -v 都是 20.14.0。 ::: 我一開始沒有設任何限制, 當 Codex 執行 `create-next-app` 指令後, 才發現它 node 版本跟我開發環境不一樣, 改查 Copilot 是跟我開發環境一樣 為什麼兩個 Extension 表現不同? 差異在於 **Runtime Context(執行環境上下文)** 的整合程度: | | GitHub Copilot | Codex – OpenAI’s coding agent | | :--- | :--- | :--- | | **運作機制** | 深度整合於 VSCode | 隔離沙盒 (Sandbox) | | **環境加載** | 繼承 IDE 初始化完的 Terminal,<br>已自動載入 NVM / Shell 設定腳本 | 初始在系統全域路徑,<br>不會自動執行 NVM / Shell 設定腳本 | | **Node 差異** | 初始 `which node` 指向 `/Users/suwanya/.nvm/versions/node/v20.14.0/bin/node` | 初始 `which node` 指向 `/usr/local/bin/node` | 雖然有其他方法讓 Codex 同步開發環境, 例如在 Spec.md 寫限制, 但我想要初始時就自動同步啊~ 光這點就打退我用的動力~ ## 前置作業 1. 在桌面新增 `ai-generated-blog` 資料夾 2. 在此資料夾新增 `Spec.md` 檔案 (內文在最下面) 4. 在 VSCode 開啟 `ai-generated-blog` 資料夾 5. 在 VSCode 開啟 `Codex – OpenAI’s coding agent` Extension 輸入 `請讀 Spec.md 檔案` - 注:不是開 `GitHub Copilot` Extension ## 以下是 `Spec.md` 檔案內文 根據 `Spec.md` 文件,來創建前端工程師的部落格。 請先列出計畫跟步驟, 審核通過再真實建立專案環境、檔案、程式碼。 **想法:** - 用 HackMD(基於 Markdown 語法的線上即時協作筆記與文件平台)當部落格後台編輯器 - HackMD 公開文章列表 api = https://hackmd.io/api/@{user_name}/overview - 建立 myBlog 前端專案,實作前台部落格 - 用 OpenSpec 作為 Spec 架構 - https://github.com/Fission-AI/OpenSpec - 用 Next.js 作為前端框架 - 用 Markdown 渲染引擎,將 HackMD 取得的文章編譯 - 部署到 github pages - **請讀參考程式碼:** - 別人做的類似專案 - https://github.com/Yukaii/daily-oops - post hackmd 文章 - https://github.com/Yukaii/daily-oops/blob/main/lib/post.ts - markdown-it-plugins - https://github.com/Yukaii/daily-oops/blob/main/lib/markdown-it-plugins/callout.js - 請讀參考資料: - https://yukai.dev/blog/2021/05/16/hackmd-as-cms-blog-feat-next-js - https://medium.com/starbugs/%E7%94%A8-hackmd-%E8%88%87-github-action-%E6%89%93%E9%80%A0%E4%BD%A0%E7%9A%84%E9%9D%9C%E6%85%8B%E7%B6%B2%E7%AB%99-%E7%B7%9A%E4%B8%8A%E6%96%87%E7%AB%A0%E7%B7%A8%E8%BC%AF%E5%B9%B3%E5%8F%B0-1d9b1a663e18 **技術棧:** - OpenSpec - Next.js - Markdown 渲染引擎 - ...請補充我不知道的 **blog url:** - https://myblog.com/home - https://myblog.com/articles - https://myblog.com/articles/{article_slug} - article_slug=`yyyymmdd-文章標題`,將標題轉為 kebab-case - 範例:article title = `CSS Grid vs. Flexbox` article date = `May 1, 2024` article url = `/articles/20240501-css-grid-vs-flexbox` - https://myblog.com/about **blog layout:** - RWD(桌機、手機) - 桌機版面:左右排版,右邊固定 sidebar,左邊根據 url 顯示對應頁面 - 手機版面:上下排版,置頂固定漢堡選單可收合,下方根據 url 顯示對應頁面 **blog pages(桌機版面):** - home - 左邊上下排版,上面是最新文章卡片,下面是熱門文章卡片 - 右邊固定 sidebar - articles - 左邊上下排版,所有文章卡片 - 右邊固定 sidebar - articles/{article_slug} - 左邊上下排版,單則文章內容 - 右邊固定 sidebar - about - 左邊上下排版,個人簡介 - 右邊固定 sidebar **blog UI:** - sidebar - 上下排版,依序有三個區塊 - 區塊一:logo+部落格名稱+簡介 - logo 為圖片,圖片為圓框 - 區塊二:navitem:1.home、2.articles、3.about、4.search articles - 區塊三:文章列表 - 分父子層,可收合 - 父層顯示年份+該年份的文章總數 - 子層顯示月份+該月份的文章總數 - article card - card body - 上下排版,依序是 - 文章的封面圖片 - 文章的 title - 文章的內容文字,四行,其餘省略 - read more - card footer - 同行左右排版,依序是文章的日期、標籤 **blog features:** - home page: - 點擊文章卡片的 [read more],切換 url 到 articles/{article_slug},顯示對應的單則文章頁面 - 點擊整張文章卡片,切換 url 到 articles/{article_slug},顯示對應的單則文章頁面 - sidebar: - 點擊 logo/部落格名稱/簡介,切換 url 到 /home,顯示對應頁面 - 點擊 navitem:articles,切換 url 到 /articles,顯示對應頁面 - 點擊 navitem:about,切換 url 到 /about,顯示對應頁面 - 點擊 navitem:search articles,跳出彈跳視窗 - 輸入框輸入文字,可依輸入文字模糊搜尋文章標題或文章內容,過濾出符合條件的文章集合 **Next.js 目錄結構** ... ├── src │ ├── app # Next.js App Router 頁面與佈局 │ │ ├── page.tsx # 首頁 (最新與熱門文章) │ │ ├── layout.tsx # 全域根佈局 (字體) │ │ ├── globals.css # 全域 CSS │ │ ├── about # 關於我頁面 │ │ │ └── page.tsx │ │ └── articles # 文章相關路由 │ │ ├── page.tsx # 所有文章列表 │ │ └── [slug] # 文章詳情頁 (動態路由) │ │ └── page.tsx │ ├── components # 共用 React 元件 │ │ ├── article-card.tsx # 文章卡片組件 (包含 Read More 連結) │ │ ├── logo-block.tsx # 側邊欄 Logo 區塊 │ │ ├── main-layout.tsx # 主佈局 (導覽列與側邊欄邏輯) │ │ ├── search-dialog.tsx # 文章搜尋對話框 │ │ ├── sidebar-nav.tsx # 側邊欄導覽選單 │ │ └── ui # ShadCN UI 底層元件 (原子組件) │ │ ├── accordion.tsx │ │ ├── avatar.tsx │ │ ├── badge.tsx │ │ ├── button.tsx │ │ ├── card.tsx │ │ ├── dialog.tsx │ │ ├── input.tsx │ │ ├── scroll-area.tsx │ │ ├── separator.tsx │ │ ├── sidebar.tsx # 核心側邊欄邏輯 │ │ └── ... (其他 UI 組件) │ ├── hooks # 自定義 React Hooks │ │ └── use-mobile.tsx # 偵測行動裝置狀態 │ ├── lib # 工具函式與資料獲取 │ │ ├── data.ts # 靜態文章資料與獲取邏輯 │ │ └── markdown.ts # Markdown 處理邏輯 ... **設計圖參考(from firebase studio: blog-a):** home  about  articles  articles/{article_slug}  search articles  sidebar mobile  
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up