Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

Extending Smarty 4

 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General
View previous topic :: View next topic  
Author Message
SlowFox
Smarty Regular


Joined: 02 Oct 2006
Posts: 55

PostPosted: Sat Jan 29, 2022 10:08 pm    Post subject: Extending Smarty 4 Reply with quote

First of all: I have read that this Forum should already have been deleted - obviously it was not, and as I don't have a reddit account and find this much more convenient anyway, I'll try my luck here first.

Then: Last week I discovered that Smarty4 is out - I installed it and liked the improvements. This motivated me to dig out my old idea to call Smarty custom plugins via autoloader instead of PluginsDir. I'd like this for a couple of reasons:

    it does not pollute the root namespace and allows much easier naming conventions

    loading would use standard techniques and could easily be intercepted by clients to adopt modifiers if needed (I do and like this with all my classes)

    other OO stuff could be used, e.g. class constants, but also splitting up complex plugins into several methods (bundled within the class)


I'd think of an initialization like:

Code:

class Smarty_Project extends \Smarty {
    public function __construct() {
        parent::construct();

        $this->setPluginsNamespace('Project\SmartyPlugins');
    }
}


and plugin definition like:

Code:

namespace Project\SmartyPlugins;

class Link {

    const PARAM_LAYOUT_1 = 1;
    const PARAM_LAYOUT_2 = 2;

    public static function function($params, $smartyInternalTemplate) {
        return doTheMagic($params['url'], $params['text'], $params['layout']);
    }
    public static function block($params, $content, $smartyInternalTemplate, &$repeat) {
        return doTheMagic($params['url'], $content, $params['layout']);
    }
}


which could then be used in a template like this:

Code:

This is {link url='http://www1.example/' layout=Project\SmartyPlugins::LAYOUT_1}the link{/link}.

{link url=http://www2.example/' text=$linkText layout=Project\SmartyPlugins::LAYOUT_2}


Problem is - I made my way up to Smarty_Internal_Method_LoadPlugin::loadPlugin() (which is really not very far) and got stuck there. The internal structure of Smarty is more complex than I thought, and there seems to be hardcoding of file name conventions difficult to overcome (but I'd really like to get rid of it for this purpose, as I'd lose most advantages otherwise).

Is there anyone both capable and interested to do this together? Whether or not it is implemented in the official build is not that important for me; I have lived with self-patched versions (adding basic OO functionality) for more than a decade already.
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Fri Feb 11, 2022 9:51 am    Post subject: Reply with quote

This is mostly question of time rather than willing or capability.
I've had this idea for last decade or more. But ouch.
Back to top
View user's profile Send private message
SlowFox
Smarty Regular


Joined: 02 Oct 2006
Posts: 55

PostPosted: Sat Feb 12, 2022 11:10 pm    Post subject: Reply with quote

AnrDaemon wrote:
But ouch.

I gave it a try over the last few days and actually a proof of concept was easier than expected. The question is now: What to do with it and how to go on? The patch is not too big, I can easily maintain and apply it just for myself - but with the risk that I'll have to rewrite my custom plugins later on.

The patch is found here (note that I have no experience whatsoever with collaborative development, so this might not be the recommended way). The most invasive thing I did is the change of
Code:
public function loadPlugin($plugin_name, $check = true)
to
Code:
public function loadPlugin($plugin_prefix, $plugin_type, $plugin_name, $check = true)
This breaks backward compatibility with more sophisticated custom plugins (it did with two or three of mine), but the separation into prefix, type and plugin name was necessary to feed the autoloader with the class name (the prefix is always "smarty" or "Smarty" and should be discarded in a next step).

I did not change any of the internal plugins, but of course they could (and in my opinion should) use the autoloader as well.

Adapting my plugins was a matter of minutes, but the quality already improved a lot by using constants and establishing a class hierarchy for some modifiers.

I'd like to create interfaces for modifiers/blocks/functions (and replace
Code:
is_callable(array($class, $method))
by
Code:
is_subclass_of($class, $interface)
, but as far as I see this would require an API change for modifiers.
Back to top
View user's profile Send private message
AnrDaemon
Administrator


Joined: 03 Dec 2012
Posts: 1785

PostPosted: Tue Feb 15, 2022 6:05 pm    Post subject: Reply with quote

SlowFox wrote:
The patch is found here (note that I have no experience whatsoever with collaborative development, so this might not be the recommended way).

I wrote some quick comments, but I did not gave it a thorough review.
Perhaps create a pull request into smarty/smaty-php and let's have a more productive discussion there?

SlowFox wrote:
I did not change any of the internal plugins, but of course they could (and in my opinion should) use the autoloader as well.

AFAIK, Smarty itself does not use namespaces yet.

Quote:
I'd like to create interfaces for modifiers/blocks/functions (and replace
Code:
is_callable(array($class, $method))
by
Code:
is_subclass_of($class, $interface)
, but as far as I see this would require an API change for modifiers.

I'd suggest instanceof operator or is_a() call.
Back to top
View user's profile Send private message
SlowFox
Smarty Regular


Joined: 02 Oct 2006
Posts: 55

PostPosted: Tue Feb 15, 2022 11:28 pm    Post subject: Reply with quote

AnrDaemon wrote:
I wrote some quick comments, but I did not gave it a thorough review

No problem - I tried to consider your remarks. The singular form PluginsNamespace has been chosen to resemble PluginsDir, but I am happier with the plural anyway. Smarty::loadPlugins() has been reverted an the new loader put into a separate class, which seems also like an improvement.

Quote:
Perhaps create a pull request into smarty/smaty-php and let's have a more productive discussion there?

I think/hope I managed to do this in the proper way...

Quote:
AFAIK, Smarty itself does not use namespaces yet

No, but IMO this should be a point to consider to minimize the efforts should Smarty ever be put into a namespace.

Quote:
I'd like to create interfaces for modifiers/blocks/functions (and replace
Code:
is_callable(array($class, $method))
by
Code:
is_subclass_of($class, $interface)
, but as far as I see this would require an API change for modifiers.

Quote:
I'd suggest instanceof operator or is_a() call.

is_callable() checks for method existance, which seems to be an advantage over is_a() here.
Back to top
View user's profile Send private message
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> General All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP