読者です 読者をやめる 読者になる 読者になる

デザイナーでも作れるスマートWebアプリ その2

Smartyでスマートプログラミング〜
デザイナーでも作れるスマートWebアプリ - maru.cc@はてな」の続きだよ


前回のはどうだったかな?
なんかね、トリッキーとかフリーダムとか言われちゃったよ。
ちゃんとテンプレートにしか書いてないのにね。


ロジックとデザイン(html)が分離していないのが原因らしいよ。
あれ? でもテンプレートエンジン使えば分離出来るんだよね。
じゃぁ、テンプレートエンジン使ってみようかな。


何を使うかだけど、Flexyとかいいらしいよ。
http://pear.php.net/manual/ja/package.html.html-template-flexy.intro.php

HTML_Template_Flexy は、HTML_Template_Xipe をシンプルにするところから始められました。 しかし、Flexy の長期的な目標は、PHP ネイティブでコンパイルを行うタイプのテンプレートに対する 汎用的な基礎 API を作り上げることにあります。

なんか、すべてのテンプレートエンジンはFlexyに通ずる。とか言ってるみたいだよね。

さっそく掲示板を改造してみる

前回の掲示板をテンプレートエンジンFlexyを使って書き直してみようね。
DBは前回と同じものを使うよ。

create table bbs (id int auto_increment,name blob,message blob,ip varchar(15),posttime timestamp,primary key(id));


あとね、DBへの接続情報が各ファイルの中に何度も書くのは大変だよね。
だから、一箇所にまとめようね。ついでに、MySQL以外にも対応できるようにライブラリとかおしゃれなものを使ってみようね。
今回は、PEAR_DBとか使ってみるよ。
え?古いって? だってEthnaで使ってて慣れてるんだもん。大目に見てよ。

■1.ディレクトリの設置
├app
├cache
├configs
├htdocs
├libs
│├HTML
││└Template <追加
│└Smarty
├templates <追加
└templates_c

libs/HTML/Templateの下にFlexyのファイルを置いてね。
もちろん、pearコマンドを使ってサーバにインストールさせてもいいよ。
あとは、テンプレートファイルを置くディレクトリの作成だよ。


それと、PEAR関連と、PEAR_DB関連だね。
こっちもpearコマンド使って入れてもいいよ。
PEARとかPEAR_DBは、サーバに入っていない場合には、libsの下に置いてね。
今回はせっかくだから同梱してみるね。

■2.index.phpファイルの設置

前回のままだと、FlexyPEAR_DBを使うようになってないので、index.phpをちょっと修正しないとだめなんだ。
これはプログラマの人に頼むか、次のソースをコピペしてね。

<?php
define('BASE', dirname(dirname(__FILE__)));

ini_set('include_path'
    , BASE.'/libs'
     .PATH_SEPARATOR.ini_get('include_path')
    );

require_once('Smarty/Smarty.class.php');
$smarty = new Smarty();
$smarty->template_dir = BASE . '/app/';
$smarty->compile_dir  = BASE . '/templates_c/';
$smarty->config_dir   = BASE . '/configs/';
$smarty->cache_dir    = BASE . '/cache/';

$act = $_REQUEST['act'];
if (is_array($act)) $act = key($act);
if (!$act) $act = 'index';
$act = strtolower(str_replace('_', '/', basename($act))) . '.tpl';
if (!$smarty->template_exists($act)) $act = 'notfound.tpl';

// PEAR_DB
require_once 'DB.php';
$db = DB::connect('mysql://USERNAME:PASSWORD@HOSTNAME/DBNAME');
$smarty->assign_by_ref('db', $db);

// HTML_Template_Flexy
require_once 'HTML/Template/Flexy.php';
$options = array(
    'templateDir'   => BASE.'/templates',
    'compileDir'    => BASE.'/templates_c',
    'forceCompile'  => 0,
    'debug'         => 0,
    'locale'        => 'ja',
    'compiler'      => 'Standard',
    'allowPHP'      => 0,
    );
$flexy = new HTML_Template_Flexy($options);
$smarty->assign_by_ref("flexy", $flexy);

$smarty->display($act);

前回のに、2つ追加しているだけだよ。
HOSTNAME、USERNAME、PASSWORD、DBNAMEのところは、適宜環境にあわせてね。

■3.次にFlexyのテンプレートだよ

まずは、Flexyのテンプレートだよ。
templatesの下はこんな感じだよ。

├templates
 ├bbs.tpl
 ├dberror.tpl
 ├index.tpl
 ├notfound.tpl
 └post.tpl
■4.Flexyのテンプレートの中身

いっきに書くけど、デザイナーな君はhtmlとか大丈夫だよね?
ちょっとFlexyの記述が入っちゃうけど、ドキュメント見てみてね。


