先日、数独のソースコードをダウンロードできるようにしたが、せっかくなのでダウンロード数をカウントできるプラグインを導入してみた。実現可能なプラグインはいくつかあるようだったが、その中で便利そうに思えた下記のプラグインを採用させてもらった。

bovendeur.org:『Download Counter for Wordpress』

導入・設定

上記URLを辿ったページに「Downloading」という項があり、文中の「here」からダウンロードできる。最初、「here」にリンクが張られていることに気づかなくて、しばらく探してしまった。

ダウンロードしたファイルを解凍すると、「wp-downloadcounter」というフォルダが作られるので、フォルダごと「wp-content/plugins」ディレクトリにアップロードし、管理画面から有効にすればひとまず導入は完了となる。

導入完了後、管理画面から「管理」→「Downloads」と辿ると、下記のような画面が表示されるので、初期設定を行う。
DownloadCounter
「Use pretty links」のチェックを外し、「Save changes」ボタンで保存する。
「Use pretty links」の詳細については後述する「きれいなURLを使う」の項を参照してもらいたい。チェックするとURLの生成方法が変わるのだが、若干手間が必要になる。まずは、プラグインの動作を簡単に確認しておきたいのでチェックを外しておく。

最後に、ファイルをアップロードするディレクトリを用意する。既にそういった用途のディレクトリがある場合はそのまま使用していいし、新たにお好みのディレクトリを作成してもいい。私は「files」というディレクトリにいろいろなファイルをアップロードしているので、そこを使用することにした。

ダウンロード数をカウントさせてみる

ダウンロードさせるファイルを上記で作成した(作成されていた)ディレクトリにアップロードする。
アップロード完了後、管理画面から「管理」→「Downloads」を辿り、「Add Download」ボタンを押してファイルの登録画面に移動する。
DownloadCounterのファイル登録
「Name」には任意の名前を、「URL」にはアップロードしたファイルのURLを入力し、「Save」ボタンで保存する。

画面下に登録したファイルの情報が表示され、ダウンロード数などが参照できるようになっている。
「With counter」に張られたリンクからダウンロードするとダウンロード数がカウントされ、「Without counter」に張られたリンクではプラグインを通さないためカウントされない。よって、前者のURLを使用すれば良い。

きれいなURLを使う(Use pretty links)

通常、「http://(サイトのURL)/?download=sudoku」といったURLが生成されるが、見るからにCGI経由なので見栄えが良くない(と考える人がいるかもしれない)。そこで、「Use pretty links」と「Download slug」を使用する。

管理画面の英文を訳すと大体下記のようになる。

Use pretty links

ここをチェックすると、ダウンロードスラッグ(以下のDownload slugのこと)を使用したURLが生成されます。チェックしなかった場合、「/?download=<名称>」のようなURLが生成されます。

Download slug

この値を変更した場合、新しいダウンロードスラッグを反映させるために管理画面の「パーマリンク設定」からパーマリンク構造を更新する必要があります。あなたがパーマリンク構造を更新するまで、訪問者は「404 NOT FOUND」ページを受け取ることになります。

「Use pretty links」をチェックし、「Download slug」に任意のスラッグを入力する。ダウンロードスラッグは既存カテゴリーのスラッグと被らない方が無難だろう。ここでは「download」とする。

設定を保存すると、登録したファイルの「With counter」のURLが変更される。

http://spring.sakurasaita.net/?download=sudoku

http://spring.sakurasaita.net/download/sudoku

プラグインで生成されるURLがダウンロードスラッグを使用したものに置き換わるだけということに注意しなければいけない。そのままでは、このURLにアクセスしても404 NOT FOUNDとなり、使用できない。解説に従えばパーマリンク構造を変更するらしいのだが、単にパーマリンク構造を変更しただけでダウンロードできるとも思えない。そこで、「.htaccess」ファイルを編集することにした。(もし、本来はその他の手順で行うべきなのだとしたら、ぜひお教えいただきたい)

