콘텐츠로 이동

ADR-003 - 템플릿 엔진

XOOPS의 Smarty 템플릿 엔진 채택을 위한 아키텍처 결정 기록입니다.


수락됨 - XOOPS 2.0 이후 핵심 결정

진화 중 - XOOPS 4.0에 대해 Smarty 4/5로 마이그레이션 예정


XOOPS에는 다음과 같은 템플릿 솔루션이 필요했습니다.

  1. 비즈니스 로직과 별도의 프리젠테이션
  2. 테마 디자이너가 PHP 지식 없이도 작업할 수 있도록 허용
  3. 템플릿 상속 지원 및 포함
  4. 성능을 위한 캐싱 제공
  5. 사용자 정의 가능한 템플릿 활성화
  6. 국제화 지원

flowchart TB
subgraph "PHP Layer"
A[Module Controller]
B[Template Variables]
end
subgraph "Smarty Engine"
C[Smarty Core]
D[Template Compiler]
E[Cache Manager]
end
subgraph "Templates"
F[Module Templates]
G[Theme Templates]
H[Block Templates]
end
subgraph "Output"
I[Compiled PHP]
J[Cached HTML]
K[Final HTML]
end
A --> B
B --> C
C --> D
C --> E
D --> F
D --> G
D --> H
F --> I
G --> I
H --> I
E --> J
I --> K
J --> K

다음과 같은 이유로 Smarty를 템플릿 엔진으로 사용합니다.

// PHP (Controller) - Business logic
$items = $itemHandler->getPublishedItems();
$xoopsTpl->assign('items', $items);
// Smarty (View) - Presentation
// templates/items.tpl
{* Smarty template - No PHP logic *}
<{foreach item=item from=$items}>
<article>
<h2><{$item.title}></h2>
<p><{$item.summary}></p>
</article>
<{/foreach}>

XOOPS는 표준 { } 대신 <{}>을 사용합니다.

{* Standard Smarty *}
{$variable}
{* XOOPS Smarty - Avoids JavaScript conflicts *}
<{$variable}>
graph TB
A[Theme Master Template<br>theme.html] --> B[Module Template<br>module_index.tpl]
A --> C[Block Templates<br>block_*.tpl]
B --> D[Partial Templates<br>_header.tpl]
B --> E[Partial Templates<br>_footer.tpl]
style A fill:#f9f,stroke:#333
style B fill:#9ff,stroke:#333
style C fill:#ff9,stroke:#333
  • 데이터베이스: 되돌리기 기능을 위해 저장된 사용자 정의 템플릿
  • 파일 시스템: 모듈 디렉터리의 원본 템플릿
  • 캐시: 성능을 위해 컴파일된 템플릿

// XOOPS Smarty initialization
$xoopsTpl = new XoopsTpl();
// Custom delimiters
$xoopsTpl->left_delim = '<{';
$xoopsTpl->right_delim = '}>';
// Caching
$xoopsTpl->caching = XOOPS_TEMPLATE_CACHE;
$xoopsTpl->cache_lifetime = 3600;
// Security
$xoopsTpl->security_policy = new Smarty_Security($xoopsTpl);
$xoopsTpl->security_policy->php_functions = [];
$xoopsTpl->security_policy->php_modifiers = ['escape', 'count'];

{* Simple variable *}
<{$title}>
{* Object property *}
<{$item.title}>
{* With modifier *}
<{$content|truncate:200:'...'}>
{* Escaped output *}
<{$userInput|escape:'html'}>
{* Conditional *}
<{if $isAdmin}>
<a href="admin.php">Admin</a>
<{elseif $isUser}>
<a href="profile.php">Profile</a>
<{else}>
<a href="login.php">Login</a>
<{/if}>
{* Loop *}
<{foreach item=item from=$items name=itemloop}>
<{$smarty.foreach.itemloop.index}>: <{$item.title}>
<{/foreach}>
{* Include another template *}
<{include file="db:mymodule_header.tpl"}>
{* Include with variables *}
<{include file="db:mymodule_item.tpl" item=$currentItem}>
{* Include from theme *}
<{include file="file:$theme_path/partials/sidebar.tpl"}>

  1. 디자이너 친화적: HTML과 유사한 구문
  2. 캐싱: 내장 템플릿 캐싱
  3. 보안: PHP 코드 격리
  4. 유연성: 수정자, 기능, 플러그인
  5. 사용자 정의: 사용자가 템플릿을 수정할 수 있습니다.
  6. 커뮤니티: 대규모 Smarty 생태계
  1. 학습 곡선: Smarty 특정 구문
  2. 오버헤드: 컴파일 단계가 필요합니다.
  3. 디버깅: 템플릿 오류는 난해할 수 있습니다.
  4. 버전 문제: 버전 간의 주요 변경 사항
  • 학습: 종합 문서
  • 성능: 적극적인 캐싱
  • 디버깅: 디버그 콘솔, 오류 메시지 지우기
  • 버전: XOOPS의 호환성 레이어

timeline
title Smarty in XOOPS
2003 : Smarty 2.x
: Initial integration
2013 : Smarty 3.0
: XOOPS 2.5.5
2020 : Smarty 3.1
: XOOPS 2.5.10
2026 : Smarty 4/5
: XOOPS 4.0

{* Smarty 3 - Deprecated *}
<{php}>echo date('Y');<{/php}>
{* Smarty 4+ - Use modifiers or assign from PHP *}
<{$current_year}>
{* Smarty 3 - {section} deprecated *}
<{section name=i loop=$items}>
<{$items[i].title}>
<{/section}>
{* Smarty 4+ - Use {foreach} *}
<{foreach $items as $item}>
<{$item.title}>
<{/foreach}>

XOOPS는 원활한 전환을 위해 호환성 레이어를 제공합니다.

// XoopsTpl extends Smarty with compatibility methods
class XoopsTpl extends Smarty
{
public function assign($tpl_var, $value = null)
{
// Handles both Smarty 3 and 4 syntax
return parent::assign($tpl_var, $value);
}
}

장점: 현대적인 Symfony 생태계 단점: 다른 구문, 마이그레이션 노력 결정: XOOPS 3.x에 가능한 향후 옵션

장점: 깔끔한 구문, 인기 있음 단점: Laravel 관련 결정: 독립형 사용에는 적합하지 않습니다.

장점: 학습 곡선이 없고 빠릅니다. 단점: 보안 위험, 분리 불가 결정: 유지보수성 문제로 거부됨


  • ADR-001: 모듈형 아키텍처
  • ADR-002: 데이터베이스 추상화


#xoops #아키텍처 #adr #smarty #템플릿 #디자인 결정