AWS Builder 文章

為 AWS Manila Community Day 打造 Tagalog 學習 App 的開發流程深度解析

這個 Tagalog 學習 App 是以檔案優先的專案方式打造。開發流程不是從後端、資料庫或框架開始,而是從結構化文章中繼資料、可重用句庫、卡片擴展邏輯、語言輔助函式、HTML 渲染、響應式 CSS、發布檢查,以及最後封裝開始。這是一個很適合技術分享的模式,因為產品的每個部分都能被解釋成可見的建置步驟。

Tagalog 學習 App 文章系列

English 繁體中文 简体中文

這個 Tagalog 學習 App 是以檔案優先的專案方式打造。開發流程不是從後端、資料庫或框架開始,而是從結構化文章中繼資料、可重用句庫、卡片擴展邏輯、語言輔助函式、HTML 渲染、響應式 CSS、發布檢查,以及最後封裝開始。這是一個很適合技術分享的模式,因為產品的每個部分都能被解釋成可見的建置步驟。

Tagalog 學習 App 產生器是一個有用的技術分享範例,因為它結合了內容工程、靜態網站產生、在地化意識、行動 UI 思維,以及發布驗證。程式碼不大,但其中的開發技能可以轉移到許多社群學習工具。

免責聲明

目的:本專案是教育原型,用於語言學習與技術分享。它協助學習者在 AWS Manila Community Day 前練習禮貌 Tagalog 片語,同時展示產生器背後的建置方式。

非商業用途:本專案沒有商業模式、付費存取、廣告計畫、聯盟行銷方案或營利目標。它是為社群準備與開發者教育而建立的學習作品。

不保證正確性:App 可能使用生成式 AI 內容,因此翻譯、發音指南、文法說明與文化註解,在公開使用前都應由 Tagalog 母語者審閱。

範圍:本 App 不是官方 AWS 產品、不是官方翻譯工具,也不是人類語言教學的替代品。它是一個具有實用學習內容的技術 demo。

尊重社群:App 應避免刻板印象,並謹慎教導禮貌用語。像 poopokayoninyo 這類詞,應被解釋為表達尊重的工具,而不是裝飾。

審閱需求:語言內容,尤其是文化與禮貌 Tagalog 說明,在正式使用前應由母語人士審閱。


Demo

Lagyan po ng yelo.

文法拆解

  • Lagyan:意思是把某物加到某處或某個東西上。
  • po:禮貌標記,用於尊重語氣。
  • ng:常放在受詞前的連接或標記。
  • yelo:意思是「冰」。

發音指南

慢慢念時可讀作: lahg-yahn poh ngah yeh-loh.

  • Lagyan:lahg-yahn。
  • po:poh。
  • ng:ngah。
  • yelo:yeh-loh。 向攤販或店員點飲料時,保持短句柔和清楚。

Content Snapshot

自然 Tagalog:Lagyan po ng yelo.
禮貌 Tagalog:Lagyan po ng yelo.
額外範例 1:Sa palengke, lagyan po ng yelo.
額外範例 2:Ganito na lang, lagyan po ng yelo.
相關市場範例:Konting asukal lang po.

目錄

第 1 部分:把內容視為產品契約

本節說明文章中繼資料、分類、slug 與摘要如何成為靜態網站的第一個 API。

第 2 部分:把句庫作為可重用來源資料

本節展示基礎句子 tuple 如何支援自然 Tagalog、禮貌 Tagalog、友善 Filipino-English、俏皮 Filipino-English,以及語氣標籤。

第 3 部分:把小型輸入擴展成更大的學習卡組

本節說明如何透過結合基礎片語與情境變體,讓小型句庫為每篇文章產生 40 張卡片。

第 4 部分:從結構化資料渲染靜態 HTML

本節說明產生器如何把內容物件轉成文章頁面、導覽清單、句子卡片與首頁。

第 5 部分:封裝並驗證 Demo

