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

How do I pass inline js vars to js in file?

#1
I'm ashamed :oops: to ask such a stupid question:
I know how to do it the classic way:
Just a simple example... (just invented it, the real thing is much more complex)
normally I would include this in <head>
HTML:
<script type="text/javascript">

var amount = '{$amount}';

</script>
<script type="text/javascript" src="my.js"></script>
and my.js having as content
Code:
function count(factor) {

var newamount = amount*factor;

return newamount;

}
if I want to do it the xenforo way i would :
have:

<xen:require js="my.js" />
this moves the js file call to head..
but how do i get the:
<script type="text/javascript">
var amount = '{$amount}';
</script>
into head?????? I looked for a container or something...
 

Mike

XenForo developer
Staff member
#2
You don't have to use the XF way. Actually, with your approach, order is quite important. The XF approach is really designed around using selectors to initialize objects that involve certain HTML elements. The XF JS files basically don't run any code when they're called and don't access the global scope.

To reapproach your existing code to that probably isn't worthwhile.

That said, with the particular code you referenced, as I understand closure scope, you could define (and edit) the var amount after count() is defined. In that case, you could use this in your template:
Code:
<xen:container var="$head.myJs"><script type="text/javascript">
var amount = '{$amount}';
</script></xen:container>
I haven't tested this though. :)
 
#3
Thx for the reply mike.
Good and bad news.. just tested.
First the good news..
It works.. the inline javascript is in head... hurray!!

but its under the my.js file..
didnt find a way to place it above...

but.. to make it work.. (as jquery is loaded on every page) i just changed the code in the file and embedded it in:
Code:
$(function () {

});
a little tweaking and it works perfectly.
 

Jaxel

Well-known member
#4
Do you really want inline javascript in the head?

I've always been told by Firebug's YSlow features that inline javascript should always be in the footer of a page...
 
#5
Well, this is not real javascript (i mean it does nothing except populating js vars with php vars)
I need these vars in js file
this is the actual code:
Code:
<xen:container var="$head.qgJs"><script type="text/javascript">
var bigimg ='{xen:link 'imgserver/2', $image}',
smallimg ='{xen:link 'imgserver/1', $image}',
bigImgHeight = '{$image.bigheight}',
bigImgWidth = '{$image.bigwidth}',
medImgHeight = '{$image.mediumheight}',
medImgWidth = '{$image.mediumwidth}',
sizeFactor = (medImgWidth>medImgHeight)? (medImgWidth/medImgHeight) : (medImgHeight/medImgWidth),
qgImgTitle = '{xen:jsescape {$image.title}}';
</script></xen:container>
<xen:require js="js/qg/qgImgLoader.js" />
Now yes, it could be in footer, it would be better, but do you know a way to put it there without editing the template manually?
Luc
 
#9
Woo, the template hook is there. Hook name is page_container_js_body.
seen it,but how do you use it?
I tried
Code:
<xen:hook name="page_container_js_body">
<script type="text/javascript">
var bigimg ='{xen:link 'imgserver/2', $image}',
smallimg ='{xen:link 'imgserver/1', $image}',
bigImgHeight = '{$image.bigheight}',
bigImgWidth = '{$image.bigwidth}',
medImgHeight = '{$image.mediumheight}',
medImgWidth = '{$image.mediumwidth}',
sizeFactor = (medImgWidth>medImgHeight)? (medImgWidth/medImgHeight) : (medImgHeight/medImgWidth),
qgImgTitle = '{xen:jsescape {$image.title}}';
</script>
</xen:hook>
but it only adds it where i put it...
not at the bottom...
any idea?
 

Indigo

Active member
#10
You would need to create a code event listener for the template_hook code event. Your callback would look something like:
PHP:
class TestApp_Listeners
{
    static public function templateHook($name, &$contents, array $params,
        XenForo_Template_Abstract $template)
    {
        if ( $name == 'page_container_js_body' ) {
            $contents .= <<<JS
            your code here
JS;
        }
    }
}
From the documentation for the event:

Called whenever a template hook is encountered (via <xen:hook> tags). You may use this event to modify the final output of that portion of the template. A template hook may pass a block of final template output with it; you may either adjust this text (such as with regular expressions) or add additional output before or after the contents. Some blocks will not pass contents with them; they are primarily designed to allow you to add additional components in those positions.

Arguments:

  • string $name - the name of the template hook being called
  • string &$contents - the contents of the template hook block. This content will be the final rendered output of the block. You should manipulate this, such as by adding additional output at the end.
  • array $params - explicit key-value params that have been passed to the hook, enabling content-aware decisions. These will not be all the params that are available to the template.
  • XenForo_Template_Abstract $template - the raw template object that has called this hook. You can access the template name and full, raw set of parameters via this object.
 
#11
Thank you very much... just tested and it works :)
but it makes me think... as i managed to remove 3 vars and move them to the file script,
that IN THIS SPECIAL CASE
if running the extra listenener, running the code, parsing it etc.. etc.. just to pass 5 vars, would not use more ressources than simply have the code in head..
of course if I had a big script it would be totally different.