web-dev-qa-db-ja.com

base62でエンコードされた投稿IDを持つカスタムパーマリンク/ショートリンク

私の投稿リンクは/%post_id62%_%postname%/のように見せたいです。%post_id62%はbase62エンコーディングの投稿IDです(例: http://example.com/y9Rlf_test/ )と私のショートリンクは/%post_id62%のみで構成されます(例: http://example.com/y9Rlf )これは私がこれまでに持ってきたものです(私のfunctions.phpで)明らかにうまくいきません:

add_action( 'init', 'yoyo_init' );
function yoyo_init() {
  add_rewrite_tag( '%post_id62%', '([A-Za-z0-9]+)' );
}

add_action('generate_rewrite_rules','yoyo_generate_rewrite_rules');
function yoyo_generate_rewrite_rules($yoyo_rewrite) {
  global $wp_rewrite;
  $new_rules['/([0-9A-Za-z]+)/?$'] = 'index.php?p=' .
    base622dec($wp_rewrite->preg_index(1));  // DOESNT WORK OF COURSE (executed only once when rewrite_rules are generated)
  $wp_rewrite->rules = array_merge($new_rules, $wp_rewrite->rules);
}

add_filter( 'post_link', 'yoyo_post_link', 10, 2 );
function yoyo_post_link( $permalink, $post ) {
  if ( false !== strpos( $permalink, '%post_id62%' ) ) {
    $post_id62 = dec2base62( $post->ID );
    $permalink = str_replace( '%post_id62%', $post_id62, $permalink );
  }
  return $permalink;
}

add_filter('pre_get_shortlink', 'yoyo_custom_shortlink', 10, 4);
function yoyo_custom_shortlink($false, $post_id, $context, $allow_slugs) {
  global $wp_query;
  if($post_id or ($context == 'query' and $post_id = $wp_query->get_queried_object_id())) {
    return home_url('/' . dec2base62($post_id));
  }
  return false;
}

function dec2base62($number) {
  $digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';  $string = '';  while($number > 0) { $string = $digits[$number % 62] . $string;  $number = floor($number / 62); }
  return $string;
}
function base622dec($string) {
  $digits = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';  $number = 0;  while(strlen($string) and ($number *= 62 or strlen($string))) { $number += strpos($digits, $string[0]);  $string  = substr($string, 1); }
  return $number;
}

どのように問題に取り組むためのアイデアはありますか?同じタイトルの別の投稿が作成されたときに-N slug接尾辞を回避するためのボーナスポイント(リンク構造を "/%post_id62%_%postname%/"に設定するときに実際には回避されるかもしれません"/%post_id62%"であるべきだと思います; %postname%自動インクリメントをオフにしますか? )。ありがとうございます。

2
user6254

Base62でエンコードされたIDを10進数のIDに変換するとき、最後の手順で間違いをしただけです。書き換えルールはパターンであり、投稿ごとの実際のルールではないため、書き換えルールを変更してこれを行うべきではありません。

あなたが欲しいのは入ってくるURLを取り、WordPressに書き換えルールを使ってそれを解析させることですが、それがクエリエンジンに渡される前にpost_id62変数をチェックしそれに基づいて実際のp(post id)変数を設定します。これはrequestフィルタで行うことができ、これは WP::parse_request() に適用されます。

add_action( 'request', 'wpse22253_request' );
function wpse22253_request( $query_vars )
{
    if ( array_key_exists( 'post_id62', $query_vars ) ) {
        $query_vars['p'] = base622dec( $query_vars['post_id62'] );
    }
    return $query_vars;
}

しかし、これはpostname-N問題を解決することはできません。 WordPressは引き続きwp_unique_post_slugフィールドでpost_nameを呼び出し、post_namepost_id62部分を含みません(データベースは書き換え規則に依存しないため)。 Mikeが で彼の答え に対するコメントを追加したので、あなたはpost_id62フィールドにpost_name部分を含める方法を考え出すか、(そしてこれはより良い方法かもしれません)無視するべきですURLの%postname%部分で、末尾にpostname-with-stripped-number-suffix文字列を入力するだけです。

ショートリンクはページと同じフォーマット(任意の文字または数字)を持っているので、あなたもあなたのショートリンクで問題に遭遇するでしょう。 /banana/は、タイトルが "Banana"のページか、IDが34440682410の投稿へのショートリンクですか?これは、base-62エンコーディングのbananaですか?

2
Jan Fabry