Clicky

Using Canonical Link Tag to Fix Duplicate Content in Drupal | suksit dot com

Using Canonical Link Tag to Fix Duplicate Content in Drupal

อธิบายสั้นๆ ก่อนสำหรับ canonical link tag ว่าคือ tag ที่เอาไว้บอก search engine ว่า หน้าที่มันกำลังอ่านอยู่นั้น มีเนื้อหาซ้ำกับหน้าอื่น และจริงๆ มันควรจะไปอ่านจากหน้าไหนแทน เพื่อไม่ให้ search engine มองว่าเราทำ duplicate content รายละเอียดเต็มๆ แนะนำให้อ่านจากบล็อกของ Matt Cutts

ใน Drupal ที่สนับสนุนการใช้งาน clean URLs ก็มีโอกาสทำให้เกิด duplicate content ได้เช่นกัน ตัวอย่างที่ง่ายที่สุดคือเมื่อเปิดใช้งานโมดูล Path ที่สามารถสร้าง alias ให้กับ node ได้ สมมติว่าเราสร้าง alias ชื่อ /content/node-123-title ให้กับ /node/123 จะทำให้เราสามารถเข้าถึงเนื้อหาของ node นี้ได้สองทางคือ http://www.example.com/node/123 และ http://www.example.com/content/node-123-title ซึ่งถ้า search engine เห็นว่า URL ต่างกัน แต่มีเนื้อหาเหมือนกันเด๊ะ ก็จะมองว่าหน้าใดหน้าหนึ่งเป็น duplicate content แน่นอน

ทางแก้ที่นิยมใช้กันคือการใช้โมดูล Global Redirect ช่วยในการ redirect URL จาก /node/123 ไปยัง /content/node-123-title โดยอัตโนมัติ ซึ่งในเคสทั่วๆ ไปก็ใช้งานได้ดีในระดับหนึ่ง

สำหรับเคสของผม (กับอีกหลายๆ บล็อกแถวนี้) จะต่างไปเล็กน้อย เพราะผมใช้โมดูล Pathauto ช่วยในการสร้าง alias สำหรับแต่ละ node โดยตั้งกฏไว้ว่าให้สร้าง alias เป็น node/[nid]/[title-raw] (ดูตัวอย่างจริงๆ ได้จาก address bar ของเบราเซอร์) สมมติว่าสร้าง /node/456 โดยมี title เป็น Drupal Rocks ผมจะได้ alias ชื่อ /node/456/drupal-rocks ซึ่ง Global Redirect ก็สามารถ redirect จาก /node/456 มาที่ /node/456/drupal-rocks ได้ตามปกติ ดูเผินๆ ก็เหมือนไม่น่าจะมีอะไร แต่มันไม่เป็นอย่างที่คิด

ปัญหามีอยู่ว่า ไม่ว่าผมจะใช้ URL อะไรก็ตาม ขอให้ขึ้นต้นด้วย /node/456/... ผมจะสามารถเข้าถึงเนื้อหาของ node ได้เสมอ เช่น /node/456/drupal-sucks หรือ /node/456/789 ก็จะมาโผล่ที่หน้าเดียวกันโดยที่โมดูล Global Redirect ไม่สามารถช่วยอะไรได้เลย ดังนั้นเวลาเปลี่ยน title ของ node หรือเวลามีลิงค์จากที่อื่นมาโดยที่ URL ด้านหลังสุดไม่เหมือนของปัจจุบัน ก็อาจทำให้ search engine มองว่าเป็น duplicate content ได้ง่ายๆ

เอาปัญหานี้ไปถามใน Drupal Thailand ได้คำตอบว่าใช้ canonical link tag น่าจะเวิร์กสุด และก็มีคน implement โมดูลของ Drupal ไว้เรียบร้อยแล้ว โดยการแก้ไขโค้ดของโมดูล Global Redirect ให้มีตัวเลือกว่าจะ redirect ไปเลย หรือให้ใส่ canonical URL เข้าไปใน <head> แทน ให้เลือกใช้แบบใดแบบหนึ่ง ซึ่งผมไม่ค่อยถูกใจเท่าไร เพราะตามความคิดผมน่าจะลอง redirect ดูก่อนเพื่อให้ทั้ง user และ search engine เห็น URL เหมือนๆ กัน ถ้าไม่ได้จริงๆ ค่อยใส่ canonical tag เพื่อไม่ให้ search engine มองว่าเป็น duplicate content

