Aller au contenu

Système de modèles XOOPS

Le système de modèles XOOPS est construit sur le puissant moteur de modèles Smarty, fournissant un moyen flexible et extensible de séparer la logique de présentation de la logique métier. Il gère les thèmes, le rendu des modèles, l’attribution des variables et la génération de contenu dynamique.

graph TD
A[XoopsTpl] -->|extends| B[Smarty]
A -->|manages| C[Themes]
A -->|manages| D[Template Variables]
A -->|handles| E[Block Rendering]
C -->|contains| F[Templates]
C -->|contains| G[CSS/JS]
C -->|contains| H[Images]
I[Theme Manager] -->|loads| C
I -->|applies| J[Active Theme]
I -->|configures| K[Template Paths]
L[Block System] -->|uses| A
M[Module Templates] -->|uses| A
N[Admin Templates] -->|uses| A

La classe moteur de modèles principale qui étend Smarty.

namespace Xoops\Core;
class XoopsTpl extends Smarty
{
protected array $vars = [];
protected string $currentTheme = '';
protected array $blocks = [];
protected bool $isAdmin = false;
}
use Xoops\Core\XoopsTpl;
class XoopsTpl extends Smarty
{
private static ?XoopsTpl $instance = null;
private function __construct()
{
parent::__construct();
$this->configureDirectories();
$this->registerPlugins();
}
public static function getInstance(): XoopsTpl
{
if (!isset(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
}

Obtient l’instance singleton du modèle.

public static function getInstance(): XoopsTpl

Retour : XoopsTpl - Instance singleton

Exemple :

$xoopsTpl = XoopsTpl::getInstance();

Assigne une variable au modèle.

public function assign(
string|array $tplVar,
mixed $value = null
): void

Paramètres :

ParamètreTypeDescription
$tplVarstring|arrayNom de variable ou tableau associatif
$valuemixedValeur de variable

Exemple :

$xoopsTpl->assign('page_title', 'Welcome');
$xoopsTpl->assign('user_name', 'John Doe');
// Multiple assignments
$xoopsTpl->assign([
'items' => $items,
'total_count' => count($items),
'show_pagination' => true
]);

Ajoute des valeurs aux variables de tableau de modèles.

public function appendAssign(
string $tplVar,
mixed $value
): void

Paramètres :

ParamètreTypeDescription
$tplVarstringNom de variable
$valuemixedValeur à ajouter

Exemple :

$xoopsTpl->assign('breadcrumbs', ['Home']);
$xoopsTpl->appendAssign('breadcrumbs', 'Blog');
$xoopsTpl->appendAssign('breadcrumbs', 'Posts');
// breadcrumbs = ['Home', 'Blog', 'Posts']

Obtient toutes les variables de modèles assignées.

public function getAssignedVars(): array

Retour : array - Variables assignées

Exemple :

$vars = $xoopsTpl->getAssignedVars();
foreach ($vars as $name => $value) {
echo "$name = " . var_export($value, true) . "\n";
}

Affiche un modèle et exporte vers le navigateur.

public function display(
string $resource,
string|array $cache_id = null,
string $compile_id = null,
object $parent = null
): void

Paramètres :

ParamètreTypeDescription
$resourcestringChemin du fichier modèle
$cache_idstring|arrayIdentifiant du cache
$compile_idstringIdentifiant de compilation
$parentobjectObjet modèle parent

Exemple :

$xoopsTpl->assign('page_title', 'Home');
$xoopsTpl->display('user:index.tpl');
// With absolute path
$xoopsTpl->display(XOOPS_ROOT_PATH . '/templates/user/index.tpl');

Affiche un modèle et retourne en tant que chaîne.

public function fetch(
string $resource,
string|array $cache_id = null,
string $compile_id = null,
object $parent = null
): string

Retour : string - Contenu du modèle affiché

Exemple :

$xoopsTpl->assign('message', 'Hello World');
$html = $xoopsTpl->fetch('user:message.tpl');
echo $html;
// Use for email templates
$emailContent = $xoopsTpl->fetch('mail:notification.tpl');
mail($to, $subject, $emailContent);

Charge un thème spécifique.

public function loadTheme(string $themeName): bool

Paramètres :

ParamètreTypeDescription
$themeNamestringNom du répertoire du thème

Retour : bool - True en cas de succès

Exemple :

if ($xoopsTpl->loadTheme('bluemoon')) {
echo "Theme loaded successfully";
}

Obtient le nom du thème actuellement actif.

public function getCurrentTheme(): string

Retour : string - Nom du thème

Exemple :

$currentTheme = $xoopsTpl->getCurrentTheme();
echo "Active theme: $currentTheme";

Ajoute un filtre de sortie pour traiter la sortie du modèle.

public function setOutputFilter(string $function): void

Paramètres :

ParamètreTypeDescription
$functionstringNom de la fonction de filtre

Exemple :

// Remove whitespace from output
$xoopsTpl->setOutputFilter('trim');
// Custom filter
function my_output_filter($output) {
// Minify HTML
$output = preg_replace('/\s+/', ' ', $output);
return trim($output);
}
$xoopsTpl->setOutputFilter('my_output_filter');

Enregistre un plugin Smarty personnalisé.

public function registerPlugin(
string $type,
string $name,
callable $callback
): void

Paramètres :

ParamètreTypeDescription
$typestringType de plugin (modifier, block, function)
$namestringNom du plugin
$callbackcallableFonction de rappel

Exemple :

// Register custom modifier
$xoopsTpl->registerPlugin('modifier', 'markdown', function($text) {
return markdown_parse($text);
});
// Use in template: {$content|markdown}
// Register custom block tag
$xoopsTpl->registerPlugin('block', 'permission', function($params, $content, $smarty, &$repeat) {
if ($repeat) return;
// Check permission
if (has_permission($params['name'])) {
return $content;
}
return '';
});
// Use in template: {permission name="admin"}...{/permission}

Structure standard du répertoire des thèmes XOOPS :

bluemoon/
├── style.css # Main stylesheet
├── admin.css # Admin stylesheet
├── theme.html # Main page template
├── admin.html # Admin page template
├── blocks/ # Block templates
│ ├── block_left.tpl
│ └── block_right.tpl
├── modules/ # Module templates
│ ├── publisher/
│ │ ├── index.tpl
│ │ └── item.tpl
│ └── news/
│ └── index.tpl
├── images/ # Theme images
│ ├── logo.png
│ └── banner.png
├── js/ # Theme JavaScript
│ └── script.js
└── readme.txt # Theme documentation
namespace Xoops\Core\Theme;
class ThemeManager
{
protected array $themes = [];
protected string $activeTheme = '';
protected string $themeDirectory = '';
public function getActiveTheme(): string {}
public function setActiveTheme(string $theme): bool {}
public function getThemeList(): array {}
public function themeExists(string $name): bool {}
}

XOOPS assigne automatiquement plusieurs variables de modèles globales :

VariableTypeDescription
$xoops_urlstringURL d’installation d’XOOPS
$xoops_userXoopsUser|nullObjet utilisateur actuel
$xoops_unamestringNom d’utilisateur actuel
$xoops_isadminboolL’utilisateur est administrateur
$xoops_bannerstringHTML de la bannière
$xoops_notificationstringBalisage de notification
$xoops_versionstringVersion d’XOOPS

Lors du rendu des blocs :

VariableTypeDescription
$blockarrayInformations du bloc
$block.titlestringTitre du bloc
$block.contentstringContenu du bloc
$block.idintID du bloc
$block.modulestringNom du module

Les modules assignent généralement :

VariableTypeDescription
$module_namestringNom d’affichage du module
$module_dirstringRépertoire du module
$xoops_module_headerstringCSS/JS du module
ModificateurDescriptionExemple
capitalizeMettre en majuscule la première lettre{$title|capitalize}
count_charactersNombre de caractères{$text|count_characters}
date_formatFormater l’horodatage{$timestamp|date_format:'%Y-%m-%d'}
escapeÉchapper caractères spéciaux{$html|escape:'html'}
nl2brConvertir sauts de ligne en <br>{$text|nl2br}
strip_tagsSupprimer étiquettes HTML{$content|strip_tags}
truncateLimiter longueur de chaîne{$text|truncate:100}
upperConvertir en majuscules{$name|upper}
lowerConvertir en minuscules{$name|lower}
{* If statement *}
{if $user->isAdmin()}
<p>Admin content</p>
{else}
<p>User content</p>
{/if}
{* For loop *}
{foreach $items as $item}
<div class="item">{$item.title}</div>
{/foreach}
{* For loop with counter *}
{foreach $items as $item name=item_loop}
{$smarty.foreach.item_loop.iteration}: {$item.title}
{/foreach}
{* While loop *}
{while $condition}
<!-- content -->
{/while}
{* Switch statement *}
{switch $status}
{case 'draft'}<span class="draft">Draft</span>{break}
{case 'published'}<span class="published">Published</span>{break}
{default}<span class="unknown">Unknown</span>
{/switch}
<?php
/**
* Module Article List Page
*/
include __DIR__ . '/include/common.inc.php';
$xoopsTpl = XoopsTpl::getInstance();
// Check if module is active
$module = xoops_getModuleByDirname('articles');
if (!$module) {
redirect_header(XOOPS_URL, 3, 'Module not found');
}
// Get item handler
$itemHandler = xoops_getModuleHandler('item', 'articles');
// Get pagination parameters
$page = !empty($_GET['page']) ? (int)$_GET['page'] : 1;
$perPage = $module->getConfig('items_per_page') ?: 10;
$offset = ($page - 1) * $perPage;
// Build criteria
$criteria = new CriteriaCompo();
$criteria->add(new Criteria('status', 1));
$criteria->setSort('published', 'DESC');
$criteria->setLimit($perPage);
$criteria->setStart($offset);
// Fetch items
$items = $itemHandler->getObjects($criteria);
$total = $itemHandler->getCount(new Criteria('status', 1));
// Calculate pagination
$pages = ceil($total / $perPage);
// Assign template variables
$xoopsTpl->assign([
'module_name' => $module->getName(),
'items' => $items,
'total_items' => $total,
'current_page' => $page,
'total_pages' => $pages,
'items_per_page' => $perPage,
'show_pagination' => $pages > 1
]);
// Add breadcrumbs
$xoopsTpl->assign('xoops_breadcrumbs', [
['url' => XOOPS_URL, 'title' => 'Home'],
['url' => $module->getUrl(), 'title' => $module->getName()],
['title' => 'Articles']
]);
// Display template
$xoopsTpl->display($module->getPath() . '/templates/user/list.tpl');
<div id="articles-list">
<h1>{$module_name|escape}</h1>
{if $items}
<div class="articles-container">
{foreach $items as $item}
<article class="article-item">
<header>
<h2>
<a href="{$item.url|escape}">
{$item.title|escape}
</a>
</h2>
<div class="meta">
<span class="author">By {$item.author|escape}</span>
<span class="date">
{$item.published|date_format:'%B %d, %Y'}
</span>
</div>
</header>
<div class="content">
<p>{$item.summary|truncate:150}</p>
</div>
<footer>
<a href="{$item.url|escape}" class="read-more">
Read More »
</a>
</footer>
</article>
{/foreach}
</div>
{* Pagination *}
{if $show_pagination}
<nav class="pagination">
{if $current_page > 1}
<a href="?page=1" class="first">« First</a>
<a href="?page={$current_page - 1}" class="prev">‹ Previous</a>
{/if}
{for $i=1 to $total_pages}
{if $i == $current_page}
<span class="current">{$i}</span>
{else}
<a href="?page={$i}">{$i}</a>
{/if}
{/for}
{if $current_page < $total_pages}
<a href="?page={$current_page + 1}" class="next">Next ›</a>
<a href="?page={$total_pages}" class="last">Last »</a>
{/if}
</nav>
{/if}
{else}
<p class="no-items">No articles found.</p>
{/if}
</div>
<?php
/**
* Custom Smarty block function for permission checking
*/
function smarty_block_permission($params, $content, $smarty, &$repeat)
{
if ($repeat) return;
if (!isset($params['name'])) {
return 'Permission name required';
}
$permName = $params['name'];
$user = $GLOBALS['xoopsUser'];
// Check if user has permission
if ($user && $user->isAdmin()) {
return $content;
}
if ($user && check_user_permission($user->uid(), $permName)) {
return $content;
}
return '';
}

Enregistrer et utiliser :

$xoopsTpl->registerPlugin('block', 'permission', 'smarty_block_permission');

Modèle :

{permission name="edit_articles"}
<button>Edit Article</button>
{/permission}
  1. Échapper le contenu utilisateur - Toujours utiliser |escape pour le contenu généré par l’utilisateur
  2. Utiliser les chemins de modèles - Référencer les modèles relatifs au thème
  3. Séparer la logique de la présentation - Garder la logique complexe en PHP
  4. Mettre en cache les modèles - Activer la mise en cache des modèles en production
  5. Utiliser les modificateurs correctement - Appliquer des filtres appropriés au contexte
  6. Organiser les blocs - Placer les modèles de blocs dans un répertoire dédié
  7. Documenter les variables - Documenter toutes les variables de modèles en PHP
  • ../Module/Module-System - Système de modules et crochets
  • ../Kernel/Kernel-Classes - Noyau et configuration
  • ../Core/XoopsObject - Classe objet de base

Voir aussi : Documentation Smarty | API de modèles XOOPS