本節深入說明 zip 產生、摘要字數修正、行動版 CSS 檢查、卡片數量檢查,以及適合發布的驗證。

第 6 部分:用純資料建模學習產品

本節說明專案如何用純 Python 資料結構來建模文章、句庫、情境、範例、文法與發音。

第 7 部分:確定性產生大型學習集

本節展示確定性擴展如何在維持一致語氣與結構的同時,建立大量學習卡片。

第 8 部分:加入文法、範例與發音輔助

本節深入說明文法拆解、範例選擇與發音指南產生。

第 9 部分:打造響應式靜態學習介面

本節說明產生器如何建立深色模式、響應式、以文章為中心的學習介面。

第 10 部分:讓 QA 與發布成為 Demo 的一部分

本節說明封裝與檢查如何把產生式原型變成可分享的技術 demo。


第 1 部分:把內容視為產品契約

目標

在撰寫 UI 邏輯前,先建立可預測的內容契約。產生器定義了十篇文章,每篇都有 idslugtitlecategorysummary。這讓每篇文章都能被定址、連結與渲染。

開發技能

這項開發技能是 schema-first 思維。即使沒有資料庫,文章清單也像 API 一樣運作。每個下游步驟都依賴穩定的鍵:

{
  "id": 1,
  "slug": "community-greetings-introductions",
  "title": "Community Day: Greetings and Respectful Introductions",
  "category": "Community Day",
  "summary": "Practice polite greetings..."
}

提示詞

建立一個包含 24 個文章頁面的靜態學習網站。
每篇文章需要:
- id
- slug
- title
- category
- 20 字摘要
- 40 張句子卡片

使用 11 篇 Community Day 文章、8 篇 Friendship 文章,以及 5 篇 Manila Daily 文章。

結果

產生器可以產生可預測的檔名,例如:

article-1-community-greetings-introductions.html
article-3-community-workshops-learning.html
article-5-community-volunteers-time-goodbye.html

這種命名模式對技術分享很有用,因為檔名本身就能說明路由、文章編號與主題。

建議

  • 使用 slug,而不是原始標題,作為檔名。
  • 保持文章 ID 為數字,方便排序。
  • 保持分類明確,方便 UI badge 顯示。
  • 將摘要與文章本文分開驗證。
  • 讓中繼資料保持易讀,即使不執行 App 也能審閱。

第 2 部分:把句庫作為可重用來源資料

目標

先把學習內容儲存成精簡的來源資料,再擴展成完整卡片。每個句子 tuple 都帶有六個實用欄位:

英文輸入
Natural Tagalog
Polite Tagalog
友善 Filipino-English
俏皮 Filipino-English
語氣

開發技能

這項技能是內容正規化。來源資料不是手動撰寫 400 張完整 HTML 卡片,而是使用精簡 tuple,並讓渲染函式加入文法、範例、文化情境與發音。

提示詞

建立適合活動使用的基礎句庫。
每個句子請提供:
- 英文輸入
- Natural Tagalog
- Polite Tagalog
- 友善 Filipino-English
- 俏皮 Filipino-English
- 語氣

包含問候、方向指引、工作坊、交流、志工、等待時間與道別。

Demo 範例

English: Sit for a moment if you feel dizzy.
Natural Tagalog: Umupo ka sandali kung nahihilo ka.
Polite Tagalog: Umupo po kayo sandali kung nahihilo kayo.
Friendly Filipino-English: Sit muna po kung dizzy.
Playful Filipino-English: Umupo muna, easy lang all right.
Tone: caring health advice
English: Thank you for being my safe friend.
Natural Tagalog: Salamat sa pagiging ligtas kong kaibigan.
Polite Tagalog: Salamat sa pagiging ligtas ko pong kaibigan.
Friendly Filipino-English: Thank you po for being my safe friend.
Playful Filipino-English: Safe friend ka, thank you all right.
Tone: gentle friendship care

結果

