คุณสมบัติปลั๊กอินราคาแหล่งข้อมูล
เปลี่ยนภาษา
แหล่งข้อมูลวิธีแปลไฟล์ .po ของ Drupal ด้วย AI

วิธีแปลไฟล์ .po ของ Drupal ด้วย AI

SimplePoTranslate Team6 มิถุนายน 2569
วิธีแปลไฟล์ .po ของ Drupal ด้วย AI

คนส่วนใหญ่เชื่อมโยงไฟล์ .po กับ WordPress แต่รูปแบบ gettext มีมาก่อน WordPress หลายสิบปี และขับเคลื่อนการแปลส่วนติดต่อผู้ใช้ทั่วโลกโอเพ่นซอร์ส Drupal เป็นหนึ่งในผู้ใช้งานรายใหญ่ที่สุด หากคุณมีเว็บไซต์ Drupal หลายภาษา ป้ายกำกับเมนู, คำอธิบายฟิลด์, ข้อความแสดงข้อผิดพลาด และสตริงโมดูลทั้งหมดจะไหลผ่านไฟล์ .po ในลักษณะเดียวกับที่เกิดขึ้นใน WordPress เพียงแต่มีภาษาของตัวยึดตำแหน่งที่แตกต่างกันและเวิร์กโฟลว์การนำเข้าที่ต่างกัน และเช่นเดียวกับ WordPress ทันทีที่เว็บไซต์ของคุณมีสตริงจำนวนมาก การแปลไฟล์เหล่านั้นด้วยมือก็กลายเป็นคอขวด

คู่มือนี้เกี่ยวกับวิธี แปลไฟล์ .po ของ Drupal ด้วย AI โดยไม่ทำให้สิ่งที่เป็นเอกลักษณ์ของ Drupal เสียหาย เราจะอธิบายระบบการแปลของ Drupal ที่มาของสตริง ไวยากรณ์ของตัวยึดตำแหน่งที่แตกต่างจาก WordPress และต้องได้รับการรักษาไว้ และวงจรการส่งออก การแปล และการนำเข้าซ้ำที่สมบูรณ์ รวมถึงคำสั่ง drush ที่ทำให้กระบวนการนี้ทำซ้ำได้

ระบบการแปลของ Drupal ทำงานอย่างไร

Drupal จัดการการแปลส่วนติดต่อผู้ใช้ผ่านโมดูลหลัก locale (บางครั้งเรียกว่า "Interface Translation" ใน Drupal สมัยใหม่) เมื่อเปิดใช้งานแล้ว โมดูลนี้จะจัดการตารางฐานข้อมูลของสตริงต้นฉบับและการแปลในแต่ละภาษา และสามารถนำเข้าและส่งออกการแปลเหล่านั้นเป็นไฟล์ gettext .po มาตรฐานได้

ส่วนติดต่อผู้ดูแลระบบอยู่ที่ /admin/config/regional/translate จากที่นั่น คุณสามารถค้นหาสตริงที่ยังไม่ได้แปล แก้ไขแบบอินไลน์ และที่สำคัญคือ นำเข้าไฟล์ .po เพื่อโหลดการแปลจำนวนมาก หรือส่งออกสถานะปัจจุบันไปยังไฟล์ .po เพื่อแก้ไขแบบออฟไลน์ วงจรการส่งออก/แก้ไข/นำเข้า นี้คือเวิร์กโฟลว์ที่เรากำลังปรับปรุง

แตกต่างจาก WordPress ที่ปลั๊กอินและธีมแต่ละตัวจะมาพร้อมกับไฟล์ .po และ .mo ของตัวเองในไดเรกทอรี languages/ นั้น Drupal จะรวมศูนย์สตริงส่วนติดต่อผู้ใช้ไว้ในฐานข้อมูล และถือว่า .po เป็นรูปแบบการแลกเปลี่ยน คุณส่งออก ทำงานกับไฟล์ และนำกลับมา ขั้นตอนการคอมไพล์ .mo ที่ WordPress ต้องการนั้นจะถูกจัดการภายใน

ที่มาของสตริง

