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

Xen:callback tag

AndyB

Well-known member
#1
In Xenforo 1.2 a new tag called <xen:callback> was introduced. This allows calling a php file directly from a template.

Here's an example where banner.php is called.

1) First create an index.php file and put it in the /library/Example/Banner folder
PHP:
<?php

class Example_Banner_index 
{
	public static function getHtml() 
	{
		include '/home/path_to_file/www/banner.php';
		return $output;
	}
}

?>
2) Create a index.php file
PHP:
<?php
$output = 'Hello World';
?>
3) Add this to the ad_above_top_breadcrumb template
Code:
<xen:callback class="Example_Banner_index" method="getHtml"></xen:callback>
 
Last edited by a moderator:

AndyB

Well-known member
#2
This improved tutorial will show how to use the xen:callback so you can easily add PHP to your templates. The PHP code calls a simple query to get the username from the userId.

1) Create two new folders in the library folder like this:

library/Andy/Example

2) Create a file in this new directory called index.php

library/Andy/Example/index.php

3) Copy this to the contents of your index.php file

PHP:
<?php

class Andy_Example_index
{
    public static function getHtml()
    {
        // get database
        $db = XenForo_Application::get('db');
  
        // assign userId
        $userId = '1';
  
        // get username from user_id
        $userName = $db->fetchOne("
        SELECT username
        FROM xf_user
        WHERE user_id = ?
        ", $userId);
  
        // echo result
        echo $userName;
    }
}

?>
4) Add this code to the ad_above_top_breadcrumb template

Code:
<xen:callback class="Andy_Example_index" method="getHtml"></xen:callback>
In this example you should see the user name displayed in the area just below the navigation bar. You can put the template code into any template you like.
 
Last edited:

TBDragon

Active member
#3
wow its something interesting

is it possible to pass a parameter to the method i use ?

for example myMethod($id) ;

and thanks
 

Fuhrmann

Well-known member
#4
wow its something interesting

is it possible to pass a parameter to the method i use ?

for example myMethod($id) ;

and thanks

Yes, you can, just pass the parameter using the "params":

Code:
<xen:callback class="Example_Banner_Index" method="printSomethingBold" params="Hello World!"></xen:callback>
Then in the code, you can get the parameter (there is another ways):

Code:
<?php

class Example_Banner_Index
{
    public static function printSomethingBold()
    {
        $phrase = func_get_arg(1);
        return '<b>' . $phrase . '</b>';
    }
}
Also, you can pass an array using this:

Code:
params="{xen:array 'thread={$thread}'}"
 
Last edited:

TBDragon

Active member
#5
Yes, you can, just pass the parameter using the "param":

Code:
<xen:callback class="Example_Banner_Index" method="printSomethingBold" params="Hello World!"></xen:callback>
Then in the code, you can get the parameter (there is another ways):

Code:
<?php

class Example_Banner_Index
{
    public static function printSomethingBold()
    {
        $phrase = func_get_arg(1);
        return '<b>' . $phrase . '</b>';
    }
}
Also, you can pass an array using this:

Code:
params="{xen:array 'thread={$thread}'}"
wow thats greats now i can do functions and call them in easy way ^_^ great

thanks again
 