這個內容模型同時支援實用的活動用語與語氣教學。學習者可以在尊敬語句旁邊看到 casual 與俏皮變體。

建議

  • 將自然 Tagalog 放在俏皮輸出之前。
  • 在情境需要尊重時使用 pokayoninyo
  • 讓俏皮表達清楚標示為非正式。
  • 早點加入語氣標籤。
  • 建立足夠多的句子分類,以測試完整活動旅程。

第 3 部分:把小型輸入擴展成更大的學習卡組

目標

透過將每個基礎句子結合四種情境變體,把 10 個基礎句子轉成每篇文章 40 張卡片。Community Day 情境包含早上報到、工作坊開始、遇到志工,以及課後使用。

開發技能

這項技能是受控擴展。產生器會放大內容量,但不讓輸出變成隨機結果。每張產生出的卡片仍然遵循相同的句子卡片範本。

提示詞

將每篇文章從 10 個基礎句子擴展成 40 張學習卡片。
每個基礎句子使用四種情境變體。
保持句子文字清楚,並把情境細節放在背景脈絡中。

實作模式

def expand(base, article_id):
    contexts = community_contexts if article_id <= 5 else friendship_contexts
    cards = []
    for sentence in base:
        for context in contexts:
            cards.append({
                "num": len(cards) + 1,
                "background": "在這個情境中使用這句話...",
                "english": sentence[0],
                "natural": sentence[1],
                "polite": sentence[2],
                "friendly": sentence[3],
                "playful": sentence[4],
                "tone": sentence[5]
            })
    return cards[:40]

結果

網站現在可以擴展到 960 張句子卡片,同時不失去結構。這實際示範了如何將 AI 輔助內容塑造成確定性的產品。

建議

  • 擴展情境,而不是隨機措辭。
  • 保持原始句子穩定,方便記憶。
  • 使用確定性的卡片編號。
  • 使用 [:40] 限制產生的卡片,避免溢出。
  • 擴展後,從每個分類審閱一組樣本。

第 4 部分:從結構化資料渲染靜態 HTML

目標

使用同一個 HTML 函式渲染每個文章頁面。產生器會建立文章導覽、hero 內容、中繼資料 badge、句子卡片、上一頁與下一頁連結,以及行動版控制項。

開發技能

這項技能是不依賴框架的範本渲染。Python 字串範本、HTML escaping 與小型輔助函式,就足以打造完整的靜態網站。

提示詞

為每篇文章產生一個 HTML 頁面。
桌面 UI:
- 左側文章清單
- 右側文章內容

行動版 UI:
- 內容優先
- 開啟文章清單按鈕
- 抽屜式文章清單

使用深色模式與響應式 CSS。

渲染職責

page_html(article)
  -> 啟用中的導覽
  -> hero 區塊
  -> 句子卡片
  -> 上一頁與下一頁連結
  -> 行動版抽屜按鈕
sentence_card_html(card, article)
  -> 背景脈絡
  -> 英文輸入
  -> natural Tagalog
  -> polite Tagalog
  -> friendly Filipino-English
  -> playful Filipino-English
  -> 文化情境
  -> 文法
  -> 範例
  -> 發音

結果

HTML 輸出保持一致,因為每篇文章都使用同一個 renderer。這避免了常見的 demo 問題:每個頁面慢慢偏離成不同版面。

建議

  • 對產生內容使用 html.escape()
  • 保留 CSS 變數來管理深色模式色彩。
  • 所有頁面使用同一個導覽 renderer。
  • 加入語意化文章卡片。
  • 讓 JavaScript 保持小型,並限制在行動版抽屜功能。

第 5 部分:封裝並驗證 Demo

目標

分享前建立 zip 檔並執行一致性檢查。封裝腳本會將摘要更新為剛好 20 個字、重寫 HTML 檔案、建立 tagalog_static_html_site.zip,並印出驗證結果。

開發技能

這項技能是發布衛生。靜態網站仍然需要發布流程:修補、封裝、驗證與審閱。

