ต้องการความช่วยเหลือเกี่ยวกับ add_rewrite_rule


55

วิธีการแก้


ฉันได้ไปกับอัปเดต 3 แล้วและทำงานได้ สิ่งที่ฉันได้เข้าใจผิดคือการที่ฉันเชื่อว่าเขียนกฎจะเปลี่ยนไปdesigners/?designer=some-designer&bid=9 /designers/some-designerแต่แน่นอนว่าเป็นวิธีอื่น ๆ


ฉันได้รับการทำวิจัยบางอย่าง แต่ฉันไม่ได้ค่อนข้างได้รับวิธีการใช้add_rewrite_rule ()

โพสต์นี้ค่อนข้างใกล้เคียงกับสิ่งที่ฉันต้องการ แต่ฉันต้องการรหัสมากขนาดนั้นจริงหรือ

ลิงค์ปัจจุบันของฉันคือ:
http://www.noronianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
สิ่งที่ฉันต้องการคือ
http://www.noronianfashion.no/designers/Batlak-og-Selvig /

  1. ฉันจะใช้งานadd_rewrite_rule()อย่างไร
  2. ฉันต้องส่งรหัสผู้ออกแบบ (การเสนอราคา) ฉันจะทำเช่นนั้นได้อย่างไรเมื่อใช้กฎ re.write โดยที่ไม่แสดงใน URL

อัปเดต 1

ฉันพบสิ่งนี้ซึ่งเป็นการอธิบายเพิ่มเติมเล็กน้อย แต่มันไม่ทำงาน:

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 Jan แนะนำในหัวข้ออื่น ฉันใส่สิ่งนี้ลงในฟังก์ชั่นของฉัน แต่มันไม่มีผลใด ๆ

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
ฉันพบตัวอย่างเล็ก ๆ น้อย ๆ ที่นี่เช่นกัน แต่นี่ไม่ได้ผลเช่นกัน :(

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;
}

ฉันจะซาบซึ้งจริงๆถ้ามีคนสามารถช่วยฉันแก้ปัญหานี้ได้


นี้มีลักษณะคล้ายกันมากกับคำถามแรกที่คุณถามที่นี่และที่ผมให้คำตอบ สถานการณ์เปลี่ยนไปตั้งแต่นั้นมาดังนั้นคำตอบของฉันจึงไม่ถูกต้องอีกต่อไป? หากคุณไม่ต้องการรหัสนักออกแบบใน URL ของคุณคุณจะต้องแปลง "กระสุน" เป็น ID ด้วยตัวคุณเอง WordPress ไม่สามารถทำสิ่งนี้ให้คุณได้ นักออกแบบยังคงเป็นวัตถุภายนอกหรือไม่?
ม.ค. Fabry

@Jan Fabry ใช่ฉันค้นพบว่าหลังจากฉันโพสต์ข้อความนี้ (ฉันลืม) ตอนนี้ฉันเข้าใจคุณแนะนำดีกว่า ดูรหัสปรับปรุงของฉันที่นี่ นักออกแบบของฉันยังคงเป็นรายการในฐานข้อมูลที่กำหนดเอง มันเป็นไปได้ที่จะใช้ POST insteed และจะได้รับการผ่านพร้อมbid?
Steven

การใช้คำขอ POST จะไม่กังวลถ้าฉันคัดลอกลิงก์และส่งไปให้คนอื่น มันเป็นปัญหาที่จะทำให้กระสุนไม่ซ้ำกันและทำการค้นหาข้อมูลจากที่นั่น?
Jan Fabry

