smarty-php / smarty-php/smarty

Unable to override built-in modifiers.

Open
#1,048 3 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
PHP
Stars
2.3k
Forks
709
PR merge metrics
No merged PRs in 30d

Description

Hello,

As it could be done in previous versions, with V5 we are not able to override a built-in modifier using registerPlugin function (Even with unregisterPlugin before).

For example :

//Will not work, default one in DefaultExtension->getModifierCallback() will be used instead.
$this->unregisterPlugin(Smarty::PLUGIN_MODIFIER,"date_format"); //With or without this line, same result
$this->registerPlugin(Smarty::PLUGIN_MODIFIER,"date_format",[$this,"myDateFormatModifier"]); 

//Will not work, defaut one on DefaultExtension->getModifierCompiler() will be used instead (during template compilation)
$this->registerPlugin(Smarty::PLUGIN_MODIFIER,"json_encode",[$this,"myJsonEncode"]); 

//Will not work, default one will be used instead (and triggers an error directly with a message to use "join" instead, changing params orders)
$this->registerPlugin(Smarty::PLUGIN_MODIFIER,"implode",[$this,"myImplodeModifier"]); 

...

//Will work, as there is no "myownmodifer" defined in DefaultExtension.
$this->registerPlugin(Smarty::PLUGIN_MODIFIER,"myownmodifier",[$this,"myOwnModifier"]); 

By Searching in the issues, i have seen that there is a workaround, as it's suggested in #1011 (kind of describing that problem with a custom "json_encode" modifier).
Solution seems to be to create a custom Extension, implementing getModifierCompiler() and getModifierCallback() functions, and register it between Core and Defaut extensions. In that way our Custom Extension can handle modifiers before DefautExtension does it.

But it's not that easy for all cases, as it brings complexity with the different types of modifiers :
"Compiler" Ones (if i understand correctly, executed first when creating compiled templates files), and "Classic" Ones (executed after).

For example, let's say that i want to handle a modifier in MyCustomExtension->getModifierCallback() (not at compilation), if that modifier exists in DefautExtension->getModifierCompiler(), my implementation will be (silently) ignored too. That's because DefaultExtension->getModifierCompiler() will be executed way before MyCustomExtension->getModifierCallback();

So to summarize, if i understand correctly, and from what i've tested so far, for now with v5, every time i want to add/handle a modifier, i have to take care of these points :

  • If it's not handled in DefaultExtension :
    Best scenario, i can do whatever i want.
    I can use registerPlugin function.
    Or i can handle it in a "MyCustomExtension" extension.

  • If it's handled in DefaultExtension->getModifierCallback() :
    I can't use registerPlugin function (it will be silently ignored)
    I can handle it in MyCustomExtension->getModifierCallback() or ->getModifierCompiler(), as both will be executed before DefaultExtension->getModifierCallback().

  • If it's handled in DefaultExtension->getModifierCompiler() :
    I can't use registerPlugin function (it will be silently ignored)
    I can't handle it in MyCustomExtension->getModifierCallback() (it will be silently ignored too)
    I have to handle the modifier in MyCustomExtension->getModifierCompiler() (i have no other choice).

  • And in the future updates of Smarty, if DefaultExtension is changed (adding more modifiers, or moving from a type to another), then MyCustomExtension could be (silently) obsolete.

I'm not very enthousiastic with that Extension solution, it's not very intuitive or user fiendly, and seems to required to think about more cases than it appears.
It would be very very much simpler if by default, adding a modifier will take the lead over default ones defined in DefaultExtension.

As soon as we use "registerPlugin" function, don't we exepect that Smarty use the callback we just explicitly defined ?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing registerPlugin and the modifier resolution paths in DefaultExtension, especially getModifierCallback() and getModifierCompiler(), along with the workaround described in issue #1011. Trace how built-in modifiers take precedence over registered callbacks, then verify that an explicitly registered modifier overrides both callback and compiler definitions without breaking unregistered built-ins.

Written by the indexing model from the issue text.

Assessment

Tech stack
php
Domain
web-dev
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.