เส้นทางปลั๊กอินที่กำหนดเองใน Wordpress


12

ตกลงดังนั้นคำถามของฉันค่อนข้างง่าย ฉันต้องใช้กฎการกำหนดเส้นทางที่กำหนดเองสำหรับปลั๊กอินของฉัน เส้นทางเหล่านั้นใช้เวลาเพียงอาร์กิวเมนต์เดียว (ไม่มีอะไรซับซ้อน) และมีลักษณะ: http://www.example.org/myroute/myargument

สิ่งนี้จะเรียกคลาสที่กำหนดเองและแสดงแม่แบบกำหนดเอง (ซึ่งสามารถเข้าถึงชั้นเรียนได้โดยตรง)

อะไรคือวิธีที่ดีที่สุดสำหรับสิ่งนี้ ไชโย

คำตอบ:


15

คุณต้องทำสามสิ่งสำคัญ:

  1. สร้างกฎการเขียนindex.phpซ้ำแบบกำหนดเองเพื่อเปลี่ยนส่วนของ URI ให้เป็นค่าที่ส่งผ่านไป
  2. เพิ่มmyrouteและเพิ่มmyargumentตัวแปรการสืบค้นของรายการที่ปลอดภัยของ WordPress เพื่อให้ WordPress ไม่เพียง แต่เพิกเฉยเมื่อปรากฏในสตริงการสืบค้น
  3. ล้างกฎการเขียนซ้ำ

ประการแรกฉันจะแนะนำว่าแทนที่จะhttp://www.example.org/myroute/myargumentให้คุณใช้คำนำหน้าหรือคำต่อท้ายแบบพิเศษเพื่อแสดงว่า URI ควรได้รับการพิจารณาว่าเป็นหนึ่งใน 'เส้นทาง' พิเศษเหล่านี้ สำหรับประโยชน์ของตัวอย่างนี้ฉันได้เลือกคำนำหน้าเพื่อที่ว่ามันจะเป็นapi http://www.example.org/api/myroute/myargumentฉันเลือกapiเพราะเมื่อฉันทำสิ่งที่สงบเช่นเดียวกับที่คุณดูเหมือนจะทำงานมันเป็นสำหรับ API

รหัส

add_filter( 'rewrite_rules_array', 'my_insert_rewrite_rules' );
add_filter( 'query_vars', 'my_insert_query_vars' );
add_action( 'wp_loaded', 'my_flush_rules' );

// flush_rules() if our rules are not yet included
function my_flush_rules() {
    $rules = get_option( 'rewrite_rules' );

    if ( ! isset( $rules['api/(.*?)/(.+?)'] ) ) {
        global $wp_rewrite;
        $wp_rewrite->flush_rules();
    }
}

// Adding a new rule
function my_insert_rewrite_rules( $rules ) {
    $newrules = array();
    $newrules['api/(.*?)/(.+?)'] = 'index.php?myroute=$matches[1]&myargument=$matches[2]';
    return $newrules + $rules;
}

// Adding the id var so that WP recognizes it
function my_insert_query_vars( $vars ) {
    array_push( $vars, 'myroute', 'myargument' );
    return $vars;
}

รายละเอียดด่วน

มันค่อนข้างตรงไปตรงมา รูปแบบ regex ถูกเพิ่มเข้าไปในรายการกฎการเขียนซ้ำทั้งหมดใน WordPress และรูปแบบที่กำหนดเองของคุณอยู่ด้านบนสุดของรายการ เมื่อรูปแบบจะถูกจับคู่ WordPress จะหยุดมองผ่านรายการของเขียนกฎและใช้ค่าจับ regex ในสถานที่ของการอ้างอิง ( $matches[1]และ$matches[2]) index.phpในสตริงแบบสอบถามผ่านไป

การเพิ่มตัวแปรคิวรี่myrouteและmyargumentรายการที่อนุญาตทำให้ WordPress สนใจพวกเขามากกว่าที่จะละทิ้งมัน

วิธีอื่นในการ 'กำหนดเส้นทาง' เส้นทางที่กำหนดเองของคุณ

หากคุณต้องการหลีกเลี่ยงการใช้/api/เป็นคำนำหน้าคุณสามารถใช้ตัวแปร / ฟิลด์สตริงการสืบค้นแทน ที่จะทำอะไรเช่นนั้นคุณจะเปลี่ยน regex เพื่อสิ่งที่ต้องการ(.*?)/(.+?)\\?api=1แล้วเพิ่มapiเป็นพารามิเตอร์เพิ่มเติมเพื่อการโทรที่เกิดขึ้นในarray_push()my_insert_query_vars()

ที่จะเปลี่ยนเส้นทางที่กำหนดเองเพื่อที่จะก่อให้เกิดเวลาใดเป็นองค์ประกอบแรกของสตริงแบบสอบถามเช่นมันจะเรียกสำหรับapi=1http://example.com/anytext/anytext?api=1

ไม่สนใจการใช้คำว่า 'namespacing' - ใช้เพื่อความกะทัดรัด

