本來這篇教程應該提前的,但是由於在教程十七寫了個自定義註冊頁面的例子,那乾脆把自定義登陸、自定義找回密碼的實例都寫出來,以便靈活掌握 WordPress 重寫規則的運用。

但是我們發現,前面的例子都是翻譯一個地址,而沒有輸出地址,比如我們前面的教程講到了自定義文章類型,在 WordPress 創建了自定義文章類型後 (比如一個 book 類型的文章),那麼這類文章的 url 地址將會是:「ashuwp.com/book/文章名」      而在 WordPress 後台固定連接中也沒有對於自定義文章類型的固定連接設置。看了前面的教程,我們可以將 ashuwp.com/book/123.html 這類地址正確翻譯到 ID 為 123 的 book 類型文章,但是我們在模板中使用 the_permalink() 函數輸出的鏈接類型還是 「ashuwp.com/book/文章名」 這種類型。這也就是我説的,只有翻譯、沒有輸出。

研究過 WordPress 固定鏈接的人可能經常看到函數 add_rewrite_tag(),這個函數 就是我們這篇教程要説的重點:重寫標籤。

在本站進階教程二:WordPress 進階教程 (二): 註冊一個自定義的文章類型中,註冊了一個自定義文章類型-book: 請參考前面的教程

假設我們上圖中的文章 《測試文章》 ID 為 123,那麼我們要通過 ashuwp.com/book/123.html 的鏈接格式來訪問這篇文章怎麼呢?

如果熟悉了前面的教程,那麼很簡單:

  1. add_action('generate_rewrite_rules', 'ashu_rewrite_rules' );   
  2. function ashu_rewrite_rules( $wp_rewrite ){   
  3.     $new_rules = array(   
  4.         'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',   
  5.         'top'   
  6.     );   
  7.     $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;   
  8. }  

上面的重寫規則中正則表達式:[0-9] 即匹配數字,在主題的 functions.php 中添加上面的代碼即可,然後訪問地址 ashuwp.com/book/123.html 就會發現,居然到了正確的頁面 (如果錯誤、請更新重寫規則,你懂的,沒懂就參考前面的教程)

然而我們從通過模板輸出的鏈接,或者通過後台點擊查看文章,發現鏈接還是:「ashuwp.com/book/測試文章」, 在主題中添加下面的代碼:

  1. add_filter('post_type_link', 'ashu_book_link', 1, 3); //過濾器 post_type_link 即輸出鏈接的時候用   
  2. function ashu_book_link( $link$post = 0 ){   
  3.     if ( $post->post_type == 'book' ){ //判斷如果是 book 類型的文章   
  4.         return 'http://www.ashuwp.com/book/'.$post->ID .'html'; //返回一個正確的鏈接   
  5.     } else {   
  6.         return $link;   
  7.     }   
  8. }  

即可輸出正確的鏈接,然而教程到了這裏,還沒進入正題--重寫標籤。上面兩個代碼知識為了熟悉一下重寫規則的使用。

重寫標籤在 WordPress 後台-設置-固定連接裏面用到的 %post_id%  %post_name% 之類的就是重寫標籤了,我們前面也説過,WordPress 後台設置的 「固定鏈接格式」 是會保存到數據庫中的_options 表中,重寫標籤的主要作用也就是用來建立一個 「固定鏈接格式」

上面添加的段代碼,完全可以用下面的一段代碼來代替:

  1. add_action('init', 'ashu_book_rewrite');   
  2. function ashu_book_rewrite() {   
  3.   global $wp_rewrite;   
  4.   $queryarg = 'post_type=book&p=';   
  5.   $wp_rewrite->add_rewrite_tag('%book_id%', '([^/]+)', $queryarg);   
  6.   //這裏的%book_id% 就是重寫標籤,第二個參數為匹配這個標籤的正則表達式,第三個參數這個標籤匹配的翻譯規則   
  7.   $wp_rewrite->add_permastruct('book', '/book/%book_id%.html', false);    
  8.   //add_permastruct 是往數據庫中保存一個固定鏈接格式,第一個參數為名稱   
  9. }   
  10.   
  11. add_filter('post_type_link', 'ashu_book_permalink', 1, 3);   
  12. function ashu_book_permalink($post_link$post = 0) {   
  13.   global $wp_rewrite;   
  14.   if ( $post->post_type == 'book' ){ //判斷文章類型   
  15.       if ( is_wp_error( $post ) )   
  16.         return $post;   
  17.       $newlink = $wp_rewrite->get_extra_permastruct('book'); //獲取前面保存的名為 book 的固定鏈接格式   
  18.       $newlink = str_replace("%post_id%"$post->ID, $newlink); //將格式裏面的重寫標籤替換為文章 ID   
  19.       $newlink = home_url(user_trailingslashit($newlink)); //完整的鏈接地址   
  20.       return $newlink//返回   
  21.     } else {   
  22.         return $post_link;   
  23.     }   
  24. }  

上面的代碼中,輸出連接就不用解釋了。翻譯:當訪客訪問地址 「www.ashuwp.com/book/123.html」,這個地址剛好匹配了名為 「book」 的固定連接格式,而這個格式裏面的標籤 「%book_id%」 是要翻譯成 「post_type=book&p=」 的,所以翻譯為 「www.ashuwp.com/?post_type=book&p=123」 這樣就能正確翻譯了。。。所以上面的 add_rewrite_tag 和 add_permastruct 兩個函數組合的效果和使用函數添加重寫的規則

  1. 'book/([0-9]+)?.html$' => 'index.php?post_type=book&p=$matches[1]',  

是一樣的。