Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

CMS admin not loading pages when navigating about #826

Closed
asecondwill opened this Issue Aug 13, 2013 · 13 comments

Comments

Projects
None yet
5 participants

When clicking between screens "pages", "Files", "Comments" etc the page is not loaded for some users some of the time. No JS error is raised in console. The ajax response is being returned with correct looking html and a 200 code but the view isn't being refreshed.

Iv'e checked the usual suspects whitespace in mysite code files, dev/build?flush=all to no avail.

Owner

chillu commented Aug 15, 2013

Sorry, but that's not an actionable ticket. For starters, which browser? Which CMS version? How often is "sometimes"? One out of every 100 requests? Unless you can provide some steps to reproduce, I'll need to close this ticket as I don't see how we can come to a resolution.

I had a similar (the same?) problem with SS 3.0.5. I was loading jQuery 1.7.2 from Google's CDN in the Controller of one of my pages. (1.7.2 is the same version as ships with SS 3.0.5) This works fine on the frontend, but in the admin it ends up loading jQuery twice because the admin interface already loads the local version from thirdparty/jQuery/jQuery.js. The results were a bit unpredictable; sometimes it would work, other times not.

Having spent more time than I'd like to admit tracing round the javascript in the CMS, I think this was caused by the on demand loading of additional javascript when new pages are created. If I tried to create a page and the system determined that it needed an additional javascript file it would go get it but then fail to parse it (javascript parse error). In my case it was repeatedly loading ToggleCompositeField.js, I think the parse error was caused by having the second copy of jQuery which would have been pulled in in a previous request, hence the unpredictability; the order in which I was doing things in the CMS determined whether the issues appeared or not. Note that the error isn't in ToggleCompositeField.js, it's caused by having 2 copies of jQuery because ToggleCompositeField.js contains jQuery functions.

If you want to see whether this is the case for you add a complete handler to the getScriptQueue function in jquery.ondemand.js (framework/javascript/jquery-ondemand) like this:
complete: function(jqXHR, textStatus) {
console.log('getScriptQueue' + textStatus);
},
and watch the console in Firebug or Chrome developer tools. If you get parse errors, you know you got problems.

Thinking about this, it could be caused by other general javascript problems. The current behaviour, to die silently, isn't very helpful so how about adding this to getScriptQueue in jquery.ondemand.js (framework/javascript/jquery-ondemand);
error: function(jqXHR, textStatus) {
errorMessage(textStatus);
},

That way we at least get notified that something went wrong.

Contributor

tractorcow commented Aug 28, 2013

Where are you loading the jquery library from? Why are your front-end requirements ending up in the CMS?

Owner

chillu commented Aug 28, 2013

Yeah, they should only be part of a preview iframe in the CMS, which is an isolated environment and shouldn't interact with the CMS JS. Are you loading the custom jQuery version in getCMSFields() or something? In terms of error reporting on jquery-ondemand, XHR network requests can already be tracked through web dev tools in the browser, including failed requests and the textStatus. Parsing errors would show in the JS console.

OK, I've narrowed this down to a reproducible minimal case.

I've got a Extension, PageExtension.php:
class PageExtension extends DataExtension {
}
class PageExtension_Controller extends Extension {
public function __construct() {
parent::__construct();
Requirements::javascript("http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js");
}
}

which I'm including from /mysite/_config.php:
DataObject::add_extension('Page', 'PageExtension');
DataObject::add_extension('Page_Controller', 'PageExtension_Controller');

Having considered this, I'm not sure that adding javascript requirements in the constructor is the right thing to do, but I don't know where else I can do it; AFAIK Extensions don't have an init method. I also have some block statements in there (not shown) because I'm trying to override previous javascript includes.

I take your point about the XHR requests being visible in the web dev tools but no javascript parse error is shown in Firebug or Chrome.
In IE you at least get an error:
SCRIPT438: Object doesn't support property or method 'entwine' 73, line 2 character 2
but it's not helpful because it doesn't indicate which script is at fault.

Thanks for the responses.

Contributor

tractorcow commented Aug 29, 2013

Hi @weboutreach, I have a few suggestions that might help you out:

  • The ideal thing to do is to add Requirements into the Controller::init() method. Since you are doing this in an extension, and not the main class, you should put this into the onBeforeInit() or onAfterInit(). These functions DON'T seem to be called on the Security controller all the time. you could also implement the contentcontrollerInit function in your PageExtension (which by the way should really be extending SiteTreeExtension not Extension).
  • Unless you need to use a specific jquery version, you might find less trouble to use the builtin jquery version with
Requirements::javascript(FRAMEWORK_DIR . '/thirdparty/jquery/jquery.js');

If any third party module requires jquery, then you won't end up with a double up, since they will typically use this version.

Still not sure why you're getting jquery in your CMS. Maybe the above will fix it? :P

Contributor

tractorcow commented Aug 29, 2013

I think I figured it out... your extension class is constructed every request, meaning the requirement is called every time. Bear in mind that an extension can be created even if none of the extended objects are created. They actually exist in a cache that is shared amongst all instances. (many controllers, one controller extension, etc).

Follow my instructions above and you'll be fine. :P

Sorry for the delay, been away for a few weeks.

which browser? - Chrome & safari so far.
Which CMS version? - 3.1
How often is "sometimes"? - Every time for some users. me and the designer, but never for the PM and the client.

Thanks @tractorcow, I didn't know about contentcontrollerInit, onBeforeInit() or onAfterInit() but I do now!. I can confirm that putting the Requirements::javascript call in contentcontrollerInit on a SiteTreeExtension or in either of the onBeforeInit() or onAfterInit() methods on a Controller extension works perfectly.
Apart from looking through the code is there an easy way to know which extend functions exist?

Thanks again for your help, it sounds like @asecondwill possibly has a different problem to me as he's using SS3.1

Owner

chillu commented Aug 29, 2013

Yep, long story short: Don't use Requirements in __construct().

@chillu chillu closed this Aug 29, 2013

Contributor

tractorcow commented Aug 29, 2013

@weboutreach Some classes such as SiteTreeExtension have stubs that help you figure out what extensions are available. contentcontrollerInit probably should be in there too, but isn't.... there isn't a base class for ContentControllerExtension though, but there could be if you wanted to make one. :)

Similar prob but different solution for me and this issue is coming up in searches for related terms so I thought I'd add one solution to avoid over-googling.

If you are having problems with admin screens not loading, it may be due to the size of the GridField being returned. In Chrome, I had 200 OK responses and no errors but no relevant GridField of records showing for the request. e.g I could click ModelAdmin tabs, the URL would change but the content loaded wouldn't. This was on a local dev slot as well so network wasn't the issue.

Changing the GridField page_length from 30 to 10 helped out (fixed it), which may point to a browser setting related to the maximum content length or similar.

In yr yaml :

ModelAdmin:
page_length: 10

hope that helps.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment