General

NP_admin

2008年12月26日

Jeans自体のコード書きは少しお預けにして、Nucleus用のSkinnable Adminの作成を始めた。これを進めていく上で、お宝を発見したと言うか、頭の中がずいぶん整理されてきたと言うか、得るものがあったので、メモしておく。

ここで得られたことは、Jeansのスキン・テンプレートエンジンの構造に大きく影響するかもしれない。やはり、実際の用途に当てはめながらこういったエンジンを作っていくほうが、色々と見えてくるものなのだろうか。

NP_admin中でスキンをどのようにパースしたら良いかについて、ドラフト記事の一覧表示部分を例に上げてみる。

まず、NP_adminクラスのvar_draftlistメソッドは、スキンで<%admin(draftlist)%>と記述されたときに呼び出される。
function var_draftlist($template='templates/draftlist.inc'){
    global $member;
    $query =  'SELECT ititle, inumber, bshortname'
           . ' FROM ' . sql_table('item'). ', ' . sql_table('blog')
           . ' WHERE iauthor='.$member->getID().' and iblog=bnumber and idraft=1';
    $this->showUsingQuery($query,$template,_OVERVIEW_NODRAFTS);
}
ここは簡単な構造で、SQLクエリーの生成を行い、showUsingQueryメソッドを呼び出すだけ。

次に、showUsingQueryメソッドを見てみる。
var $rowdata=array();
function showUsingQuery($query,$template,$note=''){
    $template=$this->getTemplate($template);
    $res=sql_query($query);
    $amount=mysql_num_rows($res);
    if (0<$amount) {
        $this->parser->parse($template['head']);
        while($this->rowdata=mysql_fetch_assoc($res)){
            $this->parser->parse($template['body']);
        }
        $this->parser->parse($template['foot']);
    } else self::p($note);
    return $amount;
}
getTemplateメソッドが行っているのは、parsedinclude等と同じようにskins/admin/ディレクトリからincファイルを読み込み、ファイル内容をhead, body, footの3つに振り分けているだけ。$this->parserは、PARSERクラスのインスタンスで、スキンをパースするように準備してあるものだ。つまり、テンプレートの内容を、スキンとしてパースしている。

テンプレート変数をどのようにして処理するかは、次のメソッドに記述されている。
function var_fill($name,$mode='hsc'){
    $row=&$this->rowdata;
    if (!isset($row[$name])) return;
    switch($mode){
        case 'row':
            echo $row[$name];
            break;
        case 'strip_tags':
            self::p(strip_tags($row[$name]));
            break;
        case 'hsc':
        default:
            self::p($row[$name]);
    }
}
上記のvar_fillメソッドは、テンプレート中で<%admin(fill,xxxx)%>と記述したときに呼び出される、いわばスキン変数である。この中で利用している$this->rowdataは、もともとshowUsingQuery中で、mysql_fetch_assocの戻り値を代入してある変数だ。

こんな簡単な仕組みで、Nucleusのテンプレート様の仕組みが実現できてしまった。やはり、スキンとテンプレートは、同じものなのであろう。

ちなみに、draftlist用のテンプレートは、次のように記述している。
<!--head-->
<table>
<thead>
<tr><th><%text(_LISTS_BLOG)%></th><th><%text(_LISTS_TITLE)%></th><th colspan='2'><%text(_LISTS_ACTIONS)%></th></tr>
</thead>
<tbody>

<!--body-->
<tr>
<td><%admin(fill,bshortname)%></td>
<td><%admin(fill,ititle,strip_tags)%></td>
<td><a href='?action=itemedit&amp;itemid=<%admin(fill,inumber)%>'><%text(_LISTS_EDIT)%></a></td>
<td><a href='?action=itemdelete&amp;itemid=<%admin(fill,inumber)%>'><%text(_LISTS_DELETE)%></a></td>
</tr>

<!--foot-->
</tbody>
</table>

コメント

コメントはありません

コメント送信