|
Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon. |
|
View previous topic :: View next topic |
Author |
Message |
nicci Smarty Rookie
Joined: 16 May 2016 Posts: 5
|
Posted: Mon May 16, 2016 11:45 am Post subject: Using classes instead of functions for plugins,nothing works |
|
|
I would like to use objects for plugins instead of global functions, and I'd like to more dynamically register / load them. Unfortunately Smarty makes this incredibly difficult and I seem to have run out of options. I'm hoping that I've missed something and am asking for help.
I first tried using the "register default plugin handler" but, this requires you to provide a callback that is not actually a callback. You cannot use objects in this, nor closures, only static or global functions. So that's useless to me.
Then I tried registering the plugin directly to a function on my main object, which would then dynamically map it to the right plugin object, like this;
$smarty->registerPlugin( 'block', 'form', [ $myObject, 'renderForm' ] );
The issue now is that Smarty seems to completely ignore the function name I provided in my callable (renderForm) and instead ALWAYS calls $object->render(). The way I have this set up, I require the custom function names, they cannot all be "render()".
Am I doing something wrong, or is Smarty really just ignoring the function and calling $object->render() regardless of the function name I provided? Is there really no way to do this without a) global functions, b) static functions or c) a method specifically named "render"? |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Mon May 16, 2016 12:59 pm Post subject: Re: Using classes instead of functions for plugins,nothing w |
|
|
nicci wrote: | I would like to use objects for plugins instead of global functions, and I'd like to more dynamically register / load them. | What could be any more dynamic, than "load only when they are needed" ?
And why objects? Are you a Java fanatic?
Quote: | Unfortunately Smarty makes this incredibly difficult and I seem to have run out of options. I'm hoping that I've missed something and am asking for help.
I first tried using the "register default plugin handler" but, this requires you to provide a callback that is not actually a callback. You cannot use objects in this, nor closures, only static or global functions. So that's useless to me. |
You can, or at least, I were able to do so. With minimal code patching. |
|
Back to top |
|
nicci Smarty Rookie
Joined: 16 May 2016 Posts: 5
|
Posted: Mon May 16, 2016 1:28 pm Post subject: |
|
|
I meant that I want to use objects AND dynamically load them. I know I can use global functions in subfolders and have Smarty find them for me, but it doesn't work that way with classes, you have to either manually register each one or use the default handler, as far as I can tell.
I would like to make use of class features in my plugins, and to also have them as part of my regular source tree, instead of a weird folder full of global functions on their own.
I don't think it's that strange, I suspect if Smarty was built from scratch today this is how they would design it.
What code did you patch? This doesn't seem like a very good alternative as it means I can't update Smarty without redoing my own patch. I was hoping there was some way to do this out of the box, I'm pretty surprised that there isn't. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Mon May 16, 2016 3:35 pm Post subject: |
|
|
You know, I was thinking about Smarty extensibility if it were rewritten to use classes.
If you want my opinion: It would be an unusable atrocity.
Either solitair-long constructions or ambiguous untraceable names.
There's no advantage to use classes where a simple function may suffice.
And even if classes were a thing, you would be bound by the interfaces, and random method calling will not be a thing either. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Mon May 16, 2016 3:35 pm Post subject: |
|
|
P.S.
I'm digging my patches but I have a work ongoing so it may take time. |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Mon May 16, 2016 8:34 pm Post subject: |
|
|
This is a bug.
Once a template is compiled with a registered plugin which is an object it will use that method name if you later register other object with with different method.
Currently you must delete the compiled and cached template files manually if
you register an object which has changed method name.
I will try to fix this ASAP. |
|
Back to top |
|
nicci Smarty Rookie
Joined: 16 May 2016 Posts: 5
|
Posted: Mon May 16, 2016 9:01 pm Post subject: |
|
|
AnrDaemon wrote: | There's no advantage to use classes where a simple function may suffice. |
I'm sure they would provide a base class for each plugin type for you to extend. Meaning all the mess you refer to would not be an issue for the end user. Otherwise I doubt you would need anything in the constructor beyond what you need in the function, in fact you would need less because not everything would be available when it's first constructed. Then a simple call function on the object that takes in the currently relevant information (attributes, content, current template state with stack and such).
There are definitely things you could benefit from by having classes. Say you have a suite of HTML tags, they can inherit various basic functionality. Perhaps you want to use existing functionality for a plugin but decorate the input or output. You could split the "events" up in to more than one call, like open / body / close tag. I can think of lots of reasons why it would be handy. IMO it is also cleaner. Instead of passing all those params to an object you can access them through the base class in cleaner ways. It makes it easier to track the state of this plugin during open / repeat / close stages. You can use the stack to call on your custom functions on parent tags to make interaction between nested tags easier.
This is a bit moot as, it is what it is, but I have used other template engines that use classes to add extensions and it's very handy and very clean, and fits in much better with the rest of your system.
U.Tews wrote: | This is a bug. |
Ohhhhhh! OK thank you so much, I will try that shortly!! |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Mon May 16, 2016 10:51 pm Post subject: |
|
|
I'm not talking about decoration and inheritance (note: inheritance is a bad practice in general).
I already said that interfaces should be provided, but what I'm talking about is not that.
What I'm talking about is usability.
How would you implement calling plugins from templates?
How would you implement the search and loading of them?
And please refrain from using terms "somehow", or "imagine".
Specific examples, please. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Mon May 16, 2016 11:55 pm Post subject: |
|
|
I seems to have deleted my experiments. :/
I'll try to get some patches up once [insert hope here] I throw away some of the current load. |
|
Back to top |
|
nicci Smarty Rookie
Joined: 16 May 2016 Posts: 5
|
Posted: Tue May 17, 2016 12:39 am Post subject: |
|
|
AnrDaemon wrote: | I'm not talking about decoration and inheritance (note: inheritance is a bad practice in general). |
How is inheritance a bad practice in general? It is one of the core features of object oriented programming, which most modern languages use extensively, and which PHP has worked very hard over the years to catch up with.
AnrDaemon wrote: | I already said that interfaces should be provided, but what I'm talking about is not that.
What I'm talking about is usability.
How would you implement calling plugins from templates?
How would you implement the search and loading of them?
Specific examples, please. |
I gave plenty of examples of how one might use it, off the top of my head. In practice I'm sure there are many more. If you want implementation examples, look at Twig, which seems to be quickly becoming more popular than other PHP template engines. I actually really tried to switch to Twig because the back end is a lot nicer, but I didn't like the actual template syntax so now I'm trying to do my best to use Smarty in the way I want. A lot of Twig plugins are just simple closures (something Smarty also does not support) but it provides a lot of freedom to use classes for more advanced things than just simple functions and modifiers. Calling from templates? The template syntax does not need to change. I am happy with the Smarty template syntax as-is. Search and loading? There are plenty of ways. Class loaders, config files, factories, dependency injection, etc... My plan is to use plain old convention combined with a default handler and the class finder + loader I already use. Perhaps it sounds over complicated on paper but these are systems used constantly throughout our system and they actually make things much simpler once you're used to them. Usability? Again look at Twig. You can provide simple functions via closures, but if you want to go deeper you can use classes. PHP callables are meant to allow any of these - global function calls, static function calls, object method calls and closures. Twig supports all of these but unfortunately Smarty does not. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Thu May 19, 2016 2:01 pm Post subject: |
|
|
nicci wrote: | How is inheritance a bad practice in general? It is one of the core features of object oriented programming, which most modern languages use extensively, and which PHP has worked very hard over the years to catch up with. |
You're confusing language functionality with usage practices.
You are not inheriting Smarty, nor are Smarty inheriting your project, to provide its services. You are embedding it into your project as an integrated byt still self-contained part.
Composition over inheritance.
nicci wrote: | I gave plenty of examples | I didn't see any code. May be I'm blind?
Twig is atrocious. |
|
Back to top |
|
nicci Smarty Rookie
Joined: 16 May 2016 Posts: 5
|
Posted: Thu May 19, 2016 8:13 pm Post subject: |
|
|
No thanks. I didn't come here for advice and debate, I came here to have a question answered. You can go on assuming you know everything and I'm just going to continue doing my work. Later. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Thu May 19, 2016 8:43 pm Post subject: |
|
|
I don't know everything, that's why I'm asking questions.
They help me sharpen my knowledge.
I think I've narrowed my thoughts to make them readable on paper, thanks to your topic. |
|
Back to top |
|
AnrDaemon Administrator
Joined: 03 Dec 2012 Posts: 1785
|
Posted: Fri May 20, 2016 3:39 pm Post subject: |
|
|
Found the patched autoloader.
Looking for the rest.
Code: | --- Smarty/smarty-3.1.29/libs/Autoloader.php 2015-12-21 04:57:06.000000000 +0300
+++ Smarty/smarty-current/libs/Autoloader.php 2016-02-23 06:52:13.058207400 +0300
@@ -24,21 +24,21 @@
*
* @var string
*/
- public static $SMARTY_DIR = '';
+ private static $SMARTY_DIR = '';
/**
* Filepath to Smarty internal plugins
*
* @var string
*/
- public static $SMARTY_SYSPLUGINS_DIR = '';
+ private static $SMARTY_SYSPLUGINS_DIR = '';
/**
* Array with Smarty core classes and their filename
*
* @var array
*/
- public static $rootClasses = array('smarty' => 'Smarty.class.php', 'smartybc' => 'SmartyBC.class.php',);
+ private static $rootClasses = array('smarty' => 'Smarty.class.php', 'smartybc' => 'SmartyBC.class.php',);
/**
* Registers Smarty_Autoloader backward compatible to older installations.
@@ -72,10 +72,9 @@
*/
public static function register($prepend = false)
{
- self::$SMARTY_DIR = defined('SMARTY_DIR') ? SMARTY_DIR : dirname(__FILE__) . DIRECTORY_SEPARATOR;
- self::$SMARTY_SYSPLUGINS_DIR = defined('SMARTY_SYSPLUGINS_DIR') ? SMARTY_SYSPLUGINS_DIR :
- self::$SMARTY_DIR . 'sysplugins' . DIRECTORY_SEPARATOR;
- if (version_compare(phpversion(), '5.3.0', '>=')) {
+ self::$SMARTY_DIR = dirname(__FILE__);
+ self::$SMARTY_SYSPLUGINS_DIR = self::$SMARTY_DIR . "/sysplugins";
+ if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
spl_autoload_register(array(__CLASS__, 'autoload'), true, $prepend);
} else {
spl_autoload_register(array(__CLASS__, 'autoload'));
@@ -90,35 +89,15 @@
public static function autoload($class)
{
$_class = strtolower($class);
- $file = self::$SMARTY_SYSPLUGINS_DIR . $_class . '.php';
- if (strpos($_class, 'smarty_internal_') === 0) {
- if (strpos($_class, 'smarty_internal_compile_') === 0) {
- if (is_file($file)) {
- require $file;
- }
- return;
- }
- @include $file;
- return;
- }
- if (preg_match('/^(smarty_(((template_(source|config|cache|compiled|resource_base))|((cached|compiled)?resource)|(variable|security)))|(smarty(bc)?)$)/',
- $_class, $match)) {
- if (!empty($match[3])) {
- @include $file;
- return;
- } elseif (!empty($match[9]) && isset(self::$rootClasses[$_class])) {
- $file = self::$rootClasses[$_class];
- require $file;
- return;
- }
+ if (isset(self::$rootClasses[$_class])) {
+ $file = self::$SMARTY_DIR . "/" . self::$rootClasses[$_class];
}
- if (0 !== strpos($_class, 'smarty')) {
- return;
+ elseif (strpos($_class, 'smarty_') === 0) {
+ $file = self::$SMARTY_SYSPLUGINS_DIR . "/{$_class}.php";
}
- if (is_file($file)) {
- require $file;
- return;
+
+ if (isset($file) && is_file($file)) {
+ return include_once $file;
}
- return;
}
} |
|
|
Back to top |
|
|
|
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
|
|