สำหรับ Yii Framework 2 นั้นแน่นอนเราสามารถกำหนด Title ให้แต่ละหน้าได้ แต่นอกเหนือจากนั้นเราจะกำหนดได้อย่างไรเช่น keywords, description หรือแม้แต่ tag ด้าน social media เช่น og:image, og:desctiption, twitter:image เป็นต้น ใน Tutorial นี้เรามาทำให้ Web Application เรารองรับ Search Engine และ Social Media กัน
เตรียมไฟล์ MetaComponent
ให้ทำการสร้างไฟล์ frontend/components/MetaComponent.php โดยสืบทอดมาจาก Component กำหนดค่าเริ่มต้นให้แก่ Property ต่างๆ ในที่นี้คือ
- keywords คือคำสำคัญที่จะแสดงใน tag meta keywords
- description คือรายละเอียดจะไปปรากฎใน meta description, twitter:description และ og:description
- image คือรูปภาพที่จะปรากฎใน og:image, twitter:image
และทำการ registerMetaTag() ใน Method displaySeo() ดังนี้
<?php
namespace frontend\components;
use yii\base\Component;
use Yii;
class MetaComponent extends Component{
public $keywords = 'เขียนโปรแกรม,เรียนเขียนโปรแกรม,สอนเขียนโปรแกรม,เรียนเขียนโปรแกรมฟรี,สอนเขียนโปรแกรมฟรี,เรียนการเขียนโปรแกรม,สอนการเขียนโปรแกรม,เรียนออนไลน์,เรียน online,เรียนแบบออนไลน์,สอนออนไลน์,สอน online,สอนแบบออนไลน์';
public $description = 'สังคมนักพัฒนาระบบ (Developer) ในประเทศไทย';
public $image = 'https://programmerthailand.com/images/programmerthailand_social.jpg';
public function displaySeo(){
Yii::$app->view->registerMetaTag([
'name' => 'description',
'content' => $this->description,
]);
Yii::$app->view->registerMetaTag([
'name' => 'keywords',
'content' => $this->keywords,
]);
Yii::$app->view->registerMetaTag([
'name' => 'og:description',
'content' => $this->description,
]);
Yii::$app->view->registerMetaTag([
'name' => 'og:image',
'content' => $this->image,
]);
Yii::$app->view->registerMetaTag([
'name' => 'twitter:description',
'content' => $this->description,
]);
Yii::$app->view->registerMetaTag([
'name' => 'twitter:image',
'content' => $this->image,
]);
}
}
ลงทะเบียน Component ใน Config
ทำการลงทะเบียน Component ใน Config ในที่นี้คือไฟล์ frontend/config/main.php โดยทำการกำหนดค่าในส่วนของ components ดังนี้
'components' => [
//....
'meta' => [
'class' => 'frontend\components\MetaComponent',
],
//....
],
เรียก Method displaySeo() ใน layout
ทำการเรียก method displaySeo() ใน component meta โดยเป็นการกำหนดให้แสดงผลตามที่ได้เขียนโปรแกรมเอาไว้ โดยทำการเรียกในไฟล์ frontend\views\layouts\main.php หรือไฟล์ layout หลัก ของ themes ที่เราได้สร้างขึ้น
<head>
...
<?php Yii::$app->meta->displaySeo() ?>
<meta property="fb:app_id" content="177188695765715" />
<meta property="og:locale" content="th_TH" />
<meta property="og:type" content="article" />
<meta property="og:title" content="<?= $this->title ?>" />
<meta property="og:url" content="<?= Url::canonical() ?>" />
<meta property="og:site_name" content="ProgrammerThailand.com" />
<meta property="article:publisher" content="https://www.facebook.com/pgmtl/" />
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="<?= $this->title ?>"/>
<meta name="twitter:site" content="ProgrammerThailand.com"/>
<meta name="twitter:domain" content="https://programmerthailand.com"/>
...
</head>
<body>
....
กำหนดค่าให้แต่ละหน้า
กำหนดค่าให้กับ Web Application ในแต่ละหน้า โดยกำหนดในส่วนของ view ดังนี้
<?php
//views/site/index.php
$this->title = 'สังคมนักพัฒนา(Developer) ในประเทศไทย';
Yii::$app->meta->keywords = 'programmer,thailand,seo,search engine';
Yii::$app->meta->description = 'โปรแกรมเมอร์ไทยแลนด์สังคมนักเขียนโปรแกรมในประเทศไทย ร่วมกันพัฒนา ช่วยเหลือเพื่อนโปรแกรมเมอร์';
Yii::$app->meta->image = Yii::getAlias('@web').'/images/myimage.jpg';
?>
<!-- Your view Content here -->
บันทึกและทดสอบการทำงานโดยคลิกขวา view source จะเห็นการเปลี่ยนแปลงดังนี้
.....
<title>สังคมนักพัฒนา(Developer) ในประเทศไทย</title>
<meta name="description" content="โปรแกรมเมอร์ไทยแลนด์สังคมนักเขียนโปรแกรมในประเทศไทย ร่วมกันพัฒนา ช่วยเหลือเพื่อนโปรแกรมเมอร์">
<meta name="keywords" content="programmer,thailand,seo,search engine">
<meta name="og:description" content="โปรแกรมเมอร์ไทยแลนด์สังคมนักเขียนโปรแกรมในประเทศไทย ร่วมกันพัฒนา ช่วยเหลือเพื่อนโปรแกรมเมอร์">
<meta name="og:image" content="https://www.programmerthailand.com/images/myimage.jpg">
<meta name="twitter:description" content="โปรแกรมเมอร์ไทยแลนด์สังคมนักเขียนโปรแกรมในประเทศไทย ร่วมกันพัฒนา ช่วยเหลือเพื่อนโปรแกรมเมอร์">
<meta name="twitter:image" content="https://www.programmerthailand.com/images/myimage.jpg">
<link rel="canonical" href="https://www.programmerthailand.com/site/index" />
<meta property="fb:app_id" content="177188695765715" />
<meta property="og:locale" content="th_TH" />
<meta property="og:type" content="article" />
<meta property="og:title" content="สังคมนักพัฒนา(Developer) ในประเทศไทย" />
<meta property="og:url" content="https://www.programmerthailand.com/site/index" />
<meta property="og:site_name" content="ProgrammerThailand.com" />
<meta property="article:publisher" content="https://www.facebook.com/pgmtl/" />
<meta name="twitter:card" content="summary"/>
<meta name="twitter:title" content="สังคมนักพัฒนา(Developer) ในประเทศไทย"/>
<meta name="twitter:site" content="ProgrammerThailand.com"/>
<meta name="twitter:domain" content="https://programmerthailand.com"/>
.....
เทคนิคการกำหนดให้ดึงรูปภาพอัตโนมัติ
การดึงรูปภาพจากเนื้อหามาแสดงผลแบบอัตโนมัตินั้นสามารถทำได้ โดยการดึงรูปภาพรูปแรก เป็นการเขียนโปรแกรมเพื่อค้นหา tag img ของ html นั่นเอง โดยสามารถเขียน method เพิ่มเติมใน MetaComponent ดังนี้
public function getFirstImage($content) {
$first_img = '';
$output = preg_match_all('/<img.+src=[\'"]([^\'"]+)[\'"].*>/i', $content, $matches);
$first_img = $matches[1][0];
if(empty($first_img)) {
$first_img = Yii::getAlias('@web').'/images/programmerthailand_social.jpg';
}
return $first_img;
}
วิธีการเรียกใช้งาน
Yii::$app->meta->image = Yii::$app->meta->getFirstImage($model->content);
เพียงเท่านี้ก็สามารถดึงรูปภาพรูปแรกจาก content หรือ เนื้อหาในฐานข้อมูลมาแสดงได้แล้ว
เทคนิคการนำข้อความในเนื้อหามาเป็น Description อัตโนมัติ
ในส่วนของ Description นั้นก็สามารถนำเอาเนื้อหาบางส่วนมาทำแบบอัตโนมัติได้เช่นกัน โดยสามารถทำได้ โดยอาจจะสร้าง method เหมือนรูปภาพก็ได้หรือไม่สร้างก็ได้ ในที่นี้จะไม่สร้าง มีตัวอย่างดังต่อไปนี้
Yii::$app->meta->description = StringHelper::truncate(strip_tags($model->content), 300, '...', 'utf-8', false);
เป็นการเลือกคำมา 300 คำเพื่อนำไปใส่ใน description โดยสามารถระบุจำนวนคำได้ตามต้องการ
เพิ่มเติมสำหรับ Social Media
Template บทความ (Article) แบบ Minimal
<head>
...
<title>หัวเรื่องควรมีความยาว 60-70 ตัวอักษร</title>
<meta name="description" content="รายละเอียด" />
<!-- Twitter Card data -->
<meta name="twitter:card" value="summary">
<!-- Open Graph data -->
<meta property="og:title" content="หัวเรื่อง" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://www.example.com/" />
<meta property="og:image" content="http://example.com/image.jpg" />
<meta property="og:description" content="รายละเอียด" />
...
</head>
Template บทความ (Article) แบบมาตรฐาน
<head>
...
<title>หัวเรื่องควรมีความยาว 60-70 ตัวอักษร</title>
<meta name="description" content="รายละเอียด" />
<!-- Twitter Card data -->
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@publisher_handle">
<meta name="twitter:title" content="หัวเรื่อง">
<meta name="twitter:description" content="รายละเอียด">
<meta name="twitter:creator" content="@author_handle">
<-- Twitter Summary card images must be at least 120x120px -->
<meta name="twitter:image" content="http://www.example.com/image.jpg">
<!-- Open Graph data -->
<meta property="og:title" content="หัวเรื่อง" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://www.example.com/" />
<meta property="og:image" content="http://example.com/image.jpg" />
<meta property="og:description" content="รายละเอียด" />
<meta property="og:site_name" content="ชื่อเว็บไซต์ เช่น ProgrammerThailand" />
<meta property="fb:admins" content="หมายเลข ID Facebook" />
...
</head>
Template บทความ (Article) แบบเต็มรูปแบบ
<html itemscope itemtype="http://schema.org/Article">
<head>
...
<title>หัวเรื่องควรมีความยาว 60-70 ตัวอักษร</title>
<meta name="description" content="รายละเอียดไ" />
<!-- Schema.org markup for Google+ -->
<meta itemprop="name" content="หัวเรื่อง">
<meta itemprop="description" content="รายละเอียด">
<meta itemprop="image" content="http://www.example.com/image.jpg">
<!-- Twitter Card data -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:site" content="@publisher_handle">
<meta name="twitter:title" content="หัวเรื่อง">
<meta name="twitter:description" content="รายละเอียด">
<meta name="twitter:creator" content="@author_handle">
<!-- Twitter summary card with large image must be at least 280x150px -->
<meta name="twitter:image:src" content="http://www.example.com/image.html">
<!-- Open Graph data -->
<meta property="og:title" content="หัวเรื่อง" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://www.example.com/" />
<meta property="og:image" content="http://example.com/image.jpg" />
<meta property="og:description" content="รายละเอียด" />
<meta property="og:site_name" content="ชื่อเว็บไซต์ เช่น ProgrammerThailand" />
<meta property="article:published_time" content="2013-09-17T05:59:00+01:00" />
<meta property="article:modified_time" content="2013-09-16T19:08:47+01:00" />
<meta property="article:section" content="Article Section" />
<meta property="article:tag" content="Article Tag" />
<meta property="fb:admins" content="หมายเลข ID Facebook" />
...
</head>
Template สินค้า (Product)
<html itemscope itemtype="http://schema.org/Product">
<head>
...
<title>หัวเรื่องควรมีความยาว 60-70 ตัวอักษร</title>
<meta name="description" content="รายละเอียด" />
<!-- Schema.org markup for Google+ -->
<meta itemprop="name" content="หัวเรื่อง">
<meta itemprop="description" content="รายละเอียด">
<meta itemprop="image" content="http://www.example.com/image.jpg">
<!-- Twitter Card data -->
<meta name="twitter:card" content="product">
<meta name="twitter:site" content="@publisher_handle">
<meta name="twitter:title" content="Page Title">
<meta name="twitter:description" content="รายละเอียด">
<meta name="twitter:creator" content="@author_handle">
<meta name="twitter:image" content="http://www.example.com/image.html">
<meta name="twitter:data1" content="$3">
<meta name="twitter:label1" content="Price">
<meta name="twitter:data2" content="Black">
<meta name="twitter:label2" content="Color">
<!-- Open Graph data -->
<meta property="og:title" content="หัวเรื่อง" />
<meta property="og:type" content="article" />
<meta property="og:url" content="http://www.example.com/" />
<meta property="og:image" content="http://example.com/image.jpg" />
<meta property="og:description" content="รายละเอียด" />
<meta property="og:site_name" content="ชื่อเว็บไซต์ เช่น ProgrammerThailand" />
<meta property="og:price:amount" content="15.00" />
<meta property="og:price:currency" content="USD" />
...
</head>
เครื่องมือในการตรวจสอบ (Validation)
https://dev.twitter.com/docs/cards/validation/validator
Google Plus
http://www.google.com/webmasters/tools/richsnippets
https://developers.facebook.com/tools/debug
http://developers.pinterest.com/rich_pins/validator/
Reference : https://moz.com/blog/meta-data-templates-123
บทสรุป
การกำหนดค่าด้าน Search Engine นั้นช่วยให้ Web Application สามารถรองรับการทำงานด้าน Search Engine ได้มากขึ้น และนอกจากนั้นการกำหนด Web Application ให้รองรับ Social Media ก็จะช่วยเพิ่มประสิทธิภาพการทำงานได้มากขึ้นอีกด้วย
หวังว่าบทเรียนรู้นี้จะเป็นประโยชน์กับผู้ที่พัฒนา Web Application ด้วย Yii Framework 2 นะครับ และหากบทเรียนรู้นี้เป็นประโยชน์ก็ได้โปรดแชร์กันต่อๆ ไปด้วยนะครับ ขอบคุณครับ @ProgrammerThailand Team
หากเพื่อนๆ สมาชิกมีประสบการณ์ดีๆ หรือบทเรียนรู้ดีๆ อยากแบ่งปันอย่าเก็บไว้คนเดียวครับ สร้างบทเรียนรู้ของคุณเอง เพื่อแบ่งปันประสบการณ์แก่ โปรแกรมเมอร์ต่อๆ ไปครับ ขอให้ทุกท่าน เจริญในธรรม
ความคิดเห็น