ดังนั้นหลักการที่คิดไว้ในใจคือให้โมดูล Global Redirect ทำหน้าที่ของมันไป และใช้ canonical link tag เข้ามาเสริม ประกอบกับอ่านคอมเมนต์ของ Matt Cutts ที่ตอบคำถามของ Geoff เลยได้ออกมาเป็นโมดูลง่ายๆ ที่จะใส่ canonical tag ให้กับหน้า node view โดยเอา URL มาจาก alias ของ node นั้นๆ

เนื่องจากโค้ดสั้นมาก ขี้เกียจทำเป็น package เอามาแปะในนี้เลยละกัน

canonical_tag.info:

; $Id$
 
name = "Canonical Tag"
description = "Searches for an alias of the current URL and adds a canonical tag if found. Stops duplicate content arising when path module is enabled."
dependencies[] = path
core = 6.x

canonical_tag.module:

<?php
// $Id$
 
function canonical_tag_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
  switch ($op) {
    case 'view':
      if ($page && function_exists('drupal_get_path_alias') && !drupal_is_front_page()) {
        $alias = drupal_get_path_alias('node/' . $node->nid, $node->language);
        $canonical_url = url($alias, array('absolute' => TRUE, 'alias' => TRUE));
        drupal_set_html_head('<link rel="canonical" href="' . $canonical_url . '" />');
      }
      break;
  }
}

ตอนนี้ลองติดตั้งและใช้งานอยู่ในบล็อกนี้ คิดว่าน่าจะช่วยแก้ปัญหา duplicate content สำหรับคนที่ใช้ alias แบบเดียวกับผมได้... มั้ยฮึ!?

9 comments

Gibbozer's picture
Gibbozer (visitor) says:

อ่านแล้ว ยังงงๆ แต่เห็น rel="canonical" แล้วคิดมันน่าจะเป็นมาตรฐานในไม่ช้า เอาฟังชั่นไปประยุกต์ใส่ในธีมเลยได้รึเปล่าครับ?

onequad's picture
onequad (visitor) says:

โอ้วว แจ่มมากครับ ถ้าเกิด node เดียวมีสอง alias จะเกิดอะไรขึ้นอ่ะครับ

kong's picture
kong says:

@gibbozer: ใส่ในธีมได้ครับ ตอนแรกผมก็กะทำในธีมเหมือนกัน แต่พอดีเห็นว่ามี theme switcher อยู่ ขี้เกียจแก้หลายธีม เลยทำเป็นโมดูลแทน

@onequad: นั่นสินะครับ =.= เท่าที่เห็นคือฟังก์ชัน drupal_get_path_alias() มันจะคืน alias มาให้แค่อันเดียว ถ้ามีหลายๆ alias คงต้องให้ user เลือกเอา ถ้าเป็นงั้นก็ต้องสร้างตารางเก็บ canonical URL ด้วย >_<

สรุปข้อจำกัดตอนนี้คือ ใช้ได้กับ node เท่านั้น และควรเป็น node ที่มี alias เพียงอันเดียว ไม่งั้นอาจจะมั่วได้

onequad's picture
onequad (visitor) says:

ควรจะเพิ่มว่าถ้าไม่ใช่ frontpage ด้วยครับ ไม่งั้นหน้าแรกกลายเป็น copy ของหน้าอื่นไป ^ ^

if ($page && function_exists('drupal_get_path_alias')
  && !drupal_is_front_page()) {
kong's picture
kong says:

แก้แล้ว ขอบคุณครับ (มีคนใช้ด้วย ดีใจ ^_^)

tum's picture
tum (visitor) says:

Canonical URLs ในwp มันเหมือนกันมั้ยครับ

kong's picture
kong says:

ถ้าหมายถึงตัวนี้ http://wordpress.org/extend/plugins/canonical โดยหลักการแล้วเหมือนกันครับ

kong's picture
kong says:

ตอนนี้มีโมดูล Canonical URL ที่ให้ผู้ใช้กำหนด canonical url ที่ต้องการได้เองเวลา edit node ด้วยครับ โดยจะเก็บข้อมูล url ไว้ในตารางต่างหาก ถ้ามีหลายๆ alias ใน 1 node ใช้โมดูลที่ว่านี้น่าจะดีกว่า

Thaimerits's picture
Thaimerits (visitor) says:

ขอบคุณมาก ไม่ใช้ drupal ในการทำเว็บประจำ แต่เคยลองๆ เหมือนกัน ปกติใช้ WP มากกว่า แต่ก็อยากลองครับ ขอบคุณมาก drupal ไม่ธรรมดาจริงๆ ไม่ทราบว่า SEO สู้ WP ได้หรือเปล่าครับ

Post new comment

The content of this field is kept private and will not be shown publicly. If you have a Gravatar account associated with the e-mail address you provide, it will be used to display your avatar.