แสดงภาพตัวอย่างอัตโนมัติกรณีไม่ได้ตั้ง Featured Image

ปกติแล้วเวลาเราออกแบบธีมเวิร์ดเพรส  มักจะออกแบบมาเผื่อให้มี Featured Image (อีกชื่อคือ Post Thumbnail) กันอยู่แล้ว  ปัญหาคือเวลาเอาไปใช้จริงๆ เรากลับไม่ได้ตั้งภาพตัวอย่างให้กับทุกๆ โพสต์  ทำให้มันออกมาหน้าตาพิการๆ ไม่เป็นอย่างที่เราต้องการ  คล้ายๆ กับแบบนี้

โพสต์ไม่มีภาพ Featured Image

โดยปกติที่ผมเจอ  จะใช้วิธีเช็ค 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);

เท่านี้ก็เรียบร้อย

ภาพ Featured Image แบบอัตโนมัติ

โค๊ดทั้งหมดก็ประมาณนี้

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” ได้เลย

Posted by Jirayu

WordPress Developer ที่พอมีประสบการณ์อยู่บ้าง วันไหนไม่ทำงานอยู่บ้านว่างๆ ก็นั่งเลี้ยงแมว

Comments