Template Hooks, including another template

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!
 
Code:
$contents .= $this->createTemplateObject($template, $subParams);

$template = name of your template
$subParams = parameters you need to send to your template.
 
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);
		}
	}
}
 
$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?
 
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.
 
$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?
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.
 
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();
 
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!
 
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.
 
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.
 
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).
 
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.
 
Top Bottom