PukiWikiでリンクおよびページ添付画像・PDFを別窓(target=”_blank”)で開く!

PukiWiki(というよりWiki全般)で致命的な問題なのが、「リンクを別窓で開く仕組みがない」だろうと思う。そもそもPukiWikiを含めWikiシステムが流行った2000年代前半のブラウザやネット環境を考えると、リンクを別窓でホイホイ開くようなサイトページは良しとされなかったし、パソコンの処理能力も今よりは貧弱なものだった。
PukiWikiの設計が古いままなのはたびたび私が一連の記事で指摘しており、だからこそ今までPukiWikiのコードに手を入れて「使える」ように改造して来ている。今回も同様にPukiWikiを「使える」ように改造するが、ついでにページに添付した画像やPDFファイルも別窓で開くようにする
前回の記事と同様にサブドメインを連番で用意してあるので、今回はmuseum-14サブドメインの内容をmuseum-15サブドメインにコピーし、検証しながら作業を進めた。メニューページが「MenuBar」ではなく「メニューバー」になっている(日本語ページ名でPukiWiki URL短縮ライブラリにより短縮される)ので要注意。

簡単にjQueryで実装する

リンクを別窓で開きたい場合を考えると、圧倒的に「外部サイト」のリンクの場合だろう。少なくとも、自ページ内のリンク(contentsプラグインで自動的に作成されるリンク等)を別窓で開きたいとは思わない。また、自サイト内のリンクを検討しても、別窓で開きたいケースがほとんどないことに気が付く。つまり、自サイト内のリンクはほぼ自分のWikiの別ページであり、そのリンクを別窓で開くよりも現在のウィンドウで開きたいケースが圧倒的だからだ。逆に、自サイト内のページのリンクで別窓で開きたいケースは、ページに添付した画像やPDFファイルに限定されそうだ。
リンクを別窓で開きたい要件を整理すると、

  1. 外部サイトのリンク
  2. ページに添付した画像ファイル(refプラグインで「nolink」を指定しない場合)
  3. ページに添付したPDFファイル

上記の場合にほぼ限られる。
であれば、jQueryで一律に別窓で開くように改造してやれば、PukiWikiで「リンクを別窓で開く仕組みがない」という問題は一気に解消されるし、既存のページを修正する必要もないから、改造して得られるメリットは非常に大きい( ̄ー ̄)ニヤリ
改造するコードの実装は「skin」フォルダのpukiwiki.skin.phpファイルになる。具体的にはpukiwiki.skin.phpの195行目付近(</head>タグのすぐ上辺り)に次のコードを追加する。

skin\pukiwiki.skin.php(追加)

<!-- リンクおよびページ添付画像・PDFを別窓で開く -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
    jQuery(/* document).ready(*/ function(){
        // 自サイト以外のリンクを別窓で開く
      jQuery('a[href^=http]')
      .not('[href*="' + location.hostname + '"]')
      .attr({target:"_blank"})
        .addClass("external-link");
        // ページ添付画像・PDFを別窓で開く
        jQuery('a[href$="jpg"],a[href$="jpeg"],a[href$="JPG"],a[href$="JPEG"],a[href$="png"],a[href$="PNG"],a[href$="pdf"],a[href$="PDF"]').click(function(){
            $(this).attr('target', '_blank');
        });
    });
</script>

<?php echo $head_tag ?>
</head>

簡単にコードを説明しよう。
自サイト以外のリンクを別窓で開く」部分は、<a>タグのリンクが自サイト(location.hostname)以外の場合に「target=”_blank”」属性を追加し、「external-link」クラス(後述)を追加する。これにより、リンクを別窓で開きたい要件の1.を満たせる。
ページ添付画像・PDFを別窓で開く」部分は、同じく<a>タグのリンクの末尾が画像(JPG(JPEG)もしくはPNG)か「PDF」の場合、クリックされたら「target=”_blank”」属性を追加する。ファイル名が小文字か大文字かを判別する必要があるし、

