ข้ามไปยังเนื้อหา
ธีม

Block Template ไม่ทำงาน? เริ่มตรวจจากฐานข้อมูลก่อน

ทำให้ WordPress กลับมาใช้ไฟล์เทมเพลตในธีมของคุณ ด้วยการล้างสำเนาใน Site Editor ที่เก็บอยู่ในฐานข้อมูลและทับไฟล์อยู่ แล้วค่อยไล่ตัดเรื่องชื่อไฟล์กับแคชออก

เผยแพร่แล้ว

ไฟล์เทมเพลตของคุณเกือบแน่นอนว่าถูกเมิน เพราะสำเนาในฐานข้อมูลกำลังชนะอยู่ วินาทีที่คุณเปิดเทมเพลตใน Site Editor แล้วกดบันทึก WordPress จะเขียนระเบียนโพสต์ wp_template ลงไป และตั้งแต่นั้นระเบียนนั้นจะถูกเสิร์ฟแทนไฟล์ .html ในโฟลเดอร์ธีมของคุณ ทุกการแก้ไฟล์หลังจากนั้นจึงไม่ปรากฏบนหน้าเว็บจริง การล้างระเบียนนั้นคือทางแก้ และเป็นสิ่งแรกที่ต้องตรวจ ก่อนจะไปแตะลำดับชั้นเทมเพลต ชื่อไฟล์ หรือแคช

ยืนยันว่ามีสำเนาในฐานข้อมูลจริง

ไปที่ Appearance → Editor → Templates เทมเพลตใดที่ WordPress เสิร์ฟจากฐานข้อมูลจะมีป้ายกำกับอยู่ในรายการ ขึ้นอยู่กับรุ่นของ WordPress ป้ายอาจเขียนว่า “Customized” หรือเทมเพลตนั้นจะไปอยู่ใต้ตัวกรอง “Customized” ป้ายนั้นแหละคือคำตอบทั้งหมด ถ้ามีป้าย แปลว่าไฟล์ของคุณไม่ถูกใช้งาน

คุณตรวจเรื่องเดียวกันจากบรรทัดคำสั่งก็ได้ ซึ่งเร็วกว่าและใช้ได้แม้ตอน Site Editor มีปัญหา

wp post list --post_type=wp_template --fields=ID,post_name,post_status,post_title
wp post list --post_type=wp_template_part --fields=ID,post_name,post_status,post_title

แต่ละแถวคือการทับจากฐานข้อมูลหนึ่งรายการ ค่า post_name จะตรงกับ slug ของเทมเพลต ดังนั้นแถวที่ชื่อ single กำลังบังไฟล์ templates/single.html อยู่

รายละเอียดหนึ่งที่ทำให้คนสะดุด คือระเบียนเหล่านี้ผูกกับธีมผ่านเทอมในทางอนุกรมวิธาน ไม่ได้ผูกผ่านเส้นทางไฟล์ ถ้าคุณเปลี่ยนชื่อโฟลเดอร์ธีม เทมเพลตที่บันทึกไว้จะยังอยู่ในฐานข้อมูลแต่เลิกจับคู่กับธีมที่ใช้งานอยู่ แล้วเว็บจะกระโดดกลับไปใช้ไฟล์ทันที อาการที่เห็นคือ “การปรับแต่งของผมหายไปหมด” แทนที่จะเป็น “ไฟล์ผมถูกเมิน” กลไกเดียวกัน แต่อาการตรงข้าม

ล้างมันทิ้ง

ใน Site Editor ให้เปิดเมนูตัวเลือกของเทมเพลต (จุดสามจุดข้าง ๆ) แล้วเลือก Clear customizations บางรุ่นใช้คำว่า Reset การทำแบบนี้จะลบระเบียนในฐานข้อมูล แล้วสิทธิ์ควบคุมจะกลับไปที่ไฟล์บนดิสก์

ถ้าเมนูขึ้นคำว่า Delete แทนที่จะเป็น Clear customizations หรือ Reset แสดงว่าเทมเพลตนั้นมีอยู่เฉพาะในฐานข้อมูลและไม่มีไฟล์รองรับ การลบมันคือการเอาเทมเพลตออกไปทั้งตัว แล้ว WordPress จะไล่ลงไปใช้ไฟล์ถัดไปตามลำดับชั้น