提示詞

發布前,請驗證:
- 每篇文章都有 40 張句子卡片
- 摘要剛好有 20 個字
- 行動版 CSS 存在
- 輸出不包含禁止的內部參照
- zip 檔包含所有 HTML 頁面

驗證模式

checks[p.name] = {
    "sentence_cards": text.count('class="sentence-card"'),
    "mentions_readme": bool(re.search(r"readme", text, re.I)),
    "has_mobile_css": "@media (max-width: 860px)" in text,
}

Demo 錨點回歸測試集

每當產生的網站變更時,請使用這些最新 HTML 範例作為 regression set:

Tagalog: Magpahinga muna tayo sa lilim.
English: Let us rest in the shade first.
Checks: health/safety context, natural conversation line, and no duplicated Extra Example pattern.

Tagalog: Umupo ka sandali kung nahihilo ka.
English: Sit for a moment if you feel dizzy.
Checks: caring advice, beginner-friendly wording, and practical Manila daily use.

Tagalog: Paki-check po kung pumasok ang bayad.
English: Please check if the payment came in.
Checks: polite request, payment context, and clear Extra Example wording.

結果

Demo 變得更適合分享,因為最後一步證明了預期內容確實存在。這對技術分享尤其重要,因為聽眾不只能看到 demo,也能看到背後的建置紀律。

建議

  • 每次 release build 後印出 JSON checks。
  • 把字數需求視為可測試的約束。
  • 只壓縮你要散佈的確切檔案。
  • 對檔案排序,讓封裝結果可預測。
  • 在修補後執行檢查,而不是修補前。

第 6 部分:用純資料建模學習產品

目標

用容易檢查、修改與渲染的簡單 Python 結構來表示學習產品。

開發技能

關鍵技能是把 dictionary 與 tuple 當成輕量內容資料庫使用。專案使用:

articles: 文章中繼資料清單
community_sets: 活動片語庫
friendship_sets: 情感片語庫
community_contexts: 實用活動情境
friendship_contexts: 情感表達情境
pron_map: 發音提示

提示詞

將學習 App 內容建模為結構化 Python 資料。
使用文章中繼資料進行導覽。
使用句庫建立學習卡片。
使用情境陣列擴展每個基礎句子。
使用輔助對應表處理發音與文法。

為什麼這很重要

這種做法讓系統容易解釋。在技術分享中,建置者可以指向一個資料結構,說明它如何變成導覽、文章內容與句子卡片。

建議

  • 將文章中繼資料與句子內容分開。
  • 將活動分類與友情或詩意分類分開。
  • 只有在欄位順序穩定時才使用 tuple。
  • 當鍵需要自我說明時,使用 dictionary。
  • 如果非 Python 使用者需要編輯,之後再將結構提升為 JSON。

第 7 部分:確定性產生大型學習集

目標

產生大型學習集,同時不失去一致性。

開發技能

這項技能是確定性產生。App 不會在執行時要求 AI 自由發明每個最終頁面。它會定義基礎資料、加以擴展,然後渲染靜態輸出。

提示詞

使用確定性產生,而不是手動重複。
針對每個基礎句子,產生四張具備情境感知的卡片。
保持輸出順序穩定。
自動指派卡片編號。
每篇文章剛好回傳 40 張卡片。

實作概念

for base_sentence in base_sentences:
    for context in contexts:
        create_card(base_sentence, context)

結果

App 可以成長,同時維持可審閱性。如果某個翻譯需要改善,開發者只要編輯一次基礎句子,然後重新產生網站。

建議

  • 將來源片語儲存一次。
  • 自動產生重複版面。
  • 保持卡片編號具確定性。
  • 避免在已發布學習內容中使用隨機化。
  • 使用建置檢查來確認精確數量。

第 8 部分:加入文法、範例與發音輔助

目標

透過產生文法註解、額外範例與發音提示,增加超越翻譯的學習價值。

開發技能

