13 Years and 6 Months - regClientScript Still Not Working

As the title says.

I have tried it with all manager events. Only a blank line is rendered in 2.8.6-pl.

A fix is not mentioned in the change log for 2.8.7.

Can you explain in more detail what exactly you are trying to do?


regClientScript Still Not Working

Functions like regClientScript(), regClientStartupScript(), regClientStartupHTMLBlock() etc. are used in various MODX extras.
So I donā€™t think itā€™s a case of this function just ā€œnot workingā€.

I think saying that I had tried it with all manager events gives you a clue that I have tested it. I was trying to use it in a plugin. As I said, it simply outputs a blank line in the rendered markup. The path to the script is fine. I have had to use a regClientStartupHTMLBlock() to append a script tag to the end of the body tag via a piece of javascript that runs on Ext.onReady(). That works fine.

So actually, it is a case of it just ā€œnot workingā€ - as described by another forum member 13 and a half years ago.

This is an interesting quandary. I see this other thread that suggests the same, but has possibly to do with the Manager loading and order of operations causing issues: Add some JS to a manager page | MODX Community Forums?

regClientScript is predominantly used for loading on the front end. It seems that given how ExtJS bulds and loads in the Manager, @sottwell suggested the </body> may be loaded after the regClientScript attempts to inject and therefore canā€™t.

Actually I never thought of using it on the front end for anything!

Could be but it did seem to be outputting a blank line where I would have expected the script element so Iā€™m not sure.

In any case, adding the script tag via javascript using a regClientStartupHTMLBlock() function call got me the same thing, just a bit more work obviously.

1 Like

Yeah. Someone would definitely need to dig in there. Itā€™s possible that itā€™s not functioning at all somehow if itā€™s leaving a blank space. If there are no front or back end errors it will be a tough one to debug.

Itā€™s not that complicated.

The function (regClientScript()) works correctly for the front-end output of a resource.

In the manager the registered scripts (to be injected before the closing BODY tag) are just never output. I donā€™t know if that is intentional or not.

Registered scripts (to be injected inside the HEAD tag) are collected here

and assigned to a Smarty variable that is then used in the header.tpl Smarty template.

The footer.tpl Smarty template (where the closing BODY tag is located) doesnā€™t have a Smarty variable for scripts.

3 Likes

I happily stand corrected.

So, it seems that this is just missing functionality in the template that could be resolved through a minor fix?

1 Like

Yes, with adding like 5 lines of code to the registerCssJs() function of the class modManagerController and a change to footer.tpl, the registered scripts could be output in the manager as well.
If that is the intended purpose of the regClientScript() and regClientHTMLBlock() functions.

2 Likes

I think that should be done because as you pointed out earlier, it would be useful to addon authors and I didnā€™t notice anything in the docs that suggested it was only intended for front end use. Thereā€™s also the matter of consistency as regClientStartupScript() and regClientStartupHTMLBlock() do work in the manager.

That sure sounds like an oversight. Is there a bug report in Github for this?

Babel uses $this->modx->controller->addCss and $this->modx->controller->addJavascript in the code during OnDocFormPrerender for years. A lot of other extras use the same controller methods. Try to change your code to those methods.

1 Like

There is no real difference between using $modx->controller->addJavascript() and using $modx->regClientStartupScript().
(Only the exact position of the script may vary slightly.)

The actual issue here is, that the function $modx->regClientStartupScript() works in the manager and the function $modx->regClientScript() doesnā€™t. And the reason why this is the case is unknown.

I created a PR for this (for MODX 3):

1 Like

It is somehow important to use only one method to avoid duplicate inclusion of same scripts (the same filename or the same code). I donā€™t remember whether it was documented to use only one method. For me one of the methods should better be deprecated for backend usage.

Well, the problem with that position is injecting the script at that point in the document is useful for ensuring that other resources the script needs have loaded - a source order concern.

In my use case I was building a dashboard widget and the script I wanted to insert can only run when the markup is in place but also after the additional scripts that hydrate the interface of the widget have run. Also, I needed the script I am injecting at the end of the body not just on the dashboard screen but on every page of the manager as it produces an interface that renders the status of a long running task.This didnā€™t work with regClientStartup() and even if it did itā€™s much harder to reason about.

Whatever gets decided, I hope it will be reflected clearly in the docs.

After some digging into the practices for loading JS in the Manager that seem to be used, none of the examples I reviewed are putting JS into the footer. All JS is being loaded into the header in various places by one of the two methods mentioned above. The critical aspect is making sure that the Ext or MODX is in a ready state and that any dependencies are loaded before a descendant script is loaded.

Examples Iā€™ve found include in Monaco Editor, SeoSuite, and Version X. All three seem to use different implementations of one of the two methods. It does seem like the slightly more used method might be the addJavascript and addLastJavascript methods, but that could be entirely because of the people learning from the people that chose those methods.

Here are the three examples I mentioned:

One could argue that regClientScript should work as regClientStartupScript does but it appears that addLastJavascript seems to resolve that issue.

Obviously, it doesnā€™t make sense to suggest removing the regClientStartupScript from the current version, but it might not make sense to add the regClientScript and its corresponding output if thereā€™s another widely accepted method used. This is especially in light of the fact that the internal team felt that the use of the regClient methods was for the front end for Extras such as Discuss or Articles that did a lot of their own front-end theme magic.

If @markh or @jako or others have thoughts on my take on this or any other thoughts around documenting the recommended way of including persistent JS in the Manager to solve the original problem this post was seeking to solve, that would be great.

1 Like

My $0.02 is that since v2.2, the modManagerController::addJavascript and -modManagerControler::addLastJavascript (and related) methods would be preferred. Certainly when writing your own controllers, as it gives you that control over the loading order that a JS-built app requires.

However, there was a time where not every controller used those classes yet. So when trying to inject some code from a plugin you want on every manager page, you would either need to conditionally call one or the other method. Might as well choose the one that worked regardless (regClient*) because theyā€™ve been around longer then, right?

regClient* was indeed originally used for the front-end (back in evo even, I think?) but its use in the manager is not new and hasnā€™t been deprecatedā€¦ so it is inconsistent if some work but others donā€™t.

Thank you @halftrainedharry for diving in and fixing that.

3 Likes