ถ้าใช้ WP-CLI โดยอ้าง ID จากรายการข้างบน

wp post delete 482 --force

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

WordPress เลือกเทมเพลตอย่างไร

block theme ใช้ตรรกะลำดับชั้นเดียวกับ classic theme เพียงแต่เป็นไฟล์ .html ใน templates/ แทนไฟล์ .php ที่รากของธีม WordPress จะไล่จากเจาะจงที่สุดไปกว้างที่สุด แล้วใช้ไฟล์แรกที่มีอยู่จริง

กำลังเปิดดูลำดับการตรวจหา
บทความเดี่ยวsingle-post-{slug}.htmlsingle-post.htmlsingle.htmlsingular.htmlindex.html
หน้าเพจpage-{slug}.htmlpage-{id}.htmlpage.htmlsingular.htmlindex.html
หน้าหมวดหมู่category-{slug}.htmlcategory-{id}.htmlcategory.htmlarchive.htmlindex.html
ชนิดเนื้อหาที่กำหนดเองsingle-{post-type}.htmlsingle.htmlsingular.htmlindex.html
หน้า 404404.htmlindex.html

มีสองอย่างที่ทับลำดับนี้ทั้งหมด อย่างแรกคือระเบียนในฐานข้อมูลที่พูดถึงข้างบน อย่างที่สองคือเทมเพลตที่ถูกกำหนดตรงให้โพสต์หรือหน้าใดหน้าหนึ่ง ให้เปิดหน้าแก้ไขเนื้อหา มองหาแผง Template ในแถบข้าง แล้วดูว่ามีอะไรถูกเลือกไว้เจาะจงหรือเปล่า การกำหนดแบบชัดเจนชนะลำดับชั้นทุกครั้ง และมันมองไม่เห็นเลยถ้าไม่ตั้งใจไปหา

เทมเพลตที่อิงกับ slug เปราะบางในแบบที่ควรจำให้ขึ้นใจ ไฟล์ page-about.html จะจับคู่ก็ต่อเมื่อ slug ของหน้านั้นคือ about เท่านั้น พอเปลี่ยนชื่อหน้าเป็น about-us เทมเพลตก็เลิกทำงานโดยไม่มีคำเตือนและไม่มีข้อผิดพลาดใด ๆ

template กับ template part

template แสดงผลทั้งมุมมองและถูกเลือกโดยลำดับชั้น ส่วน template part เป็นชิ้นส่วนย่อย เช่น ส่วนหัว ส่วนท้าย แถบข้าง ที่ template ดึงเข้ามาใช้ ชิ้นส่วนอยู่ใน parts/ เทมเพลตอยู่ใน templates/ และทั้งสองถูกเก็บแยกกันในฐานข้อมูลโดยชิ้นส่วนเก็บเป็นระเบียน wp_template_part

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

อาการกลับด้านก็เกิดเหมือนกัน คุณเอาเลย์เอาต์เต็มหน้าไปใส่ไว้ใน parts/ แล้วสงสัยว่าทำไมลำดับชั้นไม่เคยหยิบมันขึ้นมาใช้ คำตอบคือชิ้นส่วนไม่ได้เป็นตัวเลือกในลำดับชั้นเลย ไม่มีอะไรจะวิ่งไปหามันโดยตรง

การตั้งชื่อไฟล์และตำแหน่งที่วาง

