Using phrases in javascript

RichardKYA

Well-known member
Hey people,

Is it possible to use xenforo phrases in external js files?

I've had a look at the XF core js files and I have seen them been used like this...

[core]XenForo.phrases['phrase_title'] or XenForo.phrases.phrase_title[/core]

I have tried doing this my own external file, but it doesn't appear to work, is there something else that I am missing? The phrases that I am using are custom phrases and not core phrases, not sure if that makes a difference or not, but I thought it was worth mentioning.

Also, is it possible to access xenOptions values in external js files? eg: In php, you might use XenForo_Application::getOptions() for example. Is something similar available in js?

Thank you for any input

Rich
 
If you want to access phrases you should add them to XenForo.phrases object first. To do that open page_container_js_body template, find jQuery.extend(XenForo.phrases, {...}); function and add your phrases there.

For options you need to do the same thing, but make the object yourself. Should be like:

XenForo.options = {/* your stuff here */};

To find available global variables you can use Template debugging add-on.
 
Last edited:
These kinds of things should be explicitly passed in.

For options, they can be passed in in a similar way to phrases, though usually unless they have some sort of global relevance, you should pass them into the JS using data attributes attached to one of the DOM elements your JS code deals with (such as the target object itself, ideally), e.g.

Code:
<div class="Something" data-some-option="{$xenOptions.anOption}"></div>

And in JS you can access that using:

Code:
var anOption = $('.Something').data('some-option');
 
Thank you for your responses guys, I will give these methods a go (y)

Actually, while I have you here, is there any reason why js scripts shouldn't/wouldn't work in overlays? I have a small amount of js that works completely fine when it is used in other templates, but it seems to prevent the overlay from displaying if I include it in an overlay template?
 
Is there something else I need to do to access the phrases? I've added them in the page_container_js_body template but when I try to use them they just show up as "undefined", I even tried using an existing phrase, eg:

alert(XenForo.phrases.day3);

...but that too displays as "undefined", so if XF defined phrases do not display either, I must be missing something else, do I need to add something else to my js file to get them to work?
 
It's quite possible that the way you have extended the XenForo.phrases object isn't correct. I say that, because I can alert out the same phrase as you and "Wednesday" will be returned.

Can you show an example of the code you added to extend the phrases object?
 
Yeah, I did think that, so I disabled the template mod that adds my phrases and "day3" still displayed as "undefined".

A few of my phrases are:

Code:
gap_flatpickr_jan: "{xen:jsescape {xen:phrase gap_flatpickr_jan}}",
gap_flatpickr_feb: "{xen:jsescape {xen:phrase gap_flatpickr_feb}}",
gap_flatpickr_mar: "{xen:jsescape {xen:phrase gap_flatpickr_mar}}",
gap_flatpickr_apr: "{xen:jsescape {xen:phrase gap_flatpickr_apr}}",
gap_flatpickr_may: "{xen:jsescape {xen:phrase gap_flatpickr_may}}",
gap_flatpickr_jun: "{xen:jsescape {xen:phrase gap_flatpickr_jun}}",
gap_flatpickr_jul: "{xen:jsescape {xen:phrase gap_flatpickr_jul}}",
gap_flatpickr_aug: "{xen:jsescape {xen:phrase gap_flatpickr_aug}}",
gap_flatpickr_sep: "{xen:jsescape {xen:phrase gap_flatpickr_sep}}",
gap_flatpickr_oct: "{xen:jsescape {xen:phrase gap_flatpickr_oct}}",
gap_flatpickr_nov: "{xen:jsescape {xen:phrase gap_flatpickr_nov}}",
gap_flatpickr_dec: "{xen:jsescape {xen:phrase gap_flatpickr_dec}}",

...which I add to the top of the extend via a template mod.

I even tried with the temp mod disabled and nothing else in my js file apart from:

Code:
alert(XenForo.phrases.day3);

..but it still displays as "undefined" in the alert window...

Screen Shot 2016-09-03 at 00.08.51.webp

:confused:
 
I can only ever get the correct phrase back.

The content of the page_container_js_body template should be visible if you use the element inspector in the browser or View Source:

upload_2016-9-3_0-50-56.webp

If the phrases appear in there, then you ought to be able to use them.

Also, of course, check the Console tab for any errors as this can sometimes be an indicator of issues with JS.
 
OK, I've been having a look and all the phrases appear in the inspector...

Screen Shot 2016-09-03 at 11.16.07.webp Screen Shot 2016-09-03 at 11.16.29.webp

...but they all display as "undefined" in the alert window...

Screen Shot 2016-09-03 at 11.05.41.webp

The console doesn't have any errors either and the files appear to be loaded when viewing the debugger.

I've also tried adding the js file to the forum_list to see if the alert will work there, but the phrases still return "undefined" and that's with my temp mod disabled and using the XF defined phrases, eg: day1, day2, etc.

I get the feeling I must be missing something completely, but I have zero idea on what it could be, and I just know it will be something so simple lol
 
Is that the total contents of your JS file? Just the call to the phrases object?

That's likely the problem.

That code is going to load the instant that the file is loaded - this is going to be somewhat before any of the JS framework has finished loading. Generally you would be binding your code to happen on certain events or at the very least when the document "ready" event fires.

Code:
$(function()
{
   alert(XenForo.phrases.day3);
});

If you change your code to that, you should find it works as expected.
 
Yep, that'll do it. I knew it would be something simple.

I did have it inside a doc ready function when I had it directly inside the template...

Code:
$(document).ready(function () { 
// my js
}

While the js was inside the template directly, it wasn't working inside the doc ready wrap and at first I assumed that was because of something I was getting wrong with the set up for a js datetime picker that I am using, but now, after a lot more trial and error, I think I am now starting to realise it was probably because I was trying to use {xen:phrase} assuming that it would work inside the template as per norm, but I'm testing it out right now and it doesn't work.

Anyhow, when I moved the code to an external file, I didn't think to move it back inside the doc ready (y)

But with that problem solved by moving it inside a doc ready, another issue has resurfaced, whereby an overlay that also uses this js file fails when it's triggered. Doh
 
That sounds like something breaking the JS which will likely have an error in the console.
 
The console shows "ExtLoader Failure parseerror 200" when the overlay is triggered.

Digging a bit deeper I found a reference error: x is not defined.

X is defined in another file that should be getting loaded before my file, but for some reason, my file is being loaded first and it's at this stage that I get the "ExtLoader Failure".

My file seems to be loaded first no matter what order I require the files in, but with that said, I moved the file order around in a template that is not for an overlay and it all worked as expected, it just seems to be an issue with my overlay templates.
 
I'm still having some issues with this.

I have everything working fine on desktops by doing this:

Code:
var url = XenForo.canonicalizeUrl("path/to/other/js/file.min.js");

XenForo.loadJs(url, function() {

    !function ($, window, document, _undefined) {

        months = {
            shorthand: [
                XenForo.phrases.jan,
                XenForo.phrases.feb,
                XenForo.phrases.mar,
                etc...
            ]
};

....but I've just discovered that on mobile devices, the phrases do not load once the js file has been cached.

If I clear the cache, it will work fine on the first load, but after that, it's back to the phrases being "undefined".
 
This appears to only be happening in Chrome mobile browser for some reason.

Anyone came across a similar issue before?
 
Top Bottom