HackerOne users: Testing against this community violates our program's Terms of Service and will result in your bounty being denied.

Custom Smarty functions only in SmartyPlugins directory?

R_JR_J Ex-FanboyMunich Admin

I've created a Smarty function /library/vendors/SmartyPlugins/function.categoriesdiscussions_link.php and can now use it as expected. When I placed that file in a custom theme, I could not use it... :-(

Is there any way to store and access that file in my "own" folder or do I really have to clutter the core? I've searched for an answer but only found two unanswered questions:
http://vanillaforums.org/discussion/comment/152084#Comment_152084
http://vanillaforums.org/discussion/19523/how-to-add-custom-smarty-function-in-a-custom-theme

Best Answers

Answers

  • peregrineperegrine MVP
    edited June 2014

    maybe you can reset smarty to add your new dir.

    or however smarty is called. but the setPluginsDir is valid.

    // set multiple directoríes where plugins are stored
    $smarty->setPluginsDir(array(
        './plugins',
        './plugins_2',
    ));
    

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • R_JR_J Ex-Fanboy Munich Admin

    Sounds reasonable, but I do not know where to put that. I've found no "FireEvent" in class.smarty.php and don't know where to lookt at. My search on "smarty" in the core only revealed that: https://github.com/vanilla/vanilla/blob/2.1/library/core/functions.general.php#L425 and I agree ;)

  • R_JR_J Ex-Fanboy Munich Admin

    I will not be able to spent much time on a keyboard the next week, but the lines you were showing might lead to a possible solution! I'll come back and report if I'm able to inject another plugins_dir

  • peregrineperegrine MVP
    edited June 2014

    I have great faith in you R_J - you come up with great solutions.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • peregrineperegrine MVP
    edited June 2014
      public function Base_Render_Before($Sender) {
    $Smarty =Gdn_Smarty::Smarty();
    
      $Splugins = $Smarty->plugins_dir;
      $addsmarty = array('plugins2','theme');
      array_merge($Splugins,$addsmarty);
       // not sure how you put it back in the smarty Object.
       $Smarty->pluginsdir = $Splugins;
    }
    

    maybe you add a github request to add ./SmartyPlugins folders for plugins and themes.

    but it would have be done before compile I think, or re-compiled all the time.

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • R_JR_J Ex-Fanboy Munich Admin

    public function Gdn_Smarty_Init_Handler($Sender) {
    $Sender->plugin_dirs
    is what I'll look at

  • peregrineperegrine MVP
    edited June 2014

    @R_J said:
    public function Gdn_Smarty_Init_Handler($Sender) {
    $Sender->plugin_dirs
    is what I'll look at

    seems like a good idea for where to call

    I may not provide the completed solution you might desire, but I do try to provide honest suggestions to help you solve your issue.

  • R_JR_J Ex-Fanboy Munich Admin

    Thanks to your post, peregrine, I've taken a look at function CallEventHandlers and seen that this is the heart of function FireEvent so basically whenever you see that function you have a place to hook into program flow. That's great because that's the way to manipulate Smarty.

    Registering a function is way more elegant than creating a three-liner smarty function file and including that snippet, so thanks for hinting me to that, Kasper!

    But all in all I agree: Smarty sux ;)
    And I know that the next time there is any inconvenience, I'll spent the time in transforming that little default.master.tpl into a php file instead of hooking Smarty and adding missing functionality with what is basically injecting php code.

  • R_JR_J Ex-Fanboy Munich Admin

    Just in order to test things out, I've created a subfolder SmartyPlugins in my theme and added that code to the themehooks file:

    public function Gdn_Smarty_Init_Handler($Sender) {
       $Sender->plugins_dir[] = dirname(__FILE__).DS.'SmartyPlugins';
    }
    

    That way custom Smarty functions can be placed inside the theme folder

  • hgtonighthgtonight ∞ · New Moderator

    @R_J said:
    Just in order to test things out, I've created a subfolder SmartyPlugins in my theme and added that code to the themehooks file:

    public function Gdn_Smarty_Init_Handler($Sender) {
       $Sender->plugins_dir[] = dirname(__FILE__).DS.'SmartyPlugins';
    }
    


    That way custom Smarty functions can be placed inside the theme folder

    Yo, perhaps you could use Gdn_Plugin:: GetPluginFolder() method instead? Seems a little more robust.

    $Sender->plugins_dir[] = $this->GetPluginFolder();
    

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • R_JR_J Ex-Fanboy Munich Admin

    @hgtonight said:
    $Sender->plugins_dir[] = $this->GetPluginFolder();

    I'm not convinced that it would be more robust. I cannot see any danger in dirname(__FILE__) whereas a more complex framework function buries more possible errors. But usually you are right and because I couldn't see any reason why not to use your way, I've tried it out, but "it didn't work"!

    After looking closer at your solution it became obvious that I've no access to GetPluginFolder. $this is my theme hook class and that only implements Gdn_IPlugin. That brings me directly to another question:
    Would it be better to extend Gdn_Plugin instead? I know that this is the preferred way for plugins and the theme hooks file is nothing more than a plugin, as far as I've understood, but EmbedFriendly was my reference and that uses implements Gdn_IPlugin.
    To my (limited) programming understanding, implement gives me a skeleton for my class whereas extend uses an already functional class as a broad base. Thus I'd say that whether to use implement IPlugin or extend Plugin is a matter of my needs. And if I'm sure I will not need anything from Gdn_Plugin, I'm good to go with implement Gdn_IPlugin. In fact it is more resource friendly not to extend something I do not need. Correct? Or are there any other points I have to take into considerations?

  • hgtonighthgtonight ∞ · New Moderator

    @R_J said:
    After looking closer at your solution it became obvious that I've no access to GetPluginFolder. $this is my theme hook class and that only implements Gdn_IPlugin.

    GAH. Huge gaff on my part. Move along ;).

    AFAIK, theme hooks only ever implement the interface because they aren't 'real' plugins with their own folder. The only time I would implement the interface over extending the class would be if you wanted to write your own base plugin class (to extend with other custom subclasses). You would also want to make sure your base extends the Gdn_Pluggable class.

    All plugins must implement the Gdn_IPlugin interface so the PluginManager class can find and load them as needed. If you actually read the interface, it only specifies a single Setup() method.

    Hope I made everything clear as mud. ;)

    Search first

    Check out the Documentation! We are always looking for new content and pull requests.

    Click on insightful, awesome, and funny reactions to thank community volunteers for their valuable posts.

  • R_JR_J Ex-Fanboy Munich Admin

    Klar wie Kloßbrühe ;)

    I'm just happy I've done everything right :)

Sign In or Register to comment.