ทำความเข้าใจกับ add_rewrite_rule


11

ฉันพยายามadd_rewrite_ruleทำงานเพื่อดึงพารามิเตอร์จาก URL และส่งผ่านไปยังคำขอ เห็นโพสต์จำนวนมากเกี่ยวกับเรื่องนี้ แต่ดูเหมือนจะไม่สามารถใช้งานได้

หาก url เริ่มต้นด้วยสตริงที่แน่นอนฉันต้องการลบออกจาก url และส่งมันเป็น params แบบสอบถาม

ตัวอย่างคำขอ URL:

http://domain.com/foo/my_page

สิ่งนี้จะเปลี่ยนเป็น

http://domain.com/my_page?param=foo

หาก 'foo' ไม่ปรากฏขึ้นก็ควรทำตามคำขอปกติ ตรรกะนี้ควรใช้กับ URL หน้าหรือโพสต์ประเภท URL ที่กำหนดเองในเว็บไซต์ของฉัน (โดยทั่วไป foo / *) คิดว่ามันจะเป็นเหมือนการส่งผ่านหาก url มี 'foo' ดึงออกมาและจากนั้นเพียงส่งผ่านไปยัง Wordpress เพื่อให้เป็นเรื่องปกติ

ฉันมี 'param' ในฐานะ query_vars ที่อนุญาตแล้ว

โดยรวมมันจะต้องทำงานต่อไปนี้:

  • / foo / my_page (หน้า)
  • / foo / my_folder / my_page (เพจย่อย)
  • / foo / example_type (โพสต์เก็บถาวรแบบกำหนดเอง)
  • / foo / example_type / example_post (โพสต์เดี่ยวที่กำหนดเอง)

URL ความหมายโพสต์หมวดหมู่แท็ก ฯลฯ ไม่เพียง แต่pageประเภทโพสต์หรือเฉพาะหน้าใด ๆ สิ่งที่เกี่ยวกับหน้าพ่อแม่ / ลูกในลำดับชั้น?
Milo

@Milo ฉันได้ชี้แจงสิ่งนี้ให้คุณ ฉันใช้เพียงหน้าและประเภทโพสต์ที่กำหนดเองเท่านั้น
Louis W

คำตอบ:


8

กฎพื้นฐานที่เหมาะกับตัวอย่างของคุณ:

function wpd_foo_rewrite_rule() {
    add_rewrite_rule(
        '^foo/([^/]*)/?',
        'index.php?pagename=$matches[1]&param=foo',
        'top'
    );
}
add_action( 'init', 'wpd_foo_rewrite_rule' );

นี้จะใช้เวลาสิ่งที่เกิดขึ้นหลังจากfoo/และชุดว่าpagenameสำหรับการค้นหาและจากนั้นได้รับค่าคงparam fooหากคุณต้องการรูปแบบ URL ที่แตกต่างกันคุณจะต้องมีกฎพิเศษสำหรับแต่ละรูปแบบที่ไม่ซ้ำกัน อ้างถึงWP_Queryเอกสารสำหรับ vars แบบสอบถามต่างๆที่สามารถตั้งค่าภายในกฎการเขียนซ้ำ อย่าลืมลบกฎการเขียนซ้ำหลังจากเพิ่มกฎใหม่ สามารถทำได้โดยไปที่หน้าการตั้งค่าลิงก์ถาวร

ตอนนี้ไปที่ URL ตัวอย่างของคุณ:

http://domain.com/foo/my_page

จะโหลดหน้าเว็บที่ถูกต้อง แต่จะไม่ทำงานเหมือนกับการไปที่:

http://domain.com/my_page?param=foo

เพราะเมื่อใช้ rewrites ภายในparamจะถูกตั้งค่าภายใน$wp_queryวัตถุแบบสอบถามไม่ใช่$_GETsuperglobal หากคุณต้องการทำงานกับรหัสที่ค้นหาค่า$_GETคุณจะต้องมีขั้นตอนเพิ่มเติมในการตั้งค่าดังกล่าว:

function wpd_foo_get_param() {
    if( false !== get_query_var( 'param' ) ){
        $_GET['param'] = get_query_var( 'param' );
    }
}
add_action( 'parse_query', 'wpd_foo_get_param' );

อีกวิธีที่ควรพิจารณาคือใช้จุดปลายดังนั้น/foo/จะอยู่ที่ส่วนท้ายของ URL แทนที่จะเป็นส่วนนำหน้า ข้อดีของการทำเช่นนี้คือ API ของadd_rewrite_endpointการเพิ่มกฎทั้งหมดที่คุณต้องการรวมถึงการเปิดใช้งานการแบ่งหน้า


ขอบคุณสำหรับคำอธิบายผ่าน ดูเหมือนว่าปิดใช้งานได้กับหน้าเว็บ แต่ให้ข้อผิดพลาด 404 กับฉันสำหรับการโพสต์เก็บถาวรและ URL เดียว
Louis W

