更新
このWordPressコアの記述以来'do_parse_request'
、WP
クラスを拡張することなくURLルーティングをエレガントに処理できるようにするフックが追加されました。「ハードコアURLルーティング」と題された2014年のアトランタのWordCamp講演で、このトピックについて詳しく説明しました。スライドはリンクから入手できます。
元の回答
URLデザインは、10年以上にわたって重要でした。私もそれについてのブログを書いて、数年前。そして、WordPressは合計で素晴らしいソフトウェアですが、 残念ながら URL書き換えシステムは脳死に至っていません(もちろん、IMHO::)とにかく、URLデザインを気にかけてくれている人を見てうれしいです!
私が提供しようとしている答えは、Trac上のこの提案WP_Extended
の概念実証である私が呼び出すプラグインです(提案はあるものとして始まり、別のものに進化したので、どこを見るために全体を読む必要があることに注意してください向かった。)
基本的には、WP
クラスをサブクラス化し、parse_request()
メソッドをオーバーライドしてから、グローバル$wp
変数にサブクラスのインスタンスを割り当てるという考え方です。次に、URL全体に一致する必要がある正規表現のリストを使用する代わりにparse_request()
、実際にパスセグメントごとにパスを検査します。
だから、状態にそれの前に明示的に、この技術のインサートロジックparse_request()
たURLツー正規表現マッチをチェックし、タクソノミータームの試合のために代わりに最初に見えるが、それだけ置き換えparse_request()
を含むと葉WordPressのURLルーティングシステムの全体の残りの部分はそのままと特に$query_vars
変数の使用。
ユースケースでは、この実装では必要なのはURLパスセグメントと分類用語のみを比較するだけです。この実装は、親子用語の関係を尊重する分類用語を検査し、一致を見つけると、URLパス(先頭と末尾のスラッシュを除く)を$wp->query_vars['category_name']
、$wp->query_vars['tag']
または$wp->query_vars['taxonomy']
&に割り当て、クラスのメソッドを$wp->query_vars['term']
バイパスします。parse_request()
WP
一方、指定した分類法の用語とURLパスが一致しない場合parse_request()
、WP
クラスのメソッドを呼び出すことにより、URLルーティングロジックをWordPress書き換えシステムに委任します。
ユースWP_Extended
ケースに使用するには、次のようにregister_url_route()
テーマのfunctions.php
ファイル内から関数を呼び出す必要があります。
add_action('init','init_forum_url_route');
function init_forum_url_route() {
register_url_route(array('taxonomy'=>'forum'));
}
プラグインのソースコードは次のとおりです。
<?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警告#1
特定のサイトではこの手法は素晴らしいと思いますが、WordPress.orgで他のユーザーが使用できるようにプラグインを配布するためにこの手法を使用しないでください。WordPressベースのソフトウェアパッケージの中核であれば、それで問題ないかもしれません。それ以外の場合、この手法は特定のサイトの URLルーティングの改善に限定する必要があります。
どうして?そのため一つだけのプラグインは、このテクニックを使用することができます。2つのプラグインが使用しようとすると、互いに競合します。
余談として、この戦略を拡張して、必要となる可能性のある実質的にすべてのユースケースパターンを一般的に処理することができます。完全に汎用的な実装を構築します。
警告#2
parse_request()
非常に大きな関数であるオーバーライドのためにこれを書き$wp
ました。設定する必要があるグローバルオブジェクトのプロパティまたは2つを見逃した可能性が非常に高くなります。調査し、必要に応じて回答を修正します。
とにかく...
'slug' => 'forums'
空白のままにして、完全に削除してそのままにしてみました'rewrite' => array('with_front' => false, 'hierarchical' => true)
か?それは私にとって過去にうまくいったと思います。また、パーマリンクを必ずフラッシュしてください。