.po vs .mo vs .pot: ไฟล์แปลภาษาของ WordPress อธิบายโดยละเอียด

คุณเปิดโฟลเดอร์ languages ของธีม WordPress แล้วพบไฟล์สามไฟล์ที่ดูคล้ายกันมาก: twentytwentyfour.pot, twentytwentyfour-de_DE.po และ twentytwentyfour-de_DE.mo เป็นธีมเดียวกัน ภาษาเดียวกัน แต่มีนามสกุลต่างกันสามแบบ คุณควรแก้ไขไฟล์ไหน? ไฟล์ไหนที่ WordPress โหลดใช้งานจริง? และทำไมการแก้ไขไฟล์ผิดทำให้การแปลของคุณหายไปอย่างเงียบๆ?
หากคุณเคยสงสัยว่าไฟล์ไหนสำคัญในประเด็น ไฟล์ po vs mo คุณไม่ใช่คนเดียว นามสกุลทั้งสามนี้เป็นหัวใจสำคัญของเว็บไซต์ WordPress ที่แปลแล้วทุกแห่ง แต่ความแตกต่างระหว่างไฟล์เหล่านี้มักจะทำให้ทั้งมือใหม่และนักพัฒนาที่มีประสบการณ์สับสน หากแก้ไขไฟล์ผิด ผู้เข้าชมชาวเยอรมันของคุณก็ยังคงเห็นเป็นภาษาอังกฤษ หากแก้ไขไฟล์ถูกแต่ข้ามขั้นตอนไป ก็จะไม่มีอะไรเปลี่ยนแปลงเช่นกัน
คู่มือนี้จะอธิบายอย่างละเอียดว่าไฟล์ .pot, .po และ .mo คืออะไร เกี่ยวข้องกันอย่างไรในเวิร์กโฟลว์ GNU Gettext ไฟล์เหล่านี้อยู่ในส่วนไหนของ WordPress และทำไมคุณไม่ควรเปิดไฟล์ .mo ด้วยโปรแกรมแก้ไขข้อความ เมื่ออ่านจบ คุณจะรู้ว่าควรแตะต้องไฟล์ไหน และควรปล่อยไฟล์ไหนไว้
ไฟล์ .pot, .po และ .mo คืออะไร?
กล่าวโดยย่อ: ไฟล์ .pot คือเทมเพลตเปล่า, ไฟล์ .po คือไฟล์แปลที่คุณแก้ไขได้, และไฟล์ .mo คือไบนารีที่ถูกคอมไพล์แล้วซึ่ง WordPress อ่านตอนรันไทม์ ไฟล์เหล่านี้สร้างเป็นสายโซ่ และแต่ละส่วนมีหน้าที่เพียงอย่างเดียว
รูปแบบทั้งสามนี้มาจาก GNU Gettext ซึ่งเป็นระบบการแปลภาษาที่ WordPress, Drupal และโปรเจกต์ PHP และ C อีกหลายพันโปรเจกต์ใช้ Gettext แยก สตริงต้นฉบับ ที่นักพัฒนาเขียนออกจาก คำแปล ที่นักแปลจัดหาให้ เพื่อให้โค้ดเบสเดียวกันสามารถรองรับได้หลายสิบภาษาโดยไม่ต้องแก้ไขโค้ด PHP แม้แต่บรรทัดเดียว
ลองนึกถึงมันเหมือนกับการ์ดสูตรอาหาร ไฟล์ .pot คือการ์ดเปล่าที่มีช่องสำหรับส่วนผสมแต่ไม่มีปริมาณ ไฟล์ .po คือการ์ดที่กรอกข้อมูลสำหรับอาหารจานใดจานหนึ่ง และไฟล์ .mo คือสำเนาที่เคลือบพลาสติกที่เครื่องสแกนได้ซึ่งครัวใช้จริงระหว่างการบริการ คุณเขียนบนการ์ดกระดาษ; คุณไม่เคยขีดเขียนบนการ์ดที่เคลือบพลาสติกแล้ว
ไฟล์ .pot: เทมเพลตหลัก
ไฟล์ .pot (Portable Object Template) มีสตริงที่สามารถแปลได้ทั้งหมดในธีมหรือปลั๊กอิน โดยที่ช่องแปลถูกเว้นว่างไว้ เป็นรายการหลักที่นักพัฒนาจัดส่งเพื่อให้ผู้แปลรู้ว่าต้องแปลอะไรบ้าง บรรทัด msgstr จะว่างเปล่าเนื่องจากยังไม่ได้เลือกภาษา
#: includes/checkout.php:42
msgid "Add to Cart"
msgstr ""
#: includes/account.php:108
msgid "Your order has been shipped to %s"
msgstr ""
สังเกต msgstr "" ที่ว่างเปล่า ไฟล์ .pot เป็นเทมเพลต ไม่ใช่คำแปล คุณคัดลอกมันหนึ่งครั้งต่อหนึ่งภาษาแล้วกรอกข้อมูลลงไป คุณแทบจะไม่แก้ไขไฟล์ .pot ด้วยมือ; มันจะถูกสร้างใหม่จากซอร์สโค้ดทุกครั้งที่สตริงเปลี่ยนแปลง
ไฟล์ .po: คำแปลที่มนุษย์แก้ไขได้
ไฟล์ .po (Portable Object) เป็นสำเนาของไฟล์ .pot ที่มีบรรทัด msgstr กรอกข้อมูลสำหรับภาษาเดียว นี่คือไฟล์ที่นักแปลและนักพัฒนาแก้ไขจริง เป็นไฟล์ข้อความธรรมดาที่มนุษย์อ่านเข้าใจได้ และเป็นมิตรกับการควบคุมเวอร์ชัน
#: includes/checkout.php:42
msgid "Add to Cart"
msgstr "In den Warenkorb"
#: includes/account.php:108
msgid "Your order has been shipped to %s"
msgstr "Ihre Bestellung wurde an %s versandt"
msgid คือสตริงต้นฉบับภาษาอังกฤษและต้องไม่เปลี่ยนแปลง msgstr คือคำแปลของคุณ %s คือตัวยึดตำแหน่งที่ต้องคงอยู่ในการแปลโดยไม่ถูกแตะต้อง — การละทิ้งหรือการจัดลำดับใหม่เป็นสาเหตุที่พบบ่อยที่สุดที่ทำให้เลย์เอาต์เสีย ซึ่งเราจะกล่าวถึงอย่างละเอียดใน วิธีแปลไฟล์ PO โดยไม่ทำให้ตัวแปรโค้ดเสียหาย
ไฟล์ .mo: ไบนารีที่ถูกคอมไพล์
ไฟล์ .mo (Machine Object) คือเวอร์ชันไบนารีที่ถูกคอมไพล์ของไฟล์ .po ของคุณ WordPress ไม่สามารถอ่านไฟล์ .po ได้อย่างมีประสิทธิภาพในขณะรันไทม์ ดังนั้นจึงโหลดไฟล์ .mo ที่คอมไพล์ล่วงหน้าไว้แทน การเปิดไฟล์ .mo ในโปรแกรมแก้ไขข้อความจะแสดงไบต์ที่อ่านไม่ได้ — มันมีไว้สำหรับเครื่องจักร ไม่ใช่สำหรับมนุษย์
เมื่อ WordPress เรียกใช้ load_textdomain() หรือ load_theme_textdomain() มันจะมองหาไฟล์ .mo วิเคราะห์ตารางแฮชไบนารี และสลับ msgid ทุกรายการกับ msgstr ที่ตรงกันแบบทันที รูปแบบไบนารีนี้ทำให้การค้นหารวดเร็วแม้ในเว็บไซต์ที่มีสตริงเป็นพันๆ
ไฟล์ทั้งสามเกี่ยวข้องกันอย่างไรในเวิร์กโฟลว์ Gettext?
ไฟล์เหล่านี้ก่อให้เกิดไปป์ไลน์แบบทิศทางเดียว: ซอร์สโค้ดกลายเป็นไฟล์ .pot, ไฟล์ .pot กลายเป็นไฟล์ .po สำหรับแต่ละภาษา และไฟล์ .po แต่ละไฟล์จะถูกคอมไพล์เป็นไฟล์ .mo การแปลจะไหลไปในทิศทางเดียวเสมอ
ต่อไปนี้คือวงจรชีวิตทั้งหมดตามลำดับ:
- นักพัฒนาจะใส่สตริงที่ผู้ใช้เห็นในฟังก์ชัน Gettext เช่น
__()และ_e()ภายในซอร์สโค้ด PHP - เครื่องมือสแกนจะอ่านซอร์สโค้ดและสร้างเทมเพลต
.potซึ่งมีสตริงที่ใส่ไว้ทั้งหมด - นักแปลจะคัดลอกไฟล์
.potไปยังไฟล์.poเฉพาะภาษา (เช่นde_DE.po) และกรอกข้อมูลในmsgstrแต่ละรายการ - ไฟล์
.poที่เสร็จสมบูรณ์จะถูกคอมไพล์เป็นไบนารี.mo - WordPress โหลดไฟล์
.moในขณะรันไทม์และแสดงเว็บไซต์ที่แปลแล้ว
เมื่อนักพัฒนาเพิ่มสตริงใหม่ในภายหลัง ไฟล์ .pot จะถูกสร้างใหม่, รายการใหม่จะถูกรวมเข้ากับไฟล์ .po ที่มีอยู่แต่ละไฟล์ (โดยเก็บคำแปลเก่าไว้), นักแปลจะเติมช่องว่าง, และไฟล์ .po จะถูกคอมไพล์ใหม่เป็น .mo วงจรนี้จะวนซ้ำไปตลอดอายุของโปรเจกต์
ประเด็นสำคัญที่ต้องจำคือ: คุณแก้ไขไฟล์ .po แล้วคอมไพล์เป็น .mo คุณไม่เคยแก้ไขไฟล์ .mo โดยตรง และคุณไม่เคยแปลภายในไฟล์ .pot หากคุณต้องการภาพรวมแบบครบวงจรที่ลึกซึ้งยิ่งขึ้น คู่มือสุดยอดการแปล WordPress จะอธิบายไปป์ไลน์ทั้งหมดพร้อมตัวอย่าง
กฎการตั้งชื่อและที่อยู่ของไฟล์
WordPress เข้มงวดกับการตั้งชื่อไฟล์ หากตั้งชื่อผิด ไฟล์ .mo ที่แปลมาอย่างสมบูรณ์ของคุณก็จะถูกละเลยไปเฉยๆ เพราะ WordPress จะมองหาการจับคู่ที่ตรงกันอย่างแม่นยำตาม text domain และ locale
รูปแบบการตั้งชื่อสำหรับการแปลธีมและปลั๊กอินคือ:
# Pattern: textdomain-locale.po / .mo
twentytwentyfour-de_DE.po # German (Germany) translation
twentytwentyfour-de_DE.mo # compiled binary WordPress loads
twentytwentyfour-fr_FR.po # French (France)
twentytwentyfour.pot # template, no locale suffix
textdomain ต้องตรงกับสตริงที่ส่งเป็นอาร์กิวเมนต์ที่สองไปยังฟังก์ชัน Gettext เช่น __( 'Add to Cart', 'twentytwentyfour' ) ส่วน locale คือรหัสภาษาของ WordPress เช่น de_DE, fr_FR หรือ pt_BR เทมเพลต .pot ไม่มีคำต่อท้าย locale เพราะเป็นกลางทางภาษา
ตำแหน่งสำคัญไม่แพ้การตั้งชื่อ WordPress ค้นหาในเส้นทางที่คาดเดาได้ไม่กี่เส้นทาง:
- การแปลธีม จะอยู่ในโฟลเดอร์
wp-content/themes/your-theme/languages/ของธีมนั้นๆ - การแปลปลั๊กอิน จะอยู่ใน
wp-content/plugins/your-plugin/languages/ - การแปลจาก translate.wordpress.org และการเขียนทับของผู้ใช้จะอยู่ในไดเรกทอรี
wp-content/languages/themes/และwp-content/languages/plugins/ซึ่งจะมีความสำคัญเป็นอันดับแรกและอยู่รอดเมื่อมีการอัปเดต
ใส่ไฟล์ de_DE.mo ที่ตั้งชื่อถูกต้องในโฟลเดอร์ที่ถูกต้อง ผู้เข้าชมชาวเยอรมันก็จะเห็นเป็นภาษาเยอรมัน หากใส่ลึกเกินไปหนึ่งโฟลเดอร์ หรือสะกด text domain ผิด WordPress จะกลับไปใช้ภาษาอังกฤษอย่างเงียบๆ โดยไม่มีข้อความแสดงข้อผิดพลาดใดๆ หากการแปลของคุณไม่ปรากฏขึ้น สาเหตุส่วนใหญ่มักเกิดจากการตั้งชื่อหรือเส้นทางที่ไม่ตรงกัน และ คู่มือแก้ไขปัญหาการแปลที่หายไป ครอบคลุมทุกสาเหตุที่พบบ่อย
ทำไมคุณไม่ควรแก้ไขไฟล์ .mo โดยตรง
เนื่องจากไฟล์ .mo เป็นไบนารีที่ถูกคอมไพล์ จึงไม่มีวิธีที่ปลอดภัยในการแก้ไขด้วยมือ — และการเปลี่ยนแปลงใดๆ ที่คุณบังคับเข้าไปจะถูกเขียนทับในครั้งต่อไปที่ไฟล์ .po ถูกคอมไพล์ใหม่ ไฟล์ .po คือแหล่งข้อมูลที่แท้จริง ส่วนไฟล์ .mo เป็นไฟล์ที่สร้างขึ้นมาเพื่อใช้งานแล้วทิ้งไป
กฎข้อเดียวนี้อธิบายถึงคำถามส่วนใหญ่ที่ว่า “การแปลของฉันเปลี่ยนไปแต่เว็บไซต์ไม่อัปเดต” ใครบางคนแก้ไขสตริง บันทึกไฟล์ .po แล้วลืมคอมไพล์ไฟล์ .mo ใหม่ WordPress ยังคงโหลดไบนารีเก่า ดังนั้นคำพูดใหม่จึงไม่ปรากฏขึ้น วิธีแก้ไขคือ: แก้ไขไฟล์ .po, คอมไพล์เป็นไฟล์ .mo แล้วโหลดซ้ำเสมอ
มีเหตุผลที่สองที่กฎนี้สำคัญ: ไฟล์ .mo ไม่เป็นมิตรกับการเปรียบเทียบความแตกต่างในการควบคุมเวอร์ชัน เนื่องจากเป็นไบนารี การเปลี่ยนแปลงคำพูดเพียงเล็กน้อยจะสร้างข้อมูลขนาดใหญ่ที่อ่านไม่ออกในประวัติ Git ของคุณซึ่งผู้ตรวจสอบไม่สามารถอ่านได้ การเก็บไฟล์ .po เป็นแหล่งข้อมูลที่แท้จริงที่ถูกติดตาม และถือว่าไฟล์ .mo เป็นไฟล์ที่ถูกสร้างขึ้น จะทำให้คลังข้อมูลของคุณสามารถตรวจสอบได้และการแปลของคุณสามารถตรวจสอบได้
การทำด้วยตนเองสำหรับภาษาจำนวนมากนั้นน่าเบื่อและผิดพลาดง่าย นี่คือที่ที่เวิร์กโฟลว์บนคลาวด์ช่วยประหยัดเวลาได้จริง เครื่องมืออย่าง SimplePoTranslate จะแปลสตริง .po ของคุณและส่งกลับไฟล์ ZIP ไฟล์เดียวที่มี .po และ .mo ที่ตรงกัน — ซึ่งคอมไพล์แล้ว ตั้งชื่อถูกต้อง พร้อมที่จะใส่ลงใน wp-content/languages/ ไม่ต้องคอมไพล์ด้วยตนเองและไม่มีโอกาสที่ไฟล์ .mo จะล้าสมัย
นอกจากนี้ยังใช้ Syntax Locking ซึ่งจะตรึงตัวยึดตำแหน่งทุกตัว เช่น %s, %1$s และ {name} รวมถึงแท็ก HTML ก่อนการแปล ตัวแปรของคุณจะยังคงอยู่ครบถ้วน คุณจึงไม่ส่งมอบไฟล์ .mo ที่ทำให้เลย์เอาต์เสียหาย และเนื่องจากมันทำงานบนคลาวด์ทั้งหมด จึงไม่มีปลั๊กอินพิเศษที่จะถ่วงเว็บไซต์ของคุณ — คุณอัปโหลดไฟล์แล้วดาวน์โหลดคำแปลที่คอมไพล์เสร็จแล้วได้เลย
สรุปทั้งหมด
เมื่อเข้าใจความแตกต่างระหว่าง ไฟล์ po vs mo ระบบการแปล WordPress ทั้งหมดก็จะหยุดเป็นเรื่องลึกลับ ไฟล์ .pot คือเทมเพลตของนักพัฒนา, ไฟล์ .po คือฉบับแก้ไขที่นักแปลทำงานด้วย, และไฟล์ .mo คือไบนารีที่ถูกคอมไพล์ซึ่ง WordPress นำไปให้บริการแก่ผู้เข้าชมจริง การแปลจะไหลไปในทิศทางเดียว — เทมเพลตไปยัง .po ไปยัง .mo — และคุณแก้ไขด้วยมือเพียงไฟล์ตรงกลางเท่านั้น
จำกฎสามข้อที่ช่วยป้องกันปัญหาการแปลได้ถึงเก้าสิบเปอร์เซ็นต์: อย่าแปลภายในไฟล์ .pot เด็ดขาด, คอมไพล์ไฟล์ .mo ใหม่เสมอหลังจากแก้ไขไฟล์ .po, และตั้งชื่อ textdomain-locale ให้ตรงกันอย่างแม่นยำ ปฏิบัติตามกฎเหล่านี้แล้วสตริงที่แปลแล้วของคุณจะปรากฏทุกครั้ง
พร้อมที่จะหยุดการต่อสู้กับการคอมไพล์และการตั้งชื่อไฟล์แปลด้วยตนเองแล้วหรือยัง? ลอง SimplePoTranslate ฟรี — ไม่ต้องใช้บัตรเครดิต อัปโหลดไฟล์
.poหรือ.potของคุณ แล้วรับแพ็กเกจ.po+.moที่พร้อมใช้งานกลับมาในระดับฟรีภายในไม่กี่นาที