Rute plugin khusus di Wordpress

12

Oke jadi pertanyaan saya cukup sederhana. Saya perlu menerapkan beberapa aturan perutean kustom untuk plugin saya. Rute-rute itu hanya akan mengambil satu argumen (jadi tidak ada yang rumit) dan akan terlihat seperti: http://www.example.org/myroute/myargument

Dan idealnya, ini akan memanggil kelas khusus, dan menampilkan templat khusus (yang dapat langsung mengakses kelas).

Apa pendekatan terbaik untuk ini? Bersulang

Fran
sumber

Jawaban:

15

Anda perlu melakukan tiga hal penting:

  1. Buat aturan penulisan ulang khusus untuk mengubah bagian URI menjadi nilai yang diteruskan index.php.
  2. Tambahkan myroutedan myargumentke daftar putih variabel kueri WordPress, sehingga WordPress tidak hanya mengabaikannya ketika mereka muncul dalam string kueri.
  3. Siram aturan penulisan ulang.

Pertama, saya akan merekomendasikan bahwa alih-alih http://www.example.org/myroute/myargument, Anda memilih semacam awalan atau akhiran khusus untuk menyatakan kapan URI harus dianggap sebagai salah satu 'rute' khusus ini. Demi contoh ini, saya telah memilih awalan api, sehingga akan menjadi http://www.example.org/api/myroute/myargument. Saya memilih apikarena ketika saya melakukan sesuatu RESTful, seperti apa yang tampaknya sedang Anda kerjakan, itu untuk API.

Kode

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

Kerusakan Cepat

Semuanya lurus ke depan. Pola regex ditambahkan ke daftar semua aturan penulisan ulang di WordPress, dan pola kustom Anda ada di bagian atas daftar. Ketika polanya cocok, WordPress akan berhenti mencari melalui daftar aturan penulisan ulang, dan menggunakan nilai yang diambil regex sebagai pengganti referensi ( $matches[1]dan $matches[2]) dalam string kueri yang diteruskan index.php.

Menambahkan variabel permintaan myroutedan myargumentke daftar putih hanya membuat WordPress memperhatikan mereka daripada membuang mereka.

Cara alternatif 'namespacing' rute kustom Anda

Jika Anda ingin menghindari penggunaan /api/sebagai awalan, Anda bisa menggunakan variabel string / bidang sebagai gantinya. Untuk melakukan sesuatu seperti itu, Anda akan mengubah regex menjadi sesuatu seperti (.*?)/(.+?)\\?api=1dan kemudian menambahkan apisebagai parameter tambahan untuk array_push()panggilan yang dibuat my_insert_query_vars().

Itu akan mengubah rute kustom sehingga memicu kapan saja api=1adalah elemen pertama dari string kueri, misalnya itu akan memicu http://example.com/anytext/anytext?api=1.

Abaikan penggunaan istilah 'namespacing' - cukup gunakan untuk singkatnya.

Jika Anda tidak 'namespace' dengan awalan atau akhiran, Anda akan berakhir dengan bertabrakan pola URI. Ini karena WordPress tidak akan memiliki cara untuk membedakan pola kustom Anda dari yang dimaksudkan sebagai posting atau halaman. Bagaimana WordPress tahu itu myroutebukan taksonomi, istilah, atau halaman induk?

Semoga ini membantu.

eddiemoya
sumber
1
Catatan praktis: aturan didefinisikan menurut my_insert_rewrite_rulesurutan definisi! Mulailah dengan aturan terpanjang pertama kemudian bekerja ke yang paling sederhana, jika tidak / api / myroute akan menimpa / api / myroute / myargument.
emc
1
@npc Itulah poin penting yang harus diperhatikan ketika membuat aturan penulisan ulang kustom, mereka juga dapat bertabrakan dengan cara itu. Pada contoh di atas, itu bukan masalah karena / api / myroute tidak akan menjadi jalur yang valid.
eddiemoya
Bagaimana seseorang dapat memuat templat khusus dari direktori plugin mereka setiap kali halaman example.org/api/myroute/myargument diminta?
Matt Keys
1
Berikut adalah solusi aktual dan lengkap oleh wordpress: codex.wordpress.org/Rewrite_API/add_rewrite_rule
Imran Zahoor
6

Untuk sedikit memperluas apa yang dilakukan eddiemoya di atas:

Seperti poster asli dari pertanyaan ini, saya ingin membuat penulisan ulang kustom, dan juga memberikan template khusus untuk halaman penulisan ulang itu. Kode dari edditmoya membuat saya mulai di arah yang benar, dan saya menambahkan fungsi tambahan untuk melayani template kustom saya ketika halaman diakses.

Template khusus dapat ditemukan di mana saja, dalam kasus saya, template tersebut disimpan di direktori plugin.

Saya juga hanya ingin memeriksa apakah aturan penulisan ulang perlu dihapus selama aktivasi plugin, jadi saya meletakkannya di register_activation_hook

Lihat di bawah untuk contoh lengkap dari apa yang saya lakukan:

DIPERBARUI disederhanakan berdasarkan saran dari milo

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' ) );
Matt Keys
sumber
1
Anda juga bisa menggunakan add_rewrite_endpoint, yang akan menghasilkan aturan untuk Anda dan menambahkan kueri var dalam sekali jalan. juga jika Anda menambahkan aturan penulisan ulang Anda sendiri, saya sarankan add_rewrite_rulefungsi bukan penyaringan rewrite_rules_array.
Milo
Terima kasih Milo, saya memperbarui kode untuk menggunakan add_rewrite_rule alih-alih memfilter array penulisan ulang. Saya melihat add_rewrite_endpoint tapi saya pikir add_rewrite_tag mungkin lebih cocok untuk kebutuhan saya. Sepertinya add_rewrite_endpoint sebagian besar berguna jika Anda ingin menambahkan argumen tambahan ke penulisan ulang WP yang ada. Perbaiki saya jika saya salah di sini.
Matt Keys
1
Saya suka pendekatan berorientasi objek. Terlalu banyak pengembang WP yang tidak tahu cara menggunakan OOP. Terima kasih telah mencoba mengembalikan kepercayaan saya ke pengembang PHP. ;)
Arvid