ตรวจรายการเหล่านี้ก่อนจะเดาไปถึงสาเหตุที่พิสดารกว่านี้

  • โฟลเดอร์ต้องชื่อ templates/ เป็นพหูพจน์ และอยู่ที่รากของธีม ไม่ใช่ template/ และไม่ใช่ block-templates/ ชื่อ block-templates/ เคยถูกต้องในยุคที่ยังเป็นปลั๊กอิน Gutenberg ก่อน block theme จะเข้าไปอยู่ในแกนหลัก และบทเรียนจำนวนมากยังสอนแบบนั้นอยู่ ซึ่งใช้ไม่ได้กับ WordPress รุ่นปัจจุบัน
  • ชิ้นส่วนเทมเพลตไปไว้ใน parts/ ไม่ใช่ template-parts/ (ซึ่งเป็นธรรมเนียมของ classic theme สำหรับไฟล์ย่อย PHP)
  • นามสกุลต้องเป็น .html ไฟล์ .php ที่วางอยู่ใน templates/ จะถูกเมิน
  • ชื่อไฟล์ต้องเป็นตัวพิมพ์เล็กและใช้ขีดกลาง ไฟล์ single-Post.html หรือ single_post.html จะไม่จับคู่ บนระบบไฟล์ที่ไม่แยกตัวพิมพ์เล็กใหญ่อย่าง macOS มันจะทำงานได้บนเครื่องคุณแล้วไปพังบนเซิร์ฟเวอร์ Linux ซึ่งเป็นอาการ “บนเครื่องผมมันทำงานได้นะ” แบบคลาสสิก
  • ต้องมี templates/index.html อยู่จริง ถ้าไม่มี WordPress จะไม่จัดว่าธีมนี้เป็น block theme และ Site Editor อาจไม่โผล่มาเลย
  • ถ้าคุณทำงานอยู่ในธีมลูก เทมเพลตของธีมลูกมีสิทธิ์เหนือกว่าของธีมแม่ ไฟล์ตกค้างในธีมลูกจะแอบชนะไฟล์ในธีมแม่ที่คุณกำลังนั่งแก้อยู่

เทมเพลตที่กำหนดเองซึ่งควรเลือกได้จากหน้าแก้ไขเนื้อหา ต้องประกาศไว้ใน theme.json ใต้ customTemplates ด้วย โดยระบุชื่อฐานของไฟล์ ชื่อที่คนอ่านเข้าใจ และชนิดเนื้อหาที่ใช้ได้ ถ้าไม่มีรายการนี้ ไฟล์ก็ยังอยู่แต่จะไม่โผล่ในแผง Template เลย

แคช ตรวจเป็นอันดับสุดท้าย

แคชเป็นสาเหตุที่มีอยู่จริง แต่เป็นไปได้น้อยที่สุด และการรีบไปโทษมันก่อนคือวิธีเสียเวลาไปทั้งบ่าย

ล้างแคชหน้าเว็บของคุณ และถ้าคุณใช้แคชอ็อบเจ็กต์แบบถาวรอย่าง Redis หรือ Memcached ก็ล้างตัวนั้นด้วย เพราะผลลัพธ์ของการเลือกเทมเพลตอาจถูกเก็บไว้ในนั้น จากนั้นโหลดหน้าใหม่โดยข้ามแคชของเบราว์เซอร์

สิ่งที่ไม่ช่วยคือการล้าง OPcache เพราะ block template เป็นไฟล์ .html ที่ไม่เคยถูก PHP คอมไพล์ OPcache จึงไม่เกี่ยวข้องกับมันเลย ถ้าครั้งหนึ่งการล้าง OPcache ดูเหมือนจะแก้ปัญหานี้ได้ แปลว่ามีอย่างอื่นเปลี่ยนไปพร้อมกันในตอนนั้น

ยังติดอยู่ใช่ไหม

ถ้าไม่มีระเบียนในฐานข้อมูล ชื่อไฟล์ถูกต้อง ไม่มีการกำหนดเทมเพลตเจาะจงบนโพสต์ และล้างแคชไปแล้ว ให้หันไปดูปลั๊กอิน อะไรก็ตามที่ไปกรองการเลือกเทมเพลต ไม่ว่าจะเป็นตัวสร้างหน้า ปลั๊กอินระบบสมาชิก ปลั๊กอินหลายภาษา หรือระบบเรียนออนไลน์ ล้วนสามารถสลับเทมเพลตของตัวเองเข้ามาในช่วงท้ายของการประมวลผลได้ ให้ลองสลับไปใช้ block theme มาตรฐานและทดสอบโดยปิดปลั๊กอินทั้งหมด แล้วค่อยเปิดกลับทีละตัว

และถ้าเทมเพลตถูกใช้งานจริงแต่แสดงผลออกมาว่างเปล่า นั่นคือคนละปัญหา ให้ตรวจว่ามาร์กอัปบล็อกในไฟล์ถูกต้องหรือไม่ เพราะคอมเมนต์บล็อกที่เขียนผิดรูปแบบทำให้หน้าแก้ไขตัดเนื้อหาทิ้งแบบเงียบ ๆ แทนที่จะแจ้งข้อผิดพลาด