這項技能是規則式增強。產生器會檢查英文輸入與自然 Tagalog,決定要附上哪一種文法說明。

提示詞

建立輔助函式,根據句子意圖加入文法與範例。
如果句子與感謝有關,請說明 Salamat、po 與 sa。
如果句子詢問地點,請說明 Saan、po 與 ang。
如果句子是禮貌請求,請說明 Puwede、Paki-、po 與 ba。
如果句子與等待有關,請說明 Hintayin、Papunta、Pasensya、na 與 po。

輔助函式行為範例

Sentence: Let us rest in the shade first.
Grammar:
- Salamat: 謝謝
- po: 禮貌標記
- sa: 依情境可表示 for、in、at 或 to
Sentence: Sit for a moment if you feel dizzy.
Grammar:
- Puwede / Paki-: may、can 或 please
- po: 禮貌標記
- ba: 問句標記

Demo 範例

輔助系統會反覆使用適合活動的安全範例:

Tagalog: Magpahinga muna tayo sa lilim.
English: Let us rest in the shade first.

Tagalog: Umupo ka sandali kung nahihilo ka.
English: Sit for a moment if you feel dizzy.

Tagalog: Paki-check po kung pumasok ang bayad.
English: Please check if the payment came in.

結果

App 教的是模式,而不只是片語對照。這對技術 demo 更有價值,因為它展示了簡單規則層如何改善學習內容。

建議

  • 保持輔助規則透明。
  • 對初學者使用簡單文法說明。
  • 不要過度宣稱語言準確性。
  • 為文法註解加入母語人士審閱。
  • 讓輔助函式建立一致性,而不是成為最終權威。

第 9 部分:打造響應式靜態學習介面

目標

產生能在桌面與行動裝置上使用的靜態網站。

開發技能

這項 UI 技能是響應式靜態組合。App 使用:

Desktop: 側邊欄導覽 + 文章內容
Mobile: 內容優先 + 文章抽屜按鈕
Dark mode: CSS 變數與可讀對比
Cards: 重複的 sentence-card 元件
Navigation: 啟用中的文章連結與上一頁/下一頁連結

提示詞

建立深色模式的靜態 HTML 學習網站。
桌面版面應在左側顯示文章導覽,右側顯示內容。
行動版面應先顯示內容,並提供開啟文章清單按鈕。
使用語意化卡片,並讓 UI 適合閱讀長篇語言學習內容。

CSS 概念

:root {
  --bg: #090b10;
  --text: #e5e7eb;
  --muted: #9ca3af;
  --brand: #38bdf8;
  --border: #273449;
}

.layout {
  display: grid;
  grid-template-columns: 360px 1fr;
}

@media (max-width: 860px) {
  .layout {
    display: flex;
    flex-direction: column;
  }

  .content {
    order: 1;
  }

  .mobile-menu-button {
    display: block;
  }
}

結果

App 可以作為只需瀏覽器的學習工具使用。對 AWS Manila Community Day 準備而言,這很重要,因為學習者可能會在通勤、等待或課前複習時用手機練習。

建議

  • 在行動版上,把學習內容放在導覽之前。
  • 使用較大的觸控目標。
  • 讓文法區塊易於掃讀。
  • 謹慎使用深色模式,而不是把它當裝飾。
  • 讓 JavaScript 保持最小化。

第 10 部分:讓 QA 與發布成為 Demo 的一部分

目標

讓產生出的網站可靠到足以分享。

開發技能

這項技能是自動化一致性檢查。封裝腳本會檢查:

句子卡片數量
行動版 CSS 標記
禁止的內部參照提及
摘要字數
zip 建立

提示詞

建立一個 release script,會:
- 將文章摘要修補為剛好 20 個字
- 重寫所有 HTML 檔案
- 將檔案封裝成 zip
- 為每個頁面印出 JSON checks

發布模式

files = list(Path('.').glob('*.html'))

