๐Ÿ“– star365 Docs
โ† ๋ณด๊ณ ์„œ ๋ชฉ๋ก

starium.club 54 ํŽ˜์ด์ง€ i18n ์™„์„ฑ + lang switch ์ž๋™ ๊ฐ์ง€

์ž‘์„ฑ์ผ: 2026-05-17 ์ž‘์„ฑ์ž: ์ด๋งŒ์šฐ / Claude (Opus 4.7 1M) ์œ„์น˜: paperclip / /opt/star365-ceo/public/starium-global/ ๊ด€๋ จ ๋ฉ”๋ชจ๋ฆฌ: [[starium-club-i18n-mass-translation-20260517]], [[feedback_i18n-dir-split-without-translation]]

1. ๋ฐœ๊ฒฌ

์‚ฌ์šฉ์ž 1์ฐจ ์‹ ๊ณ : https://starium.club/programs/bm-medical ํŽ˜์ด์ง€์— ํ•œ๊ตญ์–ด๊ฐ€ ๊ฐ€๋“ ๋ณด์ž„ โ€” ๊ธ€๋กœ๋ฒŒ ์‚ฌ์šฉ์ž๋„ ํ•œ๊ตญ์–ด ํ‘œ์‹œ.

๊ทผ๋ณธ ์›์ธ 3๋‹จ๊ณ„:

  1. navigator.language ์ž๋™ ๊ฐ์ง€ ๋ถ€์žฌ: lang prefix ์—†๋Š” URL(/programs/<slug>) โ†’ root ํŒŒ์ผ ์‘๋‹ต โ†’ <html lang="ko"> ํ•˜๋“œ์ฝ”๋”ฉ, JS๋Š” localStorage.getItem('sg_lang')๋งŒ ์กฐํšŒ. ์ฒซ ๋ฐฉ๋ฌธ์ž๋Š” ๋ฌด์กฐ๊ฑด ko.
  2. 5/16 i18n ์ž‘์—… "๋””๋ ‰ํ† ๋ฆฌ ๋ถ„๋ฆฌ๋งŒ ํ•˜๊ณ  ๋ณธ๋ฌธ ๋ฒˆ์—ญ ๋ˆ„๋ฝ": ko/zh/en/mn/programs/<slug>.html 4 sub-lang ๋””๋ ‰ํ† ๋ฆฌ๋งŒ ์ƒ์„ฑํ•˜๊ณ  ์ฝ˜ํ…์ธ ๋Š” ํ•œ๊ตญ์–ด ๊ทธ๋Œ€๋กœ. zh ํด๋ฆญ ์‹œ zh span ์•ˆ์— ํ•œ๊ตญ์–ด ๊ทธ๋Œ€๋กœ ํ‘œ์‹œ.
  3. ์‚ฌ์šฉ์ž ์ง์ž‘์—… ์ฝ˜ํ…์ธ ๊ฐ€ lang-content span "๋ฐ–" plain HTML: ์†ก์ง€ํšจ ๋™์˜์ƒ, By the Numbers ์นด๋“œ, 5/16 ์‹ ๊ทœ ์ž‘์—… ํŽ˜์ด์ง€(STARJET/Head Spa/GFF/FPMU/G-WAVE/Foot Care) โ€” ๋ชจ๋‘ lang-content span ํŒจํ„ด ์—†์ด plain HTML ํ•œ๊ตญ์–ด๋กœ ์ž‘์„ฑ.

2. ์ฒ˜๋ฆฌ (์˜ค๋Š˜ ๋ˆ„์ )

Phase 1 โ€” navigator.language ์ž๋™ ๊ฐ์ง€ ํด๋ฐฑ (54 root)

Phase 2 โ€” 41 ํŽ˜์ด์ง€ zh/en/mn span ์ผ๊ด„ ๋ฒˆ์—ญ (6 subagent ๋ณ‘๋ ฌ)

Phase 3 โ€” bm-medical ์‚ฌ์šฉ์ž ์ฝ˜ํ…์ธ  ๋ณต์›

Phase 4 โ€” 5 ํŽ˜์ด์ง€ ์‚ฌ์šฉ์ž ์ง์ž‘์—… ๋ณต์› + plain HTML 4-lang ๋ž˜ํ•‘

Phase 5 โ€” 6 ํŽ˜์ด์ง€ 5/16 ์‹ ๊ทœ ์ž‘์—… root sync (6 subagent ๋ณ‘๋ ฌ)

3. ์ตœ์ข… ์ •๋Ÿ‰ (54 root ํŽ˜์ด์ง€)

์นดํ…Œ๊ณ ๋ฆฌ ํŽ˜์ด์ง€ ์ˆ˜
์™„์ „ ํด๋ฆฐ (in_zh=0, in_en=0, in_mn=0, outside_ko=0) 47
์˜๋„๋œ ๊ณ ์œ ๋ช…์‚ฌ ์ž”์กด (< 50) 7
์ „์ฒด PASS 54/54 โœ…

์˜๋„๋œ ์ž”์กด (๊ณ ์œ ๋ช…์‚ฌ)

4. ์ •์ฑ… ์‹ ์„ค

[[feedback_i18n-dir-split-without-translation]]

i18n "๋””๋ ‰ํ† ๋ฆฌ ๋ถ„๋ฆฌ"์™€ "๋ณธ๋ฌธ ๋ฒˆ์—ญ"์„ ํ˜ผ๋™ํ•˜์ง€ ๋ง ๊ฒƒ. lang-content span "์•ˆ" ํ•œ๊ธ€ ์นด์šดํŠธ๋กœ ์ •๋Ÿ‰ ๊ฒ€์ฆ (cross-lang ์œ„์žฅ ์ฐจ๋‹จ). 5 ์œ„์น˜ ๋™๊ธฐํ™” ์˜๋ฌด (ko/zh/en/mn/root).

# ์ •ํ™•ํ•œ ์ •๋Ÿ‰ ํŒจํ„ด
for lang in ['zh','en','mn']:
  matches = re.findall(rf'data-lang="{lang}">(.*?)</', text)
  inside_hangul = sum(len(re.findall(r'[๊ฐ€-ํžฃ]', m)) for m in matches)

๋‹จ์ˆœ grep -c '[๊ฐ€-ํžฃ]'๋Š” cross-lang span ํ•œ๊ธ€๊นŒ์ง€ ํ•ฉ์‚ฐ๋˜์–ด false PASS ๋ฐœ์ƒ.

lang-content span "๋ฐ–" plain HTML๋„ ๊ฒ€์ฆ

from bs4 import BeautifulSoup, Comment
soup = BeautifulSoup(html, 'html.parser')
for s in soup.find_all(class_='lang-content'): s.decompose()
for s in soup.find_all(['script','style','title']): s.decompose()
for c in soup.find_all(string=lambda x: isinstance(x, Comment)): c.extract()
outside = len(re.findall(r'[๊ฐ€-ํžฃ]', soup.get_text(' ', strip=True)))

5. ์•ˆ์ „ ๋ณด์กด

6. ํŒŒ์ผ ๋ณ€๊ฒฝ

์ด 270+ ํŒŒ์ผ (54 root + 54ร—4 sub-lang + ๋ฐฑ์—…)

๋ฐฑ์—… ์œ„์น˜

7. ๋ผ์ด๋ธŒ ๊ฒ€์ฆ