Access denied for admin pages show in admin theme

What every new developer in Drupal needs to get to his head (and hears all the time in the community), is that no matter what, you should never EVER hack core. Except when your problem is one that has absolutely no other solution. In our case, using an alternate administration theme, will cause access errors to administration pages to be rendered in that theme -- and that cannot be solved otherwise.

Here's what happens -- you get to develop a wonderful, sparckly theme that makes your client do a happy dance on each page load. But you don't need all the fancyness on your back end - you only need a light-weight theme there, to save on bandwidth and page speed. Plus your editors will know that this is a restricted area, just by the look of it.

The only problem arises from the fact that Drupal decides on which theme to use based on the page path, before the access rules of the page are calculated. Hence, when you load up a page that is a valid URL, albeit without the proper permission, Drupal will serve a nice 403 (access denied) error. Naturally, you have setup a nice and friendly 403 page in your error reporting setup page, and that's where you get redirected -- however that page now is rendered in your administrative theme instead of the expected, happy-client-dance theme.

This occurs due to a hardcoded check in core, specifically in the aptly named system.module, during the modules' hook_init()

function system_init() {
  // Use the administrative theme if the user is looking at a page in the admin/* path.
  if (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit'))) {

basically, if the path starts with 'admin', use the admin theme -- no matter what happens next.  The only way to fix this ( to my knowing! ) is to edit the system.module file, so that the above lines are changed to 

function system_init() {
 // Use the administrative theme if the user is looking at a page in the admin/* path, and they have permissions to that path.
 $menu_item = menu_get_item($_GET['q']);
 if ($menu_item['access'] && (arg(0) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0) == 'node' && (arg(1) == 'add' || arg(2) == 'edit')))) {

This is based off the discussion about the issue here , with the backported patch for D6 found in the comments here

REMEMBER: Do not try any of this unless you are very sure about what you are doing. Tampering with core can lead to a number of issues, ranging from performance degradation, to unexpected behavior, to extreme hair pulling when you upgrade a few months later, completely forgetting about your changes.


Article image originally appears in this article of