nazolabo

フリーランスのWebエンジニアが近況や思ったことを発信しています。

GenericView

Djangoにもある機能らしい。CRUDを実現する構造。Railsで言うところのscaffoldの骨組みだけみたいな。(多分)
今まではcontribute.generic.GenericViewだったけど、1.1.0からはgeneric.Viewsになっているので注意。(ただし互換モードでは大丈夫です)
まずlist(項目の全件表示)。bbsというテーブルの内容を表示するとして、エントリーポイントは

<?php
require_once("./__init__.php");
Rhaco::import("generic.Views");
Rhaco::importLibrary("data.Bbs");
$generic	= new Views(Bbs::connection());
$parser		= $generic->read(new Bbs());
$parser->write();

こんな感じにして、resources/templates/genericにbbs_list.html(bbsはテーブル名)というファイルを作る。中身は、

<html>
<head>
  <title>list</title>
</head>
<body>

<table>
  <tr>
    <th>id</th>
    <th>name</th>
    <th>comment</th>
  </tr>
  <rt:loop param="object_list" var="object">
  <tr>
    <td>{$object.id}</td>
    <td>{$object.name}</td>
    <td>{$object.comment}</td>
  </tr>
  </rt:loop>
</table>

{$pager.output()}
<rt:if param="{$pager.isPrev()}">
<a href="{$rhaco.self()}?page={$pager.prevOffset}">前の{$pager.limit}件</a>
</rt:if>
<rt:if param="{$pager.isNext()}">
<a href="{$rhaco.self()}?page={$pager.nextOffset}">次の{$pager.limit}件</a>
</rt:if>

</body>
</html>

こんな感じ。$generic->readが、Bbsクラスの内容を元にhtmlParserを構築してくれるというもの。
(テーブルクラスのカラム名と値を配列で返すような仕組みがあると便利かも?例えば

<table>
  <tr>
  <rt:loop param="object_list" key="column_name">
    <th>{$column_name}</th>
  </rt:loop>
  </tr>
  <rt:loop param="object_list" var="object">
  <tr>
    <rt:loop param="object" var="value">
    <td>{$value}</td>
    </rt:loop>
  </tr>
  </rt:loop>
</table>

みたいに書けるようになると便利な気がする)

generic.Urls

いわゆるURL Dispatcher?
簡単に説明すると、(rhacoのWikiのソースから借用)

Rhaco::import("generic.Urls");
$parser = Urls::parser(array(
				"^$"=>array("integral/index.html",null,"IsinViews","index"),
				"^wiki/new[/]*$"=>array("integral/newwiki.html",null,"IsinViews","create"),
				"^wiki/([w]+)/edit[/]*$"=>array("integral/updatewiki.html",null,"IsinViews","update"),
				"^wiki/([w]+)$"=>array("integral/detailwiki.html",null,"IsinViews","detail"),
				"^wiki[/]*$"=>array("integral/wiki.html",null,"IsinViews","search"),
				"^ticket/([d]+)$"=>array("integral/ticket.html",null,null),
				"^ticket[/]*$"=>array("integral/ticket.html",null,null),
));

で、表示するテンプレートをURLのパターンで分岐させることができる。
この後は、通常のHtmlParserと同様にsetVariableとかして、最後に引数無しでwrite()すれば出力される。
引数のキーの部分がURLの正規表現で、値の配列は、「テンプレートファイル名, 変数, クラス名(rhacoの書式)(省略するとgeneric.ViewsMapper), メソッド名, 引数」で、
クラス名->メソッド名(引数)を呼んで(このメソッドの戻り値はTagParser(あるいは派生クラスのTemplateParserやHtmlParser)であること)、戻り値のTagParserに変数とテンプレートファイル名をセットして出力する、という内容。
GenericViewを使うなら、

$parser = Urls::parser(array(
				"^list[/]*$"=>array("generic/bbs_list.html",null,"generic.Views","read",new Bbs()),
				(略)
$parser->write();

みたいな感じで、

$generic	= new Views(Bbs::connection());
$parser		= $generic->read(new Bbs());
$parser->write();

とほぼ同等の動作をする。

余談

generic/Urls.phpの44行目くらいの

foreach(get_class_methods($object) as $methodName){
	if(Variable::iequal($methodName,$method)){
		$parser = $object->$method(Variable::toArray($matchs,1),Variable::toArray($args));
		break;
	}
}

if (method_exists($object, $method)) {
	$parser = $object->$method(Variable::toArray($matchs,1),Variable::toArray($args));
}

じゃ駄目なのかな。(未検証)