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

Xen:callback tag

Discussion in 'XenForo Development Discussions' started by AndyB, Oct 26, 2013.

  1. AndyB

    AndyB Well-Known Member

    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: Dec 12, 2013
    sheel, krew, lsxforo and 11 others like this.
  2. AndyB

    AndyB Well-Known Member

    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: Dec 29, 2013
    sheel, lsxforo, valdet and 4 others like this.
  3. TBDragon

    TBDragon Active Member

    wow its something interesting

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

    for example myMethod($id) ;

    and thanks
     
  4. Fuhrmann

    Fuhrmann Well-Known Member


    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: Feb 21, 2014
    lsxforo, Dadparvar, robart and 5 others like this.
  5. TBDragon

    TBDragon Active Member

    wow thats greats now i can do functions and call them in easy way ^_^ great

    thanks again
     
    Fuhrmann likes this.
  6. wmnitin

    wmnitin Member

    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. wmnitin

    wmnitin Member

    Sorted out :) First we have to create template then use template name from widget framework instead of php callback.
     
  8. devRSG

    devRSG Member

    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."
     
  9. AndyB

    AndyB Well-Known Member

    I just followed the instructions in post #2 and it worked fine.
     
  10. devRSG

    devRSG Member

    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
     
  11. loplo

    loplo Active Member

    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.
     
  12. loplo

    loplo Active Member

    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) {
    }
    }
     
  13. loplo

    loplo Active Member

    anyone?
     
  14. Myke623

    Myke623 Active Member

    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').
     
    LPH and loplo like this.
  15. loplo

    loplo Active Member

    @Myke623 thanks for your input. I'll try to adapt my code following your instructions.
     
  16. The Forum Heroes

    The Forum Heroes Well-Known Member

    Commenting to bookmark this.. Thanks Andy!
     
    AndyB likes this.
  17. Sap1ent

    Sap1ent New Member

    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! :)
     
  18. Forum

    Forum Member

    Sweet as icicles.. (y)
     
  19. robart

    robart Member


    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.
     
  20. Liam W

    Liam W Well-Known Member

    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 $paramsXenForo_Template_Abstract $template) {}
    Liam
     

Share This Page