Perlu bantuan dengan add_rewrite_rule

55

LARUTAN


Saya telah menggunakan Update 3 dan membuatnya berfungsi. Apa yang saya punya salah paham, adalah bahwa saya percaya bahwa aturan penulisan ulang akan berubah designers/?designer=some-designer&bid=9ke /designers/some-designer. Tapi tentu saja sebaliknya.


Saya telah melakukan beberapa penelitian, tetapi saya tidak begitu mengerti cara menggunakan add_rewrite_rule () .

Posting ini cukup dekat dengan apa yang saya butuhkan, tetapi apakah saya benar-benar membutuhkan kode sebanyak itu?

Tautan saya saat ini adalah ini:
http://www.norwegianfashion.no/designers/?designer=Batlak-og-Selvig&bid=9
Apa yang saya inginkan adalah ini
http://www.norwegianfashion.no/designers/Batlak-og-Selvig /

  1. Bagaimana saya menggunakan add_rewrite_rule()?
  2. Saya harus melewati ID desainer (tawaran). Bagaimana saya bisa melakukan itu ketika menggunakan aturan re.write tanpa itu ditampilkan di URL?

Perbarui 1

Saya menemukan ini yang sedikit lebih menjelaskan. Tapi itu tidak berfungsi:

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')

Perbarui 2

Inilah solusi lain yang pernah saya coba, yang disarankan Jan Fabry di utas lainnya. Saya meletakkan ini di functions.php saya, tetapi tidak berpengaruh.

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

Pembaruan 3
Saya menemukan beberapa contoh di sini juga. Tapi ini juga tidak berfungsi :(

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

Pembaruan 4 Saya juga mencoba solusi ini, tetapi masih belum berhasil.

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

}

Pembaruan 5
Tampaknya aturan penulisan ulang saya tidak ditambahkan. Menjalankan peraturan baru setelah mengikuti aturan baru:, print_r($wp_rewrite)tidak termasuk aturan penulisan ulang baru saya.

