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

xenForo variables in Javascript

Discussion in 'XenForo Development Discussions' started by cclaerhout, Dec 8, 2011.

  1. cclaerhout

    cclaerhout Well-Known Member

    Is there an easy solution to get a xenForo variable in Javascript (jquery)? Let's take a simple example:
    In php to get a xenForo phrase, I do:
    Code:
    new XenForo_Phrase('toggleMe_Expand');
    If I want to get a xenForo variable I use:
    Code:
    $call->getParam('variable')
    Is there something in Javascript? Or do I have to use my php file to send those data to my Javascript ? If it's the case, do someone has a simple example to show me how to do it? I've read a lot of tutorials on Internet based on AJAX and almost each of them use a different way to do it.
     
  2. Fuhrmann

    Fuhrmann Well-Known Member

  3. cclaerhout

    cclaerhout Well-Known Member

    I've watched these videos this morning. The first was ok, the second harder, but still ok. The thirst lost me... and the fourth... well looks impressive but I need more practice ^^

    When I watched these videos, I didn't find what I was looking for. I know that if I use Javascript in xen templates, then I can access all xen variables, but from a independent js file, I was curious to know how to get those variables. If you've got time to show me an example, it would be nice of you, but take your time, there's no hurry. Thanks for your answer :)
     
  4. HeadHodge

    HeadHodge Member

    Did you ever figure this out. I'm trying to do the same thing (i.e. access php variables from my template javascript)
     
  5. cclaerhout

    cclaerhout Well-Known Member

    Yes, I figured out that my question was stupid ^^

    From a way or another you need to inject any data you need in the template (which means in the DOM) so you can get back the data in JavaScript.
    There are several way of doing it:
    • Extend the template "page_container_js_body" ; any new js element will be available then from the XenForo JavaScript objet
    • Inject some JS data using some json helper (which is done for the editor configuration) ; might be too complex to start
    • The easiest: add a "data" element do a html tag and get it back its value in JS
      HTML:
      <div id="myId" class="myClass" data-test="abc"></div>
      
      Code:
      $('#myId').data('test');
      

    This is the very basics, you will probably need to read a lot of codes and examples to get used to.
     
  6. HeadHodge

    HeadHodge Member

    Thanks for your reply.

    You might be interested in this. I just now tried it and it works!!!

    In my template:
    And then in my callback class:
     
  7. HeadHodge

    HeadHodge Member

    I don't know if anyone is interested but I just did this successfully:

    In my template:
    In my class:
    This successfully converted the php array $visitor to a javascript object. I was able to use regular javascript to iterate through the whole object (some 50+ variables) and output it to my browsers console!!!

    Javascript in template to dump variable:
    Here's a snippet of my browsers console afterwards:

    index.php?review-filter:934 user_id
    index.php?review-filter:934 username
    index.php?review-filter:934 email
    index.php?review-filter:934 gender
    index.php?review-filter:934 custom_title
    index.php?review-filter:934 language_id
     
    Last edited: Mar 12, 2015
  8. cclaerhout

    cclaerhout Well-Known Member

    @HeadHodge
    You shouldn't expose the full visitor objet in your template, It might be not a great thing for security and it's cleary not good for performance: The visitor objet can contain a lot of parameters that you don't need . By the way there's a template helper to encode with json (look at the editor template) ; you probably don't need a callback for this.
     
  9. HeadHodge

    HeadHodge Member

    Thanks for your reply.
    Had no intent of doing anything with $visitor, was just using that for testing because my little test add-on doesn't pass any params in $viewParams.

    Thanks for pointing me to the helper, I'll definitely give that a try. (y)
     
  10. HeadHodge

    HeadHodge Member

    Even though the way I did it with a xen:callback worked fine, using html <div> tags to hold json strings turned out to be simpler for me.

    1. Convert server object to json with static function: XenForo_ViewRenderer_Json::jsonEncodeForOutput($results, false);

    2. Pass string to template via params in Controller Response.

    3. In template use <div id='myData'>{$jsonData}</div> to place string in clients browser DOM

    4. In javascript parse json string: var jsObject = JSON.parse($('myData').html());
     
  11. Kintaro

    Kintaro Well-Known Member

  12. Mr. Goodie2Shoes

    Mr. Goodie2Shoes Well-Known Member

    I am guessing you know how to add the code to the PAGE_CONTAINER template...

    you can do something like:
    Code:
    <script>
      window.intercomSettings = {
        name: "{xen:jsescape $visitor.username}",
        email: "{xen:jsescape $visitor.email}",
        created_at: {$visitor.register_date},
        app_id: “XXX”
      };
    </script>
    <script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/XXX';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()</script>
    
    And maybe add a condition for only registered visitors:
    Code:
    <xen:if is="{$visitor.user_id}">
    <script>
      window.intercomSettings = {
        name: "{xen:jsescape $visitor.username}",
        email: "{xen:jsescape $visitor.email}",
        created_at: {$visitor.register_date},
        app_id: “XXX”
      };
    </script>
    <script>(function(){var w=window;var ic=w.Intercom;if(typeof ic==="function"){ic('reattach_activator');ic('update',intercomSettings);}else{var d=document;var i=function(){i.c(arguments)};i.q=[];i.c=function(args){i.q.push(args)};w.Intercom=i;function l(){var s=d.createElement('script');s.type='text/javascript';s.async=true;s.src='https://widget.intercom.io/widget/XXX';var x=d.getElementsByTagName('script')[0];x.parentNode.insertBefore(s,x);}if(w.attachEvent){w.attachEvent('onload',l);}else{w.addEventListener('load',l,false);}}})()</script>
    </xen:if>
    
     
    Kintaro likes this.
  13. Kintaro

    Kintaro Well-Known Member

    Thank you Goodies, I already done it but thant you anyway, I thought that was more difficult!

    I simply used:
    {$visitor.username}
    {$visitor.email}
    {$visitor.register_date}

    ...and it worked :D

    as you suggested I'm going to add xen:jsescape

    I'm posting the code here: XF 1.4 - Integrating Xenforo with Intercom.io
     
    Mr. Goodie2Shoes likes this.
  14. cclaerhout

    cclaerhout Well-Known Member

    For the record, an addon demo (about the topic of this thread) is available here.
     
  15. HeadHodge

    HeadHodge Member

    When I posted my objective was to create a javascript object with the data I wanted (to be used in javascript)

    So basically my approach to do that would be:

    Create a Callback file i.e. :

    Code:
    <?php
    
    class CustomPages_InsertHtml
    {
    /******************************
    ** Callback to Render HTML  **
    ******************************/
    public static function insertVisitorInfo()
    {
    $visitor = XenForo_Visitor::getInstance();
    
    $array = array(userName => $visitor->username, eMail => $visitor->email, registerDate => $visitor.register_date);
    
    $json = XenForo_ViewRenderer_Json::jsonEncodeForOutput($array, false); //convert array to json string
    
    echo  '<div id="userInfo">' . $json . '</div>';
    echo '<script>';
    echo var visitorInfo = JSON.parse($('#userInfo).html);
    echo alert(visitorInfo.username + ', ' + visitorInfo.eMail + ', ' + visitorInfo.registerDate);
    echo  '</script>';
    }
    
    And put the following in your template where you want it to be inserted:

    Code:
    <xen:callback class="CustomPages_InsertHtml" method="insertVisitorInfo"></xen:callback>
    
    Note: did this from memory and didn't test it for proper syntax. :)
     
    Last edited: Jul 14, 2015
  16. HeadHodge

    HeadHodge Member

    Or you could skip using the <div> and insert the json object directly into javascript.
    Example:

    Code:
    <?php
    
    class CustomPages_InsertHtml
    {
    /******************************
    ** Callback to Render HTML  **
    ******************************/
    public static function insertVisitorInfo()
    {
    $visitor = XenForo_Visitor::getInstance();
    
    $array = array(userName => $visitor->username, eMail => $visitor->email, registerDate => $visitor.register_date);
    
    $json = XenForo_ViewRenderer_Json::jsonEncodeForOutput($array, false); //convert array to json string
    
    echo '<script>';
    echo 'var visitorInfo = ' . XenForo_ViewRenderer_Json::jsonEncodeForOutput($array, false)) . ';';
    echo 'alert(visitorInfo.username + ', ' + visitorInfo.eMail + ', ' + visitorInfo.registerDate);';
    echo  '</script>';
    }
    
    This example is probably overkill for your needs. But the reason I like this technique is that you can inject html anywhere into your template with only the use of a single <xen .... > command. It lets me focus more on what needs to be done using PHP , no matter how complicated, instead of trying to jump through a bunch of hoops with <xen> commands.
     

Share This Page