MEMPERBARUI
Sejak menulis inti WordPress ini telah menambahkan 'do_parse_request'
pengait yang memungkinkan perutean URL ditangani secara elegan dan tanpa perlu memperpanjang WP
kelas. Saya membahas topik ini secara mendalam dalam ceramah Atlanta WordCamp 2014 saya yang berjudul " Hardcore URL Routing " ; slide tersedia di tautan.
JAWABAN ASLI
Desain URL telah menjadi penting selama lebih dari satu dekade; Saya bahkan menulis blog tentang itu beberapa tahun yang lalu. Dan meskipun WordPress adalah jumlah perangkat lunak yang brilian, sayangnya sistem penulisan ulang URL-nya hanya kekurangan otak (IMHO, tentu saja. :) Bagaimanapun, senang melihat orang-orang peduli dengan desain URL!
Jawaban yang akan saya berikan adalah plugin yang saya panggil WP_Extended
yang merupakan bukti konsep untuk proposal ini pada Trac (Perhatikan bahwa proposal dimulai sebagai satu hal dan berkembang menjadi yang lain, jadi Anda harus membaca semuanya untuk melihat di mana itu menuju.)
Pada dasarnya idenya adalah untuk mensubkelas WP
kelas, mengganti parse_request()
metode, dan kemudian menetapkan $wp
variabel global dengan turunan dari subkelas. Kemudian di dalam diri parse_request()
Anda sebenarnya memeriksa jalan demi segmen alih-alih menggunakan daftar ekspresi reguler yang harus cocok dengan URL secara keseluruhan.
Jadi untuk menyatakannya secara eksplisit, teknik ini menyisipkan logika di depan parse_request()
yang memeriksa kecocokan URL-ke-RegEx dan sebagai gantinya pertama-tama mencari kecocokan istilah taksonomi, tetapi teknik ini HANYA menggantikan parse_request()
dan membiarkan seluruh sisa sistem perutean URL WordPress utuh termasuk dan terutama penggunaan $query_vars
variabel.
Untuk kasus penggunaan Anda, implementasi ini hanya membandingkan segmen jalur URL dengan istilah taksonomi karena hanya itu yang Anda butuhkan. Implementasi ini memeriksa persyaratan taksonomi yang menghormati hubungan istilah orangtua-anak dan ketika menemukan kecocokan, ia menetapkan jalur URL (dikurangi garis miring utama dan garis belakang) ke $wp->query_vars['category_name']
, $wp->query_vars['tag']
atau $wp->query_vars['taxonomy']
& & $wp->query_vars['term']
serta mem-bypass parse_request()
metode WP
kelas.
Di sisi lain jika jalur URL tidak cocok dengan istilah dari taksonomi yang telah Anda tetapkan itu mendelegasikan logika routing URL ke sistem penulisan ulang WordPress dengan memanggil parse_request()
metodeWP
kelas.
Untuk menggunakan WP_Extended
case-use Anda, Anda harus memanggil register_url_route()
fungsi dari dalam functions.php
file tema Anda seperti:
add_action('init','init_forum_url_route');
function init_forum_url_route() {
register_url_route(array('taxonomy'=>'forum'));
}
Apa yang ada di sini adalah kode sumber untuk plugin:
<?php
/*
Filename: wp-extended.php
Plugin Name: WP Extended for Taxonomy URL Routes
Author: Mike Schinkel
*/
function register_url_route($args=array()) {
if (isset($args['taxonomy']))
WP_Extended::register_taxonomy_url($args['taxonomy']);
}
class WP_Extended extends WP {
static $taxonomies = array();
static function on_load() {
add_action('setup_theme',array(__CLASS__,'setup_theme'));
}
static function register_taxonomy_url($taxonomy) {
self::$taxonomies[$taxonomy] = get_taxonomy($taxonomy);
}
static function setup_theme() { // Setup theme is 1st code run after WP is created.
global $wp;
$wp = new WP_Extended(); // Replace the global $wp
}
function parse_request($extra_query_vars = '') {
$path = $_SERVER['REQUEST_URI'];
$domain = str_replace('.','\.',$_SERVER['SERVER_NAME']);
//$root_path = preg_replace("#^https?://{$domain}(/.*)$#",'$1',WP_SITEURL);
$root_path = $_SERVER['HTTP_HOST'];
if (substr($path,0,strlen($root_path))==$root_path)
$path = substr($path,strlen($root_path));
list($path) = explode('?',$path);
$path_segments = explode('/',trim($path,'/'));
$taxonomy_term = array();
$parent_id = 0;
foreach(self::$taxonomies as $taxonomy_slug => $taxonomy) {
$terms = get_terms($taxonomy_slug);
foreach($path_segments as $segment_index => $path_segment) {
foreach($terms as $term_index => $term) {
if ($term->slug==$path_segments[$segment_index]) {
if ($term->parent!=$parent_id) { // Make sure we test parents
$taxonomy_term = array();
} else {
$parent_id = $term->term_id; // Capture parent ID for verification
$taxonomy_term[] = $term->slug; // Collect slug as path segment
unset($terms[$term_index]); // No need to scan it again
}
break;
}
}
}
if (count($taxonomy_term))
break;
}
if (count($taxonomy_term)) {
$path = implode('/',$taxonomy_term);
switch ($taxonomy_slug) {
case 'category':
$this->query_vars['category_name'] = $path;
break;
case 'post_tag':
$this->query_vars['tag'] = $path;
break;
default:
$this->query_vars['taxonomy'] = $taxonomy_slug;
$this->query_vars['term'] = $path;
break;
}
} else {
parent::parse_request($extra_query_vars); // Delegate to WP class
}
}
}
WP_Extended::on_load();
PS CAVEAT # 1
Meskipun untuk situs tertentu saya pikir teknik ini berfungsi dengan baik tetapi teknik ini TIDAK PERNAH digunakan untuk plugin yang akan didistribusikan di WordPress.org untuk digunakan orang lain . Jika itu adalah inti dari paket perangkat lunak berbasis WordPress maka itu mungkin tidak apa-apa. Kalau tidak, teknik ini harus dibatasi untuk meningkatkan perutean URL untuk situs tertentu .
Mengapa? Karena hanya satu plugin yang dapat menggunakan teknik ini . Jika dua plugin mencoba menggunakannya, mereka akan saling bertentangan.
Selain itu, strategi ini dapat diperluas untuk secara umum menangani hampir semua pola penggunaan yang mungkin diperlukan dan itulah yang ingin saya terapkan segera setelah saya menemukan waktu luang atau klien yang dapat mensponsori waktu yang diperlukan untuk membangun implementasi sepenuhnya generik.
CAVEAT # 2
Saya menulis ini untuk mengesampingkan parse_request()
yang merupakan fungsi yang sangat besar, dan sangat mungkin bahwa saya melewatkan satu atau dua properti dari $wp
objek global yang seharusnya saya atur .. Jadi jika ada sesuatu yang tidak beres, beri tahu saya dan saya akan senang untuk riset dan revisi jawabannya jika perlu.
Bagaimanapun...
'slug' => 'forums'
kosong hanya dengan menghapus semuanya sekaligus'rewrite' => array('with_front' => false, 'hierarchical' => true)
? Saya pikir itu telah berhasil di masa lalu bagi saya. Pastikan juga Anda membersihkan permalinks.