こんばんは。昨日に引き続き。
ppBlogでは、ブログのエントリーとは別に自由にページを作成することが出来るので、いわばCMSGのような使い方も可能です。このページ作成機能ですが、以前から改善したいなぁと思っていたことがありました。それは、作成したページの中に記述したPHPがスクリプトとしてちゃんと動作するということです。
現状では、例えば、以下のような記述をしてページを作成してもそのまま書いた文字列が出力されてしまいます。
<?php echo "Bonjour à tous!"; // やぁ、みんな! ?>
上の記述は、以下のようになる。
echo "Bonjour à tous!"; // やぁ、みんな! ?>
ページ作成画面でPHPスクリプトを自由に記述できれば、PHPに慣れた方なら色んなことが出来るようになります。なので、そうできるようにしてみましょう。ppBlogでは、作ったページは、単なるテキストファイルとして、pagesディレクトリに保存され、それをmodules/pages.inc.phpを介して、HTMLとして出力されます。なので、pages.inc.phpモジュールをいじります。具体的には、このファイルの中で定義されているoutputPage()関数に手を加えれば良いです。
流れとしては、テキストファイル中に書かれてあるPHPタグ<?php・・・?>があれば、その中身をeval関数で評価、その結果を保持しておく。eval関数はその場ですぐに評価されるため、それがHTMLとして出力されるのを防ぐために、出力のバッファリングを有効にしておく、ということです。簡単に実装出来そうですね。以下のような記述でいけるかと思います。
if(preg_match_all('{<¥?php(.+?)¥?>}s', $page, $mt)){ // PHPタグを含むなら $BUFF = array(); // 評価した結果を保存する入れ物を用意しておく ob_start(); // 出力のバッファリングを有効に $length = count($mt[0]); for($i = 0; $i < $length; $i++){ $php = $mt[1][$i]; // 実行させたいPHPスクリプトの中身 if(eval($php) === FALSE){ // PHPのパースエラーなら $BUFF[] = "ppBlog warning: parse error!"; } else $BUFF[] = ob_get_contents(); // きちんと評価されれば、その結果を取得 } ob_end_clean(); }
ポイントは、ob_start関数とeval関数の組み合わせです。その際に、eval関数の返り値は、パースエラーならFALSEを返すけど、きちんと評価されれば、ob_get_contents関数で補足可能ということですかね。
実際には、これ以外の微調整が必要ですが、それも反映させたPHP記述が有効になるpages.inc.phpを添付しておきます。既存のやつを上書きして問題ないです。
と、これを書いている途中で思いついたのですが、ppBlogでは、[style]...[/style]の形式で、その記事だけに適用させるスタイルシートを指定出来ますが、これもページ作成画面でも指定出来るようにしました。このサイトで「人気記事ランキング」というページを作りましたが、そのソースは以下のようになってます。これをそのままページ作成画面のテキストエリアに貼り付ければOKです。
<h2>人気記事ランキング</h2> <?php echo '<ol>'.NL; echo showRanking(); // utils.phpで定義している独自の関数も使える! echo '</ol>'.NL; ?> [style] h2 { color: slateblue; margin: 1em auto 2em auto; } ol li span { background: pink; font: bold 12px Arial; color: navy; padding: 2px 3px; } ol { list-style-type: decimal; width: 480px; margin: auto; } [/style]
コメントにもありますが、utils.phpで定義している関数も使えるので色々と応用が利きそうです。ちなみに、上のスタイルシートの指定で、実際には以下のように、div.page-boxが自動的に付加された形で出力されます。
<style type="text/css"> div.page-box h2 { color: slateblue; margin: 1em auto 2em auto; } div.page-box ol li span { background: pink; font: bold 12px Arial; color: navy; padding: 2px 3px; } div.page-box ol { list-style-type: decimal; width: 480px; margin: auto; } </style>
スタイルシート指定も有効するには、utils.phpもちょいと書き換えが必要です。これも添付しておきます。最近のバージョン(1.7-1.8)であれば、既存のを上書きしても特に動作に問題はないかと思います(いつでも元に戻せるように元のutils.phpのバックアップはとっておいて下さい)。
1. にこにこ — 2009/08/17@20:09:48