สตริงของ Drupal มีที่มาจากสามแห่ง และการแปลที่สมบูรณ์จะต้องครอบคลุมทั้งหมด:

  • Core มาพร้อมกับสตริงที่แปลได้หลายพันรายการสำหรับ UI ผู้ดูแลระบบ ฟอร์ม และข้อความระบบ
  • โมดูล Contrib (Views, Webform, Commerce และอื่น ๆ) แต่ละตัวจะลงทะเบียนสตริงของตนเองผ่านฟังก์ชัน t()
  • ธีม มีส่วนร่วมในการสร้างสตริงเทมเพลต ป้ายกำกับภูมิภาค และคำอธิบายการตั้งค่าธีม

เมื่อคุณส่งออกข้อมูลจาก /admin/config/regional/translate คุณสามารถกำหนดขอบเขตการส่งออกเป็นสตริงที่แปลแล้ว ที่ยังไม่ได้แปล หรือทั้งหมดได้ สำหรับการแปลใหม่ การส่งออกเฉพาะสตริงที่ยังไม่ได้แปลจะทำให้คุณได้ไฟล์ .po ที่เน้นงานที่เหลืออยู่ได้อย่างแม่นยำ

ผลที่ตามมาในทางปฏิบัติของโครงสร้างสามแหล่งนี้คือ งานแปลของคุณไม่เคย "เสร็จสิ้น" อย่างแท้จริง ทุกครั้งที่คุณเพิ่มโมดูล contrib เปิดใช้งานคุณสมบัติใหม่ หรืออัปเดต Drupal core สตริง msgid ที่ยังไม่ได้แปลชุดใหม่จะปรากฏในตาราง locale นี่คือเหตุผลที่ทีม Drupal ถือว่าการแปลเป็นไปป์ไลน์ที่เกิดขึ้นซ้ำๆ แทนที่จะเป็นงานเปิดตัวครั้งเดียว วงจรการส่งออก การแปล และการนำเข้าซ้ำเดียวกันนี้จะทำงานในการปรับใช้ทุกครั้งที่เกี่ยวข้องกับโมดูล และยิ่งวงจรนั้นเร็วเท่าไร หนี้การแปลก็จะสะสมน้อยลงระหว่างการเผยแพร่

สิ่งที่ควรทราบอีกประการคือ Drupal สามารถดึงการแปลที่ชุมชนมีส่วนร่วมโดยอัตโนมัติจาก localize.drupal.org สำหรับโมดูลหลักและโมดูล contrib ยอดนิยม สิ่งเหล่านั้นครอบคลุมสตริงทั่วไป แต่ไม่ค่อยครอบคลุมโมดูลที่คุณกำหนดเอง ธีมของคุณ หรือวลีเฉพาะโครงการที่เว็บไซต์ของคุณใช้จริง ช่องว่างระหว่างการแปลของชุมชนกับเว็บไซต์ที่ได้รับการโลคัลไลซ์อย่างสมบูรณ์คืองานที่ AI สามารถจัดการได้อย่างรวดเร็ว

ตัวยึดตำแหน่งของ Drupal ไม่ใช่ตัวยึดตำแหน่งของ WordPress

นี่คือสิ่งสำคัญที่สุดที่ต้องทำความเข้าใจก่อนส่งไฟล์ .po ของ Drupal ไปยังเครื่องมือแปล AI: Drupal ไม่ใช้ตัวยึดตำแหน่งแบบ printf เช่น %s และ %1$s ที่พบได้บ่อยใน WordPress ฟังก์ชัน t() ของ Drupal ใช้คำนำหน้าตัวยึดตำแหน่งที่แตกต่างกันสามแบบ โดยแต่ละแบบมีพฤติกรรมการหลีกเลี่ยง (escaping) ที่แตกต่างกัน:

  • @variable — ค่าจะถูกหลีกเลี่ยง HTML (HTML-escaped) เป็นค่าเริ่มต้นที่ปลอดภัยสำหรับข้อความที่ผู้ใช้ป้อน
  • %variable — ค่าจะถูกหลีกเลี่ยงและล้อมรอบด้วยมาร์กอัปเน้น <em>
  • :placeholder — ใช้สำหรับแอตทริบิวต์ URL ผ่านการตรวจสอบความปลอดภัยของ URL (URL sanitization)

สตริงต้นฉบับของ Drupal ทั่วไปมีลักษณะเช่นนี้ในไฟล์ .po ที่ส่งออก:

