問題描述
解
我已經和 Update 3 一起工作了。我所誤解的是,我相信重寫規則會將 designers/?designer=some-designer&bid=9 改為/designers/some-designer 。但這當然是相反的。
我一直在做一些研究,但我不太瞭解如何使用 add_rewrite_rule()。
This post 非常接近我需要的,但是我真的需要很多程式碼嗎?
我當前的連結是這樣的:http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9 我想要的是這個 http://www.norwegianfashion.no/designers/Batlak-og-Selvig/
- 如何使用
add_rewrite_rule()? - 我需要透過設計師 ID(bid) 。使用 re.write 規則時,如何在 URL 中顯示該怎麼做?
更新 1
I found this 這是一個更多的解釋。但它不工作:
function add_rewrite_rules( $wp_rewrite )
{
$new_rules = array(
'('.$template_page_name.')/designers/(.*?)/?([0-9]{1,})/?$' => 'designers.php?designer='.
$wp_rewrite->preg_index(1).'&bid='.
$wp_rewrite->preg_index(2)
);
// Always add your rules to the top, to make sure your rules have priority
$wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
}
add_action('generate_rewrite_rules', 'add_rewrite_rules');
function query_vars($public_query_vars) {
$public_query_vars[] = "designer";
$public_query_vars[] = "bid";
return $public_query_vars;
}
add_filter('query_vars', 'query_vars')
更新 2
這是我試過的另一個解決方案,Jan Fabry suggesten 在另一個執行緒中。我把它放在我的 functions.php 中,但沒有效果。
add_action('generate_rewrite_rules', 'add_rewrite_rules');
add_filter('query_vars', 'query_vars');
/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function add_rewrite_rules( $wp_rewrite )
{
add_rewrite_rule('^designers/([^/]*)/([^/]*)$ /designers/?designer=$1&bid=$2 [L]', 'top');
flush_rewrite_rules(false);
}
function query_vars($public_query_vars) {
$public_query_vars[] = "designer";
$public_query_vars[] = "bid";
return $public_query_vars;
}
更新 3 I found a few examples here 以及。但這不是工作:(
add_filter('rewrite_rules_array','wp_insertMyRewriteRules');
add_filter('query_vars','wp_insertMyRewriteQueryVars');
add_filter('init','flushRules');
// Remember to flush_rules() when adding rules
function flushRules(){
global $wp_rewrite;
$wp_rewrite->flush_rules();
}
// Adding a new rule
function wp_insertMyRewriteRules($rules)
{
$newrules = array();
$newrules['(designers)/(d*)$'] = 'index.php?pagename=designers&designer=$matches[1]';
return $newrules + $rules;
}
// Adding the bid var so that WP recognizes it
function wp_insertMyRewriteQueryVars($vars)
{
array_push($vars, 'designer');
return $vars;
}
更新 4 我也嘗試過這個解決方案,但還沒有成功。
add_filter('search_rewrite_rules', 'designers_createRewriteRules');
function designers_createRewriteRules($rewrite) {
global $wp_rewrite;
// add rewrite tokens
$designer_token = '%designers%';
$wp_rewrite->add_rewrite_tag($designer_token, '(.+)', 'designers=');
$bid_token = '%bid%';
$wp_rewrite->add_rewrite_tag($bid_token, '(.+)', 'bid=');
$keywords_structure = $wp_rewrite->root . "designers/$designer_token/$bid_token";
$keywords_rewrite = $wp_rewrite->generate_rewrite_rules($keywords_structure);
return ( $rewrite + $keywords_rewrite );
}
更新 5 似乎沒有新增我的重寫規則。執行以下新規則:print_r($wp_rewrite),不包括我的新的重寫規則。
更新 6 我測試了 Jan 的解決方案。但是 URL 不會改變:(
/* Initiation script for NF template
------------------------------------------------------------------------------*/
add_action('after_setup_theme','norwegianfashion_setup');
if ( ! function_exists( 'norwegianfashion_setup' ) ):
function norwegianfashion_setup() {
/* Here I do a lot of stuff */
// SEO friendly URL for desigenrs
add_action( 'init', 'wpa5413_init' );
add_filter( 'query_vars', 'wpa5413_query_vars' );
}
endif;
/* Custom re-write rules for desigenrs
------------------------------------------------------------------------------*/
function wpa5413_init()
{
// Remember to flush the rules once manually after you added this code!
add_rewrite_rule(
'designers/([^/]+)/?',
'index.php?pagename=designers&designer=$matches[1]',
'top' );
}
function wpa5413_query_vars( $query_vars )
{
$query_vars[] = 'designer';
return $query_vars;
}
如果有人能夠幫助我解決這個問題,我真的很感激。
最佳解決方案
一些重寫規則的背景
WP Rewrite 系統看起來很複雜,但實際上並不難理解它如何工作。它用於解析漂亮的 URL(/designers/),就像它們是 non-pretty(/index.php?pagename=designers) 一樣。基本思想是,您有一個重寫規則列表,可以匹配傳入 URL 的正規表示式,並將其重寫為其他 URL,主要以 index.php 和一些查詢變數的形式。這些變數被設定為與 URL 匹配的正規表示式的部分。規則從頂部到底部進行評估,因此如果兩個規則可能匹配,則第一個”wins” 。
這些重寫規則透過呼叫 flush_rewrite_rules()儲存在資料庫中,但由於生成和寫入這些規則是一項昂貴的操作,因此您不應該在每個 init 上執行。相反,您只能在更改規則時執行此操作:可能在外掛啟用 (使用 register_activation_hook()) 或手動訪問 「固定連結設定」 頁面 (because it’s hard to do this automatically on theme activation) 時。如果不重新整理規則,呼叫 add_rewrite_rule()沒有任何效果。即使在重新整理規則後,也可以在每個 init 上呼叫 add_rewrite_rule()。
有很多方法可以新增重寫規則,如果只想新增一條規則,可以使用 add_rewrite_rule()來實現。因為帖子,頁面,分類法的規則導致了多個規則,所以它們是用 add_rewrite_tag(),add_permastruct()等高階函式建立的,但是我們在這裡的簡單例子不需要這些規則。
還有一些過濾器,因此您還可以使用 generate_rewrite_rules 或 generate_rewrite_rules_array 鉤子新增規則。這些給你非常詳細的控制完整的規則,但是再次,如果你只想新增一個規則,add_rewrite_rule()就夠了。
我建立了 a little plugin that allows you to analyze the current rewrite rules,當然,我建議您在嘗試更改任何內容時使用它。
從 URL 獲取您的額外資訊
我們以您給出的例子為基礎。您有設計師品牌 Batlak og Selvig,數量為 (bid)9 。您不希望該 URL 中的此 ID,而只需要該名稱。我們稱之為 URL-friendly 版本的名稱 (無空格或特殊字元)slug:Batlak-og-Selvig 。
一般來說,網址應包含所有資訊來標識您要在頁面上顯示的內容。您可以使用 Cookie 或 POST 請求來儲存要顯示的實際設計師 ID,但如果有人共享連結,則透過郵件,Facebook,Twitter 傳送或只是透過電話大聲朗讀,這將分解。如果您不想在 URL 中使用數字識別符號,則應確保該外掛是唯一的:然後首先根據該外掛進行 ID 的查詢,然後像以前一樣繼續。
所以我們現在學到的是,我們要為 「/designers/之後的任何直到下一個/」 的模式新增重寫規則,並將”anything” 儲存在 designer_slug 查詢變數中。在你的情況下,我相信你也想使用這個頁面的 designers 作為一般的頁面內容,所以我們也會告訴 WordPress 。
add_action( 'init', 'wpa5413_init' );
function wpa5413_init()
{
// Remember to flush the rules once manually after you added this code!
add_rewrite_rule(
// The regex to match the incoming URL
'designers/([^/]+)/?',
// The resulting internal URL: `index.php` because we still use WordPress
// `pagename` because we use this WordPress page
// `designer_slug` because we assign the first captured regex part to this variable
'index.php?pagename=designers&designer_slug=$matches[1]',
// This is a rather specific URL, so we add it to the top of the list
// Otherwise, the "catch-all" rules at the bottom (for pages and attachments) will "win"
'top' );
}
唯一要做的就是告訴 WordPress 還要將 designer_slug 儲存在查詢變數中,以便以後訪問它。 WordPress 使用允許的查詢變數的白名單,以防止人們透過 URL 修改帖子查詢的每個引數。這個列表上的所有內容都被忽略。只需鉤入 query_vars 鉤子並新增額外的變數:
add_filter( 'query_vars', 'wpa5413_query_vars' );
function wpa5413_query_vars( $query_vars )
{
$query_vars[] = 'designer_slug';
return $query_vars;
}
正如你所看到的,這個答案基本上與 my previous answer 相同,但沒有規則在程式碼中重新整理 (所以你可以在主題的 functions.php 而不是外掛中使用它),並且有一點更確定和解釋,因為我學到了很多關於重寫規則,因為 (並因為) 回答你的第一個問題。
聊天室討論
我們清理了這個問題 in the chat room 的最終問題。最後,Steven 使用了 generate_rewrite_rules 鉤子,因為 add_rewrite_rule()功能似乎不適合他。
參考文獻
注:本文內容整合自 Google/Baidu/Bing 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。