Nucleusのスキン変数<%prevlink%>、<%nextlink%>の挙動を変えてみる
ブログツールのNucleusCMSでは、各アイテム(ブログ記事)の表示内容をスキンやテンプレートで柔軟に調整できる。
そして、スキンの中では<%prevlink%>と<%nextlink%>という変数が、前の記事へのリンクと次の記事へのリンクに対応する。また、前の記事と次の記事のタイトルを取得する変数<%prevlinktitle%>、<%nextlinktitle%>も用意されているので、<a>タグを使えば、前の記事のタイトルを表示して前の記事のリンクにする(次の記事も同様)とすることが可能だ。
しかし、いろいろ使っているうちに問題点が生じてきた。記事の日時をまったく同じに設定すると、同一日時の記事が前のアイテムや次のリンクと認識されないのだ。これは、ブログとして使っている分にはほとんど問題ないだろうけれど、日時を順番を置き換えるのに使っていると、かなり面倒なことになる。
そして、スキンの中では<%prevlink%>と<%nextlink%>という変数が、前の記事へのリンクと次の記事へのリンクに対応する。また、前の記事と次の記事のタイトルを取得する変数<%prevlinktitle%>、<%nextlinktitle%>も用意されているので、<a>タグを使えば、前の記事のタイトルを表示して前の記事のリンクにする(次の記事も同様)とすることが可能だ。
しかし、いろいろ使っているうちに問題点が生じてきた。記事の日時をまったく同じに設定すると、同一日時の記事が前のアイテムや次のリンクと認識されないのだ。これは、ブログとして使っている分にはほとんど問題ないだろうけれど、日時を順番を置き換えるのに使っていると、かなり面倒なことになる。
そこで、もう言わなくてもおわかりだろうけれど、同一日時のアイテム(ブログ記事)があった場合、<%prevlink%>や<%nextlink%>にうまく反映させることを考えてみた。
私はNucleusのプログラム構造をよく把握していないが、とりあえずnucleus/libs/あたりを総当たり(笑)で調べてみたところ、ACTIONS.php(ACTION.phpではない!どうしてこういう紛らわしい名前をつけるのか不明)に、それらしい記述があることを発見。しかし、実際の動作は$itemidnextなどの変数に任せて、このファイルでは実質的な処理はしてなさそう。
そこでもう一度総当たり(笑)してみたところ、globalfunctions.phpというファイルで具体的にMySQLのクエリーを発行しているらしい。そこで、それらしい部分を修正。
842行目あたり
(修正前)
(修正後)
同じタイムスタンプの記事があれば、その中でitemidのより小さい(or大きい)記事を探す、それで結果が得られなければ、もう一度今度はタイムスタンプが前の(or後の)記事を探すという従来のクエリーを発行する、という形を取っている。
MySQLのクエリー文なんてほとんどいじったことなくて、リファレンス片手に慣れないことするから最初エラーが出て「やっぱダメなのか」と思ったら、論理演算子のandが抜けていただけだった。英語みたいに、A B and Cではダメで、A and B and Cと書くのね・・・
ひとつのクエリーでなんとかなりそうだけど、そこまで知識がないので、わかる方いたら教えてください。
私はNucleusのプログラム構造をよく把握していないが、とりあえずnucleus/libs/あたりを総当たり(笑)で調べてみたところ、ACTIONS.php(ACTION.phpではない!どうしてこういう紛らわしい名前をつけるのか不明)に、それらしい記述があることを発見。しかし、実際の動作は$itemidnextなどの変数に任せて、このファイルでは実質的な処理はしてなさそう。
そこでもう一度総当たり(笑)してみたところ、globalfunctions.phpというファイルで具体的にMySQLのクエリーを発行しているらしい。そこで、それらしい部分を修正。
842行目あたり
(修正前)
// get previous itemid and title
$query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime<' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidprev = $obj->inumber;
$itemtitleprev = $obj->ititle;
}
// get next itemid and title
$query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate($b->getCorrectTime()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidnext = $obj->inumber;
$itemtitlenext = $obj->ititle;
}
(修正後)
// get previous itemid and title
$query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE inumber<' . $itemid . ' and itime=' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidprev = $obj->inumber;
$itemtitleprev = $obj->ititle;
} else {
$query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime<' . mysqldate($timestamp) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime DESC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidprev = $obj->inumber;
$itemtitleprev = $obj->ititle;
}
}
// get next itemid and title
$query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE inumber>' . $itemid . ' and itime=' . mysqldate($timestamp) . ' and itime <= ' . mysqldate($b->getCorrectTime()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidnext = $obj->inumber;
$itemtitlenext = $obj->ititle;
} else {
$query = 'SELECT inumber, ititle FROM ' . sql_table('item') . ' WHERE itime>' . mysqldate($timestamp) . ' and itime <= ' . mysqldate($b->getCorrectTime()) . ' and idraft=0 and iblog=' . $blogid . $catextra . ' ORDER BY itime ASC LIMIT 1';
$res = sql_query($query);
$obj = mysql_fetch_object($res);
if ($obj) {
$itemidnext = $obj->inumber;
$itemtitlenext = $obj->ititle;
}
}
同じタイムスタンプの記事があれば、その中でitemidのより小さい(or大きい)記事を探す、それで結果が得られなければ、もう一度今度はタイムスタンプが前の(or後の)記事を探すという従来のクエリーを発行する、という形を取っている。
MySQLのクエリー文なんてほとんどいじったことなくて、リファレンス片手に慣れないことするから最初エラーが出て「やっぱダメなのか」と思ったら、論理演算子のandが抜けていただけだった。英語みたいに、A B and Cではダメで、A and B and Cと書くのね・・・
ひとつのクエリーでなんとかなりそうだけど、そこまで知識がないので、わかる方いたら教えてください。
