III. EFFICIENT (2)
12.  함수
템플릿표현식 내에 PHP 함수를 PHP 문법대로 자유롭게 사용할 수 있습니다. 단, 함수를 사용할 때는 출력명령어(=)를 생략할 수 없습니다.
{= date('Y-m-d h:i:s', timestamp) }
{= number_format(user.money) }
{= str_repeat( preg_replace('/\d+/', '', user.info), 10 ) }
{? empty(_COOKIE) || click=='first' || userFunc(arg) } hello {/}
 함수 플러그인
사용자정의 함수를 배포된 플러그인 디렉토리내에 'function.함수이름.php' 로 저장만 하면, 별도로 인클루드할 필요없이 템플릿 파일 내에서 사용할 수 있습니다.
function.returnHello.php
<?php
function returnHello($user) {
    return 'hello '.$user;
}
?>
index.php
...
$tpl->assign('user', 'Julia');
...
index.tpl
<div>
{= returnHello(user) }
</div>
>>output
<div>
Hello Julia
</div>
같은 이름의 함수가 여러 하위템플릿에 사용되거나, 또는 PHP 파일에서 사용될 경우에도 에러없이 필요한 만큼만 정확하게 자동인클루드됩니다.
실행 파일에서 템플릿용 사용자정의 함수를 미리 인클루드해서 사용하고자 한다면, 간단히 include_() 메서드를 이용할 수 있습니다.
$tpl->include_('returnHello');
$tpl->include_('returnHello', 'someUserFunc');
13.  상수
형(type) 지정자 (예약어) 의미 사용법
c. (또는 C.) 뒤의 붙은 아이디가 상수임 { c.CONSTANT }
PHP 에 내장된 상수 또는 define() 함수에 의한 사용자정의 상수를 별도의 할당없이 템플릿내에서 사용할 수 있습니다.
{ C.SOME_USER_CONSTANT }
{= htmlspecialchars( list.data.title, C.ENT_QUOTES ) }
{? userFunc(user.name, true) == false } some message {/}
true , false , null 은 상수가 아닌 예약어이고, C. 를 붙이지 않고 사용가능합니다.
14.  객체
연산자 사용법
-> { object->method() }, { object->property }
객체 또한 표현식의 구성요소로 자유롭게 사용할 수 있습니다.
{ user->getLevel() }
{= strftime('%Y-%m-%d', env.data->timestamp) }
객체 사용 예제 
index.php
<?php
class PHP_CLASS {
    var $user = 'guest';
    function hello() {
        return 'hello! ' . $this->user;
    }
}
$phpobj = new PHP_CLASS;
$phpobj->user = 'julia';
include 'Template_.class.php';
$tpl = new Template_;
$tpl->define('index', 'index.tpl');
$tpl->assign('tplobj', $phpobj);
$tpl->print_('index');
?>
index.tpl
<div> { tplobj->user } </div><div> { tplobj->hello() } </div>
>> output
<div> julia </div><div> hello! juila </div>
다른 템플릿변수처럼, 객체도 전역변수라면 언더바를 붙여서 할당을 생략할 수 있습니다.
* 템플릿 파일내의 this 는 템플릿 객체를 참조합니다.
{ this->template_dir }
{= userFunc(this, arg1, arg2) }
 
 객체 플러그인