#: core/modules/node/node.module
msgid "@count comments"
msgid_plural "@count comments"
msgstr[0] ""
msgstr[1] ""

#: core/modules/user/user.module
msgid "Welcome @name, you last logged in on %date."
msgstr ""

หากผู้แปลเปลี่ยน @count เป็น @cuenta แทนที่ @name ด้วยคำแปลสำหรับ "name" หรือแทรกช่องว่างทำให้ @count กลายเป็น @ count ตัวยึดตำแหน่งจะไม่ตรงกับสิ่งที่ฟังก์ชัน t() ส่งผ่านเข้ามา Drupal จะพิมพ์โทเค็น @count แบบตรงตัวลงบนหน้าเพจแทนที่จะเป็นตัวเลขจริง การแปลอาจดูเหมือนเสร็จสมบูรณ์ แต่เว็บไซต์จะเสียให้เห็นได้อย่างชัดเจน

นี่คือข้อผิดพลาดประเภทเดียวกับที่เกิดขึ้นกับสตริง %s ของ WordPress และเราได้ครอบคลุมหลักการทั่วไปอย่างละเอียดใน วิธีแปลไฟล์ PO โดยไม่ทำให้ตัวแปรโค้ดเสียหาย ความซับซ้อนของ Drupal คือมีรูปแบบตัวยึดตำแหน่งถึงสามแบบแทนที่จะเป็นแบบเดียว และเครื่องมือแปลต้องรู้จักทั้งหมด

ทำไมเครื่องมือแปลทั่วไปจึงล้มเหลวในจุดนี้

ลองวางสตริง node.module นั้นลงในกล่องแปลภาษาอัตโนมัติทั่วไป คุณมักจะพบว่า @count บิดเบี้ยว %date ที่ถูกห่อด้วย <em> ถูกแปลเป็นโทเค็นอื่น หรือรูปแบบพหูพจน์ถูกยุบรวมเป็นหนึ่ง ไม่มีเครื่องมือใดที่สร้างขึ้นโดยคำนึงถึงความหมายของ gettext พวกเขาแปลข้อความ; พวกเขาไม่เข้าใจว่า @count คือสัญญาที่ผูกกับโค้ดแอปพลิเคชัน

ไปป์ไลน์การแปลที่เข้าใจ gettext พร้อม Syntax Locking จะถือว่า @variable, %variable และ :placeholder เป็นโทเค็นที่ไม่เปลี่ยนแปลง โทเค็นเหล่านี้จะถูกล็อกก่อนการแปลและถูกกู้คืนหลังจากนั้น เพื่อให้ประโยคโดยรอบได้รับการแปลในขณะที่ตัวยึดตำแหน่งยังคงไม่เปลี่ยนแปลง การล็อกแบบเดียวกันนี้ครอบคลุม %s และ %1$s ของ WordPress, {{name}} ของ i18next และ HTML แบบอินไลน์ ซึ่งเป็นเหตุผลว่าทำไมเครื่องมือเดียวจึงสามารถรองรับโครงการ Drupal, Symfony หรือ Laravel ได้ง่ายพอๆ กับ WordPress รูปแบบพหูพจน์ของ Drupal ผ่าน msgid_plural จะถูกรักษาไว้เป็นรูปแบบพหูพจน์แทนที่จะถูกทำให้แบนราบ ซึ่งเป็นสิ่งสำคัญเนื่องจากภาษาของ Drupal สามารถมีรูปแบบพหูพจน์ได้ตั้งแต่หนึ่งถึงหกแบบ

มีรูปแบบความล้มเหลวที่ละเอียดอ่อนกว่าที่ควรกล่าวถึงด้วย สตริงของ Drupal มักจะฝังมาร์กอัปและลิงก์แบบอินไลน์ไว้ในข้อความที่แปลได้ เช่น Read the <a href=":url">documentation</a> โดยที่ :url เป็นตัวยึดตำแหน่งและแท็ก <a> จะต้องยังคงอยู่ เครื่องมือแปลที่ไม่เข้าใจโครงสร้างอาจแปลแอตทริบิวต์ href ละทิ้งแท็กปิด หรือแปลชื่อตัวยึดตำแหน่ง AI ที่รับรู้บริบท ซึ่งอ่านสตริงทั้งหมดเป็นหน่วยเดียว ร่วมกับการล็อกโทเค็น จะรักษามาร์กอัปและสัญญา :url ให้คงอยู่ โดยแปลเฉพาะข้อความ "documentation" ที่มนุษย์อ่านได้ซึ่งอยู่ตรงกลาง