「.htaccess」ファイルを作成し、下記のように編集する。

<IfModule mod_rewrite.c>
    # 置換を有効にする
    RewriteEngine On
    # URL先頭から置換を開始する
    RewriteBase /
    # 先頭が「/download/」で始まる場合のみ置換する
    RewriteCond %{REQUEST_URI} ^/download/
    # 「download/文字列」を「?download=文字列」に置換する
    RewriteRule ^download/(.+) ?download=$1 [L]
</IfModule>

これでdownload以下へのアクセスは「?download=<名称>」にリダイレクトされるため、正常にアクセス出来るようになる。
もし、パーマリンク構造を変更していて、既に「.htaccess」ファイルが存在する場合は下記のように赤字を追記すれば良い。

<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_URI} ^/download/
    RewriteRule ^download/(.+) ?download=$1 [L]
    # DownloadCounterで使用するURLは置換対象から除く
    RewriteCond %{REQUEST_URI} !^/download/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule . /index.php [L]
</IfModule>

これで、エントリーへのリクエストとダウンロードへのリクエストの両方を扱えるようになる。

動作確認時の注意点

「Use pretty links」の確認を行う場合、一度ブラウザのキャッシュをクリアした方がいい。
いろいろなパターンの設定を試していた時、正常にダウンロードできるはずなのにダウンロードできない、ダウンロードできないはずなのに正常にダウンロードできるといったことがあったからだ。念のため、ブラウザのリクエストヘッダを確認してみたところ、期待しない動作の場合はそもそもリクエストヘッダが送信されていなかった。そこでキャッシュをクリアしたところ、期待通りの動作を行うようになった。

まとめ

以上でDownloadCounterの設定は完了となる。
個人的には、「Use pretty links」は使用しないで「?download=<名称>」とする方がダウンロードされるんだなということがはっきりするので好みかもしれない。

ファイルがダウンロードされたということは、少なくともエントリーに興味をもってくれた人がいたということになるので、単にアクセス数が伸びるよりもうれしい。今後もDonwloadCounterを活用させてもらおうと思う。

.htaccessの説明

上記で作成した「.htaccess」ファイルだが、Apacheにあまり馴染みの無い方は内容を把握しきれないかもしれない。把握していない設定を使用するのも気持ち悪いと思うので、簡単に説明しようと思う。本項はDownloadCounterの設定には直接関係ないので読み飛ばしても何ら問題無い。

<IfModule mod_rewrite.c>
    ~
</IfModule>

これは「mod_rewrite」モジュールがロードされている場合のみ、タグに囲われたディレクティブを読み込ませるために記述する。実際の置換には関わらない部分であり、保険のために記述する。

RewriteEngine On

置換エンジンを有効にする。もし、置換をやめたい場合、「On」→「Off」とすれば、せっかく書いた置換ルールを削除しないで置換をやめることができる。

RewriteBase /

URLのどの部分から置換を開始するのかを指定する。
RewriteBaseディレクティブを省略すると、ローカルのファイルパスが使用されてしまう。「/index.php」がローカルのパスでは「/var/www/html/index.php」となっている場合、後者が使用されることになる。これは大抵期待外れなので、常にきっちりと指定した方が良い。

RewriteCond %{REQUEST_URI} ^/download/

RewriteCondディレクティブは置換対象の条件を指定する。
%{REQUEST_URI}は、リクエストヘッダのリソース部分を扱える。リクエストヘッダが「GET /perl/28.html HTTP/1.1」だとすると、「/perl/28.html」となる。
上記例ではリソースの先頭が「/download/」で始まるURLを置換対象としてくれ、という意味になる。

RewriteRule ^download/(.+) ?download=$1 [L]

