diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c8772ed..ed6193d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added - Added support for PHP8.2 -- Added a new way to extend Smarty functionality using `Smarty::addExtension()`. Please see the docs for more information. +- Added a new way to extend Smarty functionality using `Smarty::addExtension()` or `Smarty::setExtensions()`. Please see the docs for more information. - Custom tags can accept positional parameters, so you can write a block compiler that support this: `{trans "Jack" "dull boy"}All work and no play makes %s a %s.{/trans}` [#164](https://github.com/smarty-php/smarty/issues/164) - Full support for ternary operator: `{$test ? $a : $b}` and `{$var ?: $value_if_falsy}` [#881](https://github.com/smarty-php/smarty/issues/881) - Full support for null coalescing operator: `{$var ?? $value_if_null}` [#882](https://github.com/smarty-php/smarty/issues/882) diff --git a/docs/api/extending/extensions.md b/docs/api/extending/extensions.md index 5a5c5a91..5c87d4dc 100644 --- a/docs/api/extending/extensions.md +++ b/docs/api/extending/extensions.md @@ -1,5 +1,7 @@ # Creating an extension +## Default extensions + In order to organize your custom tags and modifiers, you can create an Extension. In fact, most of Smarty itself is organized into two extensions: @@ -12,6 +14,8 @@ In fact, most of Smarty itself is organized into two extensions: > There is also the 'BCPluginsAdapter' extension, which does not add any new functionality, but > wraps calls to deprecated methods such as `Smarty\Smarty::addPluginsDir()` and `Smarty\Smarty::loadFilter()`. +## Writing your own extension + In order to write your own custom extension, you must write a class that implements `Smarty\Extension\ExtensionInterface`. However, it is usually easier to extend `Smarty\Extension\Base` which provides empty implementation for each of the methods required by `Smarty\Extension\ExtensionInterface`. This allows you to only override the method(s) you need. @@ -60,4 +64,38 @@ class MyCallablePassThroughExtension extends Base { Writing an extension allows you to add a group of tags, block tags and modifiers to the Smarty language. It also allows you to register pre-, post- and output-filters in a structured way. The files in `src/Extension/` in the `smarty/smarty` dir should give you all the information you need to start -writing your own extension. \ No newline at end of file +writing your own extension. + +## Registering an extension + +When you have written your extension, add it to a Smarty instance as follows: + +```php +addExtension(new MyCustomExtension()); +``` + +This will add `MyCustomExtension` to the end of the extension list, meaning that you cannot override tags or modifiers +from one of Smarty's default extensions. + +Should you wish to insert your extension at the top of the extension list, or create a very limited Smarty version that +only contains the core extension, you can use `Smarty\Smarty::setExtensions()` to override the list of extensions. + +```php +setExtensions([ + new Smarty\Extension\CoreExtension(), + new MyCustomExtension(), + new Smarty\Extension\DefaultExtension(), +]); +``` \ No newline at end of file diff --git a/src/Smarty.php b/src/Smarty.php index 7e3579aa..08d580bf 100644 --- a/src/Smarty.php +++ b/src/Smarty.php @@ -557,6 +557,17 @@ class Smarty extends \Smarty\TemplateBase { return $this->extensions; } + /** + * Replace the entire list extensions, allowing you to determine the exact order of the extensions. + * + * @param ExtensionInterface[] $extensions + * + * @return void + */ + public function setExtensions(array $extensions): void { + $this->extensions = $extensions; + } + /** * Check if a template resource exists * diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterModifier/RegisterModifierTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterModifier/RegisterModifierTest.php index 6d75bbc7..267448d9 100644 --- a/tests/UnitTests/SmartyMethodsTests/RegisterModifier/RegisterModifierTest.php +++ b/tests/UnitTests/SmartyMethodsTests/RegisterModifier/RegisterModifierTest.php @@ -120,6 +120,20 @@ class RegisterModifierTest extends PHPUnit_Smarty $this->assertEquals($expectedValue, $this->smarty->fetch('string:' . $template)); } + /** + * test register wildcard modifier using setExtensions + * @dataProvider dataUnknownModifiers + */ + public function testSetExtensions($template, $expectedValue) + { + $this->cleanDirs(); + $this->smarty->setExtensions([ + new \Smarty\Extension\CoreExtension(), + new WildcardExtension() + ]); + $this->assertEquals($expectedValue, $this->smarty->fetch('string:' . $template)); + } + } class WildcardExtension extends \Smarty\Extension\Base { diff --git a/tests/UnitTests/TemplateSource/NullCoalescingTest.php b/tests/UnitTests/TemplateSource/NullCoalescingTest.php index 513547b8..2432527a 100644 --- a/tests/UnitTests/TemplateSource/NullCoalescingTest.php +++ b/tests/UnitTests/TemplateSource/NullCoalescingTest.php @@ -25,7 +25,7 @@ class NullCoalescingTest extends PHPUnit_Smarty { public function dataForOther() { return [ [null, 'undefined'], - ['blah', ''], + ['blah', 'blah'], ['', ''], [false, false], ];