วงจรการส่งออก การแปล และการนำเข้าซ้ำ

เวิร์กโฟลว์ที่ทำซ้ำได้นี้มีสามขั้นตอน และ drush ทำให้การส่งออกและการนำเข้าสามารถเขียนสคริปต์ได้ คุณจึงไม่ต้องคลิกผ่าน UI ผู้ดูแลระบบทุกครั้ง

ขั้นตอนที่ 1: ส่งออกไฟล์ PO

คุณสามารถส่งออกได้จาก UI ที่ /admin/config/regional/translate โดยการเลือกภาษาและขอบเขตการส่งออก หรือทำจากบรรทัดคำสั่ง โมดูล locale จะเปิดเผยการส่งออกผ่านบริการการแปลของ Drupal และทีมส่วนใหญ่จะเขียนสคริปต์สำหรับมัน คำสั่ง drush ทั่วไปเพื่อเรียกใช้การนำเข้าการแปล (ตรงกันข้ามกับสิ่งที่เราใช้ในขั้นตอนที่สาม) มีลักษณะดังนี้:

# Re-import a translated PO file for Spanish, overwriting customized strings
drush locale:import es /var/www/translations/es-untranslated.po \
  --type=customized --override=all

# Rebuild caches so the new strings render immediately
drush cache:rebuild

สำหรับกาส่งออก ฟอร์มการส่งออกของผู้ดูแลระบบจะสร้างไฟล์ .po ทีมจำนวนมากจะห่อหุ้มบริการส่งออก locale ในคำสั่ง Drush ที่กำหนดเองขนาดเล็กเพื่อระบบอัตโนมัติเต็มรูปแบบ ไม่ว่าด้วยวิธีใด คุณก็จะได้ไฟล์ gettext .po มาตรฐานที่มีรายการ msgid ที่ยังไม่ได้แปลของคุณ

ขั้นตอนที่ 2: แปลไฟล์

นี่คือขั้นตอนที่ AI เข้ามาแทนที่การแก้ไขด้วยมือที่ใช้เวลาหลายชั่วโมง อัปโหลดไฟล์ .po ที่ส่งออกไปยังเครื่องมือแปลบนคลาวด์ เลือกภาษาเป้าหมาย และปล่อยให้มันประมวลผล เนื่องจากไฟล์ .po ของ Drupal สำหรับเว็บไซต์ขนาดใหญ่มักมีขนาดเกิน 10MB เมื่อรวม Core, Contrib และธีมเข้าด้วยกัน Smart Batching จึงมีความสำคัญที่นี่: ไฟล์จะถูกแบ่งเป็นส่วนๆ แปล และประกอบกลับคืนโดยที่คุณไม่ต้องแยกด้วยมือหรือพบข้อจำกัดด้านขนาด ผลลัพธ์ที่ได้คือไฟล์ .po ที่สมบูรณ์พร้อม msgstr ที่กรอกข้อมูลครบถ้วน และตัวยึดตำแหน่ง @count, %date และ :url แต่ละตัวอยู่ที่ตำแหน่งเดิมอย่างแม่นยำ

ขั้นตอนที่ 3: นำเข้ากลับไปยัง Drupal

นำเข้าไฟล์ที่แปลแล้วกลับผ่าน /admin/config/regional/translate หรือผ่านคำสั่ง drush locale:import ที่แสดงไว้ข้างต้น จากนั้นสร้างแคชใหม่ Drupal จะรวมการแปลเข้ากับตาราง locale และสตริงจะปรากฏทั่วทั้งเว็บไซต์ทันที รันวงจรนี้ซ้ำอีกครั้งเมื่อใดก็ตามที่คุณเพิ่มโมดูลหรืออัปเดต Core เนื่องจากแต่ละครั้งจะนำสตริงที่ยังไม่ได้แปลใหม่เข้ามา