형(type) 지정자 의미 사용법
p. (또는 P.) 뒤의 붙은 아이디가 플러그인 객체임 { p.object }
클래스 이름이 "tpl_object_객체명" 인 클래스를 플러그인 디렉토리내에 'object.객체명.php' 파일로 저장만 하면, 별도로 인클루드나 초기화 없이 템플릿 파일 내에서 사용할 수 있습니다.
object.say.php
<?php
class tpl_object_say {
    function tpl_object_say($user='guest') {     // constructor
        $this->user= $user;
    }
    function hello() {
        return 'Hello! '.$this->user;
    }
}
?>
index.tpl
<div> {p.say->hello()} </div>
>>output
<div> Hello! guest </div>
PHP 파일에서 미리 인클루드하여 사용하거나, 생성자함수에 인자를 전달하여 초기화하려면,
new_() 메서드를 사용합니다.
메서드 의미 사용법
new_() 플러그인 객체 초기화/리턴 $tpl->new_('객체명', 인자1, 인자2,..)
index.php
<?php
include 'Template_.class.php';
$tpl = new Template_;
$tpl->define('index', 'index.tpl');
$tpl->new_('say', 'julia');
$tpl->print_('index');
?>
index.tpl
<div> {p.say->hello()} </div>
>>output
<div> Hello! julia </div>
아래와 같이 초기화 한다면. $obj 객체와 템플릿파일내의 say 객체는 동일한 것입니다.
$obj = &$tpl->new_('say' ...);
Note:
PHP4 에서는 &를 붙일 경우 템플릿 내에서 사용될 객체의 참조를 리턴하고, 붙이지 않은 경우 복사본을 리턴합니다. PHP5 에서는 어떤 경우에나 참조를 리턴합니다.
15.  분기(2) - switch
분기명령어(?) 뒤에 한 개 이상의 case 명령어 (:) 가 있으면 switch 분기로 해석됩니다.
명령어 의미 사용법
? [:] switch {? test_expression : label_expression ... }
: case, default (옵션) {: label_expression ...}, {:}
/ endswitch {/}
명령어들은 if 분기문, 루프문과 공통되지만 문맥에 의해 해석되고, 다른 구문들과 자유롭게 중첩해서 사용할 수 있으며, 정확하게 작성하지 않으면 템플릿 변환기가 적절한 오류메세지를 출력합니다.
PHP's switch Template_'s switch
<?php
switch ($fruit) {
    case 'banana':
        echo 'yellow';
        break;
    case 'apple':
    case 'strawberry':
        echo 'red';
        break;
    case $var :
        echo "color of ".$var;
        break;
    default :
        echo 'unknown';
}
?>
<!--{? _fruit :'banana'}-->
    yellow
<!--{:'apple' :'strawberry'}-->
    red
<!--{: _var}-->
    color of {_var}
<!--{:}-->
    unknown
<!--{/}-->
템플릿태그 단위로 break;가 자동으로 붙습니다. 이것은 기능상의 제약이 있지만, 한 템플릿태그 내에 case 명령(:)을 여러 번 사용할 수 있으므로, 여러 조건에 대한 한 가지 출력이 가능합니다.
16.  루프(3) - 표현식
아래와 같이 루프명령어 뒤에 루프아이디 대신 표현식을 사용할 수 있습니다.
{@ P.myObj->getList() }
{@ range(1, list.estimation) }
표현식은 루프(1), 루프(2) 에서 설명되었던 배열을 리턴하면 됩니다. 루프아이디가 없기 때문에 해당루프의 변수는 루프아이디를 생략하는 형태만 가능하고 루프밖에서의 size_ 사용은 가능하지 않습니다.
아래 세 가지 중첩루프는 모두 같습니다.
{@ outer } {@ inner } {inner.var} {/} {/}
{@ outer } {@ .inner } {..var} {/} {/}
{@ outer } {@ outer.inner } {..var} {/} {/}
첫번째 inner루프아이디이고, .innerouter.inner표현식입니다.
 key_ , value_ 를 이용한 중첩루프 예제
function.getSomeList.php
<?php
function getSomeList() {
    ...
    $result = mysql_query('select group, item from some_table');
    $loop = array();
    while ($data = mysql_fetch_assoc($result)) {
        $loop[$data['group']][] = $data['item'];
    }
    return $loop;
}
?>
index.tpl
<table>
<!--{@ getSomeList()}-->
<tr><td>{.key_}</td><td>{@.value_}{..value_}, {/}</td></tr>
<!--{/}-->

</table>
>>output
<table>
<tr><td>fruit</td><td>apple, orange, pear,</td></tr>
<tr><td>sport</td><td>running, pingpong,</td></tr>
<tr><td>number</td><td>5, 100, 3, 65,</td></tr>

</table>
getSomeList() 함수가 리턴한 배열은 다음과 같습니다.
Array returned
array(
    'fruit' => array('apple', 'orange', 'pear'),
    'sport' => array('runging', 'pingpong'),
    'number'=> array(5, 100, 3, 65),
);
17.  PHP 코딩
템플릿 파일 내에서 PHP 코드를 사용할 수 있으며, PHP 코드 내에서 템플릿 변수를 사용하거나, 템플릿 변수에 값을 할당할 수 있습니다.
index.tpl
<?php {var} = 123; ?>
<div>{var}</div>
>>output
<div>123</div>
php.ini 파일의 설정에 따라 PHP 태그로 <? ?> 또는 <% %> 도 사용할 수 있습니다.
Note:
이것은 권장되는 기능이 아니며, 필요하다면 간단한 용도로만 사용하시기 바랍니다. PHP 코드의 오류에 대해서는, 템플릿변환기가 자체적인 디버깅 메세지를 출력하지 못합니다.
 
Since 2003-03-03 hosted on vultr.com