PHPackages                             xoops/smartyextensions - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Templating &amp; Views](/categories/templating)
4. /
5. xoops/smartyextensions

ActiveLibrary[Templating &amp; Views](/categories/templating)

xoops/smartyextensions
======================

XOOPS Smarty template extensions — domain-grouped plugins for Smarty 4/5

v1.3.0-Beta2(1mo ago)084↓57.1%1[1 PRs](https://github.com/XOOPS/smartyextensions/pulls)GPL-2.0-or-laterPHPPHP ^8.2CI passing

Since Jun 8Pushed 5d agoCompare

[ Source](https://github.com/XOOPS/smartyextensions)[ Packagist](https://packagist.org/packages/xoops/smartyextensions)[ Docs](https://xoops.org)[ RSS](/packages/xoops-smartyextensions/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (4)Dependencies (9)Versions (5)Used By (0)

xoops/smartyextensions
======================

[](#xoopssmartyextensions)

Domain-grouped Smarty 4/5 plugins for the XOOPS CMS.

[![PHP](https://camo.githubusercontent.com/187240af044d09d5b14a1d9d9ebdf3f7a993e4c7bc09bdb46b4ba661a891bf5b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d382e322532422d626c7565)](https://www.php.net/)[![License: GPL v2](https://camo.githubusercontent.com/77e900ae34f8da9ccccc42662fce61a94ab07ddbfe3f7d066178e824f3673dbd/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d47504c25323076322d626c75652e737667)](https://www.gnu.org/licenses/gpl-2.0)[![Smarty](https://camo.githubusercontent.com/0d587522968ea509c9d04bf3fcff8837b795cc0f8f2734a42b78142fe93eb0f9/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f536d617274792d342e78253230253743253230352e782d6f72616e6765)](https://smarty.net/)

---

Overview
--------

[](#overview)

`xoops/smartyextensions` replaces the traditional flat pile of Smarty plugin files with a structured, testable, PSR-4 library. Extensions are grouped by domain, registered through a unified `ExtensionRegistry`, and fully compatible with both Smarty 4 (`registerPlugin`) and Smarty 5 (`addExtension`).

XOOPS uses `` as Smarty delimiters. All examples below use these delimiters.

---

Requirements
------------

[](#requirements)

RequirementVersionPHP^8.2Smarty^4.5 or ^5.0---

Installation
------------

[](#installation)

```
composer require xoops/smartyextensions
```

---

Quick Start
-----------

[](#quick-start)

```
use Xoops\SmartyExtensions\ExtensionRegistry;
use Xoops\SmartyExtensions\Extension\TextExtension;
use Xoops\SmartyExtensions\Extension\SecurityExtension;

$registry = new ExtensionRegistry();
$registry->add(new TextExtension());
$registry->add(new SecurityExtension($xoopsSecurity, $xoopsGroupPermHandler));
$registry->registerAll($smarty); // works with both Smarty 4 and Smarty 5
```

Or register a single extension directly:

```
(new TextExtension())->register($smarty);
```

---

Extension Catalogue
-------------------

[](#extension-catalogue)

### TextExtension

[](#textextension)

Modifiers for string processing and readability.

NameSignatureDescription`excerpt``$text|excerpt:150:' ...'`Truncate at word boundary with multibyte safety`truncate_words``$text|truncate_words:20`Truncate at exact word count`nl2p``$text|nl2p`Convert newlines to `` and ```highlight_text``$text|highlight_text:'XOOPS'`Wrap search term in ```reading_time``$text|reading_time`Estimated reading time, e.g. "3 min read"`pluralize``$count|pluralize:'comment'`Singular/plural based on count`extract_hashtags``$text|extract_hashtags`Returns array of hashtag strings---

### FormatExtension

[](#formatextension)

Date, time, number, and display formatting.

NameSignatureDescription`format_date``$date|format_date:'Y-m-d'`Format any date string or timestamp`relative_time``$ts|relative_time`"3 days ago" / "2 hours from now"`format_currency``$amount|format_currency:'USD'`Currency formatting with ICU/intl fallback`number_format``$n|number_format:2:',':'.'`Locale-aware number formatting`bytes_format``$bytes|bytes_format:1`Human-readable file size (e.g. "1.5 MB")`format_phone_number``$phone|format_phone_number`Formats 10- or 11-digit US phone numbers`gravatar``$email|gravatar:64:'mp'`Gravatar URL for an email address`datetime_diff```Human-readable span between two dates`get_current_year```Current 4-digit year---

### NavigationExtension

[](#navigationextension)

URL generation, breadcrumbs, pagination, and social sharing.

NameTypeDescription`generate_url`functionBuild a URL with query params; direct output is HTML-escaped, `assign` stores raw URL`generate_canonical_url`functionBuild canonical URL from `XOOPS_URL`; no-op without it`url_segment`functionExtract a path segment from the current URL`social_share`functionSocial share links/bar (Twitter, Facebook, LinkedIn)`render_breadcrumbs`functionBootstrap 5 breadcrumb nav`render_pagination`functionBootstrap 5 pagination with prev/next`render_qr_code`function`` tag via Google Charts QR API`render_alert`functionBootstrap 5 dismissible alert`parse_url`modifierReturns parsed URL components as array`strip_protocol`modifierRemoves `http://` or `https://` scheme`slugify`modifierConverts text to URL-safe slug`youtube_id`modifierExtracts YouTube video ID from any URL format`linkify`modifierConverts plain-text URLs to `` anchors**Assign contract**: when `assign` is given, the **raw** value is stored. Only direct output applies `htmlspecialchars`.

```
 42] assign="articleUrl"}>
Read more
```

---

### SecurityExtension

[](#securityextension)

CSRF, permission checks, email masking, and sanitization.

**Constructor**: `new SecurityExtension(?XoopsSecurity $security, ?XoopsGroupPermHandler $permHandler)`

NameTypeDescription`sanitize_string`modifier`htmlspecialchars` with `ENT_QUOTES``sanitize_url`modifierBlocks `javascript:`, `data:`, entity-encoded variants`sanitize_filename`modifier`basename()` + allowlist + strip leading dots`sanitize_string_for_xml`modifierXML-safe entity encoding`mask_email`modifier`us***@example.com` format`obfuscate_text`modifierConverts all chars to HTML entities`hash_string`modifierHash with any algorithm; defaults to SHA-256`generate_csrf_token`functionRenders XOOPS CSRF hidden input`validate_csrf_token`functionValidates XOOPS CSRF token`has_user_permission`functionChecks group permission via `XoopsGroupPermHandler``is_user_logged_in`functionBoolean check on `$xoopsUser` global`user_has_role`functionChecks if user belongs to a group ID`xo_permission`blockConditionally renders content based on login/permission/group```

  Admin panel

```

---

### FormExtension

[](#formextension)

Form rendering with automatic CSRF injection and validation.

**Constructor**: `new FormExtension(?XoopsSecurity $security)`

NameDescription`form_open`Opens `` with CSRF token auto-injected for POST`form_close`Closes ```form_input`Renders `` with XSS-safe escaping`create_button`Renders `` with optional Bootstrap icon`render_form_errors`Renders Bootstrap 5 error alert list`validate_form`Validates data against rules; returns errors array`validate_email`Validates a single email address`display_error`Renders a single Bootstrap 5 danger alert`validate_form` rules example:

```
 ['required' => true, 'email' => true], 'bio' => ['max_length' => 500]] assign="errors"}>

```

Validation uses `mb_strlen` for `min_length`/`max_length`, ensuring multibyte UTF-8 characters (CJK, Arabic, etc.) count correctly.

---

### DataExtension

[](#dataextension)

Data manipulation, CSV export, file info, and XML sitemaps.

**Modifiers**: `array_filter`, `array_sort`, `pretty_print_json`, `get_file_size`, `get_mime_type`, `is_image`, `strip_html_comments`

**Functions**: `array_to_csv`, `base64_encode_file`, `embed_pdf`, `generate_xml_sitemap`, `generate_meta_tags`, `get_referrer`, `get_session_data`

The `get_referrer` assign path stores the **raw** referrer URL; direct output applies `htmlspecialchars`.

---

### AssetExtension

[](#assetextension)

Deferred CSS/JS asset queuing with deduplication and XSS-safe scheme validation.

FunctionDescription`require_css`Queue a stylesheet (deduplicates by file path)`require_js`Queue a script (deduplicates by file path)`flush_css`Output all queued `` tags and clear queue`flush_js`Output all queued `` tags and clear queueBlocked schemes: `javascript:`, `data:`, and their HTML entity-encoded variants. Last-write wins for conflicting attributes (e.g., `defer` vs no defer for the same file).

```

```

---

### XoopsCoreExtension

[](#xoopscoreextension)

Wrappers around XOOPS globals and handlers.

NameTypeDescription`xo_get_config`functionRead from `$xoopsConfig``xo_get_current_user`functionCurrent user as array (uid, uname, name, email, groups, is\_admin)`xo_get_module_info`functionModule info by dirname`xo_get_notifications`functionCurrent user's notification list`xo_module_url`functionModule URL; assign stores raw, output is HTML-escaped`xo_render_block`functionRender a XOOPS block object`xo_render_menu`functionModule admin menu as Bootstrap nav`xo_avatar`functionUser avatar (XOOPS upload or Gravatar fallback)`xo_debug`functionDump variable (only outputs when `debug_mode` is active)`translate`modifierResolve XOOPS language constant with string fallback```

```

---

### RayDebugExtension

[](#raydebugextension)

Zero-cost debug output via [spatie/ray](https://spatie.be/products/ray). All functions and the modifier silently no-op when Ray is not installed — no runtime dependency.

NameType`ray`function + modifier`ray_context`function`ray_dump`function`ray_table`function---

Architecture
------------

[](#architecture)

```
src/
├── AbstractExtension.php       Base class — register(), getModifiers(), getFunctions(), getBlockHandlers()
├── ExtensionRegistry.php       Collects extensions, auto-detects Smarty 4/5, registers all
├── Adapter/
│   └── Smarty5Adapter.php      Wraps AbstractExtension for Smarty 5 addExtension() API
└── Extension/
    ├── TextExtension.php
    ├── FormatExtension.php
    ├── NavigationExtension.php
    ├── SecurityExtension.php
    ├── FormExtension.php
    ├── DataExtension.php
    ├── AssetExtension.php
    ├── XoopsCoreExtension.php
    └── RayDebugExtension.php

```

`AbstractExtension::register($smarty)` iterates the three registries (modifiers, functions, block handlers) and calls `$smarty->registerPlugin()` for each — the Smarty 4 API.

`ExtensionRegistry::registerAll($smarty)` auto-detects the Smarty version: if `\Smarty\Extension\Base` exists (Smarty 5), each extension is wrapped in `Smarty5Adapter` and passed to `$smarty->addExtension()`.

---

Security Conventions
--------------------

[](#security-conventions)

All extensions follow a consistent **assign contract**:

- **Direct output** (no `assign` param): HTML-escaped with `htmlspecialchars($value, ENT_QUOTES, 'UTF-8')`.
- **Assign path** (`assign` param present): raw value is stored in the template variable. The caller is responsible for escaping when interpolating into HTML (e.g. `href=""`).

This prevents double-escaping while maintaining XSS safety at every output point.

---

Running Tests
-------------

[](#running-tests)

```
composer install
composer test
```

PHPUnit scans `tests/Unit/` and uses `tests/bootstrap.php`, which loads XOOPS class stubs so the suite runs standalone (no XOOPS installation required).

```
composer analyse   # PHPStan level 9
composer lint      # PHPCS
composer fix       # PHPCBF
```

---

Contributing
------------

[](#contributing)

1. Fork the repository.
2. Create a feature branch.
3. Write or update tests in `tests/Unit/`.
4. Ensure `composer test` passes with no failures.
5. Submit a pull request.

---

License
-------

[](#license)

GNU General Public License v2.0 or later. See [LICENSE](LICENSE) for details.

© 2000–2026 [XOOPS Project](https://xoops.org)

###  Health Score

40

—

FairBetter than 86% of packages

Maintenance96

Actively maintained with recent releases

Popularity14

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity35

Early-stage or recently created project

 Bus Factor1

Top contributor holds 55.6% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~3 days

Total

4

Last Release

38d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/122f20c0edc2c6b86e8354286b09f6e982ecc6dcfbfaffcd91c3638406ffc39f?d=identicon)[xoops](/maintainers/xoops)

---

Top Contributors

[![mambax7](https://avatars.githubusercontent.com/u/613686?v=4)](https://github.com/mambax7 "mambax7 (20 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (16 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/xoops-smartyextensions/health.svg)

```
[![Health](https://phpackages.com/badges/xoops-smartyextensions/health.svg)](https://phpackages.com/packages/xoops-smartyextensions)
```

###  Alternatives

[filament/filament

A collection of full-stack components for accelerated Laravel app development.

3929.6M3.9k](/packages/filament-filament)[prestashop/prestashop

PrestaShop is an Open Source e-commerce platform, committed to providing the best shopping cart experience for both merchants and customers.

9.2k18.1k](/packages/prestashop-prestashop)[modx/revolution

MODX Revolution is a Content Management System

1.4k9.6k12](/packages/modx-revolution)[ytake/laravel-smarty

Smarty template engine for Laravel and Lumen

85408.6k](/packages/ytake-laravel-smarty)[noiselabs/smarty-bundle

This Symfony bundle provides integration for the Smarty3 template engine.

53196.2k1](/packages/noiselabs-smarty-bundle)[abydahana/aksara

Aksara is a CodeIgniter based CRUD Toolkit you can use to build complex applications become shorter, secure and more reliable just in a few lines of code. Serving both CMS or Framework, produce both HEADLESS (RESTful API) or TRADITIONAL (Browser Based), just by writing single controller. Yet it's reusable, scalable and ready to use!

1111.2k](/packages/abydahana-aksara)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