รายละเอียดการนำเข้าที่ต้องทำให้ถูกต้องคือ แฟล็ก --override ควบคุมว่าการแปลที่เข้ามาจะแทนที่การแปลที่มีอยู่หรือไม่ ใช้ --override=all เมื่อคุณต้องการให้ไฟล์ที่แปลด้วย AI เป็นแหล่งที่มาหลัก หรือใช้การตั้งค่าที่อนุรักษ์นิยมกว่าหากคุณได้ปรับแต่งสตริงบางอย่างใน Drupal UI ด้วยตนเองและไม่ต้องการให้ถูกเขียนทับ สำหรับไปป์ไลน์อัตโนมัติส่วนใหญ่ การถือว่าไฟล์ .po เป็นแหล่งที่มาของความจริงและเขียนทับทุกอย่างจะทำให้ระบบคาดเดาได้: ไฟล์ในระบบควบคุมเวอร์ชันคือสิ่งที่เว็บไซต์แสดงผล ไม่มีข้อยกเว้น

สำหรับเว็บไซต์หลายภาษาที่มีภาษาเป้าหมายหลายภาษา วงจรนี้จะทำงานหนึ่งครั้งต่อภาษา ส่งออกชุดที่ยังไม่ได้แปล แปลเป็นภาษาเยอรมัน นำเข้า; ส่งออกอีกครั้ง แปลเป็นภาษาสเปน นำเข้า; และทำเช่นนี้ไปเรื่อยๆ เนื่องจากแต่ละภาษาเป็นไฟล์ .po อิสระ คุณสามารถรันแบบขนานได้ และเครื่องมือแปลบนคลาวด์ที่ประมวลผลพร้อมกันจะเปลี่ยนงานที่เคยใช้เวลาหนึ่งสัปดาห์ของฟรีแลนซ์ให้เสร็จได้ในหนึ่งบ่าย

PO ของ Drupal เป็นหนึ่งในหลายรูปแบบ

สิ่งที่ควรทราบคือ gettext .po ไม่ใช่วิธีเดียวที่ Drupal จัดการการแปล เอนทิตีการตั้งค่าและเนื้อหาสามารถแลกเปลี่ยนเป็น XLIFF ได้ ซึ่งเป็นมาตรฐานที่โมดูล Translation Management Tool (TMGMT) ใช้สำหรับเวิร์กโฟลว์ของผู้ให้บริการแปลมืออาชีพ หากการโลคัลไลซ์ Drupal ของคุณทำงานผ่าน XLIFF แทนที่จะเป็นไฟล์ .po สำหรับส่วนติดต่อผู้ใช้ หลักการรักษาตัวยึดตำแหน่งจะเหมือนกัน แต่โครงสร้างไฟล์จะแตกต่างกัน และเราได้ครอบคลุมเส้นทางนั้นใน การแปลไฟล์ XLIFF สำหรับ Drupal, Symfony และ Angular

อย่างไรก็ตาม สำหรับชั้นการแปลส่วนติดต่อผู้ใช้ ไฟล์ .po ยังคงเป็นเครื่องมือหลัก วงจรการส่งออก การแปลด้วย AI และการนำเข้าซ้ำ จะเปลี่ยนงานที่ต้องทำด้วยมือหลายวันให้กลายเป็นเพียงไม่กี่นาทีของการประมวลผล และตราบใดที่เครื่องมือที่คุณใช้เข้าใจตัวยึดตำแหน่ง gettext อย่างแท้จริง สัญญา @variable ของคุณก็จะยังคงอยู่ครบถ้วนและเว็บไซต์ Drupal ของคุณจะใช้งานได้อย่างไม่มีปัญหาในทุกภาษาที่คุณเผยแพร่

พร้อมที่จะแปลไฟล์ .po ของ Drupal โดยไม่ทำให้ @variable แม้แต่ตัวเดียวเสียหายแล้วหรือยัง? ลองใช้ SimplePoTranslate ฟรี — ไม่ต้องใช้บัตรเครดิต ระดับฟรีรองรับไฟล์ gettext .po และ .pot มาตรฐานพร้อม Syntax Locking เต็มรูปแบบ ดังนั้นตัวยึดตำแหน่ง Drupal ของคุณจึงผ่านไปได้อย่างถูกต้องตามที่โค้ดคาดหวัง

หัวข้อที่เกี่ยวข้อง

แชร์บทความนี้