ตามปกติข้อมูล submission information ของ node ใน Drupal จะมีหน้าตาประมาณนี้ คือมีคำว่า "Submitted by" แล้วตามด้วยชื่อ user และวัน-เวลา ที่สร้าง node นั้นๆ

แต่ใน tumblog แทนที่จะแสดงวัน-เวลาตามปกติ ผมต้องการให้มันแสดงว่า tumblog นี้โพสต์ไว้นานแค่ไหนแล้ว (time ago) แบบนี้

โชคดีที่ใน Drupal เราสามารถแก้ไขข้อมูลการแสดงผลเกือบทั้งหมดได้จากระบบ theming ของ Drupal ครับ โดยรายละเอียดคร่าวๆ ในการทำมีดังนี้
เนื่องจากการแสดงผลของ node จะถูกควบคุมด้วยไฟล์ node.tpl.php ของธีมที่เราใช้งานอยู่ สิ่งแรกที่เราจำเป็นต้องรู้ก็คือ ตัวแปรอะไรบ้างที่ Drupal จะส่งมาให้ไฟล์ node.tpl.php ซึ่งสามารถดูได้จาก Drupal API หรือถ้าเปิดไฟล์ /modules/node/node.tpl.php ก็จะมีรายละเอียดบอกไว้เป็นคอมเมนต์ในส่วนต้นของไฟล์เช่นกัน ซึ่งพอดูแล้วจะเห็นว่าตัวแปรที่น่าจะเกี่ยวข้องมีอยู่ 2 ตัว คือ
$submitted: ข้อมูล submission information ที่ได้จากฟังก์ชันtheme_node_submitted()$created: เวลาที่สร้าง node ในรูปแบบ Unix timestamp
ถ้าเราลองเปิดไฟล์ node.tpl.php ของธีมที่ใช้งานอยู่ สมมติว่าเป็นธีม Garland จะเห็นข้อมูลสำหรับแสดง submission information ดังนี้
<?php if ($submitted): ?> <span class="submitted"><?php print $submitted; ?></span> <?php endif; ?>
แสดงว่าตัวแปรที่ไฟล์ node.tpl.php เีรียกใช้คือ $submitted
จากข้อมูลข้างต้น จะพบว่าเราสามารถเปลี่ยนข้อมูล submission information ได้หลายวิธี เช่น
- แก้ไขไฟล์
node.tpl.phpของธีมที่ใช้งานอยู่ โดยเปลี่ยนตรงส่วนที่สั่งให้แสดงผลค่าจากตัวแปร$submittedให้มันพรินท์ข้อความอื่นออกมาแทน - แก้ไขค่าของตัวแปร
$submittedก่อนที่จะส่งไปให้ไฟล์node.tpl.phpแสดงผล
วิธีแรก: แก้ไขไฟล์ node.tpl.php
เนื่องจาก Drupal ส่งค่าตัวแปร $created มาให้ไฟล์ node.tpl.php ด้วย เราจึงสามารถสร้างรูปแบบการแสดงผลของ submission information ได้เอง โดยใช้ฟังก์ชัน format_interval() ร่วมกับตัวแปร $created โดยการแก้โค้ดในไฟล์ node.tpl.php ด้านบนเป็นดังนี้
<?php if ($submitted): ?> <span class="submitted"><?php print 'Posted ' . format_interval(time() - $created) . ' ago' ?></span> <?php endif; ?>
วิธีนี้มีข้อดีคือสะดวก และไม่ต้องสร้างไฟล์เพิ่มเติม แต่ก็มีข้อเสียคือ เวลาอัพเดตธีมโดยการคัดลอกไฟล์มาทับ จะทำให้ข้อมูลที่แก้ไขไว้หายไป
วิธีที่สอง: override theme function โดยใช้ไฟล์ template
เนื่องจากตัวแปร $submitted เป็นเอาท์พุทที่ได้จากฟังก์ชัน theme_node_submitted() (รู้ได้ยังไง? ดูจาก Drupal API หน้าเดิมครับ) และใน Drupal นั้นเราสามารถ override ฟังก์ชันที่มีชื่อขึ้นต้นด้วย theme_ ได้ทั้งหมด ดังนั้นเราจึงสามารถ override ฟังก์ชัน theme_node_submitted() ได้โดยการสร้างไฟล์ template ชื่อ node-submitted.tpl.php ในไดเร็กทอรีของธีมที่ใช้งานอยู่
สังเกตว่าชื่อไฟล์จะเป็นชื่อเดียวกับชื่อฟังก์ชันที่เราจะ override แต่ตัดคำว่า theme_ ออก และเปลี่ยน underscore (_) เป็น dash (-) แทน
โดยข้อมูลในไฟล์ node-submitted.tpl.php จะเป็นดังนี้
<?php print 'Posted ' . format_interval(time() - $node->created) . ' ago'; ?>
ถ้าดูเผินๆ บางคนอาจจะคิดว่า "ก็แค่ก๊อปโค้ดจากวิธีแรกมาใส่แยกเป็นอีกไฟล์ก็เท่านั้น" แต่จริงๆ แล้วไม่ใช่ครับ เพราะตัวแปรที่ Drupal ส่งมาให้ไฟล์ node-submitted.tpl.php นั้น จะมีเพียงตัวเดียวคือ $node เนื่องจากเรากำลัง override ฟังก์ชัน theme_node_submitted() และฟังก์ชันนี้มี input เป็น $node นั่นเอง โดย $node จะเป็น object ที่เก็บค่าต่างๆ ของ node นั้นๆ รวมทั้งเวลาที่สร้าง node ด้วย
วิธีดูข้อมูลใน $node ง่ายๆ คือ ใส่คำสั่ง <?php print_r($node) ?> เข้าไปในไฟล์ template ที่เราสร้างขึ้นครับ
ถ้าลองรีเฟรชหน้าเว็บเพจดูตอนนี้ จะเห็นว่ายังไม่มีการเปลี่ยนแปลง เพราะ Drupal ยังไม่รู้จักไฟล์ template ที่เราสร้างขึ้นใหม่ เราต้องทำการ rebuild theme registry ก่อน โดยไปที่หน้า /admin/build/modules จากนั้นค่อยโหลดหน้าเว็บเพจใหม่
ในหน้าที่อธิบาย theme registry มีข้อมูลเกี่ยวกับการ override theme อยู่ด้วยครับ แนะนำให้อ่านทั้งหน้าเลยจะดีที่สุด
วิธีที่สองนี้มีข้อดีคือ ไฟล์ที่เราสร้างขึ้นจะไม่ถูกเขียนทับเมื่อเราอัพเดตธีม (ในกรณีที่ธีมที่ใช้งาน ไม่มีไฟล์นี้มาก่อน) และคนอื่นสามารถแก้ไขได้ง่าย (แก้ไขไฟล์เล็กๆ โอกาสเกิด error จะน้อย และการหา error จะสะดวกกว่าการแก้ไขไฟล์ใหญ่ๆ) แต่ข้อเสียคืออาจถูก override ได้โดยวิธีแรก หรือถูก override โดย preprocess function เป็นต้น
วิธีที่ 3, 4, 5, ...
นอกจากนี้ยังมีวิธีอื่นๆ อีก เช่น การสร้างฟังก์ชัน phptemplate_node_submitted() ในไฟล์ template.php หรือการใช้ฟังก์ชัน phptemplate_preprocess_node() เป็นต้น
นี่ก็เป็นตัวอย่างง่ายๆ ในการแก้ไขการแสดงผลของธีมใน Drupal 6 ครับ ซึ่งจริงๆ เราสามารถปรับปรุงให้ดีกว่านี้ โดยการใส่ฟังก์ชัน t() คร่อมข้อมูลที่เราจะแสดงผล เพื่อสนับสนุนการใช้งานแบบหลายภาษา (ดูตัวอย่างได้จากฟังก์ชัน theme_node_submitted() ดั้งเดิม) ซึ่งผมไม่ได้ใส่ไว้ในที่นี้ เพราะต้องการให้โค้ดอ่านง่ายขึ้น

No comments yet
Post new comment