問題描述


我已經和 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/

  1. 如何使用 add_rewrite_rule()
  2. 我需要通過設計師 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_rulesgenerate_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 版本的名稱 (無空格或特殊字符)slugBatlak-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 輔助翻譯的英文資料結果。如果您對結果不滿意,可以加入我們改善翻譯效果:薇曉朵技術論壇。