Its been quite a while since I worked on Drupal 7, but I'm hitting a snag.

First please understand I only have access to the theme, I cannot create a bunch of custom modules.

Now, I want to add a page, on the URL my.domain.com/authorization, this page should only be available for administrators and I want to provide some custom markup for the "innards" of the page.

since I know that my theme's template.php can use the hook_theme hook. I declare my route and template as so :

function mytheme_theme(){
    return array(
        'authorization' => array(
            'variables' => array('var' => null),
            'template' => 'my_authorization'

so, I can add my markup easily to my_authorization.tpl.php which exists.

however when I navigate to my URL I get a Page not found.

I figured I need to add a MENU_CALLBACK to the menu for my route, I understand I can not use hook_menu from a theme but I can use hook_menu_alter, so I write this function (which also takes care of my access issue) :

function mytheme_menu_alter(&$items){
    $items['authorization'] = array(
        'type' => MENU_DEFAULT_LOCAL_TASK,
        'title' => t('Authorization'),
        'page callback' => 'page_callback',
        'access callback' => true //'mytheme_auth_access',
    return $items;

Problem here is that even if I uncomment the die and clear the cache it never hits this function! What have I done wrong?

you'll see I've added an access callback function but for testing I've just set to true (anyone can see it), you'll also see I've added it as a MENU_DEFAULT_LOCAL_TASK not a MENU_CALLBACK, again just for testing.

the page_callback function exists (returns a test string) but its never called, because the hook_menu_alter dfoesn't seem to be called from my theme.

Any assistance would be greatly received!

PS> I also read on t'internet that I need might need to implement hook_module_implements_alter which according to comments on drupal.org for a theme is implimented as hook_theme_registry_alter but I'm not sure what this is about (a single line reply comment, with no example or explanation!)

To be clear, my outcome is simply, for the theme I am working on (only), if the URL is my.domain.com/authorization, and the logged in user is an administrator, display a link on the page (to an oauth endpoint). Thats it.

Any advise please?

Edit 1

Thanks for all the responses guys, indeed I am familiar with the common case of hook_form_alter, I have in fact used it (specific and the general hook_form_alter) to disable comment previewing and fix some translation issues.

I have to admit you have confused me though @Clive when you say that "Clear all caches" does not clear all caches? I'm coming from the bad old days of Drupal 5 and I've never seem an issue of hook_alter's not being cleared or hooks in template.php not being refreshed when you "Clear all caches". Indeed inspecting the core code on menu.inc tells you when the hooks are called. I'd appriciate a link on drupal's site that explains what you mean though (there's always more to learn/understand).

Regardless, the only reason I want a custom page/route is because there is a JS API involved in the front theme (and only that theme) that requires an OAuth2 Authorisation to get an access token when the site is first placed/migrated on a server. Becasue it shows the Clients secret keys its not safe to serve it unprotected (as it is now) and it is literally only a link to the API Providers OAuth "This app requires access to X,Y,Z" page. Pretty simple really, strikes me as pretty stupid to need to create a stand alone module for this (especially if that module should only act on the custom theme, not globally).

Regardless, I shall just accept that hook_menu_alter does not work in a theme's template.php, as counter intuative as it seems (the theme is initialised, as I'm on front end pages and all my preprocess, form_alter and hook_theme functions are working).

I guess as my resolution I will take a different tack and either display the auth link under the "Sorry, this service is not available" message where the API is used, if the logged in user is an admin, or if the user is an admin add a global message with the link. I do have a "system is authorised" flag in my site variables so I can use that.

PS> I would love some links or official documentation on any of the topics @Clive or @googletorp have covered, i.e. when clearing caches doesn't clear caches, when menu_alter hooks arn't called when rebuilding the menu and when theme initialisation happens if as you say, it isn't initialised before the menu router is built?

PPS> @googletorp, what happens if I do actually google "torp"? LOL :D

  • 2
    Presumably you're clearing the cache from the admin section of the site? Unless you're using mytheme as your admin theme, the alter hook isn't going to be executed. You would need to clear the cache whilst on a page that uses your custom theme, but then obviously when the cache is cleared from a page where your custom theme isn't involved, the new route will be lost. Which should go some way to convincing you that it's a bad idea to try to add routes from the presentation layer. This code simply has to be in a module if you want the behaviour to be consistent and predictable
    – Clive
    Sep 26, 2018 at 12:41
  • 1
    @Clive The hook will never invoked in a theme (to my knowledge)
    – googletorp
    Sep 26, 2018 at 12:52
  • 1
    @googletorp It's invoked fine (all alter hooks are without exception, I just tested to be sure). Adding an item also works fine. Maintaining that item through menu rebuilds, though, is basically impossible. Or in-sensible at least
    – Clive
    Sep 26, 2018 at 12:53
  • Thanks for the comments guys, see my edit above for detail. @Clive when would the menu be rebuilt except via Clear all Caches?
    – Blatant
    Sep 26, 2018 at 15:20

1 Answer 1


I solved this as so (for info).

First a bit more background. This is basically a REST/SOAP Web Service that integrates some business info into some pages on the specific theme, part of the service is an OAuth2 layer that authenticates the server/site with the Web Service.

The Web service is not available in any other theme (indeed there are no other themes), obviously the OAuth requires exchange of secret keys and ID's so should not be exposed to the front of the site (unless the user is an authenticated admin).

My solution, firstly due to the poor coding the previous freelancer put down (he left the API and secret keys exposed, hard coded domains, no "Service Unavailable" messages, ect) I implemented a simple "Service Unavailable, please contact us or come back later" message should the web service be unavailable.

Because all this happens on specific pages of the site, I also put a block under the code that is displayed if the logged in user is an administrator.

Originally I wanted this to be a link to this supposed page that explains the Web Service is not authorized and offer the link to auth it. As this is not possible I skipped this step, shortened the explanation and present the link and explanation under the "Service is Unavailable" message, thus the admin can visit any page with the Web Service on it, see the "Unavailable" message and as an admin initialize the auth process from there.

Definitely the path of least resistance!

That solves the issue, now all that remains is for me to dig into the core for a better understanding of the way the routing table and page callbacks are built. After all, the more you know....

Finally, big thanks to everyone who took the time to stop by, read and/or comment on my query. I and SE appreciate it!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.