#6
Instead of adding this in template, i am tring to use it in widget framework, I put exact callback class and method but it is loading everything above header :( help
 
#7
Instead of adding this in template, i am tring to use it in widget framework, I put exact callback class and method but it is loading everything above header :( help
Sorted out :) First we have to create template then use template name from widget framework instead of php callback.
 
#8
Has anything happened to make this method no longer viable?

I'm receiving "Could not execute callback Example_Banner_index::getHtml() - Not callable." when I attempt using this code.

I've copied the example completely and I have removing the include while setting the $output to "Hello World."
 

AndyB

Well-known member
#9
Has anything happened to make this method no longer viable?

I'm receiving "Could not execute callback Example_Banner_index::getHtml() - Not callable." when I attempt using this code.

I've copied the example completely and I have removing the include while setting the $output to "Hello World."
I just followed the instructions in post #2 and it worked fine.
 
#10
Good to know it is still possible, though I have no idea why mine can't seem to find the callback.

Thanks for the reply, appreciate it.

EDIT: Found my pathing issue, thanks again
 

loplo

Active member
#11
Tried with the example and it works like charm.

When trying to add my own code, the forum gets blank :(

The file is located in /library/flyra/metar/ and it is called lrop.php

PHP:
<?php

class flyra_metar_lrop
{
    
$location = "LROP";

get_metar($location);

function get_metar($location) {
$fileName = "http://weather.noaa.gov/pub/data/observations/metar/stations/$location.TXT";
    $metar = '';
    $fileData = @file($fileName) or die('METAR not available');
    if ($fileData != false) {
        list($i, $date) = each($fileData);

        $utc = strtotime(trim($date));
        $time = date("D, F jS Y g:i A",$utc);

        while (list($i, $line) = each($fileData)) {
            $metar .= ' ' . trim($line);
            }
        $metar = trim(str_replace('  ', ' ', $metar));
        }
    echo "$metar";
    }
}

?>
Callback is this:
Code:
<xen:callback class="flyra_metar_lrop" method="getHtml"></xen:callback>
Changing the file as the above, my forum goes blank.

The actual php file looks like this:
PHP:
<?php
$location = "LROP";

get_metar($location);

function get_metar($location) {
$fileName = "http://weather.noaa.gov/pub/data/observations/metar/stations/$location.TXT";
    $metar = '';
    $fileData = @file($fileName) or die('METAR not available');
    if ($fileData != false) {
        list($i, $date) = each($fileData);

        $utc = strtotime(trim($date));
        $time = date("D, F jS Y g:i A",$utc);

        while (list($i, $line) = each($fileData)) {
            $metar .= ' ' . trim($line);
            }
        $metar = trim(str_replace('  ', ' ', $metar));
        }
    echo "$metar";
    }
?>
Any advice is highly appreciated.

PS
coding is not my strength, please bear with me.
 

loplo

Active member
#12
In admin I get the following error
Error info:
Code:
ErrorException: Fatal Error: Call to undefined function get_metar() - library/flyra/metar/lrop.php:11
Stack type:
Code:
#0 [internal function]: XenForo_Application::handleFatalError()
#1 {main}
Request state:
Code:
array(3) {
["url"] => string(24) "http://forum.fly-ra.com/"
["_GET"] => array(0) {
}
["_POST"] => array(0) {
}
}
 

Myke623

Active member
#14
The method you specified in your callback (getHtml) does not match the name of your function (get_metar).

Also, and more importantly, you shouldn't call get_metar from within the class definition itself. Your get_metar function is getting called in your xen:callback (that's the point of the tag!)

Even if coding isn't your strength, you should try to structure and style your code based on the example you're following :) Consider:

/library/Flyra/Metar/Lrop.php:
Code:
<?php

class Flyra_Metar_Lrop
{
    public static function getMetar()
    {
        // Your function code goes here
        // ...
      
        // And you should return something
        return $metar;
    }
}
Then your callback tag becomes:
Code:
<xen:callback class="Flyra_Metar_Lrop" method="getMetar"></xen:callback>
Follow the example(s) in Furhmann's reply if you want to pass arguments to your function (e.g. location of 'LROP').
 
#17
Could anyone provide me a method of pulling the following PHP into a xenforo template? (it's for an ad management system that rotates adsense code and static banners.)

PHP:
<?php /* Group_Ad_member_view_above_messages */ @readfile('http://www.mydomain.com/mysa2/api/index.php?in&g&i=2&c=1&at=p&r='.$_SERVER['REMOTE_ADDR'].'&h='.urlencode($_SERVER['HTTP_HOST']).'&rf='.urlencode($_SERVER['HTTP_REFERER']).'&ua='.urlencode($_SERVER['HTTP_USER_AGENT'])); ?>
Thanks enormously in advance! :)
 
#19
Yes, you can, just pass the parameter using the "params":

Code:
<xen:callback class="Example_Banner_Index" method="printSomethingBold" params="Hello World!"></xen:callback>
Then in the code, you can get the parameter (there is another ways):

Code:
<?php

class Example_Banner_Index
{
    public static function printSomethingBold()
    {
        $phrase = func_get_arg(1);
        return '<b>' . $phrase . '</b>';
    }
}
Also, you can pass an array using this:

Code:
params="{xen:array 'thread={$thread}'}"

Do you know if it's possible to pass in multiple parameters using {xen:array} ?

I am trying variations of:

params="{xen:array 'thread={$threadId}', 'node={nodeId}'}"

but nothing seems to be working for me.
 

Liam W

Well-known member
#20
Do you know if it's possible to pass in multiple parameters using {xen:array} ?

I am trying variations of:

params="{xen:array 'thread={$threadId}', 'node={nodeId}'}"

but nothing seems to be working for me.
That should work, although don't forget the $ for the node id.

Just of FYI, you can use a self closing tag as well:

HTML:
<xen:callback class="LiamW_Other_Template" method="renderFun" params="{xen:array 'key=value'}" />
The method has to begin with one the following:

Code:
get|is|has|render|view|return|print|show|display
The full PHP signature is:

PHP:
public static function renderFun($contents, array $params, XenForo_Template_Abstract $template) {}
Liam