デザイナーでも作れるスマートWebアプリ その3
〜Smartyでスマートプログラミング〜
「デザイナーでも作れるスマートWebアプリ - maru.cc@はてな」
「デザイナーでも作れるスマートWebアプリ その2 - maru.cc@はてな」の続きだよ
そろそろエセ外人の売り込みっぽい口調も限界なので普通に。
このシリーズは、1000人カンファレンスUstのIRCのログの以下のコメントで思いついたエントリでした。
16:41:02 <suztomo> そこでPHPはテンプレートエンジンですよ。 16:41:22 <hayamiz> テンプレートエンジン上でテンプレートエンジン
テンプレートエンジンと言われるphpの上の、テンプレートエンジンのSmartyの上でテンプレートエンジンを動かすとか。
前回は、Flexyを使いましたが、他のテンプレートエンジンでもやってみます。
あくまで、ネタですからね。
PHPTALでやってみる
■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'; require_once 'DB.php'; $db = DB::connect('mysql://USERNAME:PASSWORD@HOSTNAME/DBNAME'); $smarty->assign_by_ref('db', $db); require_once 'PHPTAL.php'; $tal = new PHPTAL(); $smarty->assign_by_ref('tal', $tal); $smarty->display($act);
■Smartyのindex.tpl、notfound.tpl
{assign var='template' value=$smarty.const.BASE|cat:'/templates/'|cat:$smarty.template} {assign var='result' value=$tal->setTemplate($template)} {$tal->execute()}
■Smartyのbbs.tpl
{strip} {if !$db} {assign var='template' value=$smarty.const.BASE|cat:'/templates/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_OBJECT)} {if is_array($list)} {$tal->set('list',$list)} {assign var='template' value=$smarty.const.BASE|cat:'/templates/'|cat:$smarty.template} {else} {assign var='template' value=$smarty.const.BASE|cat:'/templates/dberror.tpl'} {/if} {/if} {assign var='result' value=$tal->setTemplate($template)} {$tal->execute()} {/strip}
■PHPTALの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 tal:repeat="item list"><span tal:replace="item/message" /> [<span tal:replace="item/name" />](<span tal:replace="item/posttime" />)</li> </ul> </body> </html>
■Smartyのpost.tpl
{strip} {if !$db} {assign var='msg' value='DB接続エラー'} {assign var='template' value=$smarty.const.BASE|cat:'/templates/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.const.BASE|cat:'/templates/'|cat:$smarty.template} {/if} {$tal->set('msg',$msg)} {assign var='result' value=$tal->setTemplate($template)} {$tal->execute()} {/strip}
■PHPTALの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> <span tal:replace="msg" /> </body> </html>
Zoganでやってみる
■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); // Zogan require_once 'XML/Template/zogan.php'; class ZoganEx extends Zogan { /** * sets value */ function set($key, $value) { $this->_data[$key] = $value; } } $zogan = new ZoganEx(); $zogan->setErrorHandling(PEAR_ERROR_PRINT); $zogan->setCompileDir(BASE . '/templates_c/'); $smarty->assign_by_ref('zogan', $zogan); $smarty->display($act);
どうしても素では出来なかったので、継承してsetメソッド作ってます。
■Smartyのindex.tpl、notfound.tpl
{assign var='template' value=$smarty.const.BASE|cat:'/templates/'|cat:$smarty.template} {assign var='result' value=$zogan->setTemplateFile($template)} {assign var='result' value=$zogan->display()}
■Smartyのbbs.tpl
{strip} {if !$db} {assign var='template' value=$smarty.const.BASE|cat:'/templates/dberror.tpl'} {else} {assign var='list' value=$db->getAll('SELECT id,message,name,DATE_FORMAT(posttime,"%Y-%m-%d %H:%i:%s") AS posttime FROM bbs ORDER BY id DESC',null,$smarty.const.DB_FETCHMODE_ASSOC)} {if is_array($list)} {$zogan->set('list', $list)} {assign var='template' value=$smarty.const.BASE|cat:'/templates/'|cat:$smarty.template} {else} {assign var='template' value=$smarty.const.BASE|cat:'/templates/dberror.tpl'} {/if} {/if} {assign var='result' value=$zogan->setTemplateFile($template)} {assign var='result' value=$zogan->display()} {/strip}
■Zoganの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 var:cont="{list}"><span var:cont="{message}" /> [<span var:cont="{name}" />](<span var:cont="{posttime}" />)</li> </ul> </body> </html>
■Smartyのpost.tpl
{strip} {if !$db} {assign var='msg' value='DB接続エラー'} {assign var='template' value=$smarty.const.BASE|cat:'/templates/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.const.BASE|cat:'/templates/'|cat:$smarty.template} {/if} {$zogan->set('msg',$msg)} {assign var='result' value=$zogan->setTemplateFile($template)} {assign var='result' value=$zogan->display()} {/strip}
■Zoganの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> <span var:cont="{msg}" /> </body> </html>
さんぷる
PHPTAL版
http://maru.cc/files/20080326_smartybbs_sample3.zip (205KB)
Zogan版
http://maru.cc/files/20080326_smartybbs_sample4.zip (637KB)