index.tplとnotfound.tplは、前回のappの下にあったのをコピーすればいいよ。


dberror.tplは、DBに接続できなかった時のメッセージだよ。

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>掲示板のサンプルだよ</title>
</head>
<body>
<h1>掲示板のサンプルだよ</h1>
ごめん、DB接続でえらった
</body>
</html>

これには、Flexyの記述とか入ってないね。


bbs.tplだよ

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>掲示板のサンプルだよ</title>
</head>
<body>
<h1>掲示板のサンプルだよ 一覧だよ</h1>
    <form action="./" method="post">
        めっせーじ<input type="text" name="message" value="" size="40" />
        なまえ<input type="text" name="name" value="" size="20" />
        <input type="submit" name="act[post]" value="投稿" />
    </form>
    <ul>
        <li flexy:foreach="references[list],v">{v[message]} [{v[name]}]({v[posttime]})</li>
    </ul>
</body>
</html>


post.tplだよ

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
 "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>掲示板のサンプルだよ</title>
</head>
<body>
<h1>掲示板のサンプルだよ</h1>
<div>
    <a href="./?act=bbs">一覧に戻るよ</a>
</div>
{references[msg]}
</body>
</html>


ちょっと、良くわからない記述が入っちゃってるけど、それ以外はhtmlのままだよね。
Flexyの記述が難しいという人は、ドキュメントとか見てみるといいと思うよ。がんばって!
Manual :: HTML_Template_Flexy

■4.Smartyのindex.tplとnotfound.tpl

appの下のSmartyのテンプレートも変えないとだめだからね。
これはSmartyのタグだけだから簡単だよ。
index.tplとnotfound.tplは同じ内容でいいからね。

{assign var='result' value=$flexy->compile($smarty.template)}
{$flexy->output()}

ね? たった2行だよ。簡単簡単。

■5.掲示板の一覧ページだよ

説明の前にまずは、Smartyのタグを書いちゃうね。

{strip}
{if !$db}
    {assign var='template' value='dberror.tpl'}
{else}
    {assign var='list' value=$db->getAssoc('SELECT id,message,name,DATE_FORMAT(posttime,"%Y-%m-%d %H:%i:%s") AS posttime FROM bbs ORDER BY id DESC',true,null,$smarty.const.DB_FETCHMODE_ASSOC)}
    {if is_array($list)}
        {$flexy->setDataByRef('list',$list)}
        {assign var='template' value=$smarty.template}
    {else}
        {assign var='template' value='dberror.tpl'}
    {/if}
{/if}
{assign var='result' value=$flexy->compile($template)}
{$flexy->output($flexy->assign)}
{/strip}

どうかな? 簡単でしょ? Smartyのタグだけだからね。
DB接続をPEAR_DBにしたので、そこがちょっと前回と大きく違うかな。

■6.掲示板の投稿ページだよ

次は、投稿ページの作成だよ。

{strip}
{if !$db}
    {assign var='msg' value='ごめん、DB接続でえらった'}
    {assign var='template' value='dberror.tpl'}
{else}
    {if !strlen($smarty.post.name) || !strlen($smarty.post.message)}
        {assign var='msg' value='めっせーじとなまえは必須だよ'}
    {else}
        {assign var='name' value=$db->quote($smarty.post.name)}
        {assign var='message' value=$db->quote($smarty.post.message)}
        {assign var='ip' value=$db->quote($smarty.server.REMOTE_ADDR)}
        {assign var='sql' value="INSERT INTO bbs (name,message,ip) VALUES (%s,%s,%s)"|sprintf:$name:$message:$ip}
        {assign var='result' value=$db->query($sql)}
        {if $result==$smarty.const.DB_OK}
            {assign var='msg' value='登録したよ'}
        {else}
            {assign var='msg' value='ごめん、登録できなかったよ'}
        {/if}
    {/if}
    {assign var='template' value=$smarty.template}
{/if}
{$flexy->setDataByRef('msg',$msg)}
{assign var='result' value=$flexy->compile($template)}
{$flexy->output($flexy->assign)}
{/strip}

どうかな? こっちもSmartyのタグだけだね!

■さんぷるふぁいる

ここまでに書いたもののまとめたサンプルだよ。


PEAR_DB、FlexySmartyを同梱しているファイルだよ。
http://maru.cc/files/20080326_smartybbs_sample2_pear.zip (733KB)


PEAR_DBとかSmartyとか入っているという人はこっちを使ってね
http://maru.cc/files/20080326_smartybbs_sample2.zip (9KB)

■さいごに

どうかな?
ロジックとデザインを分けるために、テンプレートエンジンを使ってみたよ。
これで、分離もばっちりだね。


続き>「デザイナーでも作れるスマートWebアプリ その3 - maru.cc@はてな