將文章中嵌入的 YouTube 影片加入複合式摘要中

最近幫公司網站的佈景主題做更新,為了想要把嵌入的 YouTube 影片結構化資料插入頁面中,因此開始了相關的研究。

先來看一下實際執行的結果:

儘管網路上應該有其他外掛可以做到這件事,但這次主要是單純針對 YouTube 影片製作複合式摘要,因此還是決定自己客製化。

程式碼片段

只要將下列程式碼片段加入子佈景主題的 functions.php 中,或者透過 Code Snippets 嵌入下列程式碼片段,就可以發揮效果。

<?php
/**
 * Add Rich Snippets when YouTube videos are detected in posts.
 */
if ( !function_exists( 'hyc_youtube_post' ) ) :
	function hyc_youtube_post(){
		if ( 'post' !== get_post_type() ){
			return;
		}
		global $post;
		$content = $post->post_content;
		$yt_regex = '/(youtu\.be\/|youtube\.com\/(watch\?(.*&)?v=|(embed|v)\/))([-_\w]+)/';
		preg_match_all( $yt_regex, $content, $matches, PREG_SET_ORDER );
		foreach( $matches as $match ){
			$ids[] = $match[5];
		} 
		$api_url = add_query_arg( array(
			'id'     => implode( ',', array_unique( $ids ) ),
			'part'   => 'contentDetails,snippet',
			'key'    => '{{YOUR GOOGLE API KEY}}',
			), esc_url( 'https://www.googleapis.com/youtube/v3/videos' ) );
		$returns = json_decode( wp_remote_get( $api_url )['body'] );
		foreach ( $returns->items as $return ){
			$request[$return->id] = array(
				'@context'    => 'https://schema.org',
				'@type'       => 'VideoObject',
				'name'        => $return->snippet->title,
				'description' => $return->snippet->description,
				'thumbnailUrl'=> $return->snippet->thumbnails->default->url,
				'uploadDate'  => $return->snippet->publishedAt,
				'duration'    => $return->contentDetails->duration,
				'contentUrl'  => 'https://www.youtube.com/watch?v=' . $return->id,
			);
			echo '<script type="application/ld+json">' . json_encode( $request[$return->id] ) . '</script>';
		}
	}
endif;
add_action( 'wp_footer', 'hyc_youtube_post' );

程式碼說明

這個功能分成 3 個步驟:

  1. 從文章中檢查是否嵌入 YouTube 影片,並擷取其 ID
  2. 透過 YouTube 的 API,取得影片的中繼資料
  3. 將中繼資料整理為複合式資料所需的 JSON-LD 格式

檢查文章中是否有嵌入 YouTube 影片

在程式碼片段的開頭,用了 ‘post’ === get_post_type() 這項條件,檢查是否要在當前的內容類型 (post type) 啟用這項功能。

接著,透過 global $post 這個全域變數,取得當前內容,並用規則運算式 (regular expression) 比對內文是否有 YouTube 影片,接著擷取其影片 ID,存入陣列 $ids 中。

透過 YouTube Data API 取得影片中繼資料

比對出 YouTube 影片 ID 後,由於 Gutenberg 會以註解的形式標記嵌入的 YouTube 影片,所以會造成比對結果重複計算,因此利用 array_unique 的方法先將陣列重新處理一遍。

在進行這個步驟前,需要先取得 YouTube Data API 的存取權。網路上有許多相關文件,這裡附上 Google Developers 的文件 (英文),裡面的 Before you start 便提供了取得 API 金鑰的方法。

這邊為了符合 WordPress 對網址進行字元逸出 (escape) 處理的安全做法,因此用了 add_query_arg 這個函式來組裝查詢網址。上述的寫法等同於以下的寫法:

<?php
  $api_url = 'https://www.googleapis.com/youtube/v3/videos?id=' . implode( ',', array_unique( $ids ) ) 
      . '&part=contentDetails,snippet&key={{YOUR GOOGLE API KEY}}';

接著透過 wp_remote_get() 的方法,用 GET 的方式取得文章內所有影片的中繼資料。

將中繼資料轉為 JSON-LD 格式

根據 Search Console 的文件說明,影片物件必須包含下列中繼資料:

{
    "@context": "http://schema.org", //固定值
    "@type": "VideoObject", //固定值
    "name": "炸肉排的故事", 
    "description": "如何在一小時內做出美味的炸肉排",
    "thumbnailUrl": "https://example.com/imgs/schnitzel-small.jpg",
    "uploadDate": "2015-02-05T08:00:00+08:00",
    "duration": "PT1M33S",
    "contentUrl": "https://streamserver.example.com/schnitzel.mp4"
  }

透過 foreach 的方式,可以將上述資料逐一存取出來,組裝後利用 wp_footer 這個勾點,將這些複合式資料嵌入頁尾。

結論

先說結論,加入複合式資訊後,並不代表 100% 會出現複合式搜尋結果。

然而,透過標註文章中的影片,Google 的搜尋引擎可以了解到文章與影片之間有關連,進而推測搜尋特定關鍵字的人,可能也想看到什麼樣的影片。

當然,老調重彈,這些都只是幫助搜尋引擎「了解」內容的手法,但實際上能夠為使用者和網站經營者帶來效益的,還是那些真正有價值的內容。

參考資料

*Post type 目前的通譯名稱為「文章類型」,但是 post 應為「內容儲存」的單位,因此這個網站將以「內容類型」稱之。

預設圖片
Eric Chuang
正職是廣告行銷人員,因為 Google Tag Manager 的關係開始踏入網站製作的領域,進一步把 WordPress 當成 PHP + HTML + CSS + JavaScript 的學習教材。此外,因為工作的關係,曾經用 Automattic 的 Underscores (_s) 替客戶與公司官網進行全客製化佈景主題開發。

發佈留言

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料

Physical Address

304 North Cardinal St.
Dorchester Center, MA 02124