RewriteRuleディレクティブは、RewriteCondディレクティブの条件に合致したURLを実際に置換する。
URLの先頭「download/(何かの文字列)」を「?donwload=(何かの文字列)」に置換している。「$1」とは、置換元文字列の括弧で囲まれた部分を使用するよという意味になる。括弧が複数個ある場合は、「$1」「$2」「$3」と数字を増やしていけばいい。
末尾に記載されている「[L]」はLastのことで、このRewriteRuleディレクティブで置換されたURLは置換を終了するという意味だ。これ以降にもRewriteRuleディレクティブが指定されている場合に期待しない置換が行われることを防いでくれる。

RewriteCond %{REQUEST_URI} !^/download/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]

1行目は、リソースの先頭が「/download/」で始まらないURLを置換対象としてくれ、という意味になる。記述しなくても、問題ないので単なる保険だ。

2~3行目で使用されている%{REQUEST_FILENAME}はファイルのローカルパスを扱える。「/index.php」がローカルのパスでは「var/www/html/index.php」となっている場合、後者が使用される。「-f」「-d」という記述は、「ファイルだったら置換対象」「ディレクトリだったら置換対象」の意味だ。しかし、先頭に「!」が付いているため真偽が逆になり、「ファイルでなかったら」「ディレクトリでなかったら」となる。
つまり、2~3行目はローカルのパスでチェックして、ファイルでもディレクトリでもない(要は存在しない)ファイルへのリクエストだったら置換対象としてくれ、という意味になる。

4行目は、リソースをindex.phpに置換している。パーマリンク構造の細かな解析はindex.php内で行われているのだろう。末尾の「[L]」は、先の説明と同様となる。

もっと細かく知りたい場合は下記のリンクを参照して欲しい。
Apache module mod_rewrite

