View previous topic :: View next topic |
Author |
Message |
cbj4074 Smarty Regular
Joined: 10 Nov 2011 Posts: 49
|
Posted: Thu Jun 28, 2012 8:04 pm Post subject: Plug-in directories are not scanned in correct order |
|
|
According to the relevant documentation ( http://www.smarty.net/docs/en/variable.plugins.dir.tpl ):
Quote: |
... Smarty will search for your plugin in each plugin directory in the order they are given."
|
This statement is ambiguous in that it does not make clear whether Smarty will use the first match or the last.
What happens when plugins with the same name exist in multiple plugin directories?
In my particular case, the behavior is not consistent. Smarty seems to load the plugin that it finds first in some cases, and the plugin that it finds last in others.
Some may be wondering, "Why would one ever want to have two plugins with the same name in different directories?" The short answer is, "For the same reason that PHP implements method overriding in extender classes."
I have several plugins that I consider to be "universal"; that is, they are useful for nearly any project. I store these plugins in a shared code repository (in Smarty's default plugin directory).
On the other hand, I have plugins that I consider to be specific to a particular project; these plugins often extend the functionality of their universal counterparts. I store these plugins in a project-specific repository.
As such, I have done the following:
Code: |
$smarty = new Smarty();
//Project-specific plugins exist here.
$smarty->addPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');
//Universal plugins exist here.
$smarty->addPluginsDir(PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/');
|
As the above snippet demonstrates, I am defining the project-specific directory first, so that Smarty will use the project-specific plugin over its more generic counterpart (if a project-specific version exists; otherwise, Smarty will find and use the universal version).
However, the above snippet performs unpredictably, even though I always call the plugin by the same name:
Code: |
{com_domain_print_critical_error message=$criticalError}
|
Is anybody able to clarify the behavior I am observing? Is this operator error? Inadequate documentation? A use-case that was not considered?
I'm using Smarty 3.0.8.
Thanks for any help! |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Thu Jun 28, 2012 8:21 pm Post subject: |
|
|
Note that the libs/plugins folder of the distribution is setup by default and will be the first folder searched.
If you need project specific folders first you must use something like
Code: | //Project-specific plugins exist here.
$smarty->setPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');
//Universal plugins exist here.
$smarty->addPluginsDir(PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/'); |
|
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Thu Jun 28, 2012 8:25 pm Post subject: |
|
|
Code: | $smarty = new Smarty(); | executes Code: | $smarty->setPluginsDir(SMARTY_PLUGINS_DIR); | try
Code: | $smarty->setPluginsDir(array(
DOMAIN_ROOT . 'libraries-internal/smarty-plugins/',
PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/'
)); |
Also, a plugin is only loaded if it isn't yet known to the execution runtime. Including a plugin-file manually makes that plugin known to the runtime. The function exists and is - obviously - not loaded again. _________________ Twitter |
|
Back to top |
|
cbj4074 Smarty Regular
Joined: 10 Nov 2011 Posts: 49
|
Posted: Mon Jul 02, 2012 2:58 pm Post subject: |
|
|
Thank you both for the reply.
The line
Code: |
$smarty = new Smarty();
|
was there simply to demonstrate how I was instantiating Smarty. I'm not calling that line every time I want to change the plugin directories.
Both of your suggestions seem to work, which raises a final question:
Are these two blocks the same, functionally?
Code: |
$smarty->setPluginsDir(array(
DOMAIN_ROOT . 'libraries-internal/smarty-plugins/',
PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/'
));
|
Code: |
//Project-specific plugins exist here.
$smarty->setPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');
//Universal plugins exist here.
$smarty->addPluginsDir(PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/');
|
In other words, does calling setPluginsDir() with several paths within an array have the same effect as calling setPluginsDir() with the first path to be searched, and then calling addPluginsDir() for each additional path to be searched? |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Mon Jul 02, 2012 3:00 pm Post subject: |
|
|
cbj4074 wrote: | In other words, does calling setPluginsDir() with several paths within an array have the same effect as calling setPluginsDir() with the first path to be searched, and then calling addPluginsDir() for each additional path to be searched? |
yep! _________________ Twitter |
|
Back to top |
|
cbj4074 Smarty Regular
Joined: 10 Nov 2011 Posts: 49
|
Posted: Tue Jul 03, 2012 4:05 pm Post subject: |
|
|
Hmm, I thought the issue was resolved, but I'm seeing the issue again: Smarty is using the plugin from the second directory.
Here's the code (exactly as U.Tews suggested previously):
Code: |
//Project-specific plugins exist here.
$smarty->setPluginsDir(DOMAIN_ROOT . 'libraries-internal/smarty-plugins/');
//Universal plugins exist here.
$smarty->addPluginsDir(array(
PREBUILT_CLASS_PATH . 'Smarty-3.0.8/' . 'libs/plugins/',
));
|
I have two PHP pages that use the exact same application class constructor in which Smarty is initialized (see code snippet above).
If I var_dump() the Smarty object on each page, here's what I see for the "plugins_dir" property (it's the same for both pages):
Code: |
public 'plugins_dir' =>
array (size=2)
0 => string 'C:/Users/User/Documents/Apache/protected/libraries-internal/smarty-plugins/' (length=83)
1 => string 'C:/Users/User/Documents/Apache/protected/libraries-external/Smarty-3.0.8/libs/plugins/' (length=94)
|
Clearly, the project-specific plugin directory is registered first.
So, why is Smarty using the plugin from the second directory in one instance and not the other?
To be clear, Smarty (correctly) uses the plugin from the first directory on one page, but (incorrectly) uses the plugin from the second directory on another page.
Also, if I rename the plugin in the second directory temporarily, Smarty throws a fatal "Call to undefined function". So, not only does Smarty look in the wrong directory first, but it doesn't check the other directory when the plugin doesn't exist in the first directory that is examined.
Any ideas? Thanks again. |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Tue Jul 03, 2012 4:08 pm Post subject: |
|
|
a) what's the plugins name?
b) are you doing anything with the plugin besides calling it from inside a template?
c) are both applications sharing the same compiled-cache or is each instance compiling their own templates?
d) are both instances running the same smarty version?
e) do you mind upgrading to Smarty 3.1.11? _________________ Twitter |
|
Back to top |
|
U.Tews Administrator
Joined: 22 Nov 2006 Posts: 5068 Location: Hamburg / Germany
|
Posted: Tue Jul 03, 2012 4:21 pm Post subject: |
|
|
Note that Smarty saves the location of the plugins at compile time in the compiled template files. If you have changed the configuration of the plugin directories you must clear the cache and compiled template folders to make sure that the templates get recompiled with the correct setting. |
|
Back to top |
|
cbj4074 Smarty Regular
Joined: 10 Nov 2011 Posts: 49
|
Posted: Tue Jul 03, 2012 4:37 pm Post subject: |
|
|
Thanks for the exceptional support and speedy replies, guys.
U.Tews, deleting all compiled templates seems to have fixed the problem. Upon subsequent page refreshes, the correct plugin is used. Thank you for the clarification there. Operator error -- my bad!
Rodney, for academic purposes, I'm happy to answer your questions:
a) smarty_function_com_domain_print_critical_error
b) No.
c) The pages share the same $smarty->compile_dir. (And template caching is disabled altogether, for what that's worth.)
d) Yes.
e) Not at all, but given that U.Tews suggestion did the trick, it may not be necessary.
Thanks again, both of you. I'll post back if anything changes. |
|
Back to top |
|
rodneyrehm Administrator
Joined: 30 Mar 2007 Posts: 674 Location: Germany, border to Switzerland
|
Posted: Tue Jul 03, 2012 4:41 pm Post subject: |
|
|
cbj4074 wrote: | e) Not at all, but given that U.Tews suggestion did the trick, it may not be necessary. |
There have been quite some bugs fixed and performance enhancements pushed since 3.1.8 was released in February… While you don't *need* to update, you *want* to nonetheless _________________ Twitter |
|
Back to top |
|
cbj4074 Smarty Regular
Joined: 10 Nov 2011 Posts: 49
|
Posted: Wed Jul 11, 2012 7:47 pm Post subject: |
|
|
Thanks, I did go ahead and upgrade to 3.1.11. No issues.
This seems like a silly question, but how do I mark the thread "SOLVED"? |
|
Back to top |
|
|