jQuery(‘a[href$=(.*?(jpg|jpeg|png|pdf)/i]’).click(function(){~処理~});

のように書ければキレイに記述が可能なのだが(それが出来ないので)、このようにズラズラ書き連ねるしか方法がない。フィルターをかましてやるんでも良いのだが、色々検証してみるとコレが一番処理速度が出る記述なので、イマイチ美しくないが仕方がない。ともあれ、これでリンクを別窓で開きたい要件の2.と3.を満たせる。
ファイルを修正し、「skin」フォルダにFTPして検証してみよう。改造したmuseum-15サブドメインでは「FrontPage」の劇場版「銀河鉄道999」パンフレット画像が別窓で開くだろう。

分かりにくいが、フッタ部のリンクに図の赤矢印部分の「外部リンク」を示す記号が追加されたのが分かるだろうか。これはリンクに「external-link」クラスを追加したので、PukiWiki標準CSSで定義されている「外部リンク」表現が追加されたからである。
前回までのmuseum-14サブドメインと比較して、どちらがサイト訪問者にとって使い勝手が良いかは、この記事の読者の判断にお任せする。

手動でリンクを別窓で開く「仕組み」を作る

jQueryで一律に自サイト以外のリンクや、自ページの画像やPDFファイルを別窓で開くようにしたので、PukiWikiの「リンクを別窓で開く仕組みがない」という問題は一気に解消されるが、「仕組みがない」部分が放置のままとなる。そんなにニーズがあるとは思えないが、例えば自サイト内のリンクを別窓で開きたい場合、現状では「仕組みがない」以上、どうにもならない。例えば、PukiWikiで標準的に用意している「プラグインマニュアル」(「PukiWiki/1.4/Manual/Plugin」ページ)を別窓で開きたいケースがあるだろう。本稿ではこうした場合を想定している。
そこで「リンクを別窓で開く仕組み」をどのようにするのか?だが、リンク方法に次の仕様を追加する。

通常リンク [[エイリアス>ページ名orURL]]
別窓リンク [[エイリアス>>ページ名orURL]]

別窓リンクは通常リンクに比べて「>」をひとつ多く記述するものとするが、これはアットウィキが採用している仕様で、個人的にはページを記述するにも分かりやすく、非常に良い解決方法だと思っている。
具体的に実装するには「lib」フォルダにあるmake_link.phpを改造する必要がある。「[[エイリアス>>ページ名]]」とする改造は「PukiWikiのクソ長いURLをURL短縮ライブラリを組み込んで解決する!」でも手を入れているが、具体的には808行目付近のコードを修正する。

lib\make_link.php(修正前)

        // コメントアウト
        // return $al_left . '<a ' . 'href="' . $script . '?' . $r_page . $anchor .
        return $al_left . '<a ' . 'href="' . $script . $r_page . $anchor .
            '"' . $title_attr_html . ' class="' .
            $attrs['class'] . '" data-mtime="' . $attrs['data_mtime'] .
            '">' . $s_alias . '</a>' . $al_right;

lib\make_link.php(修正後)

        // コメントアウト
        // return $al_left . '<a ' . 'href="' . $script . '?' . $r_page . $anchor .
        // 別窓で開くページを記述した場合(「エイリアス>>ページ名」)エイリアスに2つ目の「>」が含まれ「&gt;」となるため、デコードする
        $s_alias = htmlspecialchars_decode($s_alias);
        if (preg_match('/(.*)>$/', $s_alias, $match_array)) {
            // エイリアス末尾が「>」の場合は別窓リンクとして編集する
            return $al_left . '<a ' . 'href="' . $script . $r_page . $anchor .
                '"' . $title_attr_html . ' class="' .
                $attrs['class'] . '" data-mtime="' . $attrs['data_mtime'] .
                '" target="_blank" ' . '>' . $matche_array[1] . '</a>' . $al_right;
        } else {
            // それ以外は通常リンクとして編集する
            return $al_left . '<a ' . 'href="' . $script . $r_page . $anchor .
                '"' . $title_attr_html . ' class="' .
                $attrs['class'] . '" data-mtime="' . $attrs['data_mtime'] .
                '">' . $s_alias . '</a>' . $al_right;
        }

次に[[エイリアス>>URL]]の部分は、「class Link_url extends Link」クラスの「function toString()」関数部分を修正する。具体的には425行目付近のコードを修正する。

lib\make_link.php(修正前)

    function toString()
    {
        if (FALSE) {
            $rel = '';
        } else {
            $rel = ' rel="nofollow"';
        }
        return '<a href="' . $this->name . '"' . $rel . '>' . $this->alias . '</a>';
    }

lib\make_link.php(修正後)

    function toString()
    {
        if (FALSE) {
            $rel = '';
        } else {
            $rel = ' rel="nofollow"';
        }
        // 別窓で開くURLを直接記述した場合(「エイリアス>>URL」)にエイリアスに2つ目の「>」が含まれ「&gt;」となるため、デコードする
        $this->alias = htmlspecialchars_decode($this->alias);
        if (preg_match('/(.*)>$/', $this->alias, $matche_array)) {
            // エイリアス末尾が「>」の場合は別窓リンクとして編集する
            return '<a href="' . $this->name . '" target="_blank" ' . $rel . '>' . $matche_array[1] . '</a>';
        } else {
            // それ以外は通常リンクとして編集する
            return '<a href="' . $this->name . '"'                  . $rel . '>' . $this->alias . '</a>';
        }
    }

ファイルを修正し、「lib」フォルダにFTPして検証してみよう。

自サイトのページながら、「プラグインマニュアル」は別窓で開いて参照したいことがあると思うので、図の赤枠のように「リンクを別窓で開く仕組みテスト」のサンプルとして「FrontPage」に追加して記述してみた。記述方法として、ページ名を指定する場合とURLを直接指定(ページ名が長いのでURL短縮ライブラリで短縮したページ名になっているが)の2つのパターンで検証する。
直接ページ名を記述する場合でも、URLを記述する場合でも、別窓でリンクが開くことが確認出来る。ここまで改造するからこそ、そこで初めて「リンクを別窓で開く仕組みがないPukiWikiの仕様的な問題を解決出来た、と言えるだろう。
ただし、実装として「美しいか?」で言えば、そうとも限らない。設計が古いPukiWikiに対して、PHPをロクに知らない私が改造するのは、この程度が限界なのだ。

ここまでの改造の成果

ここまでの改造の成果であるPukiWikiはこちらなので、「実際どうなのか?」を確認したい人は参照して欲しい。

今回も前回と同様にゲストアカウントを用意したので、スパムや破壊行為は困るが(スパムフィルタspam_filter.phpは導入済みだが)、ユーザー名とパスワードは次の通りだ。

ユーザー名:guest
パスワード:guest

ファイルの添付やページの凍結・解除は行なえないが、ほぼ全てのPukiWikiの作業が可能なので、色々と試してみて欲しい。「案外PukiWikiって使えるな」と思っていただければ、私としても嬉しく思う。

おわりに

本稿では、PukiWikiの「リンクを別窓で開く仕組みがない」という、根本的な仕様の問題に斬り込んで解決してみた。本稿の冒頭に示した通り、大概の問題はjQueryでコードを書いてやれば解決するのだが、それだけだとWikiシステムとして「片手落ち」なのが理解されただろうと思う。そこで本稿では「仕組み」を提示し、PukiWikiの深いレベルで問題を解決してみたが、どうだろうか。
あくまでも私のスタンスとしては、「PukiWiki改造計画」と銘打っているように「改造」なので、実装は必ずしも美しくはない。本家PukiWikiの設計思想の古さと現在のウェブシステムに馴染まない現状を思い知って「根本的に」改良してくれることを望むが、多分それは無理だろう。だから私はこういった改造記事を書いていたりする。
私の望みはWikiシステムの普及であって、特にPukiWiki公式がどうの、ではない。使えるシステムをもっと「使える」システムにするために、この稚拙なブログ記事を書いているし、PukiWikiを運用する管理者に対して、本カテゴリー記事が少しでもお役に立てれば幸いだ。

 

 

この記事が気に入ったら
いいね ! をお願いします


ITで何かお手伝い出来ることはありませんか?

CTA-IMAGE

本サイトでは、外部サービスと連携して「ITの困った」を解決します!

PukiWikiカテゴリの最新記事