mirror of
https://github.com/smarty-php/smarty.git
synced 2026-08-04 04:24:18 +02:00
Compare commits
180 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1f9eef51c7 | |||
| 94a27cbbc7 | |||
| badc5ef3a0 | |||
| 2ae0f9a65f | |||
| b668745acf | |||
| 3c9f77a2e0 | |||
| 042dff64a9 | |||
| 1830aa7a12 | |||
| b83ffdd2d6 | |||
| ac27e1e5b6 | |||
| 17fae11a38 | |||
| 06594a1149 | |||
| 75a738ad44 | |||
| 11e69eca68 | |||
| 31e06fc087 | |||
| 99c048ce7a | |||
| 1c9b2ce1d3 | |||
| 29a77ded2f | |||
| 6d06c5e61f | |||
| ba745f5b91 | |||
| 0775fa84d1 | |||
| 56ab75df2c | |||
| 383e20e6b4 | |||
| c139883770 | |||
| 6e648ed809 | |||
| 3577fc7091 | |||
| ff2ef3b0cb | |||
| aa2dcd82cf | |||
| 78d259d3b9 | |||
| 4ed569c674 | |||
| a46478d0cb | |||
| 5487e31c4b | |||
| 12ce28e265 | |||
| 139797a165 | |||
| 6709d000cd | |||
| aa6edc3c0b | |||
| 73da7e90f3 | |||
| c0d7a36124 | |||
| 8cc9a75964 | |||
| 21d7fbb67e | |||
| 1fc41e385d | |||
| fe325daec0 | |||
| 3f0f308a7b | |||
| b390e50974 | |||
| 0e46ae3add | |||
| 4d793ee04c | |||
| 7677b84058 | |||
| e7457d78cb | |||
| cbcd66e1de | |||
| 46cd224efb | |||
| d3b716a0b9 | |||
| 693502c341 | |||
| bb968469fa | |||
| 372f7cf41a | |||
| f659193c94 | |||
| 0b6166482a | |||
| 4ff25bbe59 | |||
| afbd71b868 | |||
| e26f82d02c | |||
| 6ad6a35824 | |||
| baa53399f5 | |||
| 37bea77ea7 | |||
| 0d33f3acde | |||
| 05adbf45f3 | |||
| df4795b803 | |||
| 5401418258 | |||
| a5bbba3f05 | |||
| a0664a4ab2 | |||
| a4b8466205 | |||
| 5d1ea5806a | |||
| ab247c723b | |||
| fb997111f4 | |||
| c6bff57950 | |||
| 07faafe4da | |||
| 295b7fb582 | |||
| cf9de567c1 | |||
| f47ac761af | |||
| 642a97adcc | |||
| 3bba3ff5e9 | |||
| b3b43af816 | |||
| 1b06b37db2 | |||
| a1b4c9c551 | |||
| cd58df7a26 | |||
| 70ed68ff5b | |||
| 598ccde435 | |||
| cb09fda90d | |||
| c8f1853bfe | |||
| 2f781e2e65 | |||
| 30c6ee64ab | |||
| fd90f7eac9 | |||
| 77b91a072b | |||
| 9ede0e40fa | |||
| 1ccfca17d6 | |||
| d6153d4d4d | |||
| 2289fa69f1 | |||
| 3cb3585432 | |||
| a2193eb4cf | |||
| 8ecde47203 | |||
| b978cb348e | |||
| 353ca06d07 | |||
| 20c08ac40d | |||
| 4aa1273a80 | |||
| 2a87c65994 | |||
| cdee97d3f1 | |||
| 06d6a5efd9 | |||
| 0be92bc8a6 | |||
| 61db287b8f | |||
| 3293a873bd | |||
| 8d53d3cbf2 | |||
| 47c4864dd1 | |||
| f411247aa1 | |||
| 9a8702d937 | |||
| 5ee4363000 | |||
| 77c0b74e3b | |||
| 34adf4e54c | |||
| 5400b53edf | |||
| 599bcee13e | |||
| 569cef71d0 | |||
| 0972503aef | |||
| 46b15e6365 | |||
| 3232277bc5 | |||
| bbd09c7bfa | |||
| 52dc8adafb | |||
| 6f054ecc2f | |||
| 4fec27ccc2 | |||
| fea0d02d99 | |||
| beafa5ec31 | |||
| 82a815aafb | |||
| 4efa427a87 | |||
| 30b1c5bf6d | |||
| 3f871f9f7a | |||
| cafe5e1e59 | |||
| a58d869502 | |||
| 28e11b114b | |||
| 1da30e76e8 | |||
| 58348c38ef | |||
| 578c03efa5 | |||
| 7255b4d73c | |||
| e161babbd4 | |||
| f8e63fc480 | |||
| 82397ec7f0 | |||
| 17da1f585e | |||
| 293bc20db0 | |||
| 818b96ffbd | |||
| 7b5ec8a065 | |||
| 4af5cc760d | |||
| 41d80b99ac | |||
| 2b0ba0eabc | |||
| 66edb56911 | |||
| 15e48b6af3 | |||
| d5adea5863 | |||
| 8041d0a4e8 | |||
| 94d9861d29 | |||
| 63ff7d81e0 | |||
| e6b6a0cbb2 | |||
| 0912124c33 | |||
| c0306d9942 | |||
| 3fff0813e8 | |||
| 3714d9ad8d | |||
| 1820e875dc | |||
| a112c7446c | |||
| aab7f3db71 | |||
| 08c90664f0 | |||
| f2a66365de | |||
| c338585791 | |||
| c011891247 | |||
| 6ca6f72750 | |||
| 39c150ae58 | |||
| 58991f3f63 | |||
| 4038fa615b | |||
| 198338e2a2 | |||
| bc4e70f2c0 | |||
| b28b85dbf4 | |||
| ad73f4943b | |||
| 4d22803c32 | |||
| 9ee3cce380 | |||
| babec0f29b | |||
| 212bf88eb2 | |||
| 26332c9de4 | |||
| af2e12d58e |
@@ -0,0 +1 @@
|
||||
github: [wisskid]
|
||||
@@ -23,6 +23,7 @@ jobs:
|
||||
matrix:
|
||||
os:
|
||||
- ubuntu-latest
|
||||
- windows-latest
|
||||
|
||||
php-version:
|
||||
- "7.2"
|
||||
@@ -31,28 +32,16 @@ jobs:
|
||||
- "8.0"
|
||||
- "8.1"
|
||||
- "8.2"
|
||||
- "8.3"
|
||||
- "8.4"
|
||||
- "8.5"
|
||||
|
||||
compiler:
|
||||
- default
|
||||
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
php-version: "8.0"
|
||||
compiler: jit
|
||||
- os: ubuntu-latest
|
||||
php-version: "8.1"
|
||||
compiler: jit
|
||||
- os: ubuntu-latest
|
||||
php-version: "8.2"
|
||||
compiler: jit
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Override PHP ini values for JIT compiler
|
||||
if: matrix.compiler == 'jit'
|
||||
run: echo "PHP_INI_VALUES::assert.exception=1, zend.assertions=1, opcache.enable=1, opcache.enable_cli=1, opcache.optimization_level=-1, opcache.jit=1255, opcache.jit_buffer_size=32M" >> $GITHUB_ENV
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install PHP with extensions
|
||||
uses: shivammathur/setup-php@v2
|
||||
@@ -64,7 +53,7 @@ jobs:
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v3
|
||||
uses: actions/cache@v4
|
||||
with:
|
||||
path: vendor
|
||||
key: v5r2-${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
|
||||
@@ -72,7 +61,7 @@ jobs:
|
||||
v5r1-${{ runner.os }}-php-${{ matrix.php-version }}-
|
||||
|
||||
- name: Install dependencies
|
||||
uses: php-actions/composer@v6
|
||||
run: composer install
|
||||
|
||||
- name: Run make
|
||||
run: make -B
|
||||
|
||||
@@ -7,3 +7,5 @@ phpunit*
|
||||
.phpunit.result.cache
|
||||
vendor/*
|
||||
composer.lock
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
# AGENTS.md
|
||||
|
||||
This file is the single source of truth for AI coding assistants working in this repo (including Claude Code, claude.ai/code).
|
||||
|
||||
## Project
|
||||
|
||||
Smarty v5 — PHP template engine. Single Composer package (`smarty/smarty`), namespace `Smarty\`, source in `src/`, autoloaded via PSR-4. Supports PHP 7.2–8.5.
|
||||
|
||||
Do not use PHP syntax newer than 7.2 in `src/` unless it is guarded for older runtimes.
|
||||
|
||||
## Commands
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
composer install
|
||||
|
||||
# Regenerate lexers and parsers (required before tests; CI runs this)
|
||||
make -B
|
||||
|
||||
# Run all tests
|
||||
php ./vendor/phpunit/phpunit/phpunit
|
||||
|
||||
# Run a single test file
|
||||
php ./vendor/phpunit/phpunit/phpunit tests/UnitTests/TemplateSource/TagTests/If/CompileIfTest.php
|
||||
|
||||
# Run tests matching a PHPUnit group
|
||||
php ./vendor/phpunit/phpunit/phpunit --group 20221124
|
||||
|
||||
# Run tests excluding slow group
|
||||
php ./vendor/phpunit/phpunit/phpunit --exclude-group slow
|
||||
```
|
||||
|
||||
There is no linter or static analysis configured. No typecheck step.
|
||||
|
||||
## Generated code — do not hand-edit
|
||||
|
||||
Four files are generated from grammar/lexer definitions via `make`:
|
||||
|
||||
| Source (edit this) | Generated (do not edit) |
|
||||
|---|---|
|
||||
| `src/Lexer/TemplateLexer.plex` | `src/Lexer/TemplateLexer.php` |
|
||||
| `src/Lexer/ConfigfileLexer.plex` | `src/Lexer/ConfigfileLexer.php` |
|
||||
| `src/Parser/TemplateParser.y` | `src/Parser/TemplateParser.php` |
|
||||
| `src/Parser/ConfigfileParser.y` | `src/Parser/ConfigfileParser.php` |
|
||||
|
||||
After editing a `.plex` or `.y` file, run `make -B` to regenerate. The generators require the `smarty/smarty-lexer` dev dependency.
|
||||
|
||||
## Architecture
|
||||
|
||||
- `src/Smarty.php` — main class, extends `TemplateBase`. Version constant: `Smarty::SMARTY_VERSION`.
|
||||
- `src/Compile/`, `src/Compiler/` — template compilation pipeline.
|
||||
- `src/Lexer/`, `src/Parser/` — lexer/parser (generated, see above).
|
||||
- `src/Extension/` — extension system (`ExtensionInterface`, `CoreExtension`, `DefaultExtension`, `BCPluginsAdapter`).
|
||||
- `src/Runtime/` — runtime helpers (foreach, capture, inheritance, tpl functions).
|
||||
- `src/Resource/`, `src/Cacheresource/` — template resource and cache resource handlers.
|
||||
- `src/BlockHandler/`, `src/FunctionHandler/`, `src/Filter/` — built-in tags, functions, and filters.
|
||||
- `libs/Smarty.class.php` — non-Composer autoload stub. Points to `src/`. Not the main source.
|
||||
- `src/functions.php` — global helper functions, always loaded via Composer `files` autoload.
|
||||
|
||||
## Tests
|
||||
|
||||
- Framework: PHPUnit 7.5/8.5 (bootstrap: `tests/Bootstrap.php`).
|
||||
- All tests extend `PHPUnit_Smarty` (defined in `tests/PHPUnit_Smarty.php`), which provides `setUpSmarty($dir)`.
|
||||
- Test suite root: `tests/UnitTests/`. Typical test `setUp()` calls `$this->setUpSmarty(__DIR__)`.
|
||||
- Each test directory may have its own `templates/`, `configs/` subdirectories. Compiled output goes to `templates_c/` and `cache/` (auto-created by the test harness).
|
||||
- Running the suite scatters generated `templates_c/`, `cache/`, and `templates_tmp/` directories (and empty runtime `templates/`/`configs/` dirs) throughout `tests/` and the repo root. These are not tracked — treat them as noise in `git status`, never commit them, and clean them with `git clean -fd` (exclude tool dirs like `.serena`).
|
||||
- Three test files are excluded in `phpunit.xml`: Memcache, APC, and HttpModifiedSince tests (require external services).
|
||||
- Tests needing MySQL/PDO are gated by constants in `tests/Config.php` (disabled by default).
|
||||
|
||||
## CI
|
||||
|
||||
GitHub Actions (`.github/workflows/ci.yml`): matrix of PHP 7.2–8.5 on ubuntu + windows. Steps: `composer install` → `make -B` → `phpunit`. No deploy step.
|
||||
|
||||
## Docs
|
||||
|
||||
Markdown in `docs/`, built with mkdocs + Material theme. Install the toolchain with `pip install -r docs/requirements.txt`, then preview with `mkdocs serve`. Published via `mike deploy 5.x`.
|
||||
|
||||
## Release
|
||||
|
||||
`./make-release.sh <version>` — only v5.x.x. Updates changelog and version constant, creates a merge commit and tag on `master`.
|
||||
|
||||
### Changelog
|
||||
|
||||
Every change that should appear in `CHANGELOG.md` must add a new markdown file under `changelog/`. At release time `utilities/update-changelog.php` concatenates all `changelog/*.md` files into the `## [Unreleased]` section, so:
|
||||
|
||||
- One file per change, containing a single line that starts with a dash (`- ...`). The filename is arbitrary; name it after the issue number (e.g. `1036.md`) when there is one, otherwise use a short descriptive slug.
|
||||
- Include a markdown link to the relevant issue when one exists, e.g. `[#1036](https://github.com/smarty-php/smarty/issues/1036)`. Omit the link when there is no public issue (e.g. embargoed security reports).
|
||||
+142
-1
@@ -6,8 +6,148 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [5.8.4] - 2026-06-29
|
||||
- Fixed a `TypeError` on PHP 8 when `Security::$static_classes` was set to a non-array value (e.g. the string `'none'`) to disable static class access; any non-array value now cleanly denies access. Use `Security::$static_classes = null` to disable access to all static classes.
|
||||
- Security: the built-in `stream:` resource type now validates the nested stream wrapper against the security policy, so a template such as `stream:php://filter/...` can no longer bypass `Security::$streams` (including `Security::$streams = null`) to read local files (CWE-22)
|
||||
|
||||
|
||||
## [5.8.3] - 2026-06-28
|
||||
- fixed a regression from #1189 where a child template's block override no longer applied to a template {include}d by the parent [#1192](https://github.com/smarty-php/smarty/issues/1192)
|
||||
|
||||
|
||||
## [5.8.2] - 2026-06-24
|
||||
- Security: prevent symlinks inside a trusted `secure_dir`/template directory from being used to read files outside of it (CWE-22 path traversal), affecting `{include}` and `{fetch}` of local files
|
||||
- Security: `{html_image}` now escapes the `file`, `path_prefix`, `href`/`link`, `width` and `height` attributes (it already escaped `alt` and pass-through attributes), and `{html_select_date}` casts `day_size`/`month_size`/`year_size` to int (matching `{html_select_time}`), preventing untrusted values passed into these attributes from breaking out of the generated HTML (CWE-79)
|
||||
- Security: `{fetch}` no longer follows HTTP redirects for remote resources while a security policy is active, preventing an open redirect on a trusted host from bypassing `trusted_uri` (CWE-918 server-side request forgery)
|
||||
- Fixed "Attempt to assign property step on null" error when using a {for} loop inside a block of an extended template [#1036](https://github.com/smarty-php/smarty/issues/1036)
|
||||
|
||||
|
||||
## [5.8.1] - 2026-06-23
|
||||
- Re-activated unit tests for user literals, which were previously disabled due to a bug in refactoring to v5.
|
||||
- fixed a bug where child template's block content leaked into subsequent rendering of the parent template [#1189](https://github.com/smarty-php/smarty/issues/1189)
|
||||
- Moved all unit test-generated output from inside the working tree to tmp files [#1178](https://github.com/smarty-php/smarty/issues/1178)
|
||||
|
||||
|
||||
## [5.8.0] - 2026-02-15
|
||||
- Added support for Backed Enums for php versions >= 8.1 [#1171](https://github.com/smarty-php/smarty/pull/1171)
|
||||
- Added support for new 'matches' operator doing regex matching [#1169](https://github.com/smarty-php/smarty/pull/1169)
|
||||
- Update documentation to clarify that include inline is currently not implemented in Smarty v5 [#1152](https://github.com/smarty-php/smarty/issues/1152)
|
||||
- Support for Laravel Collections style object chaining for objects return from function calls implemented as modifiers [#1151](https://github.com/smarty-php/smarty/issues/1151)
|
||||
|
||||
|
||||
## [5.7.0] - 2025-11-19
|
||||
- PHP 8.5 support
|
||||
|
||||
|
||||
## [5.6.0] - 2025-10-03
|
||||
- Added support for shorttags in functions [#1005](https://github.com/smarty-php/smarty/issues/1005)
|
||||
|
||||
|
||||
## [5.5.2] - 2025-08-26
|
||||
|
||||
|
||||
- Fixed escaping of array/object keys in debug_print_var
|
||||
|
||||
## [5.5.1] - 2025-05-19
|
||||
- Fix missing support for loading modifiercompilers from plugin dir in BCPluginsAdapter [#1132](https://github.com/smarty-php/smarty/pull/1132)
|
||||
|
||||
|
||||
## [5.5.0] - 2025-05-03
|
||||
- Support trailing comma in array [#1013](https://github.com/smarty-php/smarty/issues/1013)
|
||||
|
||||
|
||||
## [5.4.5] - 2025-04-15
|
||||
- Fixed deprecation notice in StringEval in PHP8.4 [#1119](https://github.com/smarty-php/smarty/issues/1119)
|
||||
|
||||
|
||||
## [5.4.4] - 2025-04-13
|
||||
- Fix syntax error occurring when registering a function plugin that ends with the string 'close' [#1122](https://github.com/smarty-php/smarty/issues/1122)
|
||||
- Replace SMARTY_VERSION constant with $smarty.version in debug.tpl [#1073](https://github.com/smarty-php/smarty/issues/1073)
|
||||
|
||||
|
||||
## [5.4.3] - 2024-12-23
|
||||
- Fix PHP backtraces by qualifying/replacing `call_user_func_array` calls [#1074](https://github.com/smarty-php/smarty/issues/1074)
|
||||
|
||||
|
||||
## [5.4.2] - 2024-11-20
|
||||
|
||||
|
||||
- Support the deprecations introduced in PHP 8.4 and added tests for PHP 8.4 [#1043](https://github.com/smarty-php/smarty/pull/1043)
|
||||
|
||||
## [5.4.1] - 2024-08-29
|
||||
|
||||
|
||||
- Enable (and fix) unit tests for Windows [#1046](https://github.com/smarty-php/smarty/pull/1046)
|
||||
- Fix the use of "extends:" to define the inheritance tree on Windows [#1018](https://github.com/smarty-php/smarty/issues/1018)
|
||||
|
||||
## [5.4.0] - 2024-08-14
|
||||
- Fixing forced OpCache invalidation on every template include, which is resulting in fast raising wasted OpCache memory [#1007](https://github.com/smarty-php/smarty/issues/1007)
|
||||
- Improvement of auto-escaping [#1030](https://github.com/smarty-php/smarty/pull/1030)
|
||||
|
||||
|
||||
## [5.3.1] - 2024-06-16
|
||||
- Fixed error when using section with nocache [#1034](https://github.com/smarty-php/smarty/issues/1034)
|
||||
|
||||
|
||||
## [5.3.0] - 2024-05-30
|
||||
- Fix warning when calling hasVariable for an undefined variable [#977](https://github.com/smarty-php/smarty/issues/977)
|
||||
- Added `$smarty->prependTemplateDir()` method [#1022](https://github.com/smarty-php/smarty/issues/1022)
|
||||
|
||||
|
||||
## [5.2.0] - 2024-05-28
|
||||
- Fixed a code injection vulnerability in extends-tag. This addresses CVE-2024-35226.
|
||||
- Added `$smarty->setCacheModifiedCheck()` setter for cache_modified_check
|
||||
- Added a PSR-4 loading script to allow Smarty to be used without Composer [#1017](https://github.com/smarty-php/smarty/pull/1017)
|
||||
|
||||
|
||||
## [5.1.0] - 2024-04-22
|
||||
- Prevent deprecation notices during compilation in PHP8.3 [#996](https://github.com/smarty-php/smarty/issues/996)
|
||||
- Fix that getTemplateVars would return an array of objects instead of the assigned variables values [#994](https://github.com/smarty-php/smarty/issues/994)
|
||||
- Fix Smarty::assign() not returning $this when called with an array as first parameter [#972](https://github.com/smarty-php/smarty/pull/972)
|
||||
- Documented support for `{if $element is in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
- Added support for `{if $element is not in $array}` syntax [#937](https://github.com/smarty-php/smarty/issues/937)
|
||||
- Using stream variables in templates now throws a deprecation notice [#933](https://github.com/smarty-php/smarty/pull/933)
|
||||
- Internal compiler classes always return a string (the internal has_code flag has been removed for simplicity) [#918](https://github.com/smarty-php/smarty/pull/918)
|
||||
- Fix invalid classnames in Runtime code for foreach [#1000](https://github.com/smarty-php/smarty/issues/1000)
|
||||
|
||||
## [5.0.2] - 2024-03-28
|
||||
- Fix Smarty::assign() not returning $this when called with an array as first parameter [#972](https://github.com/smarty-php/smarty/pull/972)
|
||||
|
||||
## [5.0.1] - 2024-03-27
|
||||
- Fix error in Smarty\Smarty::compileAllTemplates() by including missing FilesystemIterator class [#966](https://github.com/smarty-php/smarty/issues/966)
|
||||
|
||||
## [5.0.0] - 2024-03-25
|
||||
- Fixed that scoped variables would overwrite parent scope [#952](https://github.com/smarty-php/smarty/issues/952)
|
||||
- Removed publicly accessible `$tpl->_var_stack` variable
|
||||
|
||||
### Fixed
|
||||
- Too many shorthand attributes error when using a modifier as a function with more than 3 parameters in an expression [#949](https://github.com/smarty-php/smarty/issues/949)
|
||||
|
||||
### Removed
|
||||
- Dropped support for undocumented `{time()}` added in v5.0.0 since we already have the documented `{$smarty.now}`
|
||||
|
||||
## [5.0.0-rc3] - 2024-02-26
|
||||
|
||||
### Added
|
||||
- PHP8.3 support [#925](https://github.com/smarty-php/smarty/issues/925)
|
||||
- Backlink to GitHub in docs
|
||||
- Explain how to do escaping and set-up auto-escaping in docs [#865](https://github.com/smarty-php/smarty/issues/865)
|
||||
- Link to variable scope page in the documentation for the assign tag [#878](https://github.com/smarty-php/smarty/issues/878)
|
||||
- Add support for implode, substr and json_encode as modifiers/functions in templates [#939](https://github.com/smarty-php/smarty/issues/939)
|
||||
- Add template path to CompilerException to enable rich debug features [#935](https://github.com/smarty-php/smarty/issues/935)
|
||||
|
||||
### Fixed
|
||||
- The {debug} tag was broken in v5 [#922](https://github.com/smarty-php/smarty/issues/922)
|
||||
- Documentation on `{if $x is even by $y}` syntax
|
||||
- Fix incorrect compilation of expressions when escape_html=true [#930](https://github.com/smarty-php/smarty/pull/930)
|
||||
|
||||
## [5.0.0-rc2] - 2023-11-11
|
||||
|
||||
### Fixed
|
||||
- Registered output filters wouldn't run [#899](https://github.com/smarty-php/smarty/issues/899)
|
||||
- Use of negative numbers in {math} equations [#895](https://github.com/smarty-php/smarty/issues/895)
|
||||
- Do not auto-html-escape custom function results [#906](https://github.com/smarty-php/smarty/issues/906)
|
||||
- Fix case-sensitive tag names [#907](https://github.com/smarty-php/smarty/issues/907)
|
||||
|
||||
### Removed
|
||||
- Removed `$smarty->registered_filters` array
|
||||
@@ -34,7 +174,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
multibyte extension for optimal performance.
|
||||
- Smarty no longer calls `mb_internal_encoding()` and doesn't check for deprecated `mbstring.func_overload` ini directive [#480](https://github.com/smarty-php/smarty/issues/480)
|
||||
- Generated `<script>` tags lo longer have deprecated `type="text/javascript"` or `language="Javascript"` attributes [#815](https://github.com/smarty-php/smarty/issues/815)
|
||||
- Smarty will throw a compiler exception insteadd of silently ignoring a modifier on a function call, like this: `{include|dot:"x-template-id" file="included.dot.tpl"}` [#526](https://github.com/smarty-php/smarty/issues/526)
|
||||
- Smarty will throw a compiler exception instead of silently ignoring a modifier on a function call, like this: `{include|dot:"x-template-id" file="included.dot.tpl"}` [#526](https://github.com/smarty-php/smarty/issues/526)
|
||||
- The documentation was largely rewritten
|
||||
|
||||
### Deprecated
|
||||
@@ -66,6 +206,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- Removed constants such as SMARTY_DIR to prevent global side effects.
|
||||
- Removed direct access to `$smarty->template_dir`. Use `$smarty->setTemplateDir()`.
|
||||
- Removed direct access to `$smarty->cache_dir`. Use `$smarty->setCacheDir()`.
|
||||
- Removed direct access to `$smarty->compile_dir`. Use `$smarty->setCompileDir()`.
|
||||
- Removed `$smarty->loadPlugin()`, use `$smarty->registerPlugin()` instead.
|
||||
- Removed `$smarty->appendByRef()` and `$smarty->assignByRef()`.
|
||||
- Removed `$smarty->_current_file`
|
||||
|
||||
+126
@@ -0,0 +1,126 @@
|
||||
# Contributing to Smarty
|
||||
|
||||
First off, thanks for taking the time to contribute! ❤️
|
||||
|
||||
> And if you like the project, but just don't have time to contribute, that's fine. There are other easy ways to support the project and show your appreciation, which we would also be very happy about:
|
||||
> - Star the project
|
||||
> - Tell a friend about it
|
||||
> - Refer this project in your project's readme
|
||||
> - Mention the project at local meetups and tell your friends/colleagues
|
||||
|
||||
## I Have a Question
|
||||
|
||||
> If you want to ask a question, we assume that you have read the available [Documentation](https://smarty-php.github.io/smarty).
|
||||
|
||||
Before you ask a question, it is best to search for existing [Issues](https://github.com/smarty-php/smarty/issues) that might help you.
|
||||
In case you have found a suitable issue and still need clarification, you can write your question in this issue.
|
||||
It is also advisable to search the internet for answers first.
|
||||
|
||||
If you then still feel the need to ask a question and need clarification, we recommend the following:
|
||||
|
||||
- [Open an Issue](https://github.com/smarty-php/smarty/issues/new).
|
||||
- Provide as much context as you can about what you're running into.
|
||||
- Provide Smarty and PHP versions
|
||||
|
||||
We will then take care of the issue as soon as possible.
|
||||
|
||||
## I Want To Contribute
|
||||
|
||||
> ### Legal Notice
|
||||
> When contributing to this project, you must agree that you have authored 100% of the content,
|
||||
> that you have the necessary rights to the content and that the content you contribute may be provided under the project license.
|
||||
|
||||
### Reporting Bugs
|
||||
|
||||
#### Before Submitting a Bug Report
|
||||
|
||||
A good bug report shouldn't leave others needing to chase you up for more information. Therefore, we ask you to
|
||||
investigate carefully, collect information and describe the issue in detail in your report. Please complete the
|
||||
following steps in advance to help us fix any potential bug as fast as possible.
|
||||
|
||||
- Make sure that you are using the latest version.
|
||||
- Determine if your bug is really a bug and not an error on your side. (Make sure that you have read the [documentation](https://smarty-php.github.io/smarty). If you are looking for support, you might want to check [this section](#i-have-a-question)).
|
||||
- To see if other users have experienced (and potentially already solved) the same issue you are having, check if there is not already a bug report existing for your bug or error in the [bug tracker](https://github.com/smarty-php/smarty/issues?q=label%3Abug).
|
||||
- Also make sure to search the internet (including Stack Overflow) to see if users outside of the GitHub community have discussed the issue.
|
||||
- Collect information about the bug:
|
||||
- For an Exception: please provide the Stack trace
|
||||
- OS (Windows, Linux, macOS)
|
||||
- PHP version
|
||||
- Smarty version
|
||||
- A minimal snippet of (your) code that triggers the bug
|
||||
- Expected output versus actual output
|
||||
- Can you reliably reproduce the issue? And can you also reproduce it with older versions?
|
||||
|
||||
#### How Do I Submit a Good Bug Report?
|
||||
|
||||
> You must never report security related issues, vulnerabilities or bugs including sensitive information to the issue tracker, or elsewhere in public.
|
||||
> For sensitive bugs, please see [SECURITY.md](SECURITY.md).
|
||||
|
||||
We use GitHub issues to track bugs and errors. If you run into an issue with the project:
|
||||
|
||||
- Open an [Issue](https://github.com/smarty-php/smarty/issues/new). (Since we can't be sure at this point whether it is a bug or not, we ask you not to talk about a bug yet and not to label the issue.)
|
||||
- Explain the behavior you would expect and the actual behavior.
|
||||
- Please provide as much context as possible and describe the *reproduction steps* that someone else can follow to recreate the issue on their own. This usually includes your code. For good bug reports you should isolate the problem and create a reduced test case.
|
||||
- Provide the information you collected in the previous section.
|
||||
|
||||
Once it's filed:
|
||||
|
||||
- The project team will label the issue accordingly.
|
||||
- A team member will try to reproduce the issue with your provided steps. If there are no reproduction steps or no obvious way to reproduce the issue, the team will ask you for those steps and mark the issue as `needs-repro`. Bugs with the `needs-repro` tag will not be addressed until they are reproduced.
|
||||
- If the team is able to reproduce the issue, it will be marked `needs-fix`, as well as possibly other tags (such as `critical`), and the issue will be left to be implemented by someone.
|
||||
|
||||
|
||||
|
||||
### Suggesting Enhancements
|
||||
|
||||
This section guides you through submitting an enhancement suggestion for CONTRIBUTING.md, **including completely new features and minor improvements to existing functionality**. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.
|
||||
|
||||
|
||||
#### Before Submitting an Enhancement
|
||||
|
||||
- Make sure that you are using the latest version.
|
||||
- Read the [documentation](https://smarty-php.github.io/smarty) carefully and find out if the functionality is already covered, maybe by an individual configuration.
|
||||
- Perform a [search](https://github.com/smarty-php/smarty/issues) to see if the enhancement has already been suggested. If it has, add a comment to the existing issue instead of opening a new one.
|
||||
- Find out whether your idea fits with the scope and aims of the project. It's up to you to make a strong case to convince the project's developers of the merits of this feature. Keep in mind that we want features that will be useful to the majority of our users and not just a small subset. If you're just targeting a minority of users, consider writing an add-on/plugin library.
|
||||
|
||||
|
||||
#### How Do I Submit a Good Enhancement Suggestion?
|
||||
|
||||
Enhancement suggestions are tracked as [GitHub issues](https://github.com/smarty-php/smarty/issues).
|
||||
|
||||
- Use a **clear and descriptive title** for the issue to identify the suggestion.
|
||||
- Provide a **step-by-step description of the suggested enhancement** in as many details as possible.
|
||||
- **Describe the current behavior** and **explain which behavior you expected to see instead** and why. At this point you can also tell which alternatives do not work for you.
|
||||
- You may want to **include screenshots and animated GIFs** which help you demonstrate the steps or point out the part which the suggestion is related to. You can use [this tool](https://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux.
|
||||
- **Explain why this enhancement would be useful** to most CONTRIBUTING.md users. You may also want to point out the other projects that solved it better and which could serve as inspiration.
|
||||
|
||||
|
||||
### Improving The Documentation
|
||||
|
||||
The [docs](docs/index.md) are written in markdown, configured in [mkdocs.yml](mkdocs.yml) and published
|
||||
to [GitHub pages](https://smarty-php.github.io/smarty) using [mkdocs](https://www.mkdocs.org/) and [mike](https://github.com/jimporter/mike).
|
||||
|
||||
You need Python to build the docs. Install the required packages first:
|
||||
```bash
|
||||
pip install -r docs/requirements.txt
|
||||
```
|
||||
|
||||
To preview the docs while you are writing, run:
|
||||
```bash
|
||||
mkdocs serve
|
||||
```
|
||||
This should launch a local web server and give you a link to open in your browser.
|
||||
|
||||
When you are finished, commit your changes and provide a [Pull Request](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/proposing-changes-to-your-work-with-pull-requests/creating-a-pull-request).
|
||||
|
||||
#### Publishing the docs
|
||||
If you are a maintainer, you can publish the document using [mike](https://github.com/jimporter/mike). Make sure you provide the correct version.
|
||||
|
||||
```bash
|
||||
mike deploy 5.x
|
||||
```
|
||||
|
||||
Then, push the `gh-pages` branch.
|
||||
|
||||
## Attribution
|
||||
This guide is based on the **contributing.md**. [Make your own](https://contributing.md/)!
|
||||
@@ -3,12 +3,6 @@ all: lexers parsers
|
||||
lexers: src/Lexer/ConfigfileLexer.php src/Lexer/TemplateLexer.php
|
||||
parsers: src/Parser/ConfigfileParser.php src/Parser/TemplateParser.php
|
||||
|
||||
docs:
|
||||
mike deploy 5.x
|
||||
|
||||
test-docs:
|
||||
mkdocs serve
|
||||
|
||||
src/Lexer/ConfigfileLexer.php: src/Lexer/ConfigfileLexer.plex
|
||||
php ./utilities/make-lexer.php src/Lexer/ConfigfileLexer.plex src/Lexer/ConfigfileLexer.php
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ Smarty is a template engine for PHP, facilitating the separation of presentation
|
||||
Read the [documentation](https://smarty-php.github.io/smarty/) to find out how to use it.
|
||||
|
||||
## Requirements
|
||||
Smarty v5 can be run with PHP 7.2 to PHP 8.2.
|
||||
Smarty v5 can be run with PHP 7.2 to PHP 8.5.
|
||||
|
||||
## Installation
|
||||
Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/).
|
||||
@@ -18,3 +18,11 @@ composer require smarty/smarty
|
||||
````
|
||||
|
||||
More in the [Getting Started](./docs/getting-started.md) section of the docs.
|
||||
|
||||
## Sponsors
|
||||
|
||||
Smarty is sponsored by:
|
||||
- Marc Laporte [@marclaporte](https://github.com/marclaporte)
|
||||
- [Temma](https://github.com/Digicreon/Temma), the MVC framework based on Smarty
|
||||
|
||||
Thank you!
|
||||
@@ -11,10 +11,10 @@
|
||||
## include inline
|
||||
- Re-introduce merge_compiled_includes and the {include inline} attribute?
|
||||
|
||||
## Output buffering
|
||||
- Fix ob_ output buffering commands being scattered around the codebase
|
||||
## Output buffering (major)
|
||||
- Fix ob_ output buffering commands being scattered around the codebase: Smarty's output model is fundamentally "echo everything, wrap in a buffer to capture". An alternative that would be where rendering returns a string rather than echoing — but that touches the entire compiled template format (the unifunc functions all echo) and is a large change.
|
||||
|
||||
## Review public static vars
|
||||
## Review public static vars (major)
|
||||
- such as _CHARSET and _IS_WINDOWS
|
||||
|
||||
## Block / inheritance
|
||||
@@ -24,10 +24,8 @@
|
||||
## Plugin system
|
||||
- fix template security checks in one place in compiler
|
||||
|
||||
## Beatify output
|
||||
## Beatify output (major)
|
||||
- compiled templates could be proper classes, possibly using [nette/php-generator](https://packagist.org/packages/nette/php-generator)
|
||||
|
||||
## Unrelated / other
|
||||
- review (and avoid) use of 'clone' keyword
|
||||
- compiler->has_code seems silly. Why not have proper return values?
|
||||
- what is 'user literal support', why are unit tests skipped?
|
||||
|
||||
+42
-2
@@ -1,11 +1,10 @@
|
||||
version: "2"
|
||||
services:
|
||||
base:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./utilities/testrunners/php72/Dockerfile
|
||||
volumes:
|
||||
- .:/app
|
||||
- smarty-code:/app
|
||||
working_dir: /app
|
||||
php72:
|
||||
extends:
|
||||
@@ -37,3 +36,44 @@ services:
|
||||
service: base
|
||||
build:
|
||||
dockerfile: ./utilities/testrunners/php82/Dockerfile
|
||||
php83:
|
||||
extends:
|
||||
service: base
|
||||
build:
|
||||
dockerfile: ./utilities/testrunners/php83/Dockerfile
|
||||
php84:
|
||||
extends:
|
||||
service: base
|
||||
build:
|
||||
dockerfile: ./utilities/testrunners/php84/Dockerfile
|
||||
volumes:
|
||||
smarty-code:
|
||||
|
||||
x-mutagen:
|
||||
sync:
|
||||
defaults:
|
||||
symlink:
|
||||
mode: "posix-raw"
|
||||
ignore:
|
||||
vcs: true
|
||||
paths:
|
||||
- ".docker"
|
||||
- ".env.docker"
|
||||
- ".bundles"
|
||||
- "docker-compose.yml"
|
||||
- ".idea"
|
||||
- ".DS_Store"
|
||||
mode: "two-way-resolved"
|
||||
configurationBeta:
|
||||
permissions:
|
||||
defaultOwner: "id:${APP_USER_ID}"
|
||||
defaultGroup: "id:${APP_GROUP_ID}"
|
||||
defaultFileMode: 0666
|
||||
defaultDirectoryMode: 0755
|
||||
permissions:
|
||||
defaultOwner: "id:${APP_USER_ID}"
|
||||
defaultGroup: "id:${APP_GROUP_ID}"
|
||||
smarty-code:
|
||||
alpha: "."
|
||||
beta: "volume://smarty-code"
|
||||
|
||||
|
||||
+2
-1
@@ -89,4 +89,5 @@ Run this, and you will see:
|
||||
```
|
||||
|
||||
Note how the [escape modifier](../designers/language-modifiers/language-modifier-escape.md)
|
||||
translated the `&` character into the proper HTML syntax `&`.
|
||||
translated the `&` character into the proper HTML syntax `&`.
|
||||
Read more about auto-escaping in the [next section](./configuring.md).
|
||||
+60
-10
@@ -12,24 +12,27 @@ Use `getTemplateDir()` to retrieve the configured paths.
|
||||
<?php
|
||||
|
||||
// set a single directory where the config files are stored
|
||||
$smarty->setTemplateDir('./config');
|
||||
$smarty->setTemplateDir('./templates');
|
||||
|
||||
// set multiple directories where config files are stored
|
||||
$smarty->setTemplateDir(['./config', './config_2', './config_3']);
|
||||
// set multiple directories where templates are stored
|
||||
$smarty->setTemplateDir(['./templates', './templates_2', './templates_3']);
|
||||
|
||||
// add directory where config files are stored to the current list of dirs
|
||||
$smarty->addTemplateDir('./config_1');
|
||||
// add directory where templates files are stored to the current list of dirs
|
||||
$smarty->addTemplateDir('./templates_1');
|
||||
|
||||
// add multiple directories to the current list of dirs
|
||||
$smarty->addTemplateDir([
|
||||
'./config_2',
|
||||
'./config_3',
|
||||
'./templates_2',
|
||||
'./templates_3',
|
||||
]);
|
||||
|
||||
// chaining of method calls
|
||||
$smarty->setTemplateDir('./config')
|
||||
->addTemplateDir('./config_1')
|
||||
->addTemplateDir('./config_2');
|
||||
$smarty->setTemplateDir('./templates')
|
||||
->addTemplateDir('./templates_1')
|
||||
->addTemplateDir('./templates_2');
|
||||
|
||||
// insert a template dir before exising template dirs
|
||||
$smarty->prependTemplateDir('./more_important_templates')
|
||||
|
||||
// get all directories where config files are stored
|
||||
$template_dirs = $smarty->getTemplateDir();
|
||||
@@ -122,6 +125,53 @@ $smarty->setCacheDir('/data/caches');
|
||||
$cacheDir = $smarty->getCacheDir();
|
||||
```
|
||||
|
||||
## Enabling auto-escaping
|
||||
By default, Smarty does not escape anything you render in your templates. If you use
|
||||
Smarty to render a HTML-page, this means that you will have to make sure that you do
|
||||
not render any characters that have a special meaning in HTML, such as `&`, `<` and `>`,
|
||||
or apply the [escape modifier](../designers/language-modifiers/language-modifier-escape.md)
|
||||
to anything you want to render.
|
||||
|
||||
If you forget to do so, you may break your HTML page, or even create a vulnerability for
|
||||
attacks known as [XSS or Cross Site Scripting](https://cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html).
|
||||
|
||||
Luckily, you can tell Smarty to automatically apply the escape modifier to any dynamic part of your template.
|
||||
It's like Smarty magically adds `|escape` to every variable you use on a web page.
|
||||
|
||||
Enable auto-escaping for HTML as follows:
|
||||
```php
|
||||
$smarty->setEscapeHtml(true);
|
||||
```
|
||||
|
||||
When auto-escaping is enabled, the `|escape` modifier's default mode (`html`) has no effect,
|
||||
to avoid double-escaping. It is possible to force it with the `force` mode.
|
||||
Other modes (`htmlall`, `url`, `urlpathinfo`, `quotes`, `javascript`) may be used
|
||||
with the result you might expect, without double-escaping.
|
||||
|
||||
Even when auto-escaping is enabled, you might want to display the content of a variable without
|
||||
escaping it. To do so, use the `|raw` modifier.
|
||||
|
||||
Examples (with auto-escaping enabled):
|
||||
```smarty
|
||||
{* these three statements are identical *}
|
||||
{$myVar}
|
||||
{$myVar|escape}
|
||||
{$myVar|escape:'html'}
|
||||
|
||||
{* no double-escaping on these statements *}
|
||||
{$var|escape:'htmlall'}
|
||||
{$myVar|escape:'url'}
|
||||
{$myVar|escape:'urlpathinfo'}
|
||||
{$myVar|escape:'quotes'}
|
||||
{$myVar|escape:'javascript'}
|
||||
|
||||
{* no escaping at all *}
|
||||
{$myVar|raw}
|
||||
|
||||
{* force double-escaping *}
|
||||
{$myVar|escape:'force'}
|
||||
```
|
||||
|
||||
## Disabling compile check
|
||||
By default, Smarty tests to see if the
|
||||
current template has changed since the last time
|
||||
|
||||
@@ -10,4 +10,7 @@ template.
|
||||
{$foo:bar}
|
||||
```
|
||||
|
||||
NB. Support for using streams to call variables is deprecated since Smarty v5.1 and will be removed
|
||||
in a future version.
|
||||
|
||||
See also [`Template Resources`](../resources.md)
|
||||
|
||||
@@ -27,6 +27,144 @@ Various basic operators can be applied directly to variable values.
|
||||
> complex, it may be a good idea to move the bits that do not deal
|
||||
> explicitly with presentation to PHP by way of plugins or modifiers.
|
||||
|
||||
## List
|
||||
The following is a list of recognized operators, which must be
|
||||
separated from surrounding elements by spaces. Note that items listed in
|
||||
\[brackets\] are optional. PHP equivalents are shown where applicable.
|
||||
|
||||
| Operator | Alternates | Syntax Example | Meaning | PHP Equivalent |
|
||||
|--------------------|------------|----------------------|--------------------------------|--------------------|
|
||||
| == | eq | $a eq $b | equals | == |
|
||||
| != | ne, neq | $a neq $b | not equals | != |
|
||||
| > | gt | $a gt $b | greater than | > |
|
||||
| < | lt | $a lt $b | less than | < |
|
||||
| >= | gte, ge | $a ge $b | greater than or equal | >= |
|
||||
| <= | lte, le | $a le $b | less than or equal | <= |
|
||||
| === | | $a === 0 | check for identity | === |
|
||||
| ! | not | not $a | negation (unary) | ! |
|
||||
| % | mod | $a mod $b | modulo | % |
|
||||
| is \[not\] div by | | $a is not div by 4 | divisible by | $a % $b == 0 |
|
||||
| is \[not\] even | | $a is not even | \[not\] an even number (unary) | $a % 2 == 0 |
|
||||
| is \[not\] even by | | $a is not even by $b | grouping level \[not\] even | ($a / $b) % 2 == 0 |
|
||||
| is \[not\] odd | | $a is not odd | \[not\] an odd number (unary) | $a % 2 != 0 |
|
||||
| is \[not\] odd by | | $a is not odd by $b | \[not\] an odd grouping | ($a / $b) % 2 != 0 |
|
||||
| is in | | $a is in $b | exists in array | in_array($a, $b) |
|
||||
| is \[not\] in | | $a is not in $b | does not exist in array | !in_array($a, $b) |
|
||||
| matches | | $a matches $b | regex pattern match | preg_match($b, $a) |
|
||||
|
||||
## Regex Matching Operator
|
||||
|
||||
The `matches` operator allows you to test if a string matches a regular expression pattern.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```smarty
|
||||
{if "hello" matches "/^[a-z]+$/"}
|
||||
String matches the pattern!
|
||||
{/if}
|
||||
|
||||
{if $email matches "/^[^@]+@[^@]+\.[^@]+$/"}
|
||||
Valid email format
|
||||
{else}
|
||||
Invalid email format
|
||||
{/if}
|
||||
```
|
||||
|
||||
### Using Variables
|
||||
|
||||
```smarty
|
||||
{$pattern = '/^[a-zA-Z0-9]{8,}$/'}
|
||||
{if $password matches $pattern}
|
||||
Password meets requirements
|
||||
{else}
|
||||
Password must be at least 8 alphanumeric characters
|
||||
{/if}
|
||||
```
|
||||
|
||||
### Pattern Modifiers
|
||||
|
||||
The `matches` operator supports all standard PHP regex modifiers:
|
||||
|
||||
```smarty
|
||||
{* Case insensitive matching *}
|
||||
{if "HELLO" matches "/hello/i"}
|
||||
Matches (case insensitive)
|
||||
{/if}
|
||||
|
||||
{* Multiline mode *}
|
||||
{if "line1\nline2" matches "/line2$/m"}
|
||||
Matches in multiline mode
|
||||
{/if}
|
||||
|
||||
{* Dot matches newlines *}
|
||||
{if "hello\nworld" matches "/hello.world/s"}
|
||||
Matches with dotall modifier
|
||||
{/if}
|
||||
```
|
||||
|
||||
### Complex Conditions
|
||||
|
||||
The `matches` operator can be combined with other operators:
|
||||
|
||||
```smarty
|
||||
{if $username matches "/^[a-z]+$/" && $username|length > 3}
|
||||
Valid username
|
||||
{else}
|
||||
Username must be lowercase letters and at least 4 characters
|
||||
{/if}
|
||||
|
||||
{if $input matches "/^[0-9]+$/" || $input matches "/^[a-z]+$/"}
|
||||
Input is either numeric or lowercase letters
|
||||
{else}
|
||||
Invalid input format
|
||||
{/if}
|
||||
```
|
||||
|
||||
### Practical Examples
|
||||
|
||||
**Email Validation:**
|
||||
```smarty
|
||||
{if $email matches "/^[^@\s]+@[^@\s]+\.[^@\s]+$/"}
|
||||
Valid email address
|
||||
{else}
|
||||
Please enter a valid email address
|
||||
{/if}
|
||||
```
|
||||
|
||||
**Password Strength:**
|
||||
```smarty
|
||||
{if $password matches "/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{8,}$/"}
|
||||
Strong password
|
||||
{else}
|
||||
Password must contain uppercase, lowercase, numbers and be at least 8 characters
|
||||
{/if}
|
||||
```
|
||||
|
||||
**URL Validation:**
|
||||
```smarty
|
||||
{if $url matches "/^https?:\/\/(www\.)?[a-z0-9\-]+(\.[a-z]{2,})+/i"}
|
||||
Valid URL format
|
||||
{else}
|
||||
Please enter a valid URL
|
||||
{/if}
|
||||
```
|
||||
|
||||
**Numeric Validation:**
|
||||
```smarty
|
||||
{if $input matches "/^[0-9]+$/"}
|
||||
Valid numeric input
|
||||
{else}
|
||||
Please enter numbers only
|
||||
{/if}
|
||||
```
|
||||
|
||||
### Notes
|
||||
|
||||
- The `matches` operator uses PHP's `preg_match()` function internally
|
||||
- Pattern delimiters must be valid regex delimiters (typically `/`)
|
||||
- Invalid patterns will cause PHP warnings but won't break template execution
|
||||
- For complex regex patterns, consider using variables for better readability
|
||||
|
||||
## Ternary
|
||||
You can use the `?:` (or ternary) operator to test one expression and present the value
|
||||
of the second or third expression, based on the result of the test.
|
||||
|
||||
@@ -88,9 +88,6 @@ Object chaining:
|
||||
|
||||
{$object->method1($x)->method2($y)}
|
||||
|
||||
Direct PHP function access:
|
||||
|
||||
{time()}
|
||||
```
|
||||
|
||||
> **Note**
|
||||
|
||||
@@ -8,12 +8,12 @@ execution of a template**.
|
||||
|----------------|------------|-----------------------------------------------------------------------|
|
||||
| var | | The name of the variable being assigned |
|
||||
| value | | The value being assigned |
|
||||
| scope | (optional) | The scope of the assigned variable: \'parent\',\'root\' or \'global\' |
|
||||
| scope | (optional) | The scope of the assigned variable: 'parent','root' or 'global' |
|
||||
|
||||
## Attributes of the {$var=...} syntax
|
||||
| Attribute Name | Required | Description |
|
||||
|----------------|------------|-----------------------------------------------------------------------|
|
||||
| scope | (optional) | The scope of the assigned variable: \'parent\',\'root\' or \'global\' |
|
||||
| scope | (optional) | The scope of the assigned variable: 'parent','root' or 'global' |
|
||||
|
||||
## Option Flags
|
||||
| Name | Description |
|
||||
@@ -102,6 +102,8 @@ A global variable is seen by all templates.
|
||||
{$foo="bar" scope="global"}
|
||||
```
|
||||
|
||||
For more information on variable scope, please read the page on [variable scopes](../language-variables/language-variable-scopes.md).
|
||||
|
||||
To access `{assign}` variables from a php script use
|
||||
[`getTemplateVars()`](../../programmers/api-functions/api-get-template-vars.md).
|
||||
Here's the template that creates the variable `$foo`.
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
|----------------|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| file | Yes | The name of the config file to include |
|
||||
| section | No | The name of the section to load |
|
||||
| scope | no | How the scope of the loaded variables are treated, which must be one of local, parent or global. local means variables are loaded into the local template context. parent means variables are loaded into both the local context and the parent template that called it. global means variables are available to all templates. |
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -252,7 +252,7 @@ iteration.
|
||||
|
||||
```smarty
|
||||
{foreach $myNames as $name}
|
||||
{if $name@iteration is even by 3}
|
||||
{if $name@index is even by 3}
|
||||
<span style="color: #000">{$name}</span>
|
||||
{else}
|
||||
<span style="color: #eee">{$name}</span>
|
||||
|
||||
@@ -3,32 +3,8 @@
|
||||
`{if}` statements in Smarty have much the same flexibility as PHP
|
||||
[if](https://www.php.net/if) statements, with a few added features for the
|
||||
template engine. Every `{if}` must be paired with a matching `{/if}`.
|
||||
`{else}` and `{elseif}` are also permitted. All PHP conditionals and
|
||||
functions are recognized, such as *\|\|*, *or*, *&&*, *and*,
|
||||
*is_array()*, etc.
|
||||
|
||||
The following is a list of recognized qualifiers, which must be
|
||||
separated from surrounding elements by spaces. Note that items listed in
|
||||
\[brackets\] are optional. PHP equivalents are shown where applicable.
|
||||
|
||||
## Qualifiers
|
||||
|
||||
| Qualifier | Alternates | Syntax Example | Meaning | PHP Equivalent |
|
||||
|--------------------|------------|----------------------|--------------------------------|--------------------|
|
||||
| == | eq | $a eq $b | equals | == |
|
||||
| != | ne, neq | $a neq $b | not equals | != |
|
||||
| > | gt | $a gt $b | greater than | > |
|
||||
| < | lt | $a lt $b | less than | < |
|
||||
| >= | gte, ge | $a ge $b | greater than or equal | >= |
|
||||
| <= | lte, le | $a le $b | less than or equal | <= |
|
||||
| === | | $a === 0 | check for identity | === |
|
||||
| ! | not | not $a | negation (unary) | ! |
|
||||
| % | mod | $a mod $b | modulo | % |
|
||||
| is \[not\] div by | | $a is not div by 4 | divisible by | $a % $b == 0 |
|
||||
| is \[not\] even | | $a is not even | \[not\] an even number (unary) | $a % 2 == 0 |
|
||||
| is \[not\] even by | | $a is not even by $b | grouping level \[not\] even | ($a / $b) % 2 == 0 |
|
||||
| is \[not\] odd | | $a is not odd | \[not\] an odd number (unary) | $a % 2 != 0 |
|
||||
| is \[not\] odd by | | $a is not odd by $b | \[not\] an odd grouping | ($a / $b) % 2 != 0 |
|
||||
`{else}` and `{elseif}` are also permitted. All [operators](../language-basic-syntax/language-syntax-operators.md) are recognized, such as *==*,
|
||||
*\|\|*, *or*, *&&*, *and*, etc and you can use modifiers as functions, such as *is_array()*.
|
||||
|
||||
## Examples
|
||||
```smarty
|
||||
|
||||
@@ -47,11 +47,13 @@ available within the included template.
|
||||
|
||||
## Option Flags
|
||||
|
||||
| Name | Description |
|
||||
|---------|--------------------------------------------------------------------------------------|
|
||||
| nocache | Disables caching of this subtemplate |
|
||||
| caching | Enable caching of this subtemplate |
|
||||
| inline | If set, merge the compile-code of the subtemplate into the compiled calling template |
|
||||
| Name | Description |
|
||||
|-----------|--------------------------------------------------------------------------------------|
|
||||
| nocache | Disables caching of this subtemplate |
|
||||
| caching | Enable caching of this subtemplate |
|
||||
| inline \* | If set, merge the compile-code of the subtemplate into the compiled calling template |
|
||||
|
||||
\* The `inline` option flag is currently not implemented in Smarty v5. Using it will not trigger an error, however.
|
||||
|
||||
## Examples
|
||||
```smarty
|
||||
@@ -85,11 +87,11 @@ The template above includes the example `links.tpl` below
|
||||
|
||||
```smarty
|
||||
<div id="box">
|
||||
<h3>{$title}{/h3>
|
||||
<h3>{$title}</h3>
|
||||
<ul>
|
||||
{foreach from=$links item=l}
|
||||
.. do stuff ...
|
||||
</foreach}
|
||||
{/foreach}
|
||||
</ul>
|
||||
</div>
|
||||
```
|
||||
|
||||
@@ -326,10 +326,10 @@ The template to output the database result in a HTML table
|
||||
|
||||
```smarty
|
||||
<table>
|
||||
<tr><th> </th><th>Name></th><th>Home</th><th>Cell</th><th>Email</th></tr>
|
||||
<tr><th> </th><th>Name</th><th>Home</th><th>Cell</th><th>Email</th></tr>
|
||||
{section name=co loop=$contacts}
|
||||
<tr>
|
||||
<td><a href="view.php?id={$contacts[co].id}">view<a></td>
|
||||
<td><a href="view.php?id={$contacts[co].id}">view</a></td>
|
||||
<td>{$contacts[co].name}</td>
|
||||
<td>{$contacts[co].home}</td>
|
||||
<td>{$contacts[co].cell}</td>
|
||||
@@ -465,7 +465,7 @@ header block every five rows.
|
||||
<table>
|
||||
{section name=co loop=$contacts}
|
||||
{if $smarty.section.co.iteration is div by 5}
|
||||
<tr><th> </th><th>Name></th><th>Home</th><th>Cell</th><th>Email</th></tr>
|
||||
<tr><th> </th><th>Name</th><th>Home</th><th>Cell</th><th>Email</th></tr>
|
||||
{/if}
|
||||
<tr>
|
||||
<td><a href="view.php?id={$contacts[co].id}">view<a></td>
|
||||
@@ -478,13 +478,13 @@ header block every five rows.
|
||||
</table>
|
||||
```
|
||||
|
||||
An example that uses the `iteration` property to alternate a text color every
|
||||
An example that uses the `index` property to alternate a text color every
|
||||
third row.
|
||||
|
||||
```smarty
|
||||
<table>
|
||||
{section name=co loop=$contacts}
|
||||
{if $smarty.section.co.iteration is even by 3}
|
||||
{if $smarty.section.co.index is even by 3}
|
||||
<span style="color: #ffffff">{$contacts[co].name}</span>
|
||||
{else}
|
||||
<span style="color: #dddddd">{$contacts[co].name}</span>
|
||||
|
||||
@@ -3,31 +3,8 @@
|
||||
`{while}` loops in Smarty have much the same flexibility as PHP
|
||||
[while](https://www.php.net/while) statements, with a few added features for
|
||||
the template engine. Every `{while}` must be paired with a matching
|
||||
`{/while}`. All PHP conditionals and functions are recognized, such as
|
||||
*\|\|*, *or*, *&&*, *and*, *is_array()*, etc.
|
||||
|
||||
The following is a list of recognized qualifiers, which must be
|
||||
separated from surrounding elements by spaces. Note that items listed in
|
||||
\[brackets\] are optional. PHP equivalents are shown where applicable.
|
||||
|
||||
## Qualifiers
|
||||
|
||||
| Qualifier | Alternates | Syntax Example | Meaning | PHP Equivalent |
|
||||
|--------------------|------------|----------------------|--------------------------------|--------------------|
|
||||
| == | eq | $a eq $b | equals | == |
|
||||
| != | ne, neq | $a neq $b | not equals | != |
|
||||
| > | gt | $a gt $b | greater than | > |
|
||||
| < | lt | $a lt $b | less than | < |
|
||||
| >= | gte, ge | $a ge $b | greater than or equal | >= |
|
||||
| <= | lte, le | $a le $b | less than or equal | <= |
|
||||
| === | | $a === 0 | check for identity | === |
|
||||
| ! | not | not $a | negation (unary) | ! |
|
||||
| % | mod | $a mod $b | modulo | % |
|
||||
| is \[not\] div by | | $a is not div by 4 | divisible by | $a % $b == 0 |
|
||||
| is \[not\] even | | $a is not even | \[not\] an even number (unary) | $a % 2 == 0 |
|
||||
| is \[not\] even by | | $a is not even by $b | grouping level \[not\] even | ($a / $b) % 2 == 0 |
|
||||
| is \[not\] odd | | $a is not odd | \[not\] an odd number (unary) | $a % 2 != 0 |
|
||||
| is \[not\] odd by | | $a is not odd by $b | \[not\] an odd grouping | ($a / $b) % 2 != 0 |
|
||||
`{/while}`. All [operators](../language-basic-syntax/language-syntax-operators.md) are recognized, such as *==*,
|
||||
*\|\|*, *or*, *&&*, *and*, etc and you can use modifiers as functions, such as *is_array()*.
|
||||
|
||||
## Examples
|
||||
```smarty
|
||||
|
||||
@@ -27,6 +27,13 @@ which item(s) are selected by default as well.
|
||||
- All parameters that are not in the list above are printed as
|
||||
name/value-pairs inside each of the created <input\>-tags.
|
||||
|
||||
> **Security note**
|
||||
>
|
||||
> The `separator` attribute is written into the generated HTML without escaping,
|
||||
> so it can contain markup such as `separator='<br />'`. If its value originates
|
||||
> from untrusted input, escape it yourself first to avoid cross-site scripting
|
||||
> (XSS). Option values and labels are escaped automatically.
|
||||
|
||||
## Examples
|
||||
```php
|
||||
<?php
|
||||
|
||||
@@ -28,6 +28,13 @@ selected by default as well.
|
||||
- All parameters that are not in the list above are output as
|
||||
name/value-pairs inside each of the created `<input>`-tags.
|
||||
|
||||
> **Security note**
|
||||
>
|
||||
> The `separator` attribute is written into the generated HTML without escaping,
|
||||
> so it can contain markup such as `separator='<br />'`. If its value originates
|
||||
> from untrusted input, escape it yourself first to avoid cross-site scripting
|
||||
> (XSS). Option values and labels are escaped automatically.
|
||||
|
||||
## Examples
|
||||
|
||||
```php
|
||||
|
||||
@@ -47,6 +47,14 @@ name/value-pairs inside the `<select>` tags of day, month and year.
|
||||
> There is an useful php function on the [date tips page](../../appendixes/tips.md)
|
||||
> for converting `{html_select_date}` form values to a timestamp.
|
||||
|
||||
> **Security note**
|
||||
>
|
||||
> The `*_extra` attributes, `field_separator`/`option_separator`, and any
|
||||
> unrecognised parameter (which is emitted as a raw attribute on the `<select>`
|
||||
> tag) are written into the generated HTML without escaping. If any of these
|
||||
> values originate from untrusted input, escape them yourself first to avoid
|
||||
> cross-site scripting (XSS).
|
||||
|
||||
## Exaples
|
||||
|
||||
Template code
|
||||
|
||||
@@ -47,6 +47,14 @@ parseable by PHP's [`strtotime()`](https://www.php.net/strtotime).
|
||||
| meridian\_empty | null | If supplied then the first element of the meridian's select-box has this value as it's label and "" as it's value. This is useful to make the select-box read "Please select an meridian" for example. |
|
||||
|
||||
|
||||
> **Security note**
|
||||
>
|
||||
> The `*_extra` attributes, `field_separator`/`option_separator`, and any
|
||||
> unrecognised parameter (which is emitted as a raw attribute on the `<select>`
|
||||
> tag) are written into the generated HTML without escaping. If any of these
|
||||
> values originate from untrusted input, escape them yourself first to avoid
|
||||
> cross-site scripting (XSS).
|
||||
|
||||
## Examples
|
||||
|
||||
```smarty
|
||||
|
||||
@@ -31,6 +31,15 @@ dumps an array of data into an HTML `<table>`.
|
||||
- `trailpad` is the value put into the trailing cells on the last
|
||||
table row if there are any present.
|
||||
|
||||
> **Security note**
|
||||
>
|
||||
> The `loop`/`cols` data and the `caption`, `trailpad`, `table_attr`, `tr_attr`,
|
||||
> `td_attr` and `th_attr` attributes are written into the generated HTML without
|
||||
> escaping (this is by design — e.g. `table_attr='border="1"'`). If any of these
|
||||
> values originate from untrusted input, escape them yourself first (e.g. with the
|
||||
> [`escape`](../language-modifiers/language-modifier-escape.md) modifier) to avoid
|
||||
> cross-site scripting (XSS).
|
||||
|
||||
## Examples
|
||||
|
||||
```php
|
||||
|
||||
@@ -24,6 +24,14 @@ spiders to lift email addresses off of a site.
|
||||
> you can use hex encoding too.
|
||||
|
||||
|
||||
> **Security note**
|
||||
>
|
||||
> The `extra` attribute is written into the generated `<a>` tag without escaping,
|
||||
> so that you can add attributes such as `extra='class="mailto"'`. If you pass a
|
||||
> value that originates from untrusted input, escape it yourself first (e.g. with
|
||||
> the [`escape`](../language-modifiers/language-modifier-escape.md) modifier) to
|
||||
> avoid cross-site scripting (XSS).
|
||||
|
||||
## Examples
|
||||
|
||||
```smarty
|
||||
|
||||
@@ -6,34 +6,10 @@ or strings. To apply a modifier,
|
||||
specify the value followed by a `|` (pipe) and the modifier name. A
|
||||
modifier may accept additional parameters that affect its behavior.
|
||||
These parameters follow the modifier name and are separated by a `:`
|
||||
(colon). Also, *all php-functions can be used as modifiers implicitly*
|
||||
(more below) and modifiers can be
|
||||
[combined](../language-combining-modifiers.md).
|
||||
(colon).
|
||||
|
||||
- [capitalize](language-modifier-capitalize.md)
|
||||
- [cat](language-modifier-cat.md)
|
||||
- [count_characters](language-modifier-count-characters.md)
|
||||
- [count_paragraphs](language-modifier-count-paragraphs.md)
|
||||
- [count_sentences](language-modifier-count-sentences.md)
|
||||
- [count_words](language-modifier-count-words.md)
|
||||
- [date_format](language-modifier-date-format.md)
|
||||
- [default](language-modifier-default.md)
|
||||
- [escape](language-modifier-escape.md)
|
||||
- [from_charset](language-modifier-from-charset.md)
|
||||
- [indent](language-modifier-indent.md)
|
||||
- [lower](language-modifier-lower.md)
|
||||
- [nl2br](language-modifier-nl2br.md)
|
||||
- [regex_replace](language-modifier-regex-replace.md)
|
||||
- [replace](language-modifier-replace.md)
|
||||
- [spacify](language-modifier-spacify.md)
|
||||
- [string_format](language-modifier-string-format.md)
|
||||
- [strip](language-modifier-strip.md)
|
||||
- [strip_tags](language-modifier-strip-tags.md)
|
||||
- [to_charset](language-modifier-to-charset.md)
|
||||
- [truncate](language-modifier-truncate.md)
|
||||
- [unescape](language-modifier-unescape.md)
|
||||
- [upper](language-modifier-upper.md)
|
||||
- [wordwrap](language-modifier-wordwrap.md)
|
||||
Modifiers can be applied to any type of variables, including arrays
|
||||
and objects.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -65,40 +41,63 @@ These parameters follow the modifier name and are separated by a `:`
|
||||
{* php's count *}
|
||||
{$myArray|@count}
|
||||
|
||||
{* this will uppercase and truncate the whole array *}
|
||||
{* this will uppercase the whole array *}
|
||||
<select name="name_id">
|
||||
{html_options output=$my_array|upper|truncate:20}
|
||||
{html_options output=$my_array|upper}
|
||||
</select>
|
||||
```
|
||||
|
||||
- Modifiers can be applied to any type of variables, including arrays
|
||||
and objects.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> The default behavior was changed with Smarty 3. In Smarty 2.x, you
|
||||
> had to use an "`@`" symbol to apply a modifier to an array, such
|
||||
> as `{$articleTitle|@count}`. With Smarty 3, the "`@`" is no
|
||||
> longer necessary, and is ignored.
|
||||
>
|
||||
> If you want a modifier to apply to each individual item of an
|
||||
> array, you will either need to loop the array in the template, or
|
||||
> provide for this functionality inside your modifier function.
|
||||
## Combining Modifiers
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Second, in Smarty 2.x, modifiers were applied to the result of
|
||||
> math expressions like `{8+2}`, meaning that
|
||||
> `{8+2|count_characters}` would give `2`, as 8+2=10 and 10 is two
|
||||
> characters long. With Smarty 3, modifiers are applied to the
|
||||
> variables or atomic expressions before executing the calculations,
|
||||
> so since 2 is one character long, `{8+2|count_characters}`
|
||||
> gives 9. To get the old result use parentheses like
|
||||
> `{(8+2)|count_characters}`.
|
||||
You can apply any number of modifiers to a variable. They will be
|
||||
applied in the order they are combined, from left to right. They must be
|
||||
separated with a `|` (pipe) character.
|
||||
|
||||
- Custom modifiers can be registered
|
||||
with the [`registerPlugin()`](../../programmers/api-functions/api-register-plugin.md)
|
||||
function.
|
||||
```php
|
||||
<?php
|
||||
|
||||
$smarty->assign('articleTitle', 'Smokers are Productive, but Death Cuts Efficiency.');
|
||||
```
|
||||
|
||||
where template is:
|
||||
|
||||
```smarty
|
||||
{$articleTitle}
|
||||
{$articleTitle|upper|spacify}
|
||||
{$articleTitle|lower|spacify|truncate}
|
||||
{$articleTitle|lower|truncate:30|spacify}
|
||||
{$articleTitle|lower|spacify|truncate:30:". . ."}
|
||||
```
|
||||
|
||||
|
||||
The above example will output:
|
||||
|
||||
```
|
||||
Smokers are Productive, but Death Cuts Efficiency.
|
||||
S M O K E R S A R ....snip.... H C U T S E F F I C I E N C Y .
|
||||
s m o k e r s a r ....snip.... b u t d e a t h c u t s...
|
||||
s m o k e r s a r e p r o d u c t i v e , b u t . . .
|
||||
s m o k e r s a r e p. . .
|
||||
```
|
||||
|
||||
## Using modifiers in expressions
|
||||
|
||||
Modifiers can also be used in expressions. For example, you can use the [isset modifier](./language-modifier-isset.md)
|
||||
to test if a variable holds a value different from null.
|
||||
|
||||
```smarty
|
||||
{if $varA|isset}
|
||||
<b>variable A is set</b>
|
||||
{/if}
|
||||
```
|
||||
|
||||
You can also use modifiers in expressions in a PHP-style syntax:
|
||||
|
||||
```smarty
|
||||
{if isset($varA)}
|
||||
<b>variable A is set</b>
|
||||
{/if}
|
||||
```
|
||||
|
||||
See also [`registerPlugin()`](../../programmers/api-functions/api-register-plugin.md), [combining
|
||||
modifiers](../language-combining-modifiers.md). and [extending smarty with
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
# count
|
||||
|
||||
Returns the number of elements in an array (or Countable object). Will return 0 for null.
|
||||
Returns 1 for any other type (such as a string).
|
||||
|
||||
If the optional mode parameter is set to 1, count() will recursively count the array.
|
||||
This is particularly useful for counting all the elements of a multidimensional array.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{if $myVar|count > 3}4 or more{/if}
|
||||
{if count($myVar) > 3}4 or more{/if}
|
||||
```
|
||||
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|--------------------------------------------------------|
|
||||
| 1 | int | No | If set to 1, count() will recursively count the array. |
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# debug_print_var
|
||||
|
||||
|
||||
|
||||
Returns the value of the given variable in a human-readable format in HTML.
|
||||
Used in the [debug console](../chapter-debugging-console.md), but you can also use it in your template
|
||||
while developing to see what is going on under the hood.
|
||||
|
||||
> **Note**
|
||||
>
|
||||
> Use for debugging only! Since you may accidentally reveal sensitive information or introduce vulnerabilities such as XSS using this
|
||||
method never use it in production.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{$myVar|debug_print_var}
|
||||
```
|
||||
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|------------------------------------------------------------------------|
|
||||
| 1 | int | No | maximum recursion depth if $var is an array or object (defaults to 10) |
|
||||
| 2 | int | No | maximum string length if $var is a string (defaults to 40) |
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
# empty
|
||||
|
||||
Returns true if var does not exist or has a value that is empty or equal to zero, aka falsey, see conversion to boolean. Otherwise returns false.
|
||||
|
||||
## Basic usage
|
||||
|
||||
```smarty
|
||||
{if $myVar|empty}it's an empty variable{/if}
|
||||
{if empty($myVar)}it's an empty variable{/if}
|
||||
```
|
||||
@@ -73,6 +73,6 @@ This snippet is useful for emails, but see also
|
||||
<a href="mailto:{$EmailAddress|escape:'hex'}">{$EmailAddress|escape:'mail'}</a>
|
||||
```
|
||||
|
||||
See also [escaping smarty parsing](../language-basic-syntax/language-escaping.md),
|
||||
See also [auto-escaping](../../api/configuring.md#enabling-auto-escaping), [escaping smarty parsing](../language-basic-syntax/language-escaping.md),
|
||||
[`{mailto}`](../language-custom-functions/language-function-mailto.md) and the [obfuscating email
|
||||
addresses](../../appendixes/tips.md#obfuscating-e-mail-addresses) page.
|
||||
addresses](../../appendixes/tips.md#obfuscating-e-mail-addresses) pages.
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
# in_array
|
||||
|
||||
test if value is contained in an array
|
||||
|
||||
## Basic usage
|
||||
|
||||
```smarty
|
||||
{if in_array('value2', $myarray)} value2 is in myarray{/if}
|
||||
```
|
||||
|
||||
Can be replaced by operator *is in*
|
||||
|
||||
```smarty
|
||||
{if 'value2' is in $myarray}value2 is in myarray{/if}
|
||||
```
|
||||
|
||||
See Also [operators](../language-basic-syntax/language-syntax-operators.md)
|
||||
@@ -0,0 +1,9 @@
|
||||
# is_array
|
||||
|
||||
Return true if the variable passed to it is an array.
|
||||
|
||||
## Basic usage
|
||||
|
||||
```smarty
|
||||
{if $myVar|is_array}it's an array{/if}
|
||||
```
|
||||
@@ -0,0 +1,11 @@
|
||||
# isset
|
||||
|
||||
Returns true if the variable(s) passed to it are different from null.
|
||||
|
||||
If multiple parameters are supplied then isset() will return true only if all of the parameters are
|
||||
not null.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{if $myVar|isset}all set!{/if}
|
||||
```
|
||||
@@ -0,0 +1,26 @@
|
||||
# join
|
||||
|
||||
Returns a string containing all the element of the given array
|
||||
with the separator string between each.
|
||||
|
||||
## Basic usage
|
||||
|
||||
For `$myArray` populated with `['a','b','c']`, the following will return the string `abc`.
|
||||
```smarty
|
||||
{$myArray|join}
|
||||
```
|
||||
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|--------|----------|-------------------------------------------------------------|
|
||||
| 1 | string | No | glue used between array elements. Defaults to empty string. |
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
For `$myArray` populated with `[1,2,3]`, the following will return the string `1-2-3`.
|
||||
```smarty
|
||||
{$myArray|join:"-"}
|
||||
```
|
||||
@@ -0,0 +1,27 @@
|
||||
# json_encode
|
||||
|
||||
Transforms a value into a valid JSON string.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{$user|json_encode}
|
||||
```
|
||||
Depending on the value of `$user` this would return a string in JSON-format, e.g. `{"username":"my_username","email":"my_username@smarty.net"}`.
|
||||
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-------------------------------------------------------------------------------------------|
|
||||
| 1 | int | No | bitmask of flags, directly passed to [PHP's json_encode](https://www.php.net/json_encode) |
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
By passing `16` as the second parameter, you can force json_encode to always format the JSON-string as an object.
|
||||
Without it, an array `$myArray = ["a","b"]` would be formatted as a javascript array:
|
||||
|
||||
```smarty
|
||||
{$myArray|json_encode} # renders: ["a","b"]
|
||||
{$myArray|json_encode:16} # renders: {"0":"a","1":"b"}
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
# noprint
|
||||
|
||||
Always returns an empty string. This can be used to call a function or a method on an object that
|
||||
returns output, and suppress the output.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{$controller->sendEmail()|noprint}
|
||||
```
|
||||
@@ -0,0 +1,32 @@
|
||||
# number_format
|
||||
|
||||
Allows you to format a number using decimals and a thousands-separator. By default, the number of decimals is 0
|
||||
and the number is rounded.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{$num = 2000.151}
|
||||
{$num|number_format} # renders: 2,000
|
||||
```
|
||||
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|--------|----------|---------------------------------------|
|
||||
| 1 | int | No | number of decimals (defaults to 0) |
|
||||
| 2 | string | No | decimal separator (defaults to ".") |
|
||||
| 3 | string | No | thousands-separator (defaults to ",") |
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
```smarty
|
||||
{$num = 2000.151}
|
||||
{$num|number_format:2} # renders: 2,000.15
|
||||
```
|
||||
|
||||
```smarty
|
||||
{$num = 2000.151}
|
||||
{$num|number_format:2:".":""} # renders: 2000.15
|
||||
```
|
||||
@@ -0,0 +1,8 @@
|
||||
# raw
|
||||
|
||||
Prevents variable escaping when [auto-escaping](../../api/configuring.md#enabling-auto-escaping) is activated.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{$myVar|raw}
|
||||
```
|
||||
@@ -0,0 +1,35 @@
|
||||
# round
|
||||
|
||||
Rounds a number to the specified precision.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{3.14|round} # renders: 3
|
||||
```
|
||||
|
||||
```smarty
|
||||
{3.141592|round:2} # renders: 3.14
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|---------------------------|
|
||||
| 1 | int | No | precision (defaults to 0) |
|
||||
| 2 | int | No | mode (defaults to 1) |
|
||||
|
||||
If 'precision' is negative, the number is rounded to the nearest power of 10. See examples below.
|
||||
|
||||
The parameter 'mode' defines how the rounding is done. By default, 2.5 is rounded to 3, whereas 2.45 is rounded to 2.
|
||||
You usually don't need to change this. For more details on rounding modes,
|
||||
see [PHP's documentation on round](https://www.php.net/manual/en/function.round).
|
||||
|
||||
## Examples
|
||||
|
||||
By passing `16` as the second parameter, you can force json_encode to always format the JSON-string as an object.
|
||||
Without it, an array `$myArray = ["a","b"]` would be formatted as a javascript array:
|
||||
|
||||
```smarty
|
||||
{$myArray|json_encode} # renders: ["a","b"]
|
||||
{$myArray|json_encode:16} # renders: {"0":"a","1":"b"}
|
||||
```
|
||||
@@ -0,0 +1,32 @@
|
||||
# split
|
||||
|
||||
Splits a string into an array, using the optional second parameter as the separator.
|
||||
|
||||
## Basic usage
|
||||
|
||||
For `$chars` populated with `'abc'`, the following will produce a html list with 3 elements (a, b and c).
|
||||
```smarty
|
||||
<ol>
|
||||
{foreach $chars|split as $char}
|
||||
<li>{$char|escape}</li>
|
||||
{/foreach}
|
||||
</ol>
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|--------|----------|------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 1 | string | No | separator used to split the string on. Defaults to empty string, causing each character in the source string to be separate. |
|
||||
|
||||
## Examples
|
||||
|
||||
|
||||
For `$ids` populated with `'1,2,3'`, the following will produce a html list with 3 elements (1, 2 and 3).
|
||||
```smarty
|
||||
<ol>
|
||||
{foreach $ids|split:',' as $id}
|
||||
<li>{$id|escape}</li>
|
||||
{/foreach}
|
||||
</ol>
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
# str_repeat
|
||||
|
||||
Repeats the given value n times.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{"hi"|str_repeat:2} # renders: hihi
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-----------------------|
|
||||
| 1 | int | yes | number of repetitions |
|
||||
@@ -0,0 +1,9 @@
|
||||
# strlen
|
||||
|
||||
Returns the length (number of characters) in the given string, including spaces.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{"Smarty"|strlen} # renders: 6
|
||||
{156|strlen} # renders: 3
|
||||
```
|
||||
@@ -0,0 +1,25 @@
|
||||
# substr
|
||||
|
||||
Returns a part (substring) of the given string starting at a given offset.
|
||||
|
||||
## Basic usage
|
||||
```smarty
|
||||
{"Smarty"|substr:2} # renders: arty
|
||||
{"Smarty"|substr:2:3} # renders: art
|
||||
```
|
||||
|
||||
## Parameters
|
||||
|
||||
| Parameter | Type | Required | Description |
|
||||
|-----------|------|----------|-----------------------------------------------------|
|
||||
| 1 | int | yes | offset (zero based, can be negative) |
|
||||
| 2 | int | no | length of substring returned (unlimited of omitted) |
|
||||
|
||||
|
||||
## Examples
|
||||
|
||||
When used with a negative offset, the substring starts n characters from the end of the string counting backwards.
|
||||
```smarty
|
||||
{"Smarty"|substr:-2} # renders: ty
|
||||
{"Smarty"|substr:-2:1} # renders: t
|
||||
```
|
||||
@@ -29,5 +29,5 @@ If Strike isn't Settled Quickly it may Last a While.
|
||||
IF STRIKE ISN'T SETTLED QUICKLY IT MAY LAST A WHILE.
|
||||
```
|
||||
|
||||
See also [`lower`](lower) and
|
||||
See also [`lower`](./language-modifier-lower.md) and
|
||||
[`capitalize`](language-modifier-capitalize.md).
|
||||
|
||||
@@ -123,4 +123,89 @@ this will output:
|
||||
```html
|
||||
name: Zaphod Beeblebrox<br />
|
||||
email: zaphod@slartibartfast.example.com<br />
|
||||
```
|
||||
```
|
||||
|
||||
## Backed Enums (PHP 8.1+)
|
||||
|
||||
Smarty supports accessing properties of [backed enums](https://www.php.net/manual/en/language.enumerations.backed.php) introduced in PHP 8.1.
|
||||
|
||||
### Accessing Enum Properties
|
||||
|
||||
You can access the `name` and `value` properties of backed enum cases:
|
||||
|
||||
```smarty
|
||||
{* Access enum case properties *}
|
||||
<option id="{MyEnum::Foo->name}">{MyEnum::Foo->value}</option>
|
||||
```
|
||||
|
||||
### Complete Example
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Smarty\Smarty;
|
||||
|
||||
// Define a backed enum
|
||||
enum Status: string {
|
||||
case Active = 'active';
|
||||
case Inactive = 'inactive';
|
||||
case Pending = 'pending';
|
||||
}
|
||||
|
||||
$smarty = new Smarty();
|
||||
$smarty->assign('currentStatus', Status::Active);
|
||||
$smarty->display('template.tpl');
|
||||
```
|
||||
|
||||
`template.tpl`:
|
||||
|
||||
```smarty
|
||||
{* Display enum properties *}
|
||||
Current status: {$currentStatus->name} (value: {$currentStatus->value})
|
||||
|
||||
{* Use in HTML attributes *}
|
||||
<select name="status">
|
||||
<option value="{Status::Active->value}" {if $currentStatus->name === 'Active'}selected{/if}>Active</option>
|
||||
<option value="{Status::Inactive->value}" {if $currentStatus->name === 'Inactive'}selected{/if}>Inactive</option>
|
||||
<option value="{Status::Pending->value}" {if $currentStatus->name === 'Pending'}selected{/if}>Pending</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
This would output:
|
||||
|
||||
```html
|
||||
Current status: Active (value: active)
|
||||
|
||||
<select name="status">
|
||||
<option value="active" selected>Active</option>
|
||||
<option value="inactive">Inactive</option>
|
||||
<option value="pending">Pending</option>
|
||||
</select>
|
||||
```
|
||||
|
||||
### Integer-backed Enums
|
||||
|
||||
Integer-backed enums work the same way:
|
||||
|
||||
```php
|
||||
<?php
|
||||
enum Priority: int {
|
||||
case Low = 1;
|
||||
case Medium = 2;
|
||||
case High = 3;
|
||||
}
|
||||
|
||||
$smarty->assign('priority', Priority::High);
|
||||
```
|
||||
|
||||
```smarty
|
||||
{* Access integer enum properties *}
|
||||
Priority level: {$priority->value} ({$priority->name})
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```html
|
||||
Priority level: 3 (High)
|
||||
```
|
||||
|
||||
> **Note**: Backed enum support requires PHP 8.1 or higher. The enum must be registered or available in the current namespace.
|
||||
+4
-2
@@ -22,6 +22,8 @@ Some of Smarty's features:
|
||||
- [Template Inheritance](api/inheritance.md) for
|
||||
easy management of template content.
|
||||
- [Plugin](api/extending/introduction.md) architecture
|
||||
- Regex pattern matching with the [`matches`](designers/language-basic-syntax/language-syntax-operators.md#regex-matching-operator) operator
|
||||
- Support for PHP 8.1+ [backed enums](designers/language-variables/language-assigned-variables.md#backed-enums-php-81)
|
||||
|
||||
## Separation of presentation from application code
|
||||
- This means templates can certainly contain logic under the condition
|
||||
@@ -134,8 +136,8 @@ that would be needed otherwise? Does the codebase or framework you plan
|
||||
on using have the features you need for the presentation component?
|
||||
|
||||
## Sites using Smarty
|
||||
Many well-known PHP projects make use of Smarty such as XOOPS CMS, CMS Made Simple, Tiki
|
||||
CMS/Groupware and X-Cart to name a few.
|
||||
Many well-known PHP projects make use of Smarty such as XOOPS CMS, CMS Made Simple,
|
||||
Tiki Wiki CMS Groupware and X-Cart to name a few.
|
||||
|
||||
## Summary
|
||||
Whether you are using Smarty for a small website or massive enterprise
|
||||
|
||||
+28
-4
@@ -1,7 +1,7 @@
|
||||
# Getting started
|
||||
|
||||
## Requirements
|
||||
Smarty can be run with PHP 7.2 to PHP 8.2.
|
||||
Smarty can be run with PHP 7.2 to PHP 8.5.
|
||||
|
||||
## Installation
|
||||
Smarty can be installed with [Composer](https://getcomposer.org/).
|
||||
@@ -16,18 +16,26 @@ To get the latest, unreleased version, use:
|
||||
composer require smarty/smarty:dev-master
|
||||
```
|
||||
|
||||
To get the previous stable version of Smarty, Smarty 3, use:
|
||||
To get the previous stable version of Smarty, Smarty 4, use:
|
||||
```shell
|
||||
composer require smarty/smarty:^3
|
||||
composer require smarty/smarty:^4
|
||||
```
|
||||
|
||||
Here's how you create an instance of Smarty in your PHP scripts:
|
||||
```php
|
||||
<?php
|
||||
|
||||
// Instantiated via composer
|
||||
require 'vendor/autoload.php';
|
||||
use Smarty\Smarty;
|
||||
$smarty = new Smarty();
|
||||
|
||||
// or ...
|
||||
|
||||
// Instantiated directly
|
||||
require("/path/to/smarty/libs/Smarty.class.php");
|
||||
use Smarty\Smarty;
|
||||
$smarty = new Smarty();
|
||||
```
|
||||
|
||||
Now that the library files are in place, it's time to set up the Smarty
|
||||
@@ -86,7 +94,7 @@ needs to be located in the [`$template_dir`](./programmers/api-variables/variabl
|
||||
|
||||
```smarty
|
||||
{* Smarty *}
|
||||
Hello {$name}, welcome to Smarty!
|
||||
<h1>Hello {$name|escape}, welcome to Smarty!</h1>
|
||||
```
|
||||
|
||||
> **Note**
|
||||
@@ -132,6 +140,20 @@ Now, run your PHP file. You should see *"Hello Ned, welcome to Smarty!"*
|
||||
|
||||
You have completed the basic setup for Smarty!
|
||||
|
||||
## Escaping
|
||||
You may have noticed that the example template above renders the `$name` variable using
|
||||
the [escape modifier](./designers/language-modifiers/language-modifier-escape.md). This
|
||||
modifier makes string 'safe' to use in the context of an HTML page.
|
||||
|
||||
If you are primarily using Smarty for HTML-pages, it is recommended to enable automatic
|
||||
escaping. This way, you don't have to add `|escape` to every variable you use on a web page.
|
||||
Smarty will handle it automatically for you!
|
||||
|
||||
Enable auto-escaping for HTML as follows:
|
||||
```php
|
||||
$smarty->setEscapeHtml(true);
|
||||
```
|
||||
|
||||
## Extended Setup
|
||||
|
||||
This is a continuation of the [basic installation](#installation), please read that first!
|
||||
@@ -156,6 +178,8 @@ class My_GuestBook extends Smarty {
|
||||
$this->setCompileDir('/web/www.example.com/guestbook/templates_c/');
|
||||
$this->setConfigDir('/web/www.example.com/guestbook/configs/');
|
||||
$this->setCacheDir('/web/www.example.com/guestbook/cache/');
|
||||
|
||||
$this->setEscapeHtml(true);
|
||||
|
||||
$this->caching = Smarty::CACHING_LIFETIME_CURRENT;
|
||||
$this->assign('app_name', 'Guest Book');
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 343.3 174.5" style="enable-background:new 0 0 343.3 174.5;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#E60000;}
|
||||
.st1{fill:#FFFFFF;}
|
||||
</style>
|
||||
<path class="st0" d="M333.8,0H9.5C4.3,0,0,4.3,0,9.5v155.4c0,5.3,4.3,9.5,9.5,9.5h324.3c5.3,0,9.5-4.3,9.5-9.5V9.5
|
||||
C343.3,4.3,339,0,333.8,0z"/>
|
||||
<g>
|
||||
<path class="st1" d="M148.7,58.5c-5.2,0-4.7,4.3-4.7,9.5v38.6c0,5.3,4.3,9.5,9.5,9.5c5.2,0,9.5-4.3,9.5-9.5V81.5
|
||||
C163,65.7,154,58.5,148.7,58.5L148.7,58.5z"/>
|
||||
<path class="st1" d="M47.1,72.6c-5.2,0-4.7,4.3-4.7,9.5v24.5c0,5.2,4.3,9.5,9.5,9.5c5.2,0,9.5-4.3,9.5-9.5V95.5
|
||||
C61.4,79.8,52.4,72.6,47.1,72.6L47.1,72.6z"/>
|
||||
<path class="st1" d="M200.7,58.3c-7.4,0-13.8,6.9-15.2,11.4c-3-7.6-8.5-11.2-12.2-11.2c-5.2,0-4.7,4.3-4.7,9.5l0.1,9.5v29.1
|
||||
c0,5.2,4.3,9.5,9.5,9.5c5.2,0,9.5-4.3,9.5-9.5V84.4c0-3.8,1.2-8.4,7-8.4c1.7,0,6.8,0,6.8,8.4v22.2c0,5.2,4.3,9.5,9.5,9.5
|
||||
c5.2,0,9.5-4.3,9.5-9.5V79.8C220.5,66.5,212.9,58.3,200.7,58.3L200.7,58.3z"/>
|
||||
<path class="st1" d="M130.8,58.4c-4.4,0-7.7,2.6-9.1,7.1l-6.1,19.9l-6.1-19.7c-1.4-4.6-5.1-7.4-9.6-7.4h-0.9
|
||||
c-4.5,0-8.2,2.8-9.6,7.4l-5.4,17.5c-1.5-4.9-5.8-31.4-31.1-33c-8.7-0.5-11.2,4.7-12,7.6c-0.7,2.8-0.4,5.2,1.3,7.3
|
||||
c1.7,2.2,5,2.5,8.9,4C61,73,63.6,81.8,65.9,87.3c0.8,1.9,6.4,20.8,6.4,20.8c1.8,5.2,5.4,8.1,10.2,8.1H83c4.8,0,8.4-2.9,10-7.8
|
||||
l6.3-19.7l6.2,19.7c1.6,5,5.2,7.8,10,7.8h0.5c4.8,0,8.4-2.9,10.2-8L139.2,71l0-0.1c0.2-0.7,0.6-2.3,0.6-3.6
|
||||
C139.8,62.3,135.9,58.4,130.8,58.4L130.8,58.4z"/>
|
||||
<path class="st1" d="M276,99.9c-0.2-0.2-0.4-0.4-0.6-0.6l-14.1-14.4l11.3-9.6l0,0c1.9-1.8,4.1-4.3,4.1-8c0-4.3-3.2-8.7-8.6-8.7
|
||||
c-3.6,0-5.9,1.9-8,3.9l-15,14.2c-1.6-12.5-9.2-18.4-14-18.4c-4.2,0-4.8,2.7-4.8,6.5c-0.1,1.1-0.1,2.4-0.1,3.7v38
|
||||
c0,4.9,3.8,9.1,8.6,9.6c0.3,0,0.7,0.1,1,0.1c5.3,0,9.5-4.4,9.5-9.6v-7.5l3.3-3l14.5,16.4c0.6,0.6,1.3,1.3,2.1,1.9
|
||||
c1.1,0.9,2.5,1.5,4.2,1.8c0.1,0,1.2,0.1,1.8,0.1c4.3-0.1,8.7-3.2,8.6-8.6C279.6,104.1,277.9,101.9,276,99.9L276,99.9z"/>
|
||||
<circle class="st1" cx="293.3" cy="106.7" r="9.5"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Generator: Adobe Illustrator 25.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" style="enable-background:new 0 0 1000 1000;" xml:space="preserve">
|
||||
<style type="text/css">
|
||||
.st0{fill:#F5E0B4;}
|
||||
.st1{fill:#383535;}
|
||||
.st2{fill:#FBDE3D;}
|
||||
.st3{fill:#8C919F;}
|
||||
.st4{fill:#CACED5;}
|
||||
.st5{fill:#FFFFFF;}
|
||||
</style>
|
||||
<g>
|
||||
<polygon class="st0" points="782.2,925.8 733.4,643.2 996.4,532.7 745.7,396.4 823.6,120.2 560.7,232.2 391.6,0 313.7,274.7 26.5,260.1 194.4,491.3 3.6,705.5 289.4,721.3 340.5,1000 529.1,787 "/>
|
||||
<path class="st1" d="M706.9,493.4c0-126-102.2-228.2-228.2-228.2c-126,0-228.2,102.2-228.2,228.2c0,81.8,43.1,153.6,107.8,193.8 v202.6l43.5,43.5l0.2-0.2h150.6l0.2,0.2l43.5-43.5V689C662.6,649,706.9,576.4,706.9,493.4z"/>
|
||||
<path class="st2" d="M682.2,492.9c0-112.7-91.3-204-204-204s-204,91.3-204,204c0,78,43.8,145.8,108.1,180.1v93.6h191.7V673 C638.4,638.7,682.2,571,682.2,492.9z"/>
|
||||
<g>
|
||||
<polygon class="st3" points="382.7,790.4 382.7,881.1 412,910.3 544.9,910.3 574.1,881.1 574.1,790.4 "/>
|
||||
<polygon class="st4" points="540,813.2 540,866.5 527,879.5 540.4,892.9 558.7,874.6 558.9,874.6 558.9,813.2 "/>
|
||||
</g>
|
||||
<path class="st5" d="M478.3,310.4c-5,0-9.1,4.1-9.1,9.1c0,5,4.1,9.1,9.1,9.1c90.7,0,164.3,73.5,164.3,164.3c0,5,4.1,9.1,9.1,9.1 s9.1-4.1,9.1-9.1C660.8,392.1,579.1,310.4,478.3,310.4z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="195mm"
|
||||
height="43.093071mm"
|
||||
viewBox="0 0 195 43.093071"
|
||||
version="1.1"
|
||||
id="svg1156"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<defs
|
||||
id="defs1153" />
|
||||
<g
|
||||
id="layer1"
|
||||
transform="translate(-6.9662436,-7.8467567)">
|
||||
<g
|
||||
id="g21305-1"
|
||||
style="font-size:33.5139px;line-height:1.25;stroke-width:0.0700042"
|
||||
transform="translate(1.0553387,0.93988827)">
|
||||
<g
|
||||
id="g21248-5">
|
||||
<rect
|
||||
style="font-size:33.5139px;line-height:1.25;fill:#107ef4;fill-opacity:1;stroke:none;stroke-width:0.0727743"
|
||||
id="rect846-9-0-1-2-7-2-1-9"
|
||||
width="43.093071"
|
||||
height="43.093071"
|
||||
x="5.9109049"
|
||||
y="6.9068685"
|
||||
ry="2.4179134" />
|
||||
<path
|
||||
d="M 22.234889,18.179756 V 36.734061 H 19.567887 V 18.179756 h -6.882585 v -2.35155 h 16.403494 v 2.35155 z"
|
||||
style="font-size:31.75px;line-height:1.25;font-family:FreeSans;-inkscape-font-specification:FreeSans;fill:#ffffff;stroke-width:0.238978"
|
||||
id="path16874-7-9-2-4" />
|
||||
<path
|
||||
d="m 41.725989,35.328866 v 1.806679 q -0.946355,0.258097 -1.634613,0.258097 -2.380228,0 -2.46626,-2.380228 -1.691969,2.380228 -4.674422,2.380228 -1.548582,0 -2.580969,-0.745614 v 6.395069 H 27.989497 V 21.707084 h 2.380228 v 10.639329 q 0,1.347839 0.831645,2.150808 0.831646,0.802968 2.23684,0.802968 1.864034,0 2.982454,-1.376517 1.11842,-1.405195 1.11842,-3.699389 v -8.517199 h 2.380227 v 12.503362 q 0,1.175775 1.290485,1.175775 0.229419,0 0.516193,-0.05736 z"
|
||||
style="font-size:31.75px;line-height:1.25;font-family:FreeSans;-inkscape-font-specification:FreeSans;fill:#ffffff;stroke-width:0.238978"
|
||||
id="path16871-6-1-9-9" />
|
||||
</g>
|
||||
<g
|
||||
aria-label="Temma"
|
||||
transform="matrix(0.91459055,0,0,0.9686482,-4.3308403,0.67015143)"
|
||||
id="text87274-2-5-0"
|
||||
style="font-size:39.8454px;line-height:1.25;font-family:'DejaVu Sans';-inkscape-font-specification:'DejaVu Sans';fill:#000000;stroke-width:0.0205099">
|
||||
<path
|
||||
d="m 89.719297,15.597759 v 4.50253 h -10.24872 v 23.30956 h -5.578356 v -23.30956 h -10.24872 v -4.50253 z"
|
||||
style="font-weight:600;font-family:Poppins;-inkscape-font-specification:'Poppins Semi-Bold';fill:#000000"
|
||||
id="path7781-61-0-9" />
|
||||
<path
|
||||
d="m 109.19647,31.894528 q 0,1.195362 -0.15939,2.151652 H 92.899673 q 0.199227,2.390724 1.673504,3.745467 1.4743,1.354744 3.62597,1.354744 3.107933,0 4.422823,-2.669642 h 6.01666 q -0.95629,3.187632 -3.66578,5.259593 -2.70948,2.032115 -6.654173,2.032115 -3.18765,0 -5.737768,-1.394588 -2.51026,-1.434435 -3.944694,-4.024386 -1.394589,-2.589951 -1.394589,-5.97681 0,-3.426705 1.394589,-6.016656 1.394589,-2.589951 3.904849,-3.98454 2.510273,-1.394589 5.777613,-1.394589 3.147783,0 5.618193,1.354743 2.51026,1.354744 3.86501,3.865004 1.39459,2.470415 1.39459,5.697893 z m -5.77759,-1.593816 q -0.0398,-2.151652 -1.55397,-3.426705 -1.51411,-1.314898 -3.705613,-1.314898 -2.07197,0 -3.50643,1.275053 -1.394586,1.235207 -1.713349,3.46655 z"
|
||||
style="font-weight:600;font-family:Poppins;-inkscape-font-specification:'Poppins Semi-Bold';fill:#000000"
|
||||
id="path7783-8-3-1" />
|
||||
<path
|
||||
d="m 140.67428,21.016733 q 4.06423,0 6.53465,2.51026 2.51026,2.470415 2.51026,6.9331 v 12.949756 h -5.57836 V 31.217156 q 0,-2.589951 -1.3149,-3.944695 -1.3149,-1.394589 -3.58608,-1.394589 -2.27119,0 -3.62594,1.394589 -1.31489,1.354744 -1.31489,3.944695 v 12.192693 h -5.57836 V 31.217156 q 0,-2.589951 -1.3149,-3.944695 -1.3149,-1.394589 -3.58608,-1.394589 -2.31104,0 -3.66578,1.394589 -1.3149,1.354744 -1.3149,3.944695 v 12.192693 h -5.57836 V 21.335496 h 5.57836 v 2.669642 q 1.07583,-1.394589 2.74933,-2.191497 1.71336,-0.796908 3.74547,-0.796908 2.58995,0 4.62207,1.115671 2.03211,1.075826 3.14778,3.107942 1.07583,-1.91258 3.10795,-3.068096 2.07196,-1.155517 4.46268,-1.155517 z"
|
||||
style="font-weight:600;font-family:Poppins;-inkscape-font-specification:'Poppins Semi-Bold';fill:#000000"
|
||||
id="path7785-7-6-7" />
|
||||
<path
|
||||
d="m 182.4322,21.016733 q 4.06423,0 6.53465,2.51026 2.51026,2.470415 2.51026,6.9331 v 12.949756 h -5.57836 V 31.217156 q 0,-2.589951 -1.31489,-3.944695 -1.3149,-1.394589 -3.58609,-1.394589 -2.27119,0 -3.62593,1.394589 -1.3149,1.354744 -1.3149,3.944695 v 12.192693 h -5.57836 V 31.217156 q 0,-2.589951 -1.31489,-3.944695 -1.3149,-1.394589 -3.58609,-1.394589 -2.31103,0 -3.66578,1.394589 -1.3149,1.354744 -1.3149,3.944695 v 12.192693 h -5.57835 V 21.335496 h 5.57835 v 2.669642 q 1.07583,-1.394589 2.74934,-2.191497 1.71335,-0.796908 3.74546,-0.796908 2.58996,0 4.62207,1.115671 2.03212,1.075826 3.14779,3.107942 1.07582,-1.91258 3.10794,-3.068096 2.07196,-1.155517 4.46268,-1.155517 z"
|
||||
style="font-weight:600;font-family:Poppins;-inkscape-font-specification:'Poppins Semi-Bold';fill:#000000"
|
||||
id="path7787-9-1-7" />
|
||||
<path
|
||||
d="m 195.34205,32.292982 q 0,-3.347014 1.3149,-5.936965 1.35474,-2.589951 3.62593,-3.98454 2.31104,-1.394589 5.14006,-1.394589 2.47041,0 4.3033,0.996135 1.87274,0.996135 2.98841,2.51026 v -3.147787 h 5.6182 v 22.074353 h -5.6182 v -3.227478 q -1.07583,1.553971 -2.98841,2.589952 -1.87273,0.996134 -4.34315,0.996134 -2.78917,0 -5.10021,-1.434434 -2.27119,-1.434434 -3.62593,-4.024385 -1.3149,-2.629797 -1.3149,-6.016656 z m 17.3726,0.07969 q 0,-2.032116 -0.79691,-3.46655 -0.79691,-1.47428 -2.15165,-2.231343 -1.35475,-0.796908 -2.90872,-0.796908 -1.55397,0 -2.86887,0.757063 -1.31489,0.757062 -2.15165,2.231342 -0.79691,1.434435 -0.79691,3.426705 0,1.99227 0.79691,3.506395 0.83676,1.47428 2.15165,2.271188 1.35475,0.796908 2.86887,0.796908 1.55397,0 2.90872,-0.757062 1.35474,-0.796908 2.15165,-2.231343 0.79691,-1.47428 0.79691,-3.506395 z"
|
||||
style="font-weight:600;font-family:Poppins;-inkscape-font-specification:'Poppins Semi-Bold';fill:#000000"
|
||||
id="path7789-2-0-1" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.0 KiB |
@@ -8,6 +8,25 @@ It allows you to write **templates**, using **variables**, **modifiers**, **func
|
||||
<p>
|
||||
The number of pixels is: {math equation="x * y" x=$height y=$width}.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
{if $email matches "/^[^@]+@[^@]+\.[^@]+$/"}
|
||||
Valid email address
|
||||
{else}
|
||||
Please enter a valid email
|
||||
{/if}
|
||||
</p>
|
||||
```
|
||||
```html
|
||||
<h1>Hello world</h1>
|
||||
|
||||
<p>
|
||||
The number of pixels is: 307200.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Valid email address
|
||||
</p>
|
||||
```
|
||||
|
||||
When this template is rendered, with the value "Hello world" for the variable $title, 640 for $width,
|
||||
@@ -26,5 +45,20 @@ and 480 for $height, the result is:
|
||||
- [Features](./features.md) - or "Why do I want Smarty?"
|
||||
|
||||
## Help
|
||||
- [Search or create an issue](https://github.com/smarty-php/smarty/issues)
|
||||
- [Upgrading from an older version](upgrading.md)
|
||||
- [Some random tips & tricks](./appendixes/tips.md)
|
||||
- [Troubleshooting](./appendixes/troubleshooting.md)
|
||||
|
||||
## Source code
|
||||
- [Smarty repository at GitHub](https://github.com/smarty-php/smarty)
|
||||
|
||||
## Sponsors
|
||||
|
||||
### <img src="img/iwink-logo.svg" alt="iWink logo" width="100">
|
||||
|
||||
[iWink](https://www.iwink.nl/), fullservice digital agency
|
||||
|
||||
### <img src="img/temma-logo.svg" alt="Temma logo" width="100">
|
||||
|
||||
[Temma](https://www.temma.net/), the MVC framework based on Smarty
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Python dependencies for building/previewing the docs.
|
||||
#
|
||||
# pip install -r docs/requirements.txt
|
||||
# mkdocs serve # local preview
|
||||
# mike deploy 5.x # publish
|
||||
#
|
||||
# pymdown-extensions must be >=11: earlier releases pass filename=None to
|
||||
# Pygments, and Pygments >=2.19 then crashes with
|
||||
# "'NoneType' object has no attribute 'replace'" on any untitled code block.
|
||||
mkdocs>=1.6
|
||||
mkdocs-material>=9.7
|
||||
pymdown-extensions>=11
|
||||
Pygments>=2.19
|
||||
mike>=2.2
|
||||
@@ -0,0 +1,171 @@
|
||||
# Upgrading from an older version
|
||||
|
||||
## Upgrading from v4 to v5
|
||||
|
||||
Smarty 5 adds support for PHP8.2 and drops support for PHP7.1. Smarty also adds support for new features
|
||||
such as the ternary operator (`{$test ? $a : $b}` and `{$var ?: $value_if_falsy}`), the null coalescing operator (`{$var ?? $value_if_null}`)
|
||||
and positional parameters for custom tags.
|
||||
Smarty 5 also has a brand-new extension architecture that allows you to write neat extension packs.
|
||||
|
||||
### Namespaces
|
||||
All Smarty code has been moved into the `\Smarty` namespace. This reduces
|
||||
the chance of conflicts with other (your) code.
|
||||
|
||||
For simple use-cases, you only need to add `use Smarty\Smarty;` to your script and everything will work.
|
||||
|
||||
```php
|
||||
<?php
|
||||
use Smarty\Smarty;
|
||||
$smarty = new Smarty();
|
||||
|
||||
$smarty->display('homepage.tpl');
|
||||
```
|
||||
For more information, see [getting started](getting-started.md).
|
||||
|
||||
If you extend Smarty or use Smarty plug-ins, please review your code to see if they assume specific class or method names.
|
||||
E.g.: `Smarty_Internal_Template` is now `\Smarty\Template\`, `SmartyException` is now `\Smarty\Exception`.
|
||||
|
||||
### Variable scope bubbling
|
||||
Template variable scope bubbling has been simplified and made more consistent. The global scope now equals the Smarty
|
||||
scope in order to avoid global state side effects. Please read the [documentation on language variable scope](designers/language-variables/language-variable-scopes.md)
|
||||
for more details.
|
||||
|
||||
Also, `{config_load}` no longer has a `scope` parameter, which means you can no longer load config
|
||||
from inside your template into the global scope (again, to avoid global state side effects). If you
|
||||
need to set global config, use the [configLoad API method](api/variables/config-files.md) from your PHP code.
|
||||
|
||||
### Using native PHP-functions or userland functions in your templates
|
||||
You can no longer use native PHP-functions or userland functions in your templates without registering them.
|
||||
If you need a function in your templates, register it first.
|
||||
|
||||
The easiest way to do so is as follows:
|
||||
```php
|
||||
// native PHP functions used as modifiers need to be registered
|
||||
$smarty->registerPlugin('modifier', 'substr', 'substr');
|
||||
|
||||
// userland PHP functions used as modifiers need to be registered
|
||||
$smarty->registerPlugin('modifier', 'my_special_func', 'my_special_func');
|
||||
```
|
||||
|
||||
But you may want to consider writing a proper [extension](api/extending/extensions.md).
|
||||
|
||||
#### Passing parameters by reference
|
||||
You cannot use plugins that expect a parameter by reference anymore. PHP-function such as `reset()`, `prev()`,
|
||||
`next()` and `end()` can be registered as plugin, but they won't work because they expect a parameter by
|
||||
reference and Smarty will try to pass it by value.
|
||||
|
||||
### Removed undocumented tags
|
||||
|
||||
Smarty 4 still supported some tags that have been carried over from previous version, but have never been documented.
|
||||
|
||||
- `{block_parent}` should be replaced with `{$smarty.block.parent}`
|
||||
- `{parent}` should be replaced with `{$smarty.block.parent}`
|
||||
- `{block_child}` should be replaced with `{$smarty.block.child}`
|
||||
- `{child}` should be replaced with `{$smarty.block.child}`
|
||||
|
||||
- `{make_nocache}` is no longer supported
|
||||
- `{insert}` is no longer supported
|
||||
|
||||
### Removed Smarty API properties
|
||||
|
||||
In Smarty 4, you could make many configuration changes by directly accessing public properties on the Smarty object in PHP.
|
||||
In many cases, these properties have been made private, and you should now use the appropriate setter method:
|
||||
|
||||
- `$smarty->left_delimiter` should be replaced with `$smarty->getLeftDelimiter()`/`$smarty->setLeftDelimiter()`
|
||||
- `$smarty->right_delimiter` should be replaced with `$smarty->getRightDelimiter()`/`$smarty->setRightDelimiter()`
|
||||
- `$smarty->autoload_filters` should be replaced with `$smarty->registerFilter()`
|
||||
- `$smarty->template_dir` should be replaced with `$smarty->setTemplateDir()`
|
||||
- `$smarty->cache_dir` should be replaced with `$smarty->setCacheDir()`
|
||||
- `$smarty->compile_dir` should be replaced with `$smarty->setCompileDir()`
|
||||
|
||||
Other public properties have been removed altogether, and you should no longer access them:
|
||||
|
||||
- `$smarty->_current_file`
|
||||
- `$smarty->allow_ambiguous_resources` (ambiguous resources handlers should still work)
|
||||
- `$smarty->registered_filters`
|
||||
- `$smarty->direct_access_security`
|
||||
- `$smarty->trusted_dir`
|
||||
- `$smarty->allow_php_templates`
|
||||
- `$smarty->php_functions`
|
||||
- `$smarty->php_modifiers`
|
||||
|
||||
### Backwards incompatible changes to custom plugins
|
||||
|
||||
We have dropped support for `$smarty->plugins_dir` and `$smarty->use_include_path`.
|
||||
Use `$smarty->addPluginsDir()` or consider writing a proper [extension](api/extending/extensions.md).
|
||||
|
||||
The 'insert' plugin type is no longer supported.
|
||||
|
||||
The `$cache_attrs` parameter for registered plugins is no longer supported.
|
||||
|
||||
### Removed Smarty API methods
|
||||
|
||||
Search your code for the following changes:
|
||||
|
||||
- `$smarty->getTags()` is no longer supported
|
||||
- `$smarty->appendByRef()` should be replaced with `$smarty->append()`
|
||||
- `$smarty->assignByRef()` should be replaced with `$smarty->assign()`
|
||||
- `$smarty->loadPlugin()` should be replaced with `$smarty->registerPlugin()`
|
||||
|
||||
### Removed undocumented magic API methods
|
||||
|
||||
Smarty v4 allowed setting (internal) properties for which no setter existed by using magic methods
|
||||
that start with either `set` or `get`. This has been removed in Smarty 5.
|
||||
|
||||
For example, `$smarty->setErrorUnassigned(true);` would set the `error_unassigned` property.
|
||||
|
||||
Every setter of getter that was ever documented or unit tested has been kept.
|
||||
|
||||
### Removed PHP constants
|
||||
|
||||
The following constants have been removed to prevent global side effects.
|
||||
|
||||
- `SMARTY_DIR`
|
||||
- `SMARTY_SYSPLUGINS_DIR`
|
||||
- `SMARTY_PLUGINS_DIR`
|
||||
- `SMARTY_MBSTRING`
|
||||
- `SMARTY_HELPER_FUNCTIONS_LOADED`
|
||||
|
||||
### Other changes
|
||||
|
||||
- Smarty now always runs in multibyte mode. Make sure you use the [PHP multibyte extension](https://www.php.net/manual/en/book.mbstring.php) in production for optimal performance.
|
||||
- Generated `<script>` tags lo longer have deprecated `type="text/javascript"` or `language="Javascript"` attributes
|
||||
- Smarty will throw a compiler exception instead of silently ignoring a modifier on a function call, like this: `{include|dot:"x-template-id" file="included.dot.tpl"}`
|
||||
- The ::getFile() method of a CompilerException will now return the full path of the template being compiled, if possible. This used to be 'file:relative_dir/filename.tpl'.
|
||||
|
||||
## Upgrading from v3 to v4
|
||||
|
||||
Smarty 4 is mostly identical to Smarty 3. Most notably, it adds support for PHP8 and drops support for PHP7.0 and below.
|
||||
Additionally, some deprecated features that have long been discouraged have been dropped from the language.
|
||||
|
||||
### Muting PHP8 warnings
|
||||
If you simultaneously upgrade Smarty to v4 van PHP to v8, you may notice your error logs filling up with warnings about undefined or null template vars
|
||||
due to a change in how PHP handles these. This may be helpful to spot errors, but if you find this annoying, you can use
|
||||
`$smarty->muteUndefinedOrNullWarnings()` to make Smarty convert these warnings into notices.
|
||||
|
||||
### ASP tags
|
||||
You can no longer user ASP-style tags like `<% %>` and `<%= %>` in your templates.
|
||||
Replace them with `{...}` tags.
|
||||
|
||||
### SmartyBC
|
||||
Check your codebase for `SmartyBC`.
|
||||
We have dropped deprecated API calls that where only accessible through the SmartyBC class.
|
||||
|
||||
### No more embedded PHP
|
||||
We have completely dropped support for `{php}` and `{include_php}` tags and embedded PHP in templates.
|
||||
Check your templates for this, and rewrite any embedded PHP blocks, by moving logic to your PHP files or by
|
||||
creating a [custom tag](./api/extending/tags.md).
|
||||
|
||||
### Other changes
|
||||
|
||||
Search your code for the following changes:
|
||||
|
||||
- `SMARTY_RESOURCE_CHAR_SET` and `SMARTY_RESOURCE_DATE_FORMAT` constants have been removed
|
||||
- `Smarty::muteExpectedErrors` and `Smarty::unmuteExpectedErrors` API methods have been removed
|
||||
- `Smarty::getVariable` method has been removed. Use [Smarty::getTemplateVars](designers/language-builtin-functions/language-function-assign.md) instead.
|
||||
- [Smarty::registerResource](api/resources.md) no longer accepts an array of callback functions
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// This is a stub PSR-4 loading script that gets all the pieces of //
|
||||
// Smarty 5.x loaded without requiring the use of composer. It's //
|
||||
// not really a 'class' file, but the name is used so we're //
|
||||
// backwards compatible with previous versions of Smarty. //
|
||||
// //
|
||||
// Example: //
|
||||
// require_once("/path/to/smarty/libs/Smarty.class.php"); //
|
||||
// //
|
||||
// $smarty = new Smarty\Smarty; //
|
||||
// $smarty->testInstall(); //
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
define('__SMARTY_DIR', __DIR__ . '/../src/');
|
||||
|
||||
// Global function declarations
|
||||
require_once(__SMARTY_DIR . "/functions.php");
|
||||
|
||||
spl_autoload_register(function ($class) {
|
||||
// Class prefix
|
||||
$prefix = 'Smarty\\';
|
||||
|
||||
// Does the class use the namespace prefix?
|
||||
$len = strlen($prefix);
|
||||
if (strncmp($prefix, $class, $len) !== 0) {
|
||||
// If not, move to the next registered autoloader
|
||||
return;
|
||||
}
|
||||
|
||||
// Hack off the prefix part
|
||||
$relative_class = substr($class, $len);
|
||||
|
||||
// Build a path to the include file
|
||||
$file = __SMARTY_DIR . str_replace('\\', '/', $relative_class) . '.php';
|
||||
|
||||
// If the file exists, require it
|
||||
if (file_exists($file)) {
|
||||
require_once($file);
|
||||
}
|
||||
});
|
||||
+4
-3
@@ -8,10 +8,11 @@ else
|
||||
fi
|
||||
|
||||
git checkout -b "release/$1"
|
||||
sed -i "s/## \\[Unreleased\\]/## \\[Unreleased\\]\\n\\n## \\[$1\\] - $(date +%Y-%m-%d)/" CHANGELOG.md
|
||||
sed -i "s/const SMARTY_VERSION = '[^']\+';/const SMARTY_VERSION = '$1';/" src/Smarty.php
|
||||
|
||||
git add CHANGELOG.md src/Smarty.php
|
||||
php utilities/update-changelog.php $1
|
||||
php utilities/update-smarty-version-number.php $1
|
||||
|
||||
git add changelog CHANGELOG.md src/Smarty.php
|
||||
git commit -m "version bump"
|
||||
|
||||
git checkout master
|
||||
|
||||
+19
-2
@@ -26,7 +26,9 @@ markdown_extensions:
|
||||
|
||||
nav:
|
||||
- Home: 'index.md'
|
||||
- 'Getting started': 'getting-started.md'
|
||||
- 'Getting started':
|
||||
- Introduction: 'getting-started.md'
|
||||
- 'Upgrading from an older version': 'upgrading.md'
|
||||
- 'Language reference':
|
||||
- 'Basic Syntax':
|
||||
- Introduction: 'designers/language-basic-syntax/index.md'
|
||||
@@ -47,29 +49,44 @@ nav:
|
||||
- 'Introduction': 'designers/language-modifiers/index.md'
|
||||
- 'capitalize': 'designers/language-modifiers/language-modifier-capitalize.md'
|
||||
- 'cat': 'designers/language-modifiers/language-modifier-cat.md'
|
||||
- 'count': 'designers/language-modifiers/language-modifier-count.md'
|
||||
- 'count_characters': 'designers/language-modifiers/language-modifier-count-characters.md'
|
||||
- 'count_paragraphs': 'designers/language-modifiers/language-modifier-count-paragraphs.md'
|
||||
- 'count_sentences': 'designers/language-modifiers/language-modifier-count-sentences.md'
|
||||
- 'count_words': 'designers/language-modifiers/language-modifier-count-words.md'
|
||||
- 'date_format': 'designers/language-modifiers/language-modifier-date-format.md'
|
||||
- 'debug_print_var': 'designers/language-modifiers/language-modifier-debug-print-var.md'
|
||||
- 'default': 'designers/language-modifiers/language-modifier-default.md'
|
||||
- 'empty': "designers/language-modifiers/language-modifier-empty.md"
|
||||
- 'escape': 'designers/language-modifiers/language-modifier-escape.md'
|
||||
- 'from_charset': 'designers/language-modifiers/language-modifier-from-charset.md'
|
||||
- 'indent': 'designers/language-modifiers/language-modifier-indent.md'
|
||||
- 'in_array': 'designers/language-modifiers/language-modifier-in_array.md'
|
||||
- 'is_array': 'designers/language-modifiers/language-modifier-is_array.md'
|
||||
- 'isset': 'designers/language-modifiers/language-modifier-isset.md'
|
||||
- 'join': 'designers/language-modifiers/language-modifier-join.md'
|
||||
- 'json_encode': 'designers/language-modifiers/language-modifier-json-encode.md'
|
||||
- 'lower': 'designers/language-modifiers/language-modifier-lower.md'
|
||||
- 'noprint': 'designers/language-modifiers/language-modifier-noprint.md'
|
||||
- 'number_format': 'designers/language-modifiers/language-modifier-number-format.md'
|
||||
- 'nl2br': 'designers/language-modifiers/language-modifier-nl2br.md'
|
||||
- 'raw': 'designers/language-modifiers/language-modifier-raw.md'
|
||||
- 'regex_replace': 'designers/language-modifiers/language-modifier-regex-replace.md'
|
||||
- 'replace': 'designers/language-modifiers/language-modifier-replace.md'
|
||||
- 'round': 'designers/language-modifiers/language-modifier-round.md'
|
||||
- 'spacify': 'designers/language-modifiers/language-modifier-spacify.md'
|
||||
- 'split': 'designers/language-modifiers/language-modifier-split.md'
|
||||
- 'str_repeat': 'designers/language-modifiers/language-modifier-str-repeat.md'
|
||||
- 'string_format': 'designers/language-modifiers/language-modifier-string-format.md'
|
||||
- 'strip': 'designers/language-modifiers/language-modifier-strip.md'
|
||||
- 'strip_tags': 'designers/language-modifiers/language-modifier-strip-tags.md'
|
||||
- 'strlen': 'designers/language-modifiers/language-modifier-strlen.md'
|
||||
- 'substr': 'designers/language-modifiers/language-modifier-substr.md'
|
||||
- 'to_charset': 'designers/language-modifiers/language-modifier-to-charset.md'
|
||||
- 'truncate': 'designers/language-modifiers/language-modifier-truncate.md'
|
||||
- 'unescape': 'designers/language-modifiers/language-modifier-unescape.md'
|
||||
- 'upper': 'designers/language-modifiers/language-modifier-upper.md'
|
||||
- 'wordwrap': 'designers/language-modifiers/language-modifier-wordwrap.md'
|
||||
- 'Combining Modifiers': 'designers/language-combining-modifiers.md'
|
||||
- 'Builtin Tags':
|
||||
- 'Introduction': 'designers/language-builtin-functions/index.md'
|
||||
- '{append}': 'designers/language-builtin-functions/language-function-append.md'
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
<testsuite name="foo">
|
||||
<directory>./tests/UnitTests/</directory>
|
||||
<exclude>./tests/UnitTests/CacheResourceTests/Memcache/CacheResourceCustomMemcacheTest.php</exclude>
|
||||
<exclude>./tests/UnitTests/CacheResourceTests/Apc/CacheResourceCustomApcTest.php</exclude>
|
||||
<exclude>./tests/UnitTests/CacheModify/ModifiedSince/HttpModifiedSinceTest.php</exclude>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
@@ -5,9 +5,13 @@
|
||||
# - ./run-tests-for-all-php-versions.sh --group 20221124
|
||||
# - ./run-tests-for-all-php-versions.sh --exclude-group slow
|
||||
|
||||
docker-compose run php72 ./run-tests.sh $@ && \
|
||||
docker-compose run php73 ./run-tests.sh $@ && \
|
||||
docker-compose run php74 ./run-tests.sh $@ && \
|
||||
docker-compose run php80 ./run-tests.sh $@ && \
|
||||
docker-compose run php81 ./run-tests.sh $@ && \
|
||||
docker-compose run php82 ./run-tests.sh $@
|
||||
COMPOSE_CMD="docker compose"
|
||||
|
||||
$COMPOSE_CMD run --rm php72 ./run-tests.sh $@ && \
|
||||
$COMPOSE_CMD run --rm php73 ./run-tests.sh $@ && \
|
||||
$COMPOSE_CMD run --rm php74 ./run-tests.sh $@ && \
|
||||
$COMPOSE_CMD run --rm php80 ./run-tests.sh $@ && \
|
||||
$COMPOSE_CMD run --rm php81 ./run-tests.sh $@ && \
|
||||
$COMPOSE_CMD run --rm php82 ./run-tests.sh $@
|
||||
$COMPOSE_CMD run --rm php83 ./run-tests.sh $@
|
||||
$COMPOSE_CMD run --rm php84 ./run-tests.sh $@
|
||||
|
||||
@@ -14,6 +14,6 @@ class BlockPluginWrapper extends Base {
|
||||
}
|
||||
|
||||
public function handle($params, $content, Template $template, &$repeat) {
|
||||
return call_user_func_array($this->callback, [$params, $content, &$template, &$repeat]);
|
||||
return \call_user_func_array($this->callback, [$params, $content, &$template, &$repeat]);
|
||||
}
|
||||
}
|
||||
@@ -20,9 +20,6 @@ use Smarty\Template;
|
||||
* - indent_char - string (" ")
|
||||
* - wrap_boundary - boolean (true)
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.function.textformat.php {textformat}
|
||||
* (Smarty online manual)
|
||||
*
|
||||
* @param array $params parameters
|
||||
* @param string $content contents of the block
|
||||
* @param Template $template template object
|
||||
|
||||
@@ -44,7 +44,7 @@ abstract class Base
|
||||
*/
|
||||
abstract public function process(
|
||||
Template $_template,
|
||||
Cached $cached = null,
|
||||
?Cached $cached = null,
|
||||
$update = false
|
||||
);
|
||||
|
||||
|
||||
@@ -139,7 +139,7 @@ abstract class Custom extends Base
|
||||
*/
|
||||
public function process(
|
||||
Template $_smarty_tpl,
|
||||
\Smarty\Template\Cached $cached = null,
|
||||
?\Smarty\Template\Cached $cached = null,
|
||||
$update = false
|
||||
) {
|
||||
if (!$cached) {
|
||||
|
||||
@@ -99,7 +99,7 @@ class File extends Base
|
||||
*/
|
||||
public function process(
|
||||
Template $_smarty_tpl,
|
||||
Cached $cached = null,
|
||||
?Cached $cached = null,
|
||||
$update = false
|
||||
) {
|
||||
$_smarty_tpl->getCached()->setValid(false);
|
||||
@@ -127,8 +127,6 @@ class File extends Base
|
||||
&& (!function_exists('ini_get') || strlen(ini_get('opcache.restrict_api'))) < 1
|
||||
) {
|
||||
opcache_invalidate($_template->getCached()->filepath, true);
|
||||
} elseif (function_exists('apc_compile_file')) {
|
||||
apc_compile_file($_template->getCached()->filepath);
|
||||
}
|
||||
$cached = $_template->getCached();
|
||||
$cached->timestamp = $cached->exists = is_file($cached->filepath);
|
||||
@@ -145,7 +143,7 @@ class File extends Base
|
||||
*
|
||||
* @param Template $_template template object
|
||||
*
|
||||
* @return string content
|
||||
* @return string|false content
|
||||
*/
|
||||
public function retrieveCachedContent(Template $_template)
|
||||
{
|
||||
@@ -223,10 +221,8 @@ class File extends Base
|
||||
$_filepath = (string)$_file;
|
||||
// directory ?
|
||||
if ($_file->isDir()) {
|
||||
if (!$_cache->isDot()) {
|
||||
// delete folder if empty
|
||||
@rmdir($_file->getPathname());
|
||||
}
|
||||
// delete folder if empty
|
||||
@rmdir($_file->getPathname());
|
||||
} else {
|
||||
// delete only php files
|
||||
if (substr($_filepath, -4) !== '.php') {
|
||||
@@ -279,8 +275,6 @@ class File extends Base
|
||||
&& (!function_exists('ini_get') || strlen(ini_get("opcache.restrict_api")) < 1)
|
||||
) {
|
||||
opcache_invalidate($_filepath, true);
|
||||
} elseif (function_exists('apc_delete_file')) {
|
||||
apc_delete_file($_filepath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,7 +103,7 @@ abstract class KeyValueStore extends Base
|
||||
*/
|
||||
public function process(
|
||||
Template $_smarty_tpl,
|
||||
Cached $cached = null,
|
||||
?Cached $cached = null,
|
||||
$update = false
|
||||
) {
|
||||
if (!$cached) {
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
<?php
|
||||
|
||||
namespace Smarty\Compile;
|
||||
|
||||
/**
|
||||
* This class handles compiling the attributes.
|
||||
*/
|
||||
class AttributeCompiler
|
||||
{
|
||||
/**
|
||||
* Array of names of required attributes required by tag
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $required_attributes = [];
|
||||
|
||||
/**
|
||||
* Array of names of optional attribute required by tag
|
||||
* use array('_any') if there is no restriction of attributes names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $optional_attributes = [];
|
||||
|
||||
/**
|
||||
* Shorttag attribute order defined by its names
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $shorttag_order = [];
|
||||
|
||||
/**
|
||||
* Array of names of valid option flags
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $option_flags = [];
|
||||
|
||||
public function __construct(
|
||||
array $required_attributes = [],
|
||||
array $optional_attributes = [],
|
||||
array $shorttag_order = [],
|
||||
array $option_flags = []
|
||||
) {
|
||||
$this->required_attributes = $required_attributes;
|
||||
$this->optional_attributes = $optional_attributes;
|
||||
$this->shorttag_order = $shorttag_order;
|
||||
$this->option_flags = $option_flags;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function checks if the attributes passed are valid
|
||||
* The attributes passed for the tag to compile are checked against the list of required and
|
||||
* optional attributes. Required attributes must be present. Optional attributes are check against
|
||||
* the corresponding list. The keyword '_any' specifies that any attribute will be accepted
|
||||
* as valid
|
||||
*
|
||||
* @param object $compiler compiler object
|
||||
* @param array $attributes attributes applied to the tag
|
||||
*
|
||||
* @return array of mapped attributes for further processing
|
||||
*/
|
||||
public function getAttributes($compiler, $attributes)
|
||||
{
|
||||
$_indexed_attr = [];
|
||||
$options = array_fill_keys($this->option_flags, true);
|
||||
foreach ($attributes as $key => $mixed) {
|
||||
// shorthand ?
|
||||
if (!is_array($mixed)) {
|
||||
// options flag ?
|
||||
if (isset($options[trim($mixed, '\'"')])) {
|
||||
$_indexed_attr[trim($mixed, '\'"')] = true;
|
||||
// shorthand attribute ?
|
||||
} elseif (isset($this->shorttag_order[$key])) {
|
||||
$_indexed_attr[$this->shorttag_order[$key]] = $mixed;
|
||||
} else {
|
||||
// too many shorthands
|
||||
$compiler->trigger_template_error('too many shorthand attributes', null, true);
|
||||
}
|
||||
// named attribute
|
||||
} else {
|
||||
foreach ($mixed as $k => $v) {
|
||||
// options flag?
|
||||
if (isset($options[$k])) {
|
||||
if (is_bool($v)) {
|
||||
$_indexed_attr[$k] = $v;
|
||||
} else {
|
||||
if (is_string($v)) {
|
||||
$v = trim($v, '\'" ');
|
||||
}
|
||||
|
||||
// Mapping array for boolean option value
|
||||
static $optionMap = [1 => true, 0 => false, 'true' => true, 'false' => false];
|
||||
|
||||
if (isset($optionMap[$v])) {
|
||||
$_indexed_attr[$k] = $optionMap[$v];
|
||||
} else {
|
||||
$compiler->trigger_template_error(
|
||||
"illegal value '" . var_export($v, true) .
|
||||
"' for options flag '{$k}'",
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
// must be named attribute
|
||||
} else {
|
||||
$_indexed_attr[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if all required attributes present
|
||||
foreach ($this->required_attributes as $attr) {
|
||||
if (!isset($_indexed_attr[$attr])) {
|
||||
$compiler->trigger_template_error("missing '{$attr}' attribute", null, true);
|
||||
}
|
||||
}
|
||||
// check for not allowed attributes
|
||||
if ($this->optional_attributes !== ['_any']) {
|
||||
$allowedAttributes = array_fill_keys(
|
||||
array_merge(
|
||||
$this->required_attributes,
|
||||
$this->optional_attributes,
|
||||
$this->option_flags
|
||||
),
|
||||
true
|
||||
);
|
||||
foreach ($_indexed_attr as $key => $dummy) {
|
||||
if (!isset($allowedAttributes[$key]) && $key !== 0) {
|
||||
$compiler->trigger_template_error("unexpected '{$key}' attribute", null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// default 'false' for all options flags not set
|
||||
foreach ($this->option_flags as $flag) {
|
||||
if (!isset($_indexed_attr[$flag])) {
|
||||
$_indexed_attr[$flag] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $_indexed_attr;
|
||||
}
|
||||
}
|
||||
+8
-80
@@ -82,84 +82,12 @@ abstract class Base implements CompilerInterface {
|
||||
* @return array of mapped attributes for further processing
|
||||
*/
|
||||
protected function getAttributes($compiler, $attributes) {
|
||||
$_indexed_attr = [];
|
||||
$options = array_fill_keys($this->option_flags, true);
|
||||
foreach ($attributes as $key => $mixed) {
|
||||
// shorthand ?
|
||||
if (!is_array($mixed)) {
|
||||
// options flag ?
|
||||
if (isset($options[trim($mixed, '\'"')])) {
|
||||
$_indexed_attr[trim($mixed, '\'"')] = true;
|
||||
// shorthand attribute ?
|
||||
} elseif (isset($this->shorttag_order[$key])) {
|
||||
$_indexed_attr[$this->shorttag_order[$key]] = $mixed;
|
||||
} else {
|
||||
// too many shorthands
|
||||
$compiler->trigger_template_error('too many shorthand attributes', null, true);
|
||||
}
|
||||
// named attribute
|
||||
} else {
|
||||
foreach ($mixed as $k => $v) {
|
||||
// options flag?
|
||||
if (isset($options[$k])) {
|
||||
if (is_bool($v)) {
|
||||
$_indexed_attr[$k] = $v;
|
||||
} else {
|
||||
if (is_string($v)) {
|
||||
$v = trim($v, '\'" ');
|
||||
}
|
||||
|
||||
// Mapping array for boolean option value
|
||||
static $optionMap = [1 => true, 0 => false, 'true' => true, 'false' => false];
|
||||
|
||||
if (isset($optionMap[$v])) {
|
||||
$_indexed_attr[$k] = $optionMap[$v];
|
||||
} else {
|
||||
$compiler->trigger_template_error(
|
||||
"illegal value '" . var_export($v, true) .
|
||||
"' for options flag '{$k}'",
|
||||
null,
|
||||
true
|
||||
);
|
||||
}
|
||||
}
|
||||
// must be named attribute
|
||||
} else {
|
||||
$_indexed_attr[$k] = $v;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if all required attributes present
|
||||
foreach ($this->required_attributes as $attr) {
|
||||
if (!isset($_indexed_attr[$attr])) {
|
||||
$compiler->trigger_template_error("missing '{$attr}' attribute", null, true);
|
||||
}
|
||||
}
|
||||
// check for not allowed attributes
|
||||
if ($this->optional_attributes !== ['_any']) {
|
||||
$allowedAttributes = array_fill_keys(
|
||||
array_merge(
|
||||
$this->required_attributes,
|
||||
$this->optional_attributes,
|
||||
$this->option_flags
|
||||
),
|
||||
true
|
||||
);
|
||||
foreach ($_indexed_attr as $key => $dummy) {
|
||||
if (!isset($allowedAttributes[$key]) && $key !== 0) {
|
||||
$compiler->trigger_template_error("unexpected '{$key}' attribute", null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// default 'false' for all options flags not set
|
||||
foreach ($this->option_flags as $flag) {
|
||||
if (!isset($_indexed_attr[$flag])) {
|
||||
$_indexed_attr[$flag] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $_indexed_attr;
|
||||
return (new AttributeCompiler(
|
||||
$this->required_attributes,
|
||||
$this->optional_attributes,
|
||||
$this->shorttag_order,
|
||||
$this->option_flags
|
||||
))->getAttributes($compiler, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -226,8 +154,8 @@ abstract class Base implements CompilerInterface {
|
||||
* @param Template $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return bool|string compiled code or true if no code has been compiled
|
||||
* @return string compiled code as a string
|
||||
* @throws \Smarty\CompilerException
|
||||
*/
|
||||
abstract public function compile($args, Template $compiler, $parameter = array(), $tag = null, $function = null);
|
||||
abstract public function compile($args, Template $compiler, $parameter = array(), $tag = null, $function = null): string;
|
||||
}
|
||||
|
||||
@@ -50,7 +50,8 @@ class BlockCompiler extends Base {
|
||||
* @throws CompilerException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function compile($args, Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
public function compile($args, Template $compiler, $parameter = [], $tag = null, $function = null): string
|
||||
{
|
||||
|
||||
if (!isset($tag[5]) || substr($tag, -5) !== 'close') {
|
||||
$output = $this->compileOpeningTag($compiler, $args, $tag, $function);
|
||||
@@ -77,7 +78,6 @@ class BlockCompiler extends Base {
|
||||
);
|
||||
}
|
||||
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']]['callsChild'] = true;
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
|
||||
$output = "<?php \n";
|
||||
@@ -102,7 +102,6 @@ class BlockCompiler extends Base {
|
||||
$compiler->getParser()->lex->taglineno
|
||||
);
|
||||
}
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
|
||||
$output = "<?php \n";
|
||||
|
||||
@@ -17,10 +17,10 @@ interface CompilerInterface {
|
||||
* @param \Smarty\Compiler\Template $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return bool|string compiled code or true if no code has been compiled
|
||||
* @return string compiled code as a string
|
||||
* @throws \Smarty\CompilerException
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null);
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null): string;
|
||||
|
||||
public function isCacheable(): bool;
|
||||
}
|
||||
@@ -27,7 +27,8 @@ class DefaultHandlerFunctionCallCompiler extends Base {
|
||||
* @throws \Smarty\CompilerException
|
||||
* @throws \Smarty\Exception
|
||||
*/
|
||||
public function compile($args, Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
public function compile($args, Template $compiler, $parameter = [], $tag = null, $function = null): string
|
||||
{
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
unset($_attr['nocache']);
|
||||
|
||||
@@ -3,24 +3,18 @@
|
||||
* Smarty Internal Plugin Compile Registered Function
|
||||
* Compiles code for the execution of a registered function
|
||||
*
|
||||
|
||||
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
namespace Smarty\Compile;
|
||||
|
||||
use Smarty\Compiler\Template;
|
||||
use Smarty\CompilerException;
|
||||
use Smarty\FunctionHandler\AttributeFunctionHandlerInterface;
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Registered Function Class
|
||||
*
|
||||
|
||||
|
||||
*/
|
||||
class FunctionCallCompiler extends Base {
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
@@ -34,7 +28,7 @@ class FunctionCallCompiler extends Base {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $shorttag_order = ['var1', 'var2', 'var3'];
|
||||
protected $shorttag_order = [];
|
||||
|
||||
/**
|
||||
* Compiles code for the execution of a registered function
|
||||
@@ -49,28 +43,35 @@ class FunctionCallCompiler extends Base {
|
||||
* @throws \Smarty\CompilerException
|
||||
* @throws \Smarty\Exception
|
||||
*/
|
||||
public function compile($args, Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
public function compile($args, Template $compiler, $parameter = [], $tag = null, $function = null): string
|
||||
{
|
||||
if ($functionHandler = $compiler->getSmarty()->getFunctionHandler($function)) {
|
||||
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
unset($_attr['nocache']);
|
||||
$attribute_overrides = [];
|
||||
|
||||
$_paramsArray = $this->formatParamsArray($_attr);
|
||||
$_params = 'array(' . implode(',', $_paramsArray) . ')';
|
||||
|
||||
try {
|
||||
$value = array_shift($_attr);
|
||||
$output = $compiler->compileModifier([array_merge([$function], $_attr)], $value);
|
||||
} catch (\Smarty\CompilerException $e) {
|
||||
if ($functionHandler = $compiler->getSmarty()->getFunctionHandler($function)) {
|
||||
|
||||
// not cacheable?
|
||||
$compiler->tag_nocache = $compiler->tag_nocache || !$functionHandler->isCacheable();
|
||||
$output = "\$_smarty_tpl->getSmarty()->getFunctionHandler(" . var_export($function, true) . ")";
|
||||
$output .= "->handle($_params, \$_smarty_tpl)";
|
||||
} else {
|
||||
throw $e;
|
||||
if ($functionHandler instanceof AttributeFunctionHandlerInterface) {
|
||||
$attribute_overrides = $functionHandler->getSupportedAttributes();
|
||||
}
|
||||
|
||||
// check and get attributes
|
||||
$_attr = (new AttributeCompiler(
|
||||
$attribute_overrides['required_attributes'] ?? $this->required_attributes,
|
||||
$attribute_overrides['optional_attributes'] ?? $this->optional_attributes,
|
||||
$attribute_overrides['shorttag_order'] ?? $this->shorttag_order,
|
||||
$attribute_overrides['option_flags'] ?? $this->option_flags
|
||||
))->getAttributes($compiler, $args);
|
||||
|
||||
unset($_attr['nocache']);
|
||||
|
||||
$_paramsArray = $this->formatParamsArray($_attr);
|
||||
$_params = 'array(' . implode(',', $_paramsArray) . ')';
|
||||
|
||||
// not cacheable?
|
||||
$compiler->tag_nocache = $compiler->tag_nocache || !$functionHandler->isCacheable();
|
||||
$output = "\$_smarty_tpl->getSmarty()->getFunctionHandler(" . var_export($function, true) . ")";
|
||||
$output .= "->handle($_params, \$_smarty_tpl)";
|
||||
} else {
|
||||
$compiler->trigger_template_error("unknown function '{$function}'", null, true);
|
||||
}
|
||||
|
||||
if (!empty($parameter['modifierlist'])) {
|
||||
|
||||
@@ -11,8 +11,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Input: string to catenate
|
||||
* Example: {$var|cat:"foo"}
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.cat.php cat
|
||||
* (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: count_characters
|
||||
* Purpose: count the number of characters in a text
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.count.characters.php count_characters (Smarty online
|
||||
* manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: count_paragraphs
|
||||
* Purpose: count the number of paragraphs in a text
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
|
||||
* count_paragraphs (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: count_sentences
|
||||
* Purpose: count the number of sentences in a text
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.count.paragraphs.php
|
||||
* count_sentences (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: count_words
|
||||
* Purpose: count the number of words in a text
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.count.words.php count_words (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: default
|
||||
* Purpose: designate default value for empty variables
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.default.php default (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ use Smarty\Exception;
|
||||
* Name: escape
|
||||
* Purpose: escape string for output
|
||||
*
|
||||
* @link https://www.smarty.net/docsv2/en/language.modifier.escape count_characters (Smarty online manual)
|
||||
* @author Rodney Rehm
|
||||
*/
|
||||
|
||||
@@ -25,22 +24,32 @@ class EscapeModifierCompiler extends Base {
|
||||
}
|
||||
switch ($esc_type) {
|
||||
case 'html':
|
||||
case 'force':
|
||||
// in case of auto-escaping, and without the 'force' option, no double-escaping
|
||||
if ($compiler->getSmarty()->escape_html && $esc_type != 'force')
|
||||
return $params[0];
|
||||
// otherwise, escape the variable
|
||||
return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
|
||||
var_export($double_encode, true) . ')';
|
||||
// no break
|
||||
case 'htmlall':
|
||||
$compiler->setRawOutput(true);
|
||||
return 'htmlentities(mb_convert_encoding((string)' . $params[ 0 ] . ', \'UTF-8\', ' .
|
||||
var_export($char_set, true) . '), ENT_QUOTES, \'UTF-8\', ' .
|
||||
var_export($double_encode, true) . ')';
|
||||
// no break
|
||||
case 'url':
|
||||
$compiler->setRawOutput(true);
|
||||
return 'rawurlencode((string)' . $params[ 0 ] . ')';
|
||||
case 'urlpathinfo':
|
||||
$compiler->setRawOutput(true);
|
||||
return 'str_replace("%2F", "/", rawurlencode((string)' . $params[ 0 ] . '))';
|
||||
case 'quotes':
|
||||
$compiler->setRawOutput(true);
|
||||
// escape unescaped single quotes
|
||||
return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'", (string)' . $params[ 0 ] . ')';
|
||||
case 'javascript':
|
||||
$compiler->setRawOutput(true);
|
||||
// escape quotes and backslashes, newlines, etc.
|
||||
// see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
|
||||
return 'strtr((string)' .
|
||||
@@ -54,4 +63,4 @@ class EscapeModifierCompiler extends Base {
|
||||
}
|
||||
return '$_smarty_tpl->getSmarty()->getModifierCallback(\'escape\')(' . join(', ', $params) . ')';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: indent
|
||||
* Purpose: indent lines of text
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.indent.php indent (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
namespace Smarty\Compile\Modifier;
|
||||
use Smarty\CompilerException;
|
||||
|
||||
/**
|
||||
* Smarty is_array modifier plugin
|
||||
*/
|
||||
class IsArrayModifierCompiler extends Base {
|
||||
|
||||
public function compile($params, \Smarty\Compiler\Template $compiler) {
|
||||
|
||||
if (count($params) !== 1) {
|
||||
throw new CompilerException("Invalid number of arguments for is_array. is_array expects exactly 1 parameter.");
|
||||
}
|
||||
|
||||
return 'is_array(' . $params[0] . ')';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Smarty\Compile\Modifier;
|
||||
|
||||
/**
|
||||
* Smarty json_encode modifier plugin
|
||||
*/
|
||||
class JsonEncodeModifierCompiler extends Base {
|
||||
|
||||
public function compile($params, \Smarty\Compiler\Template $compiler) {
|
||||
return 'json_encode(' . $params[0] . (isset($params[1]) ? ', (int) ' . $params[1] : '') . ')';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: lower
|
||||
* Purpose: convert string to lowercase
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.lower.php lower (Smarty online manual)
|
||||
* @author Monte Ohrt <monte at ohrt dot com>
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: nl2br
|
||||
* Purpose: insert HTML line breaks before all newlines in a string
|
||||
*
|
||||
* @link https://www.smarty.net/docs/en/language.modifier.nl2br.tpl nl2br (Smarty online manual)
|
||||
*/
|
||||
|
||||
class Nl2brModifierCompiler extends Base {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
namespace Smarty\Compile\Modifier;
|
||||
|
||||
use Smarty\Exception;
|
||||
|
||||
/**
|
||||
* Smarty raw modifier plugin
|
||||
* Type: modifier
|
||||
* Name: raw
|
||||
* Purpose: when escaping is enabled by default, generates a raw output of a variable
|
||||
*
|
||||
* @author Amaury Bouchard
|
||||
*/
|
||||
|
||||
class RawModifierCompiler extends Base {
|
||||
|
||||
public function compile($params, \Smarty\Compiler\Template $compiler) {
|
||||
$compiler->setRawOutput(true);
|
||||
return ($params[0]);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: round
|
||||
* Purpose: Returns the rounded value of num to specified precision (number of digits after the decimal point)
|
||||
*
|
||||
* @link https://www.smarty.net/docs/en/language.modifier.round.tpl round (Smarty online manual)
|
||||
*/
|
||||
|
||||
class RoundModifierCompiler extends Base {
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: str_repeat
|
||||
* Purpose: returns string repeated times times
|
||||
*
|
||||
* @link https://www.smarty.net/docs/en/language.modifier.str_repeat.tpl str_repeat (Smarty online manual)
|
||||
*/
|
||||
|
||||
class StrRepeatModifierCompiler extends Base {
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: string_format
|
||||
* Purpose: format strings via sprintf
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.string.format.php string_format (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Example: {$var|strip} {$var|strip:" "}
|
||||
* Date: September 25th, 2002
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.strip.php strip (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: strip_tags
|
||||
* Purpose: strip html tags from text
|
||||
*
|
||||
* @link https://www.smarty.net/docs/en/language.modifier.strip.tags.tpl strip_tags (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: strlen
|
||||
* Purpose: return the length of the given string
|
||||
*
|
||||
* @link https://www.smarty.net/docs/en/language.modifier.strlen.tpl strlen (Smarty online manual)
|
||||
*/
|
||||
|
||||
class StrlenModifierCompiler extends Base {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Smarty\Compile\Modifier;
|
||||
|
||||
/**
|
||||
* Smarty substr modifier plugin
|
||||
*/
|
||||
class SubstrModifierCompiler extends Base {
|
||||
|
||||
public function compile($params, \Smarty\Compiler\Template $compiler) {
|
||||
return 'substr((string) ' . $params[0] . ', (int) ' . $params[1] .
|
||||
(isset($params[2]) ? ', (int) ' . $params[2] : '') . ')';
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: lower
|
||||
* Purpose: convert string to uppercase
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.upper.php lower (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@ namespace Smarty\Compile\Modifier;
|
||||
* Name: wordwrap
|
||||
* Purpose: wrap a string of text at a given length
|
||||
*
|
||||
* @link https://www.smarty.net/manual/en/language.modifier.wordwrap.php wordwrap (Smarty online manual)
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
|
||||
|
||||
@@ -33,9 +33,8 @@ class ModifierCompiler extends Base {
|
||||
* @throws \Smarty\CompilerException
|
||||
* @throws \Smarty\Exception
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
|
||||
$compiler->has_code = true;
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null): string
|
||||
{
|
||||
|
||||
$output = $parameter['value'];
|
||||
|
||||
@@ -43,16 +42,19 @@ class ModifierCompiler extends Base {
|
||||
foreach ($parameter['modifierlist'] as $single_modifier) {
|
||||
/* @var string $modifier */
|
||||
$modifier = $single_modifier[0];
|
||||
$single_modifier[0] = $output;
|
||||
$params = implode(',', $single_modifier);
|
||||
|
||||
|
||||
$modifier_params = array_values($single_modifier);
|
||||
|
||||
$modifier_params[0] = $output;
|
||||
$params = implode(',', $modifier_params);
|
||||
|
||||
if (!is_object($compiler->getSmarty()->security_policy)
|
||||
|| $compiler->getSmarty()->security_policy->isTrustedModifier($modifier, $compiler)
|
||||
) {
|
||||
|
||||
if ($handler = $compiler->getModifierCompiler($modifier)) {
|
||||
$output = $handler->compile($single_modifier, $compiler);
|
||||
|
||||
$output = $handler->compile($modifier_params, $compiler);
|
||||
} elseif ($compiler->getSmarty()->getModifierCallback($modifier)) {
|
||||
$output = sprintf(
|
||||
'$_smarty_tpl->getSmarty()->getModifierCallback(%s)(%s)',
|
||||
@@ -60,7 +62,7 @@ class ModifierCompiler extends Base {
|
||||
$params
|
||||
);
|
||||
} elseif ($callback = $compiler->getPluginFromDefaultHandler($modifier, \Smarty\Smarty::PLUGIN_MODIFIERCOMPILER)) {
|
||||
$output = (new \Smarty\Compile\Modifier\BCPluginWrapper($callback))->compile($single_modifier, $compiler);
|
||||
$output = (new \Smarty\Compile\Modifier\BCPluginWrapper($callback))->compile($modifier_params, $compiler);
|
||||
} elseif ($function = $compiler->getPluginFromDefaultHandler($modifier, \Smarty\Smarty::PLUGIN_MODIFIER)) {
|
||||
if (!is_array($function)) {
|
||||
$output = "{$function}({$params})";
|
||||
@@ -73,7 +75,7 @@ class ModifierCompiler extends Base {
|
||||
}
|
||||
}
|
||||
}
|
||||
return $output;
|
||||
return (string)$output;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,7 +39,8 @@ class ObjectMethodCallCompiler extends Base {
|
||||
* @throws \Smarty\CompilerException
|
||||
* @throws \Smarty\Exception
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null): string
|
||||
{
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
unset($_attr['nocache']);
|
||||
|
||||
@@ -47,9 +47,8 @@ class PrintExpressionCompiler extends Base {
|
||||
* @return string
|
||||
* @throws \Smarty\Exception
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
|
||||
$compiler->has_code = true;
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null): string
|
||||
{
|
||||
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
@@ -83,12 +82,13 @@ class PrintExpressionCompiler extends Base {
|
||||
$output = $compiler->compileModifier($modifierlist, $output);
|
||||
}
|
||||
|
||||
if ($compiler->getTemplate()->getSmarty()->escape_html) {
|
||||
$output = "htmlspecialchars((string) {$output}, ENT_QUOTES, '" . addslashes(\Smarty\Smarty::$_CHARSET) . "')";
|
||||
if ($compiler->getTemplate()->getSmarty()->escape_html && !$compiler->isRawOutput()) {
|
||||
$output = "htmlspecialchars((string) ({$output}), ENT_QUOTES, '" . addslashes(\Smarty\Smarty::$_CHARSET) . "')";
|
||||
}
|
||||
|
||||
}
|
||||
$output = "<?php echo {$output};?>\n";
|
||||
$compiler->setRawOutput(false);
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -37,9 +37,8 @@ class SpecialVariableCompiler extends Base {
|
||||
* @return string compiled code
|
||||
* @throws CompilerException
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
|
||||
$compiler->has_code = true;
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null): string
|
||||
{
|
||||
|
||||
$_index = preg_split("/\]\[/", substr($parameter, 1, strlen($parameter) - 2));
|
||||
$variable = smarty_strtolower_ascii($compiler->getId($_index[0]));
|
||||
@@ -129,5 +128,7 @@ class SpecialVariableCompiler extends Base {
|
||||
}
|
||||
return $compiled_ref;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user