FAQ

คำถาม

ทำไม block template ถึงไม่ทำงานใน WordPress

ส่วนใหญ่เป็นเพราะสำเนาที่บันทึกไว้ในฐานข้อมูลทับไฟล์อยู่ วินาทีที่คุณแก้เทมเพลตใน Site Editor แล้วกดบันทึก WordPress จะสร้างระเบียนโพสต์ชนิด wp_template ขึ้นมา แล้วเสิร์ฟระเบียนนั้นแทนไฟล์ .html ในโฟลเดอร์ธีม ทุกการแก้ไฟล์หลังจากนั้นจะไม่มีผลบนหน้าเว็บจริง

จะทำให้ WordPress ใช้ไฟล์ในธีมแทนเวอร์ชันจาก Site Editor ได้อย่างไร

เปิด Appearance แล้ว Editor แล้ว Templates หาเทมเพลตที่ต้องการ แล้วใช้เมนูตัวเลือกของมันเพื่อล้างการปรับแต่งหรือรีเซ็ต การทำแบบนี้จะลบระเบียนในฐานข้อมูลและคืนสิทธิ์ให้ไฟล์บนดิสก์ ถ้าเมนูขึ้นคำว่าลบแทนที่จะเป็นรีเซ็ต แสดงว่าเทมเพลตนั้นมีอยู่แค่ในฐานข้อมูลและไม่มีไฟล์รองรับ

ไฟล์ block template ต้องวางไว้ที่ไหนในธีม WordPress

เทมเพลตเต็มหน้าไปไว้ในโฟลเดอร์ templates ที่รากของธีม ส่วนชิ้นส่วนที่ใช้ซ้ำได้ไปไว้ในโฟลเดอร์ parts ทั้งสองใช้นามสกุล .html ชื่อไฟล์เป็นตัวพิมพ์เล็ก และใช้ขีดกลางแทนขีดล่าง อีกอย่างคือ block theme ต้องมี templates/index.html อยู่ด้วย ไม่อย่างนั้น WordPress จะไม่นับว่าธีมนี้เป็น block theme เลย

template กับ template part ต่างกันอย่างไร

template แสดงผลทั้งหน้าและถูกเลือกโดยลำดับชั้นเทมเพลตตามสิ่งที่กำลังเปิดดูอยู่ ส่วน template part เป็นชิ้นส่วนย่อย เช่น ส่วนหัวหรือส่วนท้าย ที่ template ดึงเข้ามาใช้ การแก้ส่วนหัวจะเปลี่ยนทุก template ที่ดึงมันไปใช้ ซึ่งเป็นเหตุผลที่การแก้ชิ้นส่วนมักดูเหมือนไปมีผลผิดที่

แคชทำให้ block template ไม่อัปเดตได้ไหม

ได้บ้าง แต่เป็นสาเหตุที่เป็นไปได้น้อยที่สุดและควรตรวจเป็นอันดับสุดท้าย แคชหน้าเว็บและแคชอ็อบเจ็กต์แบบถาวรอาจเก็บมาร์กอัปเก่าไว้ จึงควรล้างทั้งสองอย่างก่อนสรุปอะไร ส่วนการล้าง OPcache ไม่ช่วยอะไรเลยในเรื่องนี้ เพราะ block template เป็นไฟล์ .html ที่ไม่เคยถูก PHP คอมไพล์ตั้งแต่แรก

ทำไมเทมเพลตที่ตั้งชื่อตาม slug ของหน้าถึงหยุดทำงาน

เทมเพลตที่อิงกับ slug จะถูกจับคู่กับ slug ปัจจุบันของโพสต์ตอนที่มีคนเรียกหน้านั้น การเปลี่ยนชื่อหน้าทำให้ slug เปลี่ยน ไฟล์ page-about.html จึงเลิกจับคู่แบบเงียบ ๆ เมื่อหน้ากลายเป็น about-us เรื่องเดียวกันนี้ใช้กับเทมเพลตของหมวดหมู่และแท็กด้วย ทางแก้คือเปลี่ยนชื่อไฟล์ให้ตรงกับ slug ใหม่ หรือกำหนดเทมเพลตให้ชัดเจนจากแถบข้างในหน้าแก้ไขเนื้อหา