@Jan Fabry: คุณหมายถึงslugอะไร? `การดึงข้อมูลผู้ออกแบบนั้นง่ายกว่าการใช้bidมากกว่าdesigner
Steven

คำตอบ:


87

พื้นหลังบางส่วนเกี่ยวกับกฎการเขียนใหม่

ระบบ WP Rewrite นั้นดูซับซ้อน แต่จริงๆแล้วมันไม่ยากที่จะเข้าใจว่ามันทำงานอย่างไร มันถูกใช้เพื่อแยกURL สวย ( /designers/) ราวกับว่าพวกเขาไม่สวย ( /index.php?pagename=designers) แนวคิดพื้นฐานคือคุณมีรายการกฎการเขียนซ้ำนิพจน์ทั่วไปที่สามารถจับคู่กับ URL ขาเข้าและเขียนลงใน URL อื่น ๆ ส่วนใหญ่อยู่ในรูปแบบของindex.phpตัวแปรคิวรีบางอย่าง ตัวแปรเหล่านี้ถูกตั้งค่าเป็นส่วนของนิพจน์ทั่วไปที่ตรงกับ URL กฎจะได้รับการประเมินจากบนลงล่างดังนั้นหากมีกฎสองข้อที่อาจตรงกันกฎข้อแรก "ชนะ"

กฎการเขียนซ้ำเหล่านี้ถูกเก็บไว้ในฐานข้อมูลโดยการโทรflush_rewrite_rules()แต่เนื่องจากการสร้างและการเขียนกฎเหล่านี้เป็นการดำเนินการที่มีราคาแพงคุณจึงไม่ควรทำในทุกinitๆ แต่คุณทำได้เมื่อคุณเปลี่ยนกฎ: อาจเป็นการเปิดใช้งานปลั๊กอิน (โดยใช้register_activation_hook()) หรือด้วยตนเองโดยไปที่หน้าการตั้งค่าลิงก์ถาวร ( เนื่องจากเป็นการยากที่จะทำสิ่งนี้โดยอัตโนมัติเมื่อเปิดใช้งานธีม ) หากคุณไม่ได้ล้างกฎการโทรadd_rewrite_rule()จะไม่มีผล จะไม่มีปัญหาในการเรียกadd_rewrite_rule()ใช้ทุกครั้งinitแม้หลังจากที่คุณล้างกฎแล้ว

add_rewrite_rule()มีหลายวิธีที่จะเพิ่มเขียนกฎของคุณและถ้าคุณเพียงต้องการที่จะเพิ่มกฎหนึ่งที่คุณสามารถทำเช่นนี้กับ เพราะกฎระเบียบสำหรับการโพสต์หน้า taxonomies ... ส่งผลให้หลายกฎพวกเขาถูกสร้างขึ้นด้วยฟังก์ชั่นระดับสูงเช่นadd_rewrite_tag(), add_permastruct()... แต่เหล่านี้ไม่จำเป็นต้องใช้สำหรับกรณีที่เรียบง่ายเราได้ที่นี่

นอกจากนี้ยังมีตัวกรองบางส่วนดังนั้นคุณสามารถเพิ่มกฎของคุณโดยใช้generate_rewrite_rulesหรือgenerate_rewrite_rules_arrayhooks สิ่งเหล่านี้ช่วยให้คุณควบคุมรายละเอียดกฎที่สมบูรณ์ได้ แต่add_rewrite_rule()ก็เพียงพอแล้วหากคุณต้องการเพิ่มกฎหนึ่งข้อ

ฉันสร้างปลั๊กอินเล็ก ๆ ที่ช่วยให้คุณวิเคราะห์กฎการเขียนปัจจุบันและ (แน่นอน) ฉันขอแนะนำให้คุณใช้มันเมื่อคุณพยายามที่จะเปลี่ยนแปลงอะไร

รับข้อมูลพิเศษของคุณจาก URL

มาสร้างตัวอย่างที่คุณให้ คุณมีแบรนด์ของนักออกแบบBatlak og Selvigที่มี ID numberic ( )bid 9คุณไม่ต้องการ ID นี้ใน URL แต่เป็นเพียงชื่อ เราเรียกรุ่น URL ที่เป็นมิตรของชื่อ (ไม่มีช่องว่างหรืออักขระพิเศษ) กระสุนBatlak-og-Selvig :

โดยทั่วไป URL ควรมีข้อมูลทั้งหมดเพื่อระบุเนื้อหาที่คุณต้องการแสดงในหน้า คุณสามารถใช้คุกกี้หรือคำขอ POST เพื่อจัดเก็บรหัสนักออกแบบที่แท้จริงที่คุณต้องการแสดง แต่สิ่งนี้จะพังถ้าใครแบ่งปันลิงก์โดยส่งทางอีเมล, Facebook, Twitter หรือเพียงแค่อ่านออกเสียงทางโทรศัพท์ หากคุณไม่ต้องการใช้รหัสตัวเลขใน URL ของคุณคุณควรตรวจสอบให้แน่ใจว่าตัวบุ้งนั้นไม่เหมือนใคร: จากนั้นคุณทำการค้นหา ID ตามตัวบุ้งก่อนและดำเนินการต่อเหมือนที่เคยทำมาก่อน

ดังนั้นสิ่งที่เราได้เรียนรู้ในตอนนี้คือเราต้องการเพิ่มกฎการเขียนซ้ำสำหรับรูปแบบ" /designers/ตามด้วยสิ่งใดถึงถัดไป/"และบันทึก"อะไร"ใน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;
}

อย่างที่คุณเห็นคำตอบนี้โดยทั่วไปเหมือนกับคำตอบก่อนหน้าของฉันแต่ไม่มีกฎการล้างในโค้ด (เพื่อให้คุณสามารถใช้ในชุดรูปแบบของคุณfunctions.phpแทนปลั๊กอิน) และด้วยความมั่นใจและคำอธิบายเพิ่มเติมเล็กน้อยเพราะฉันเรียนรู้ มากมายเกี่ยวกับการเขียนกฎใหม่ตั้งแต่ (และเพราะ) การตอบคำถามแรกของคุณ

การสนทนาในห้องสนทนา

เราเคลียร์ประเด็นสุดท้ายสำหรับคำถามนี้ในห้องแชท ในท้ายที่สุดสตีเว่นใช้generate_rewrite_rulesตะขอเพราะadd_rewrite_rule()ฟังก์ชั่นไม่ได้ผลสำหรับเขา


2
@Steven: pagenameเป็นตัวบุ้งของหน้า WordPress ที่คุณต้องการแสดง (บันทึกในฐานข้อมูล) หน้านี้สามารถระบุได้ว่าต้องการใช้designers.phpไฟล์เทมเพลตในพื้นที่ผู้ดูแลระบบ WP ดังนั้นคุณชี้ไปที่บุ้งหน้าไม่ใช่ชื่อเทมเพลตเนื่องจากเทมเพลตเดียวกันสามารถใช้กับหลาย ๆ หน้า: ในกรณีนี้ WordPress ไม่ทราบว่าคุณต้องการทำอะไร
Jan Fabry

1
@ สตีเว่น: ฉันคิดว่าคุณซับซ้อนเกินไปวิธีที่คุณตั้งค่า hooks ลบadd_rewrite_rules()ฟังก์ชั่นและโทรadd_filter()/add_action()โดยตรง หากสิ่งนี้อยู่ในไฟล์ธีมให้ลบflush_rewrite_rules()และเพียงไปที่หน้าการตั้งค่า permalinks เพื่อล้างกฎ (หรือเพิ่มในwpse5413_init()และลบออกในภายหลัง) และปลั๊กอินของฉันจะแสดงกฎการเขียนใหม่ในปัจจุบัน โปรดจำไว้ว่านี่เป็นการเปลี่ยนแปลงวิธีจัดการ URL ที่เข้ามาเท่านั้นไม่ใช่วิธีที่โค้ดของคุณจะเขียน URL ใน HTML
ม.ค. Fabry

1
@ สตีเว่น: ฉันไม่คิดว่าคุณจะต้องกดปุ่มบันทึกเพียงแค่เปิดหน้า Permalinks ก็จะล้างออก และอีกครั้งสิ่งนี้จะเพิ่มความสามารถให้ WordPress ยอมรับ/designers/designer-slug/URL เท่านั้นคุณต้องเปลี่ยนสถานที่ที่คุณเขียน URL เหล่านี้ใน HTML ของคุณเอง ทดสอบโดยไปที่/designers/Batlak-og-Selvig/ตัวคุณเองถ้าใช้งานได้ให้หาสถานที่ทั้งหมดที่สร้าง URL เหล่านี้และเปลี่ยนให้ใช้โครงสร้างใหม่
Jan Fabry

1
อาตอนนี้ฉันคิดว่าฉันเริ่ม udnerstand ฉันคิดว่ากฎการเขียนซ้ำจะเปลี่ยนวิธีการแยก URL ในฟิลด์ URL ของเบราว์เซอร์ แต่สิ่งที่เป็นไปได้คือฉันต้องส่งออก URL จริง ๆwww.mysite.com/batlat-og-selvig/9แล้วนี่คือ "แปล" เป็น/?designer=Batlak-og-Selvig&bid=9
Steven

1
@Steven: ใช่แน่นอน: กฎการเขียนใหม่จะจัดการกับลิงค์ที่เข้ามาและ (เฉพาะในบางกรณีที่เลือก) จะไม่มีผลกับลิงค์ที่สร้างขึ้นในรหัสของคุณ
Jan Fabry
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.