- #130
i18n 實作必須要留意不同語言語序邏輯不同
近期翻新了一下我自製的個人網站模板:Letter,看到讓我有點在意的地方是下面這段:
{t('Hero-1', { name: t('Me-1') })}<br />{t('Hero-2', { number: '100' })} <a class="highlight" href={`https://www.webdong.dev/${Astro.currentLocale}/post/`}>{t('Hero-3')}</a> {t('Hero-4')} {t('Hero-5', {number: '800'})}{t('Hero-6')} <a class="highlight" href={getRelativeLocaleUrl(Astro.currentLocale || defaultLocale, '/work')}>{t('Hero-7')}</a> {t('Hero-8')}"Hero-1": "哈囉,我是{name}","Hero-2": "我撰寫超過 {number} 篇","Hero-3": "技術文章","Hero-4": "紀錄與傳達知識","Hero-5": "幫助 {number} 位以上開發者消除他們的疑惑。","Hero-6": "可以觀賞","Hero-7": "作品集","Hero-8": "了解我是如何解決真實世界問題的。",真的有點醜且光是想到要替換就很頭痛,特別是換個語序差別大一點的語言根本沒辦法運作,所以最好這樣寫,根據「概念而非語序或樣式去拆分」:
<Fragment set:html={t('Hero-2', {articles: '100',articlesLink: `<a class="highlight" href="https://www.webdong.dev/${Astro.currentLocale}/post/">${t('Hero-ArticlesLink')}</a>`,developers: '800'})} /><Fragment set:html={t('Hero-3', {portfolioLink: `<a class="highlight" href="${getRelativeLocaleUrl(Astro.currentLocale || defaultLocale, '/work')}">${t('Hero-PortfolioLink')}</a>`})} />"Hero-2": "我撰寫超過 {articles} 篇{articlesLink}紀錄與傳達知識,幫助 {developers} 位以上開發者消除他們的疑惑。","Hero-3": "可以觀賞{portfolioLink}了解我是如何解決真實世界問題的。","Hero-ArticlesLink": "技術文章","Hero-PortfolioLink": "作品集",當時這麼做應該是想要保持翻譯文件單純,不要又摻雜樣式或 Markup 結構,還可能會有 XSS 的麻煩問題,不過事後權衡下來大多時候直接寫進翻譯內是更省事⋯⋯
t是自製的 i18n 翻譯工具,應該大多 i18n 套件都有類似 placeholder 的方式去處理翻譯。 - #129
- #128
- #127
- #126
- #125
- #124
- #123
- #122
- #121
- #120
- #119
- #118
- #117
- #116
- #115
- #114
- #113
- #112
- #111
- #110
- #109
- #108
- #107
- #106
- #105
- #104
- #103
- #102
- #101
- #100
- #99
- #98
- #97
- #96
- #95
- #94
- #93
- #92
- #91
- #90
- #89
- #88
- #87
- #86
- #85
- #84
- #83
- #82
- #81
- #80
- #79
- #78
- #77
- #76
- #75
- #74
- #73
- #72
- #71
- #70
- #69
- #68
- #67
- #66
- #65
- #64
- #63
- #62
- #61
- #60
- #59
- #58
- #57
- #56
- #55
- #54
- #53
- #52
- #51
- #50
- #49
- #48
- #47
- #46
- #45
- #44
- #43
- #42
- #41
- #40
- #39
- #38
- #37
- #36
- #35
- #34
- #33
- #32
- #31
- #30
- #29
- #28
- #27
- #26
- #25
- #24
- #23
- #22
- #21
- #20
- #19
- #18
- #17
- #16
- #15
- #14
- #13
- #12
- #11
- #10
- #9
- #8
- #7
- #6
- #5
- #4
- #3
- #2
- #1