Pembaruan 6
Saya menguji solusi Jan. Tetapi URL tidak berubah :(

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

Saya akan sangat menghargai jika seseorang dapat membantu saya memecahkan masalah ini.

Steven
sumber
Ini terlihat sangat mirip dengan pertanyaan pertama yang Anda tanyakan di sini, dan untuk itu saya memberikan jawaban . Sudahkah situasi berubah sejak saat itu, jadi jawaban saya tidak valid lagi? Jika Anda tidak ingin ID perancang di URL Anda, Anda harus mengonversi sendiri "siput" ke ID, WordPress tidak dapat melakukan ini untuk Anda. Apakah desainer masih menjadi objek eksternal?
Jan Fabry
@ Jan Fabry Ya, saya menemukan bahwa setelah saya memposting ini (saya lupa). Sekarang saya mengerti saran Anda lebih baik. Lihat kode saya yang diperbarui di sini. Desainer saya masih entri dalam DB khusus. Apakah mungkin untuk menggunakan POST insteed dan GET untuk meneruskan bid?
Steven
Menggunakan permintaan POST tidak akan bekerja jika saya menyalin tautan dan mengirimkannya ke orang lain. Apakah ini masalah untuk membuat siput unik dan melakukan pencarian data dari sana?
Jan Fabry
@ Jan Fabry: Apa maksudmu slug? `Mengambil data Desainer jauh lebih mudah menggunakan biddaripadadesigner
Steven

Jawaban:

87

Beberapa latar belakang aturan penulisan ulang

Sistem WP Rewrite terlihat rumit, tetapi sebenarnya tidak terlalu sulit untuk memahami cara kerjanya. Ini digunakan untuk mem-parsing URL cantik ( /designers/) seolah-olah mereka tidak cantik ( /index.php?pagename=designers). Ide dasarnya adalah bahwa Anda memiliki daftar aturan penulisan ulang , ekspresi reguler yang dapat cocok dengan URL yang masuk, dan menulis ulang mereka ke dalam URL lain, sebagian besar dalam bentuk index.phpdengan beberapa variabel kueri. Variabel-variabel ini diatur ke bagian dari ekspresi reguler yang cocok dengan URL. Aturan dievaluasi dari atas ke bawah, jadi jika dua aturan mungkin cocok, yang pertama "menang".

Aturan penulisan ulang ini disimpan dalam database dengan menelepon flush_rewrite_rules(), tetapi karena membuat dan menulis aturan ini adalah operasi yang mahal, Anda tidak boleh melakukannya di setiap init. Sebaliknya, Anda hanya melakukannya saat Anda mengubah aturan: mungkin pada aktivasi plugin (menggunakan register_activation_hook()), atau secara manual dengan mengunjungi halaman pengaturan Permalinks ( karena sulit untuk melakukan ini secara otomatis pada aktivasi tema ). Jika Anda tidak menghapus aturan, panggilan add_rewrite_rule()tidak akan berpengaruh. Tidak ada masalah untuk memanggil add_rewrite_rule()setiap init, bahkan setelah Anda memerah aturan.

Ada banyak cara untuk menambahkan aturan penulisan ulang Anda, dan jika Anda hanya ingin menambahkan satu aturan, Anda dapat melakukannya dengan add_rewrite_rule(). Karena aturan untuk posting, halaman, taksonomi, ... hasilnya dalam beberapa aturan, mereka diciptakan dengan fungsi tingkat tinggi seperti add_rewrite_tag(), add_permastruct(), ... Tapi ini tidak diperlukan untuk kasus sederhana kita miliki di sini.

Ada juga beberapa filter, sehingga Anda juga dapat menambahkan aturan menggunakan generate_rewrite_rulesatau generate_rewrite_rules_arraykait. Ini memberi Anda kontrol yang sangat rinci atas aturan lengkap, tetapi sekali lagi, add_rewrite_rule()cukup jika Anda hanya ingin menambahkan satu aturan.

Saya membuat sebuah plugin kecil yang memungkinkan Anda untuk menganalisis aturan penulisan ulang saat ini , dan (tentu saja) saya sarankan Anda menggunakannya ketika Anda mencoba mengubah apa pun.

Dapatkan info ekstra dari URL

Mari kita membangun contoh yang Anda berikan. Anda memiliki merek desainer Batlak og Selvig, dengan nomor ID ( bid) 9. Anda tidak ingin ID ini ada di URL, tetapi hanya namanya saja. Kami menyebutnya versi ramah-URL dari nama (tanpa spasi atau karakter khusus) yang slug : Batlak-og-Selvig.

Secara umum, URL harus berisi semua info untuk mengidentifikasi konten yang ingin Anda tampilkan di halaman. Anda dapat menggunakan cookie atau permintaan POST untuk menyimpan ID desainer yang sebenarnya ingin Anda tampilkan, tetapi ini akan rusak jika ada yang membagikan tautan, dengan mengirimkannya melalui surat, Facebook, Twitter, atau hanya membacanya dengan keras melalui telepon. Jika Anda tidak ingin menggunakan ID numerik di URL Anda, Anda harus memastikan siput itu unik: maka Anda pertama-tama melakukan pencarian ID berdasarkan siput, dan lanjutkan seperti yang Anda lakukan sebelumnya.

Jadi apa yang telah kita pelajari sekarang adalah bahwa kita ingin menambahkan aturan penulisan ulang untuk pola " /designers/diikuti oleh apa pun hingga yang berikutnya /" , dan simpan "apa saja" dalam designer_slugvariabel kueri. Dalam kasus Anda, saya yakin Anda juga ingin menggunakan halaman dengan siput designerssebagai konten halaman umum, jadi kami juga akan memberi tahu 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' );
}

Satu-satunya yang tersisa untuk dilakukan adalah memberi tahu WordPress untuk juga menyimpan designer_slugvariabel kueri, sehingga Anda dapat mengaksesnya nanti. WordPress menggunakan daftar putih variabel kueri yang dibolehkan, untuk mencegah orang memodifikasi setiap parameter kueri posting melalui URL. Segala sesuatu yang tidak ada dalam daftar ini diabaikan. Cukup kaitkan ke query_varskait dan tambahkan variabel tambahan Anda:

add_filter( 'query_vars', 'wpa5413_query_vars' );
function wpa5413_query_vars( $query_vars )
{
    $query_vars[] = 'designer_slug';
    return $query_vars;
}

Seperti yang Anda lihat, jawaban ini pada dasarnya sama dengan jawaban saya sebelumnya , tetapi tanpa aturan pembilasan dalam kode (sehingga Anda dapat menggunakannya di tema Anda, functions.phpbukan plugin), dan dengan sedikit lebih banyak kepastian dan penjelasan karena saya belajar banyak tentang menulis ulang aturan sejak (dan karena) menjawab pertanyaan pertama Anda.

Diskusi ruang obrolan

Kami menyelesaikan masalah terakhir untuk pertanyaan ini di ruang obrolan . Pada akhirnya, Steven menggunakan generate_rewrite_rulespengait, karena add_rewrite_rule()fungsi itu sepertinya tidak berhasil untuknya.

Jan Fabry
sumber
2
@ Seven: pagenameadalah siput dari halaman WordPress yang ingin Anda tampilkan (rekam dalam basis data). Halaman ini kemudian dapat menunjukkan bahwa ia ingin menggunakan designers.phpfile templat di area admin WP. Jadi Anda menunjuk ke halaman siput, bukan nama templat, karena templat yang sama dapat digunakan untuk beberapa halaman: dalam hal ini WordPress tidak tahu apa yang ingin Anda lakukan.
Jan Fabry
1
@ Seven: Saya pikir Anda terlalu rumit cara Anda mengatur kait. Hapus add_rewrite_rules()fungsi dan hubungi add_filter()/add_action()langsung. Jika ini ada dalam file tema, hapus flush_rewrite_rules()dan kunjungi halaman pengaturan permalinks untuk wpse5413_init()menghapus aturan (atau menambahkannya dan menghapusnya nanti). Dan plugin saya menampilkan aturan penulisan ulang saat ini. Ingat bahwa ini hanya mengubah cara URL masuk ditangani, bukan bagaimana kode Anda akan menulis URL dalam HTML.
Jan Fabry
1
@ Sebelas: Saya tidak berpikir Anda bahkan harus menekan tombol simpan, hanya membuka halaman permalinks juga akan menyiramnya. Dan lagi, ini hanya akan menambah kemampuan WordPress untuk menerima /designers/designer-slug/URL, Anda perlu mengubah tempat Anda menulis URL ini dalam HTML Anda sendiri. Uji dengan pergi ke /designers/Batlak-og-Selvig/diri Anda sendiri, jika itu berhasil, temukan semua tempat yang menghasilkan URL ini dan ubah untuk menggunakan struktur baru.
Jan Fabry
1
Ah, sekarang saya pikir saya mulai mengerti. Saya pikir aturan penulisan ulang akan mengubah cara URL itu dibubarkan di bidang URL browser. Tapi apa artinya adalah bahwa saya harus benar-benar menampilkan URL www.mysite.com/batlat-og-selvig/9dan kemudian ini "diterjemahkan" ke/?designer=Batlak-og-Selvig&bid=9
Steven
1
@ Sebelas: Ya, memang: aturan penulisan ulang menangani tautan yang masuk, dan (hanya dalam beberapa kasus tertentu) tidak memengaruhi tautan yang dibuat dalam kode Anda.
Jan Fabry