for page in files:
    text = page.read_text(encoding='utf-8')
    # 修補內容
    page.write_text(text, encoding='utf-8')

with zipfile.ZipFile(zip_name, 'w', zipfile.ZIP_DEFLATED) as z:
    for page in sorted(files):
        z.write(page.name)

結果

最終成品不只是一組產生出來的頁面,而是經過檢查與封裝的建置成果。這個差異在技術分享中很重要,因為它展現了專業的發布思維。

建議

  • 將驗證輸出印成 JSON。
  • 每次修補後都檢查需求。
  • 只封裝預期檔案。
  • 讓 release script 保持小而可稽核。
  • 在技術分享中,把檢查結果作為說明重點。

現場筆記

先有內容契約,再有 UI

背景:這個 App 現在需要 24 篇文章、960 張卡片、摘要、分類、語氣變體,以及 2,680 行獨特的 Extra Example。

目標:防止手寫頁面逐漸漂移。

提示詞:在渲染 HTML 前,先定義文章中繼資料與句子 tuple。

結果:同一個產生器可以渲染整個網站。

審閱檢查:每篇文章都能從 idslugtitlecategorysummarycards 渲染出來嗎?

受控擴展

背景:手動為每篇文章撰寫 40 張獨特卡片既慢又不一致。

目標:安全地將 10 個基礎句子擴展成 40 張卡片。

提示詞:將基礎句子與四種情境結合,同時保持句子穩定。

結果:每篇文章都達到所需卡片數量,且沒有隨機結構。

審閱檢查:每篇文章是否剛好顯示 40 張卡片?

把發布腳本當成 QA

背景:第一次產生可能會漏掉字數或發布規則。

目標:封裝前修補並驗證最終輸出。

提示詞:替換摘要、壓縮檔案並印出檢查結果。

結果:最終建置有 20 字摘要、行動版 CSS,且沒有禁止的內部參照。

審閱檢查:建置紀錄是否顯示摘要字數、行動版 CSS 與卡片數量?

純 Python 也能是靜態網站產生器

背景:App 需要很多頁面,但不需要執行時伺服器邏輯。

目標:先產生 HTML,然後在任何地方提供服務。

提示詞:使用 Python 從結構化內容建立文章頁面與 index 頁面。

結果:網站變得容易封裝、檢查與分享。

審閱檢查:網站是否能在沒有後端的情況下開啟?

輔助函式就是產品決策

背景:文法拆解與發音不是原始資料;它們會形塑學習者的理解。

目標:一致地編碼適合初學者的說明。

提示詞:加入處理發音、文法拆解、範例與相關模式的輔助函式。

結果:每張卡片都獲得學習支援,不需要反覆手寫相同說明。

審閱檢查:輔助說明是否符合句子意圖?

QA 是故事的一部分

背景:如果數量或行動版規則錯誤,產生式 demo 可能會安靜地失敗。

目標:讓驗證可見。

提示詞:印出卡片數量、行動版 CSS 與禁止用語的檢查結果。

結果:建置輸出成為 demo 符合需求的證據。

審閱檢查:最終 JSON 檢查是否顯示預期值?

技術分享應該展示流程

背景:當建置者看到檔案、提示詞、schema 與檢查如何連接時,會學得更快。

目標:把專案呈現為可重複的建置模式。

提示詞:說明從資料模型到產生頁面,再到 release zip 的流程。

結果:這場分享變得不只對這個 Tagalog App 有用。

審閱檢查:另一位建置者能否把同一套流程重用到其他學習主題?

結語反思

這個開發流程對技術分享很有價值,因為它展示了從內容想法到可散佈靜態網站的完整路徑。重要的課題不只是如何撰寫 HTML 或 Python,而是如何設計內容契約、產生一致頁面、驗證需求,並有信心地封裝結果。Tagalog 學習 App 背後的工程技能,是把文化學習目標轉成可重複的內容管線,讓資料建模、確定性產生、輔助函式、響應式渲染與發布驗證一起運作。