ใช่เช่นที่ฉันพูดคุณต้องเพิ่มกฎเพิ่มเติมที่ตรงกับแต่ละรูปแบบเหล่านั้น ฉันไม่ทราบว่า URL เหล่านั้นมีลักษณะอย่างไรในการตั้งค่าของคุณ
Milo

ฉันมีประเภทเพจที่กำหนดเองชื่อ 'โครงการ' ซึ่งมีไฟล์เก็บถาวรและหน้าเดียว คุณสามารถยกตัวอย่างสำหรับสิ่งนั้นและฉันสามารถทำให้คนอื่นทั้งหมด
Louis W

นอกจากนี้ดูเหมือนว่าจะไม่ทำงานสำหรับหน้าย่อย
Louis W

1
แก้ไขคำถามของคุณเพื่อเพิ่มตัวอย่างของรูปแบบ URL แต่ละรายการที่ต้องการกฎ ฉันไม่ได้กังวลเกี่ยวกับคำตอบของฉันที่ได้รับการยอมรับบางครั้งฉันสามารถหลอกคนให้ตอบคำถามของตัวเองได้โดยให้บางอย่างเริ่มต้นด้วย
Milo

6

ตกลงฉันได้รับตัวอย่างการทำงานสำหรับคำขอทั้ง 3 ประเภท การทดลองและใช้เวลาหลายตันเพื่อให้พวกเขาทำงานได้ ฉันเดาว่าไมโลเก่งกาจในการตอบคำถามของตัวเอง

หลังจากการเปลี่ยนแปลงมากมายและการรีเฟรช Permalinks ฉันรู้ว่ามันง่ายกว่ามากที่จะหา URL ที่อยู่นอก add_rewrite_url และเมื่อทำงานแล้วกำหนดให้เขียนใหม่ index.php?param=foo&post_type=example_typeตัวอย่างความเป็นอยู่

อีกสิ่งที่ชัดเจน แต่เพิ่มที่นี่เพื่อช่วยคนอื่น คุณต้องกำหนดกฎการโพสต์ที่กำหนดเองประเภท add_rewrite_rule ก่อนที่คุณจะกำหนดกฎตัวแทนในหน้า / เพจย่อย ฉันเสียเวลาไปกับมันและคิดว่ามันเป็นสิ่งสำคัญที่ทำให้ฉันไม่เข้าใจว่าทำไมกฎไม่ทำงาน

นี่คือกฎ 3 ข้อที่ใช้งานได้ในทุกความต้องการของฉัน กฎของเพจ / เพจย่อยนั้นรวมกันเป็นกฎเดียว

// Custom Post Archive
add_rewrite_rule(
    '^foo/example_type/?$',
    'index.php?param=foo&post_type=example_type',
    'top'
    );

// Custom Post Individual
add_rewrite_rule(
    '^foo/example_type/([^/]*)/?$',
    'index.php?param=foo&example_type=$matches[1]',
    'top'
    );

// Pages, Top-Level and Sub-Pages
// This MUST be placed in the code AFTER custom post add_rewrite_rule
add_rewrite_rule(
    '^foo/(.+)/?$',    
    'index.php?param=foo&pagename=$matches[1]',
    'top'
    );

นอกจากนี้สิ่งที่ฉันทำคือตั้งค่าการวนซ้ำเพื่อเพิ่มกฎประเภทโพสต์ที่กำหนดเองหลายรายการ โปรดจำไว้ว่าคุณต้องกำหนดกฎการโพสต์ประเภท add_rewrite_rule ที่กำหนดเองก่อนที่คุณจะกำหนดกฎตัวแทนในหน้า / เพจย่อย

$custom_types = array('example_type', 'projects', 'people');

foreach($custom_types as $type) {

    // Custom Post Archive
    add_rewrite_rule(
        '^foo/'.$type.'/?$',
        'index.php?param=foo&post_type='.$type,
        'top'
        );

    // Custom Post Individual
    add_rewrite_rule(
        '^foo/'.$type.'/([^/]*)/?$',
        'index.php?param=foo&'.$type.'=$matches[1]',
        'top'
        );

}

Rewrite วิเคราะห์ซึ่งไมโลผ่านไปเป็นประโยชน์มากเมื่อพยายามที่จะเข้าใจถึงวิธีการคำสั่ง Wordpress สำหรับหน้า / โพสต์


สายไปที่การแสดง แต่ฉันสามารถ ping คุณสำหรับตัวอย่างอื่นได้หรือไม่ โปรดทราบว่าฉันไม่เข้าใจพารามิเตอร์ $ tag ของ add_rewrite_rule ไม่มีเงื่อนงำความหมาย ฉันไม่เข้าใจตัวอย่างโดยใช้ pagename = $ match [1] ' ฮะ??? ฉันมี URL เช่น domain.com/detail?id=2&it=3 ฉันต้องการให้หน้าเว็บเป็น domain.com/detail/2-3/ คุณเต็มใจไหม
Debbie Kurth
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.