หากคุณไม่มี 'namespace' ที่มีคำนำหน้าหรือคำต่อท้ายคุณจะได้รูปแบบ URI ที่ขัดแย้งกัน เนื่องจาก WordPress จะไม่มีวิธีแยกแยะรูปแบบที่กำหนดเองของคุณจากจุดประสงค์เดียวเพื่อเป็นโพสต์หรือเพจ WordPress จะรู้ได้อย่างไรว่านั่นmyrouteไม่ใช่ taxonomy, term หรือ parent page?

หวังว่านี่จะช่วยได้


1
หมายเหตุที่มีประโยชน์: กฎที่กำหนดmy_insert_rewrite_rulesตามคำจำกัดความตาม! เริ่มต้นด้วยกฎที่ยาวที่สุดก่อนจากนั้นทำงานให้ง่ายที่สุดมิฉะนั้น / api / myroute จะแทนที่ / api / myroute / myargument
emc

1
@npc เป็นจุดสำคัญที่ควรระวังเมื่อสร้างกฎการเขียนซ้ำที่กำหนดเองพวกเขาสามารถชนกันได้เช่นกัน ในตัวอย่างข้างต้นแม้ว่าจะไม่ใช่ปัญหาเพราะ / api / myroute จะไม่ใช่เส้นทางที่ถูกต้อง
eddiemoya

มีคนโหลดเทมเพลตที่กำหนดเองจากไดเรกทอรีปลั๊กอินของตนได้อย่างไรเมื่อใดก็ตามที่มีการร้องขอหน้าexample.org/api/myroute/myargument
แมตต์คีย์

1
นี่คือทางออกที่แท้จริงและสมบูรณ์โดย wordpress: codex.wordpress.org/Rewrite_API/add_rewrite_rule
Imran Zahoor

6

หากต้องการขยายเล็กน้อยเกี่ยวกับสิ่งที่ eddiemoya ทำอยู่เหนือ:

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

แม่แบบที่กำหนดเองอาจอยู่ที่ใดก็ได้ในกรณีของฉันมันถูกเก็บไว้ในไดเรกทอรีปลั๊กอิน

ฉันแค่อยากจะตรวจสอบว่ากฎการเขียนใหม่ที่จำเป็นต้องล้างออกในระหว่างการเปิดใช้งานปลั๊กอินหรือไม่ดังนั้นฉันจึงใส่ลงใน register_activation_hook

ดูตัวอย่างด้านล่างของสิ่งที่ฉันทำด้านล่าง:

ปรับปรุงง่ายขึ้นอยู่กับคำแนะนำจากไมโล

class Your_Class
{

    public function init()
    {
        add_filter( 'template_include', array( $this, 'include_template' ) );
        add_filter( 'init', array( $this, 'rewrite_rules' ) );
    }

    public function include_template( $template )
    {
        //try and get the query var we registered in our query_vars() function
        $account_page = get_query_var( 'account_page' );

        //if the query var has data, we must be on the right page, load our custom template
        if ( $account_page ) {
            return PATH_TO_PLUGIN_TEMPLATES_DIR . 'register.php';
        }

        return $template;
    }

    public function flush_rules()
    {
        $this->rewrite_rules();

        flush_rewrite_rules();
    }

    public function rewrite_rules()
    {
        add_rewrite_rule( 'account/(.+?)/?$', 'index.php?account_page=$matches[1]', 'top');
        add_rewrite_tag( '%account_page%', '([^&]+)' );
    }

}

add_action( 'plugins_loaded', array( new Your_Class, 'init' ) );

// One time activation functions
register_activation_hook( PATH_TO_PLUGIN_FILE, array( new Your_Class, 'flush_rules' ) );

1
คุณยังสามารถใช้add_rewrite_endpointซึ่งจะสร้างกฎสำหรับคุณและเพิ่ม var แบบสอบถามในครั้งเดียว หากคุณเพิ่มกฎการเขียนซ้ำของคุณเองฉันขอแนะนำให้ใช้add_rewrite_ruleฟังก์ชันแทนการกรอง rewrite_rules_array
มิโล

ขอบคุณ Milo ฉันอัปเดตรหัสเพื่อใช้ add_rewrite_rule แทนที่จะกรองอาเรย์เขียนใหม่ ฉันดูที่ add_rewrite_endpoint แต่ฉันคิดว่า add_rewrite_tag อาจเหมาะกับความต้องการของฉันมากกว่า ดูเหมือนว่า add_rewrite_endpoint มีประโยชน์เป็นส่วนใหญ่หากคุณต้องการเพิ่มอาร์กิวเมนต์พิเศษลงในการเขียน WP ที่มีอยู่ ถูกต้องฉันถ้าฉันผิดที่นี่
Matt Keys

1
ฉันชอบวิธีการเชิงวัตถุ นักพัฒนา WP จำนวนมากยังไม่รู้วิธีใช้ OOP ขอขอบคุณที่พยายามคืนความศรัทธาให้กับนักพัฒนา PHP ;)
Arvid
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.