แสดงภาพตัวอย่างอัตโนมัติกรณีไม่ได้ตั้ง Featured Image
ปกติแล้วเวลาเราออกแบบธีมเวิร์ดเพรส มักจะออกแบบมาเผื่อให้มี Featured Image (อีกชื่อคือ Post Thumbnail) กันอยู่แล้ว ปัญหาคือเวลาเอาไปใช้จริงๆ เรากลับไม่ได้ตั้งภาพตัวอย่างให้กับทุกๆ โพสต์ ทำให้มันออกมาหน้าตาพิการๆ ไม่เป็นอย่างที่เราต้องการ คล้ายๆ กับแบบนี้
โดยปกติที่ผมเจอ จะใช้วิธีเช็ค if … else กับฟังก์ชัน has_post_thumbnail() กัน ว่ามีภาพ Featured Image หรือไม่ ถ้าออกมาเป็น false จึงค่อยแสดงภาพที่เตรียมไว้ … โค๊ดมันก็จะรกๆ ประมาณนี้
if(has_post_thumbnail()){ the_post_thumbnail(); }else{ echo '<img src="http://placehold.it/390x280">'; }
ครับ มันรก จริงๆ แล้วเราสามารถทำให้เหลือแค่ the_post_thumbnail() อันเดียวโดดๆ ได้ ด้วยการใช้ Filter เข้ามาช่วยครับ
เพิ่มฟังก์ชันสำหรับกำหนด Featured Image อัตโนมัติ
อย่างแรกให้เราสร้างฟังก์ชันขึ้นมาตัวหนึ่งในไฟล์ functions.php ของธีมที่ใช้ โค๊ดคร่าวๆ เป็นประมาณนี้
function default_post_thumbnail( $html ) { if(!$html){ $html = '<img src="http://placehold.it/390x280" class="img-responsive">'; } return $html; }
คือขั้นตอนการทำงานของ Filter เนี่ย มันจะส่ง HTML ที่พร้อมสำหรับการแสดงผลเข้ามาให้ (ผ่าน $html) ซึ่งถ้าไม่มีการกำหนด Featured Image เอาไว้ WordPress จะไม่สร้าง HTML ส่วนนี้ไว้ให้ ทำให้ $html ที่ถูกส่งเข้ามานั้นเป็นค่าว่าง
เราก็ใช้ตรงนี้แหละครับ ตรวจสอบว่า $html นั้นเป็นค่าว่างหรือเปล่า ถ้าใช่ก็แปลว่าไม่มี Featured Image ดังนั้นเราก็แก้ $html ใหม่แล้วส่งกลับออกไป (ถ้ามีค่ามา เราก็ไม่แก้ แล้วส่งค่าเดิมกลับออกไป)
เรียกใช้ Filter
จากนั้นเราก็ add_filter() เข้าไปครับ
add_filter( 'post_thumbnail_html', 'default_post_thumbnail', 10);
เท่านี้ก็เรียบร้อย
โค๊ดทั้งหมดก็ประมาณนี้
function default_post_thumbnail( $html ) { if(!$html){ $html = '<img src="http://placehold.it/390x280" class="img-responsive">'; } return $html; } add_filter( 'post_thumbnail_html', 'default_post_thumbnail', 10);
อัพเดท กรณีในเว็บมี Post Thumbnail หลายขนาด
เขียนไปได้วันเดียวก็เจอปัญหาเองเลย เมื่อเว็บที่กำลังทำอยู่นี้ดันมี Post Thumbnail หลายขนาด (อยู่ในหน้าแรกขนาดนึง และเป็น Related Posts อีกขนาดนึง) ซึ่งโค๊ดเก่าก็มีปัญหาจะพ่นภาพตัวอย่างออกมาเป็นขนาดเดียว
ทางแก้ของเราคือบอกให้ add_filter() นั้นส่งอาร์กิวเมนต์เพิ่มเติมด้วย เพื่อจะเอาขนาดภาพมาใช้ ซึ่งฟิลด์เตอร์ post_thumbnail_html นั้นมีอาร์กิวเมนต์ทั้งหมด 5 ตัวด้วยกัน และอาร์กิวเมนต์ $size นั้นอยู่ลำดับที่ 4 ดังนั้นเราต้องแก้ add_filter() ให้ส่งอาร์กิวเมนต์เข้าไปในฟังก์ชันทั้งหมด 4 ตัว (เพื่อจะใช้ตัวที่ 4 ตัวเดียวนี่แหละครับ)
add_filter( 'post_thumbnail_html', 'default_post_thumbnail', 10, 4);
จากนั้นกลับไปแก้ฟังก์ชัน defaulth_post_thumbnail() ของเรา ให้รับอาร์กิวเมนต์เพิ่มให้ครับด้วย
function default_post_thumbnail( $html, $post_id, $post_thumbnail_id, $size ) { ... }
กรณีคนใช้ placehold.it หรือบริการ placeholder image ต่างๆ
กรณีของผมเนี่ย ผมใช้ placeholder จากเว็บ placehold.it ซึ่งสามารถกำหนดขนาดลงไปตรงๆ ทาง URL ได้เลย วิธีของผมก็จะซับซ้อนหน่อย คือต้องหาขนาดกว้างยาวแล้วค่อยแปะลงไป
$size ที่ส่งเข้ามาจะมาเป็นชื่อขนาด เช่น thumbnail, medium, large ดังนั้นเราต้องเอาขนาดนี่ไปหาขนาดกว้างยาวจริงๆ ที่ตั้งไว้อีกที
ตรงนี้จะแปลกๆ นิดนึง ใน WordPress จะมี predefined เอาไว้ให้ 3 ขนาด คือ thumbnail, medium, และ large ซึ่งจะเก็บค่าเอาไว้ในตาราง wp_options ส่วนขนาดอื่นๆ ที่เราเพิ่มเข้าไปผ่านทาง add_image_size() จะถูกเก็บอยู่ในตัวแปรชื่อว่า $_wp_additional_image_sizes
ตรงนี้เป็นโค๊ดส่วนเช็คขนาด โดย predefined สามารถใช้ get_option() ดึงได้เลย ส่วนขนาดอื่นๆ ต้องไปดึงจากตัวแปรแทน
จากนั้นก็แก้ $html ใหม่ เป็นอันเรียบร้อย
global $_wp_additional_image_sizes; if(!$html){ if (in_array($size, array('thumbnail', 'medium', 'large'))) { $width = get_option($size."_size_w"); $height = get_option($size."_size_h"); }elseif((isset( $_wp_additional_image_sizes[$size]))){ $width = $_wp_additional_image_sizes[$size]['width']; $height = $_wp_additional_image_sizes[$size]['height']; } $html = '<img src="http://placehold.it/'.$width.'x'.$height.'/lava" class="img-responsive '.$size.'">'; }
ณ จุดนี้ โค๊ดทั้งหมดของผมก็จะออกมาประมาณนี้
function default_post_thumbnail( $html, $post_id, $post_thumbnail_id, $size ) { global $_wp_additional_image_sizes; if(!$html){ if (in_array($size, array('thumbnail', 'medium', 'large'))) { $width = get_option($size."_size_w"); $height = get_option($size."_size_h"); }elseif((isset( $_wp_additional_image_sizes[$size]))){ $width = $_wp_additional_image_sizes[$size]['width']; $height = $_wp_additional_image_sizes[$size]['height']; } $html = '<img src="holder.js/'.$width.'x'.$height.'/lava" class="img-responsive '.$size.'">'; } return $html; } add_filter('post_thumbnail_html', 'default_post_thumbnail', 10, 4);
กรณีคนทำภาพ Placeholder ใช้เองเลย
อันนี้ง่ายหน่อย คุณสามารถใช้ switch … case ในการตรวจขนาด แล้วแก้ $html เป็นลิงค์ตรงๆ ไปหาภาพของคุณได้เลยครับ หรือถ้าตั้งชื่อไฟล์ตรงกับชื่อขนาด ก็อาจจะเรียก src ไปที่ “placeholder-“.$size.”.jpg” ได้เลย
ขอบคุณครับ ปกติผมก็ใช้ if เช็คเอา เดี๊ยวลองเอาไปประยุกต์ใช้งานดูครับ
รบกวนถามอีกนิดครับ คำสั่ง add_filter นี้ตัวเลขข้างหลัง 10 ก็คือ $priority แต่ละตัวมันมีความหมายแบบไหนบ้างหรือครับ พอดีอ่านที่ codex แล้วยังไม่เข้าใจเท่าไรน่ะครับ
ขอบคุณครับ ปกติผมก็ใช้ if เช็คเอา เดี๊ยวลองเอาไปประยุกต์ใช้งานดูครับ
รบกวนถามอีกนิดครับ คำสั่ง add_filter นี้ตัวเลขข้างหลัง 10 ก็คือ $priority แต่ละตัวมันมีความหมายแบบไหนบ้างหรือครับ พอดีอ่านที่ codex แล้วยังไม่เข้าใจเท่าไรน่ะครับ