Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Try Vanilla Forums Cloud product

Ready to contribute?

Amazing! Sign our contributors' agreement and then join us on GitHub.

Update for critical security issue in PHPMailer included in release Vanilla 2.3.1

How to create custom Smarty functions

R_JR_J Cheerleader & TroubleshooterMunich Moderator

If you are creating your own theme, you might come to the point where you would need PHP code to achieve something that isn't possible with the existing Smarty functions in /library/vendors/SmartyPlugins/ - you will need your own custom function. Here is a way to create them as reusable files in a separate folder.

You may already have a theme hooks file for your custom theme. If not, create the file /themes/MyTheme/class.mythemethemehooks.php with that content:

<?php defined('APPLICATION') or die();

/**
 * Sample implementation of a theme hooks class to show
 * the use of custom Smarty plugins.
 */
class MyThemeThemeHooks implements Gdn_IPlugin {
    /**
     * Setup function is needed for this class, so don't delete it!
     *
     * @return bool Dummy return value.
     */
    public function setup() {
        return true;
    }

    /**
     * This function hooks the Smarty init to add our directory
     * containing our custom Smarty functions
     *
     * @param object $sender Smarty object.
     * @return void
     */
    public function gdn_smarty_init_handler($sender) {
        // add directory "/themes/MyTheme/SmartyPlugins/"
        $sender->plugins_dir[] = dirname(__FILE__).DS.'SmartyPlugins';
    }

    // whatever...
}

Now that we have told where to find our custom function, let's create one!
Do you know the plugin "Participated"? It adds a link to the menu showing all discussions that you have participated in. But what if you want to have that special link anywhere else? Yes, you'll need a custom Smarty function. Here is one possibility to create the function, save it as /themes/MyTheme/SmartyPlugins/function.participated_link.php:

<?php defined('APPLICATION') or die();

/**
 * Returns a link to "Participated Discussions" (for logged in users).
 * Accepts an associative array with following options:
 * By default the link is wrapped in an <li> element - you could specify another html here ("" will surpress any wrap).
 * "text" is the text that is displayed as the links text.
 * With "format" you could fine tune the html that is created.
 *
 * @param mixed $params Array: [wrap|text|format].
 * @param object $smarty Smarty object.
 * @return string HTML of the Participated Link or empty string.
 */
function smarty_function_participated_link($params, &$smarty) {
    // only makes sense for logged in users
    if (!Gdn::PluginManager()->CheckPlugin('Participated') || !Gdn::Session()->IsValid()) {
        return "";
    }

    // wrap link in <li> element by default
    if (array_key_exists('wrap', $params)) {
        $Wrap = $params['wrap'];
    } else {
        $Wrap = 'li';
    }

    // Sets default text for link
    if (array_key_exists('text', $params)) {
        $Text = $params['text'];
    } else {
        $Text = T('Participated Discussions');
    }

    // Specify default format for HTML link
    if (array_key_exists('format', $params)) {
        $Format = $params['format'];
    } else {
        $Format == Wrap('<a href="%url" class="%class">%text</a>', $Wrap);
    }

    // return a valid link to the plugins target from our input
    return Gdn_Theme::Link('discussions/participated', $Text, $Format);
}

(Yes, it is longer than /library/vendors/SmartyPlugins/function.discussions_link.php which does nearly the same, but my implementation is more easy to read, I think)

Now, with that function, you can do things like that in your theme (/themes/MyTheme/views/default.master.tpl):

< ul >
  {home_link}
  < li >{discussions_link wrap=""}
    < ul >
      {mydiscussions_link}
      {participated_link}
      {bookmarks_link}
      {drafts_link}
    < /ul >
  < /li >
  ...

Share your custom Smarty functions here if you are proud of your work! ;)

peregrinehgtonightBleistivtwhu606phreakjackmaessenSwennet

Comments

  • R_JR_J Cheerleader & Troubleshooter Munich Moderator

    I haven't found a way to show the users avatar alone, so I've created that function:

    <?php defined('APPLICATION') or die();
    
    /**
     * Encapsulates UserPhoto function.
     *
     * Returns the users avatar.
     * Valid params are "userid" to manually choose a user and "wrap" to
     * specify a tag that the output should be surrounded with.
     *
     * @param mixed  $params Array with function parameters.
     * @param object &$smarty Reference to Smarty template object.
     * @return string         HTML image link to user profile
     */
    function smarty_function_userphoto($params, &$smarty) {
        $UserID = (int)$params['userid'];
        if ($UserID > 0) {
            $User = Gdn::UserModel()->GetID($UserID);
        } elseif (Gdn::Session()->IsValid()) {
            $User = Gdn::Session()->User;
        } else {
            return;
        }
    
        $Wrap = $params['wrap'];
        return Wrap(UserPhoto($User), $Wrap);
    }
    
  • BleistivtBleistivt MVP
    edited September 2014

    I always add this to my mobile themes to replace the standard profile link:

    function smarty_function_profile_link_notifications($Params, &$Smarty) {
       return Gdn_Theme::Link('profile',
          val('text', $Params, ''),
         '<li><a href="%url/notifications" class="%class">%text</a><li>');
    }
    

    so the link points to the notifications, which are, in my opinion, much more important on the mobile theme as there is no notifications popup.

    Could probably be improved to only do that, when there are notifications for that user.

    My themes: pure | minusbaseline - My plugins: CSSedit | HTMLedit | InfiniteScroll | BirthdayModule | [all] - PM me about customizations

    R_Jperegrinehgtonightvrijvlinder
  • Just wanted to point out a really elegant way of adding a function, that I just discovered through @Adrian's newest plugin:

    https://github.com/adrianspeyer/VanExtend/blob/master/Plugins/JustDucky/class.justducky.plugin.php

    My themes: pure | minusbaseline - My plugins: CSSedit | HTMLedit | InfiniteScroll | BirthdayModule | [all] - PM me about customizations

    hgtonight
Sign In or Register to comment.