2008年02月02日(土) 2:51 [WordPress

WordPress標準のエディタが非常に使いづらい。デフォルトではビジュアルエディタが有効になっており、投稿の編集時はまずビジュアルエディタに投稿が読み込まれるのだが、私はもっぱらコードエディタで編集を行っている。そのためすぐにコードエディタへ切り替えるのだが、一度ビジュアルエディタで読み込んでしまうとソースが意図しない形に変換されてしまう。これでは編集を行うたびに細かい修正が必要になってしまい、非常に不便だ。

また、投稿を表示する際に改行コードをbrタグに変換するなどの処理が行われているのだが、意図しない部分にpタグが挿入されてしまうことが多い。基本的には重宝する機能なわけだが、codeタグ内にpタグを埋め込まれてしまうとcodeタグのCSSが効かなくなってしまい困ってしまう(何かうまいCSSの書き方があるのかもしれないが、見つけることが出来なかった)。
それだけではなく、「<p></code></p>」のように不可思議なネストが生成されてしまう場合もある。

機械的に文章を解析しタグを挿入しているわけだから、不都合が生じるのは仕方のないことだが、如何せん不便と思うパターンが多すぎる。そこで、WordPressの癖を覚えつつ、やむを得ない部分はソースの改造を行い、エディタと上手な関係を築けるように工夫していこうと思う。

ビジュアルエディタを無効にする

冒頭に書いた通り、ビジュアルエディタはソースを変換してしまうので無効に設定する。

管理画面の「ユーザー」タブからビジュアルエディタを無効にしたいユーザーを選び、編集画面の「ビジュアルエディタを使用する」のチェックを外し、「ユーザーを更新」を押してやれば無効になる。これで、編集画面からはビジュアルエディタのタブが無くなり、最初からコードエディタでソースが読み込まれるようになる。

codeタグ内のpタグを除去する

投稿表示の際に挿入されるpタグをどこまで制御するか迷ったが、回避策を見つけることが出来なかった「codeタグに挿入されるpタグ」に対してのみ対策を取ることにした。これには、WordPressのソースを一部変更する必要がある。

wp-includesのformatting.phpを編集する。「function wpautop」で検索するとpタグやbrタグの挿入処理を行っている関数が見つかるので、関数末尾の「return $pee」の前に下記の2行を挿入する。

$pee = preg_replace('| {4}|', str_repeat('&nbsp;',4), $pee);
$pee = str_replace('\\', '\\\\', $pee);
$pee = preg_replace(
        '|<code.*?>.*?</code>|se'
        , "str_replace(array('<p>', '</p>'), array('', '<br /><br />'), '$0')"
        , $pee);
$pee = StripSlashes($pee);

1行目では、半角スペースが4つ続いた場合に「&nbsp;」に変換し、ブラウザ上でも半角スペースを複数個表示できるようにしている。CSSで「white-space: pre;」とすれば、スペースのままでも期待通りに表示されるのだが、枠から溢れて表示されてしまうのに抵抗があったため、使用していない。

2行目では、投稿内の「\」を「\\」にエスケープしている。理由は4行目に関わってくる。

3行目では、pタグを削除し、段落を設けるためにクロージング側のタグをbrタグ2つに変換している。今回のコードではここが主の部分となる。

4行目では、StripSlashesにより投稿内のエスケープを除去している。理由はpreg_replaceをeオプションで実行した場合に、文字列内のクォートがエスケープされてしまうからだ。例えば、<span class="comment">などとしている場合に、「"」が「\"」となってしまい、HTMLタグが正常に認識されなくなってしまう。その対策としてStripSlashesを使用するのだが、この関数は全てのエスケープ文字を除去してしまうため、「\n」などの「\」までが削除されてしまう。そこで2行目の処理が必要になってくるわけだ。

PHP未経験者とはいえ、後手に回る対応が多く、とてもスマートとは言えない手順となってしまったが、実利は得られるので良しとする。

ちなみに、pタグ・brタグの挿入を完全に停止してしまうには、wp-includesのdefault-filters.phpを下記のように変更すればいい。

add_filter('the_content', 'wpautop');
add_filter('the_excerpt', 'wpautop');
    ↓
// pタグ・brタグの挿入を停止するためコメントアウト
// add_filter('the_content', 'wpautop');
// add_filter('the_excerpt', 'wpautop');

これでそもそも変換処理が行われなくなる。

codeタグ前後のpタグを調整する

上述の手順でcodeタグ内のpタグは除去されるようになったが、codeタグ外のpタグが期待しない形で挿入されてしまう。具体的には、下記のようになる。

<p>下記がコードです。<br />
<code>ここがコードです</code><br />
上記がコードです。</p>

本来は下記のように挿入して欲しい。

<p>下記がコードです。</p>
<code>ここがコードです</code>
<p>上記がコードです。</p>

前者の例になるのは、codeタグがインライン要素だからだ。「display:block」として無理やりブロック要素としているために、期待と相容れなくなってしまっている。そこで、codeタグがブロック要素として扱われるように変更する。

wp-includesのformatting.phpを編集する。pタグの除去と同様に「function wpautop」で検索した関数を変更する。

$allblocks = '(?:table|thead|tfoot|caption|colgroup|tbody~省略~)';
    ↓
// 先頭にcodeを追記する
$allblocks = '(?:code|table|thead|tfoot|caption|colgroup|tbody~省略~)';

これで、codeタグがブロック要素として扱われるようになるので、期待した通りにpタグが挿入されるようになる。当然ながら、pタグ除去の手順でpタグ・brタグの挿入を完全に停止してしまっていた場合はこの対応を行う意味が無い。

クォートの変換を無効にする

WordPressでは「'」や「"」のようなクォートなどが「&#****;」といったコードに変換されてしまうようだ。これではコードを記述する際に意図しない形になってしまい困ってしまう。コピー&ペーストも出来ない。

また、私の場合は下記のような問題が発生していた。二度登場する「'A'」に注目して欲しい。

if(my $query = $res->search($host, 'A')){
    # <span class="comment">を利用したあとのクォートが変換される。
    print map {$_->address."\n"} grep($_->type eq ‘A’, $query->answer);
}

この中途半端な状態について原因の特定は行っていないのだが、実はcodeタグ内のクォートは変換されないように作られているのではないかと予想している。しかし、<span>といった別のタグが呼び出されることで、それ以降がcodeタグ内ではないと判断され変換されてしまっているのではないか。もちろん想像に過ぎないのだが。

原因は何にせよ、クォートも入力した通りに表示して欲しいので変換機能を停止させてしまう。これにはプラグインを使用する。

Multimeter:『Kill WPTexturize』

このプラグインをwp-content\pluginsにアップロードし、管理画面から有効にするだけで全投稿のクォートが元のままで表示されるようになる。

また、この問題の解決には以下のサイトを参考にさせてもらった。

BirDesign:『クォーテーションを変換しないようにする』

まとめ

以上の作業を行うことで、WordPressでの編集作業がずいぶんと気楽に行えるようになった。

後は挿入されるpタグ・brタグのため、改行の位置にほんの少し気を遣っていくだけだ。

2008年01月30日(水) 0:16 [WordPress

いざブログを初めてみると、コンテンツの作成はだいぶ時間がかかってしまうし、小ネタもなかなか出てこない。このまま投稿無しに過ぎていくのも時間がもったいないので、WordPressの導入話を少し書いてみようと思う。(そもそも、そういうのが小ネタなのか?)

公開前から現在に至るまで、テーマをいじってみたり、未経験のPHPをちょっとだけ(本当にちょっとだけ)触ってみたりを繰り返しているのだけど、今日はプラグインというものを導入してみた。プラグインとは、名前の通りWordPressの機能をあれこれ拡張できちゃったりする便利な代物で、豊富なプラグインの存在がWordPressの魅力の一つとなっている(らしい)。しかし、英語サイトを見て回るのはやや疲れるので、下記のエントリを参考にさせてもらった。

Standing Tall:『WordPressプラグイン一覧』

大量のプラグインがジャンル別に(しかも簡潔に分かりやすく!)紹介されており、非常に参考になった。おかげ様で下記のプラグインを見つけ出し、導入することが出来た。

Fuzzy Recent Posts
最近の投稿を表示できる。対象を「投稿のみ」、「ページのみ」、「両方」で指定可能。
Fuzzy Recent Updates
最近の更新を表示できる。対象を「投稿のみ」、「ページのみ」、「両方」で指定可能。
Post Updated
投稿・ページの更新日を表示することができる。
Subscribe me
サイドバーにフィードを表示することができる。

WordPressのプラグイン導入手順も非常に簡単で、プラグインの「*****.php」ファイルを「wp-content/plugins」にアップロードし、管理画面の「プラグイン」タブから有効にするだけ。以前、MovableTypeにプラグインを導入したときは、(知識不足が大いに手助けし)非常に手間取った経験があるため、たったこれだけで幸せになれるものかと感心した。

現在、サイドバーに表示されている「最近の投稿」、「最近の更新」、「フィード」や、コンテンツに表示されている更新日などは上記プラグインのおかげとなる。

Recent Posts/Recent Updatesの改造

「Fuzzy Recent Posts」「Fuzzy Recent Updates」をサイドバーに追加するとレイアウトが崩れてしまう問題が起きた。各プラグインが出力する<DIV>タグでネストがおかしくなってしまうことが原因のようだったので、この部分を修正することにした。PHPは分からないけれど、この程度の変更ならばどうにでもなる。

$o .= $params['before_widget']
   . '<div class="tile sem_recent">';

$o .= $params['before_widget'];
$o .= '<div class="tile_body">';

*削除*
$o .= '</div>'
   . '</div>'
   . $params['after_widget'];

$o .= $params['after_widget'];

本来ならばよりスマートな解決方法があるのだろうけど、問題も解決したことだし、良しとしておく。それにしても、本当にプラグインは便利なものなので、お遊び系も含めまたいろいろと探してみようと思う。

Copyright 2008 As You Like It All rights reserved.
Powered by Wordpress, Base template by WEB MAGIC, Photo by Encyclorecorder