トップ/pukiwiki1.5/redirect

pukiwiki1.5/redirect の変更点


#author("2026-08-06T23:14:07+09:00","default:nemusg.pad","nemusg.pad")
#author("2026-08-06T23:16:32+09:00","default:nemusg.pad","nemusg.pad")
* Pukiwiki内でリダイレクトしたい [#m66b4cc9]

#contents

** 経緯 [#zd53fcb2]

- Pukiwikiのページ名に自由に大文字を使ってしまっていたが、冷静になると全て小文字統一したほうが良かった。

> 大文字と小文字を混ぜてURLを設定することはできますが、ユーザーが手入力するとき大文字があると間違えやすくなります。 大文字と小文字が違うだけでもWEBサイトは開かないため、大文字と小文字を混ぜたURLはユーザビリティの高いWEBサイトであるとはいえません。
[[東京SEOメーカー:https://www.switchitmaker2.com/web-production/capital-small-letter/]]

** 標準機能で実現 [#b090546b]

- 1.5.2からはリダイレクト機能が実装されていた。ありがたい。 [[PageRedirection:https://pukiwiki.sourceforge.io/?PukiWiki/PageRedirection]]

`pukiwiki.ini.php` を編集する

#code_x{{
// Page redirect rules
$page_redirect_rules = array(
	'#^Twitch/Yomiage#' => 'twitch/yomiage',
	//'#^FromProject($|(/(.+)$))#' => 'ToProject$1',
	//'#^FromProject($|(/(.+)$))#' => function($matches) { return 'ToProject' . $matches[1]; },
);
}}

少なくとも[[TwitterでURL呟いた箇所:https://twitter.com/search?q=note.nemusg.com&src=typed_query&f=top]]はリダイレクトしないと...

ちなみにこのリダイレクト設定を行っても include には対応していない

 #include(Parts/ThanksTerms,notitle)

** 設定を [[InterRedirect]] にまとめて楽に追加できるようにする [#r265c261]
** 設定を [[InterRedirect]] にまとめて追加できるようにする [#r265c261]

InterRedirectページに設定をまとめて、`pukiwiki.ini.php` を更新しなくてもリダイレクト設定ができるようになります。

`pukiwiki.ini.php` の Page redirect rules 部分 を編集します。

#code_x{{
/////////////////////////////////////////////////
// Page redirect rules loaded from InterRedirect

$page_redirect_rules = array();

/**
 * InterRedirectページからサイト内リダイレクト設定を読み込む
 *
 * 書式:
 *   -旧ページ => 新ページ
 *
 * 配下のページもまとめて転送:
 *   -旧カテゴリ/* => 新カテゴリ/*
 *
 * 外部URLは指定不可。
 */
function load_interredirect_rules($config_page = 'InterRedirect')
{
    $rules = array();

    /*
     * PukiWikiのページ保存ファイル名を取得
     *
     * 通常はencode()を使用する。
     * 万一この時点でencode()が未定義なら、
     * UTF-8版PukiWiki用として16進数化する。
     */
    if (function_exists('encode')) {
        $encoded_page = encode($config_page);
    } else {
        $encoded_page = strtoupper(bin2hex($config_page));
    }

    $filename = DATA_DIR . $encoded_page . '.txt';

    if (!is_file($filename) || !is_readable($filename)) {
        return $rules;
    }

    $lines = file($filename, FILE_IGNORE_NEW_LINES);

    if ($lines === false) {
        return $rules;
    }

    foreach ($lines as $line) {
        $line = trim($line);

        if ($line === '') {
            continue;
        }

        // PukiWikiのコメント、見出し、プラグイン行を無視
        if (
            strpos($line, '//') === 0 ||
            strpos($line, '*') === 0 ||
            strpos($line, '#') === 0
        ) {
            continue;
        }

        // リスト記号を除去
        $line = preg_replace('/^[\-\+]+\s*/u', '', $line);

        // 「旧ページ => 新ページ」に分割
        $parts = preg_split('/\s*=>\s*/u', $line, 2);

        if (count($parts) !== 2) {
            continue;
        }

        $from = trim($parts[0]);
        $to   = trim($parts[1]);

        if ($from === '' || $to === '') {
            continue;
        }

        /*
         * 外部URLを拒否
         *
         * 例:
         * https://example.com/
         * mailto:test@example.com
         * //example.com/
         */
        if (
            preg_match('/^[a-z][a-z0-9+\-.]*:/i', $to) ||
            strpos($to, '//') === 0
        ) {
            continue;
        }

        /*
         * 単純な自己リダイレクトを拒否
         *
         * PageA => PageA
         */
        if ($from === $to) {
            continue;
        }

        /*
         * 配下ページをまとめて転送
         *
         * 例:
         * elec2/* => electrical/*
         *
         * elec2/gakka
         * ↓
         * electrical/gakka
         */
        if (
            substr($from, -2) === '/*' &&
            substr($to, -2) === '/*'
        ) {
            $from_base = rtrim(substr($from, 0, -2), '/');
            $to_base   = rtrim(substr($to, 0, -2), '/');

            if ($from_base === '' || $to_base === '') {
                continue;
            }

            if ($from_base === $to_base) {
                continue;
            }

            $pattern = '#^' . preg_quote($from_base, '#') . '(/.*)?$#u';

            /*
             * クロージャーを使うことで、転送先ページ名に
             * $ や \ が含まれても置換文字として誤解されにくくする。
             */
            $rules[$pattern] = function ($matches) use ($to_base) {
                return $to_base .
                    (isset($matches[1]) ? $matches[1] : '');
            };

            continue;
        }

        /*
         * 片方だけ「/*」の場合は書式ミスとして無視
         */
        if (
            substr($from, -2) === '/*' ||
            substr($to, -2) === '/*'
        ) {
            continue;
        }

        // 通常ルールはページ名の完全一致
        $pattern = '#^' . preg_quote($from, '#') . '$#u';

        $rules[$pattern] = $to;
    }

    return $rules;
}

$page_redirect_rules = load_interredirect_rules('InterRedirect');
}}


#include(parts/feedback,notitle)