1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Template Hooks, including another template

Discussion in 'XenForo Development Discussions' started by bambua, Dec 3, 2010.

  1. bambua

    bambua Well-Known Member

    I'm working on an update for my addon, and i'm trying to make use of the template hooks so that it doesn't require any edits by the user to get it to show up.

    I've figure out how to make the code listener work and thanks to a few of the posts on here what needs to be in the listener. What can't figure out is how to tell it to render another template, right now here is what I have:

    Code:
    class RecentStatus_Listener_TemplateHook
    {
    	public static function template_hook($name, &$contents, array $params, XenForo_Template_Abstract $template)
    	{
    		// Choose the hook you want to manipulate
    		if ($name === 'forum_list_sidebar')
    		{
    			// Change the value of $contents in any way you want
    			$contents .= "<xen:include template=\"recent_status\"></xen:include>";
    		}
    	}
    }
    
    What it does is just put that xen:include portion straight into the html, so it looks like it doesn't actually render it after it's sent to the hook function. Reading a bit deeper this is expected.

    Does anyone know a function/class I can call within XF to get a rendered version of my recent_status template?

    Thanks in advance!
     
  2. Jaxel

    Jaxel Well-Known Member

    Code:
    $contents .= $this->createTemplateObject($template, $subParams);
    $template = name of your template
    $subParams = parameters you need to send to your template.
     
    bambua likes this.
  3. bambua

    bambua Well-Known Member

    Makes sense, I gave the shot and I'm getting the following:

    Fatal error: Using $this when not in object context in /path/to/file/community/library/RecentStatus/Listener/TemplateHook.php on line 17

    Here's the updated code:
    Code:
    
    class RecentStatus_Listener_TemplateHook
    {
    	public static function template_hook($name, &$contents, array $params, XenForo_Template_Abstract $template)
    	{
    		// Choose the hook you want to manipulate
    		if ($name === 'forum_list_sidebar')
    		{
    			// Change the value of $contents in any way you want
    $contents .= $this->createTemplateObject("recent_status", $params);
    		}
    	}
    }
    
     
  4. Shadab

    Shadab Well-Known Member

    $this doesn't work from inside a static function call. You'll have to either directly create a new object of class XenForo_Template_Public; or reuse the $template object to create another template of same class.

    PHP:
    $contents .= $template->create('recent_status')->render();
    Also, are you sure your template doesn't require any parameters (external variables) to work?
     
    bambua likes this.
  5. Floris

    Floris Guest

    While I understand stuff like this when I read through it, and fix stuff as I go, making it from scratch is a bit of a challenge for me. Having examples like in this thread and explanations realllly helps. :) Thanks Shadab.
     
    Shadab likes this.
  6. bambua

    bambua Well-Known Member

    That works perfectly, and yeah I do need a parameter, trying to figure out how to pass it back to it, I know we have to send it to the $template class that was sent to the hook function.

    Here's what I've got at the moment:
    Code:
    	public static function template_hook($name, &$contents, array $params, XenForo_Template_Abstract $template)
    	{
    		// Choose the hook you want to manipulate
    		if ($name === 'forum_list_sidebar')
    		{
    			// Change the value of $contents in any way you want
    			$xfRecentStatus = RecentStatus_Model_StatusList::getStatusArray();
    			$params = array(
    							array('xfRecentStatus' => $xfRecentStatus['status']),
    							array('xfRecentStatusComments' => $xfRecentStatus['comments'])
    							);
    			$renderedTemplate = new Xenforo_Template_Public('recent_status',$params);
    			$contents .= $renderedTemplate->create('recent_status')->render();
    		}
    	}
    
    This is giving me the following on page load:
    Code:
    Template Errors: recent_status
    Invalid argument supplied for foreach() in /home/ss/public_html/dev/community/library/XenForo/Template/Abstract.php(243) : eval()'d code, line 6:
    5: 	';
    6: foreach ($xfRecentStatus AS $user)
    7: {
    
    So it's definatly loading the template, it's just not getting it's params.
     
  7. Shadab

    Shadab Well-Known Member

    You have to choose one method of creating the template object.
    This should suffice:
    PHP:
    $xfRecentStatus RecentStatus_Model_StatusList::getStatusArray();
    $params = array(
        
    'xfRecentStatus'         => $xfRecentStatus['status'],
        
    'xfRecentStatusComments' => $xfRecentStatus['comments']
    );

    $contents .= $template->create('recent_status'$params)->render();
     
    bambua likes this.
  8. bambua

    bambua Well-Known Member

    Here's the final code that worked:

    Code:
    
    class RecentStatus_Listener_TemplateHook extends XenForo_ViewPublic_Base
    {
    	public static function template_hook($name, &$contents, array $params, XenForo_Template_Abstract $template)
    	{
    		// Choose the hook you want to manipulate
    		if ($name === 'forum_list_sidebar')
    		{
    			// Change the value of $contents in any way you want
    			$xfRecentStatus = RecentStatus_Model_StatusList::getStatusArray();
    			$params = array('xfRecentStatus' => $xfRecentStatus['status'],
    							'xfRecentStatusComments' => $xfRecentStatus['comments'],
    							);
    
    			$contents .= $template->create('recent_status',$params)->render();
    		}
    	}
    }
    
    Thanks a million for your help Shadab and Jaxel!
     
    Shadab likes this.
  9. Shadab

    Shadab Well-Known Member

    Btw,

    You can safely drop the extends X part from your class definition.
    It's not really required.
     
  10. bambua

    bambua Well-Known Member

    Yeah I pulled that out, now to figure out the one last mystery, it doesn't have the $visitor parameter, and I'm not sure where that gets pulled from...time to dive into the code.
     
  11. ragtek

    ragtek Guest

    Do you mean the current user?

    $visitor = XenForo_Visitor::getInstance();
     
    bambua likes this.
  12. bambua

    bambua Well-Known Member

    Yeah I had just found that in the code, thanks Rage...this has been an awesome learning experience actually :D
     
  13. Shadab

    Shadab Well-Known Member

    The visitor data can be pulled from the global template parameters.
    PHP:
    $xfRecentStatus RecentStatus_Model_StatusList::getStatusArray();
    $globalParams $template->getParams();

    $params = array(
        
    'xfRecentStatus'         => $xfRecentStatus['status'],
        
    'xfRecentStatusComments' => $xfRecentStatus['comments'],
        
    'visitor'                => $globalParams['visitor']
    );
    You can do a Zend_Debug::dump() on the entire $globalParams array to see what's available to you at that point.
     
  14. Lawrence

    Lawrence Well-Known Member

    If your custom template is relatively simple, wouldn't it be better to append the HTML directly to $contents? It will save creating another listener to pre-cache your custom template (saving a query).
     
  15. bambua

    bambua Well-Known Member

    I could just do the looping logic I'm doing in the template in the listener i'm using for the hook, not a bad idea. Then the whole thing would be sans templates ;)

    The only plus to doing it this way is really that it makes it easier for an admin to change the look and feel of it.
     

Share This Page